kobj_attribute and followup to earlier post

Robert P. J. Day rpjday at crashcourse.ca
Thu Oct 11 08:36:03 EDT 2012


  just to add a bit more to what i posted/asked earlier regarding
sysfs attributes and show()/store() routines, here's the declaration
of the very generic kobj_attribute from kobject.h:

struct kobj_attribute {
        struct attribute attr;
        ssize_t (*show)(struct kobject *kobj, struct kobj_attribute *attr,
                        char *buf);
        ssize_t (*store)(struct kobject *kobj, struct kobj_attribute *attr,
                         const char *buf, size_t count);
};

  note first that the show/store routines for kobj_attribute *do*
include an actual kobj_attribute pointer (as the second arg), so it's
possible to define a single pair of callback routines that handles a
number of kobject attributes, given that those routines can check and
distinguish between them.  but that's not always what happens.

  note first how sysfs.h supplies a couple macros that can make
defining attributes really convenient:

#define __ATTR(_name,_mode,_show,_store) { \
        .attr = {.name = __stringify(_name), .mode = _mode },   \
        .show   = _show,                                        \
        .store  = _store,                                       \
}

#define __ATTR_RO(_name) { \
        .attr   = { .name = __stringify(_name), .mode = 0444 }, \
        .show   = _name##_show,                                 \
}

 note how (interestingly), while the general __ATTR macro still allows
you to specify the show and store routines, the __ATTR_RO macro for
defining read-only attributes *forces* the show routine to be
constructed using the name of the attribute itself, which then forces
each attribute to need its own show routine, even if a number of them
could have shared the same callback.

  this happens in, for example, mm/ksm.c:

#define KSM_ATTR_RO(_name) \
        static struct kobj_attribute _name##_attr = __ATTR_RO(_name)
#define KSM_ATTR(_name) \
        static struct kobj_attribute _name##_attr = \
                __ATTR(_name, 0644, _name##_show, _name##_store)
... snip ...
KSM_ATTR(sleep_millisecs);
KSM_ATTR(pages_to_scan);
KSM_ATTR(run);
KSM_ATTR_RO(pages_shared);
KSM_ATTR_RO(pages_sharing);
KSM_ATTR_RO(pages_unshared);
KSM_ATTR_RO(pages_volatile);
KSM_ATTR_RO(full_scans);
... snip ...


  so all of those KSM_ATTR_RO-defined attributes are forced to have
separate show() routines, which is fine.

  another example is drivers/staging/speakup/kobjects.c, which also
combines the two approaches:

/*
 * Declare the attributes.
 */
static struct kobj_attribute keymap_attribute =
        __ATTR(keymap, ROOT_W, keymap_show, keymap_store);
static struct kobj_attribute silent_attribute =
        __ATTR(silent, USER_W, NULL, silent_store);
static struct kobj_attribute synth_attribute =
        __ATTR(synth, USER_RW, synth_show, synth_store);
static struct kobj_attribute synth_direct_attribute =
        __ATTR(synth_direct, USER_W, NULL, synth_direct_store);
static struct kobj_attribute version_attribute =
        __ATTR_RO(version);

static struct kobj_attribute delimiters_attribute =
        __ATTR(delimiters, USER_RW, punc_show, punc_store);
static struct kobj_attribute ex_num_attribute =
        __ATTR(ex_num, USER_RW, punc_show, punc_store);
static struct kobj_attribute punc_all_attribute =
        __ATTR(punc_all, USER_RW, punc_show, punc_store);
static struct kobj_attribute punc_most_attribute =
        __ATTR(punc_most, USER_RW, punc_show, punc_store);
static struct kobj_attribute punc_some_attribute =
        __ATTR(punc_some, USER_RW, punc_show, punc_store);
static struct kobj_attribute repeats_attribute =
        __ATTR(repeats, USER_RW, punc_show, punc_store);
... anip ...

  here, we have some attributes defined with distinct show/store
callbacks, while others are defined to *share* a pair of routines
(punc_show, punc_store), which uses the attribute name to determine
what to do.

  finally, at the top of that very source file, we read:

 * This code is based on kobject-example.c, which came with linux 2.6.x.

well, ok, except that i don't think samples/kobject/kobject-example.c
really drives home the variations of defining sysfs attributes.

  in any event, this still brings me back to my original curiosity --
why were *some* sysfs attribute show/store callbacks defined as
accepting an attribute pointer (allowing them to multiplex among
attributes) while others weren't?  was there some rationale for this?


rday

-- 

========================================================================
Robert P. J. Day                                 Ottawa, Ontario, CANADA
                        http://crashcourse.ca

Twitter:                                       http://twitter.com/rpjday
LinkedIn:                               http://ca.linkedin.com/in/rpjday
========================================================================



More information about the Kernelnewbies mailing list