lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-Id: <20071219223206.ada18362.randy.dunlap@oracle.com>
Date:	Wed, 19 Dec 2007 22:32:06 -0800
From:	Randy Dunlap <randy.dunlap@...cle.com>
To:	Greg KH <greg@...ah.com>
Cc:	linux-kernel@...r.kernel.org, Kay Sievers <kay.sievers@...y.org>,
	Alan Stern <stern@...land.harvard.edu>,
	Jonathan Corbet <corbet@....net>
Subject: Re: [RFC] kobject/kset/ktype documentation and example code updated

On Wed, 19 Dec 2007 16:30:31 -0800 Greg KH wrote:

> Everything you never wanted to know about kobjects, ksets, and ktypes
> 
> Greg Kroah-Hartman <gregkh@...e.de>
> 
> Based on an original article by Jon Corbet for lwn.net written October 1,
> 2003 and located at http://lwn.net/Articles/51437/
> 
> Last updated December 19, 2007
> 
> 
...
>  - A ktype is the type of object that embeds a kobject. Every structure
>    that embeds a kobject needs a corresponding ktype.  The ktype controls
>    what happens when a kobject is no longer referenced and the kobject's
>    default representation in sysfs.

I can't quite parse the last sentence above.  Is it:

The ktype controls (a) what happens ...
and (b) the kobject's default representation in sysfs.

?

> Embedding kobjects
> 
> So, for example, the UIO code has a structure that defines the memory
> region associated with a uio device:
> 
> struct uio_mem {
> 	struct kobject kobj;
> 	unsigned long addr;
> 	unsigned long size;
> 	int memtype;
> 	void __iomem *internal_addr;
> };
> 
> If you have a struct uio_mem structure, finding its embedded kobject is
> just a matter of using the kobj structure.  Code that works with kobjects
> will often have the opposite problem, however: given a struct kobject
> pointer, what is the pointer to the containing structure?  You must avoid
> tricks (such as assuming that the kobject is at the beginning of the
> structure) and, instead, use the container_of() macro, found in
> <linux/kernel.h>:
> 
> 	container_of(pointer, type, member)
> 
> where pointer is the pointer to the embedded kobject, type is the type of
> the containing structure, and member is the name of the structure field to
> which pointer points.  The return value from container_of() is a pointer to
> the given type. So, for example, a pointer to a struct kobject embedded

This is (still) confusing to me.  Is it:
                                   a pointer "kp" to a ...
or is struct uio_mem the "kp"?

> within a struct uio_mem called "kp" could be converted to a pointer to the
> containing structure with:
> 
>     struct uio_mem *u_mem = container_of(kp, struct uio_mem, kobj);
> 
> Programmers will often define a simple macro for "back-casting" kobject

Drop the "will".

> pointers to the containing type.
> 
> 
> Initialization of kobjects
> 
> 
>     int kobject_add(struct kobject *kobj, struct kobject *parent, const char *fmt, ...);
> 
> This sets up the parent of the kobject, and the name for the kobject

Drop the comma.

> properly.  If the kobject is to be associated with a specific kset, that
> assignment must be done before calling kobject_add().  If a kset is
> associated with a kobject, then the parent for the kobject can be set to
> NULL in the call to kobject_add() and then the kobject will be placed under
> the kset itself.
> 
> As the name of the kobject is set when it is added to the kernel, the name
> of the kobject should never be manipulated directly.  If you must change
> the name of the kobject, call kobject_rename():
> 
>     int kobject_rename(struct kobject *kobj, const char *new_name);
> 
> There is a function called kobject_set_name() but that is legacy cruft and
> is being removed.  If your code needs to call this function, it is
> incorrect and needs to be fixed.

Is kobject_set_name() marked as __deprecated ?

> Uevents
> 
> After a kobject has been registered with the kobject core, it needs to be
> announced to the world that it has been created.  This can be done with
> call to kobject_uevent():

  a call ...

> 
>     int kobject_uevent(struct kobject *kobj, enum kobject_action action);
> 
> Use the KOBJ_ADD action for when the kobject is first added to the kernel.
> This should be done only after any attributes or children of the kobject
> have been initialized properly, as userspace will instantly start to look

		s/will/may/

> for them when this call happens.
> 
> When the kobject is removed from the kernel (details on how to do that is

									 are

> below), the uevent for KOBJ_REMOVE will be automatically created by the
> kobject core, so the caller does not have to worry about doing that by
> hand.
> 
> 
> Reference counts
> 
...
> 
> Because kobjects are dynamic, they must not be declared statically or on
> the stack, but instead, always allocated from the heap.  Future versions of

The kernel has heapspace?

> the kernel will contain a run-time check for kobjects that are created
> statically and will warn the developer of this improper usage.
> 
> If all that you are wanting to use a kobject for is to provide a reference

  If all that you want to use a kobject for is to provide a reference

> counter for your structure, please use the struct kref instead, a kobject
> would be overkill.  For more information on how to use struct kref, please
> see the file, Documentation/kref.txt in the Linux kernel source tree.

Drop comma.

> 
> 
> Creating "simple" kobjects
> 
> Sometimes all that a developer wants is a way to create a simple directory
> in the sysfs hierarchy, and not have to mess with the whole complication of
> ksets, show and store functions, and other details.  This is the one
> exception where a single kobject should be created.  To create such an
> entry, use the function:
> 
>     struct kobject *kobject_create_and_add(char *name, struct kobject *parent);
> 
> This function will create a kobject and place it in sysfs in the location
> underneath the specified parent kobject.  To create simple attributes
> associated with this kobject, use:
> 
>     int sysfs_create_file(struct kobject *kobj, struct attribute *attr);
> or
>     int sysfs_create_group(struct kobject *kobj, struct attribute_group *grp);
> 
> Both types of attributes used here, with a kobject that has been created
> with the kobject_create_and_add() can be of type kobj_attribute, no special
> custom attribute is needed to be created.

^ multi-run-on sentences....

> See the example module, samples/kobject/kobject-example.c for an
> implementation of a simple kobject and attributes.
> 
> 
> 
> ktypes and release methods
> 
...
> The end result is that a structure protected by a kobject cannot be freed
> before its reference count goes to zero. The reference count is not under
> the direct control of the code which created the kobject. So that code must

                                                   kobject, so that code

> be notified asynchronously whenever the last reference to one of its
> kobjects goes away.
> 
> Once you registered your kobject via kobject_add(), you must never use
> kfree() to free it directly. The only safe way is to use kobject_put(). It
> is good practice to always use kobject_put() after kobject_init() to avoid
> errors creeping in.
> 
> This notification is done through a kobject's release() method. Usually
> such a method has a form like:
> 
>     void my_object_release(struct kobject *kobj)
>     {
>     	    struct my_object *mine = container_of(kobj, struct my_object, kobj);
> 
> 	    /* Perform any additional cleanup on this object, then... */
> 	    kfree (mine);

No space after "kfree".  :)

>     }
> 
> One important point cannot be overstated: every kobject must have a
> release() method, and the kobject must persist (in a consistent state)
> until that method is called. If these constraints are not met, the code is
> flawed.  Note that the kernel will warn you if you forget to provide a
> release() method.  Do not try to get rid of this warning by providing an
> "empty" release function, you will be mocked mercilessly by the kobject

s/,/;/

> maintainer if you attempt this.
> 
...
> 
> ksets
> 
> A kset is merely a collection of kobjects that want to be associated with
> each other.  There is no restriction that they be of the same ktype, but be
> very careful if they are not.
> 
> A kset serves these functions:
> 
...
> 
> Kobject cleaning up
> 
...
> Any initialization of the kobject that has been done will be automatically
> cleaned up by the kobject core.  If a KOBJ_ADD uevent has been sent for
> the object, a corrisponding KOBJ_REMOVE uevent will be sent, and any other

                corresponding

> sysfs housekeeping will be handled for the caller properly.
> 
> In the future, the kobject_unregister() call will be going away to help
> clean up the kobject api.
> 
> 
> For a more complete example of using ksets and kobjects properly, see the
> sample/kobject/kset-example.c code.
> --

---
~Randy
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@...r.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ