From: Daniel Stekloff <dsteklof@us.ibm.com>
To: linux-hotplug@vger.kernel.org
Subject: Re: libsysfs/udev hang
Date: Tue, 23 Mar 2004 19:19:10 +0000 [thread overview]
Message-ID: <200403231119.10323.dsteklof@us.ibm.com> (raw)
In-Reply-To: <4060259D.4000905@gmx.net>
Hi Carl-Daniel,
On Tuesday 23 March 2004 03:55 am, Carl-Daniel Hailfinger wrote:
> Hi,
>
> while writing an ataraid replacement on top of device mapper, I stumbled
> upon a freeze in sysfs_close_device which only happens if udev is NOT
> compiled with DEBUG=true.
>
> Test routine (modified udevinfo function) follows:
> static int print_device_chain(const char *path)
> {
> struct sysfs_class_device *class_dev;
> struct sysfs_class_device *class_dev_parent;
> struct sysfs_attribute *attr;
> struct sysfs_device *sysfs_dev;
> struct sysfs_device *sysfs_dev_parent;
> struct dlist *cur_attrs;
> int retval = 0;
> unsigned int vendor,device,subsystem_vendor,subsystem_device;
> unsigned long devsize;
> unsigned char *buf;
>
> /* get the class dev */
> class_dev = sysfs_open_class_device_path(path);
> if (class_dev = NULL) {
> printf("couldn't get the class device\n");
> return -1;
> }
>
> cur_attrs = sysfs_get_classdev_attributes(class_dev);
>
> /* get device size in 512 byte blocks from 'size' */
> buf = sysfs_get_value_from_attributes(cur_attrs, "size");
> devsize = strtoul(buf, NULL, 10);
>
> /* read the 'dev' file for major/minor*/
> buf = sysfs_get_value_from_attributes(cur_attrs, "dev");
> printf("device '%s' has size %lu blocks and major:minor %s\n",
> class_dev->path, devsize, buf);
>
> sysfs_close_list(cur_attrs);
>
> /* get the device link (if parent exists look here) */
> class_dev_parent = sysfs_get_classdev_parent(class_dev);
> if (class_dev_parent != NULL) {
> class_dev = class_dev_parent;
> }
First of all, you've opened a class_dev with an "open" call ->
sysfs_open_class_device_path. This should have a matching "close" call to
clean up the class device you've created. Instead, you assign the parent
reference that's returned from a "get" call to class_dev. This isn't a good
idea.
Second, you use a "get" function to retrieve a reference to the class_dev's
attributes -> sysfs_get_classdev_attributes. Then you close the list using
sysfs_close_list() rather than leaving that to the sysfs_close_classdev()
function.
Open functions in libsysfs create a device - and the memory for it - and
return you the structure. These "open" functions must be followed with a
"close" function to clean everything up.
Get functions are used on opened structures to return references to what you'd
like to see like attributes or devices. They don't need to be "closed".
> sysfs_dev = sysfs_get_classdev_device(class_dev);
> if (sysfs_dev != NULL)
> printf("follow the class device's \"device\"\n");
>
> /* look the device chain upwards */
> while (sysfs_dev != NULL) {
>
> printf("point1\n");
> /* open sysfs device directory and print all attributes */
> if (strcmp(sysfs_dev->bus, "pci") = 0) {
> cur_attrs = sysfs_get_device_attributes(sysfs_dev);
> buf = sysfs_get_value_from_attributes(cur_attrs,
> "vendor");
> vendor = (unsigned int)strtoul(buf + 2, NULL, 16);
> buf = sysfs_get_value_from_attributes(cur_attrs,
> "device");
> device = (unsigned int)strtoul(buf + 2, NULL, 16);
> buf = sysfs_get_value_from_attributes(cur_attrs,
> "subsystem_vendor");
> subsystem_vendor = (unsigned int)strtoul(buf + 2,
> NULL, 16);
> buf = sysfs_get_value_from_attributes(cur_attrs,
> "subsystem_device");
> subsystem_device = (unsigned int)strtoul(buf + 2,
> NULL, 16);
> sysfs_close_list(cur_attrs);
Here's where you close a list that you received through a "get" call. You
shouldn't call close on references you receive with "get" functions.
> printf("device '%s' has vendor %x device %x
> subvendor %x subdevice %x\n",
> class_dev->path, vendor, device,
> subsystem_vendor, subsystem_device);
> printf("point2\n");
> break;
> }
> printf("point3\n");
>
> sysfs_dev_parent = sysfs_get_device_parent(sysfs_dev);
> printf("point4\n");
> if (sysfs_dev_parent = NULL)
> break;
> printf("point5\n");
>
> sysfs_dev = sysfs_dev_parent;
> printf("point6\n");
> }
> printf("point7\n");
> sysfs_close_device(sysfs_dev);
Here's where you close a reference you received through a "get" call.
> printf("point8\n");
> exit:
> return retval;
> }
>
>
> And if I compile udev with DEBUG=true, it works perfectly. If I compile
> udev without debugging, it hangs between point7 and point8.
>
> Did I make any mistakes in the above routine which trigger the hang? I ask
> here because the libsysfs version in udev differs from libsysfs 1.0.0.
I will create a similar routine, using correct libsysfs formats, and see if I
run into a race.
Please let me know if this helps or if I can explain further.
Thanks,
Dan
> Regards,
> Carl-Daniel
-------------------------------------------------------
This SF.Net email is sponsored by: IBM Linux Tutorials
Free Linux tutorial presented by Daniel Robbins, President and CEO of
GenToo technologies. Learn everything from fundamentals to system
administration.http://ads.osdn.com/?ad_id\x1470&alloc_id638&opÌk
_______________________________________________
Linux-hotplug-devel mailing list http://linux-hotplug.sourceforge.net
Linux-hotplug-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/linux-hotplug-devel
next prev parent reply other threads:[~2004-03-23 19:19 UTC|newest]
Thread overview: 8+ messages / expand[flat|nested] mbox.gz Atom feed top
2004-03-23 11:55 libsysfs/udev hang Carl-Daniel Hailfinger
2004-03-23 15:57 ` Greg KH
2004-03-23 17:04 ` Carl-Daniel Hailfinger
2004-03-23 19:09 ` Greg KH
2004-03-23 19:19 ` Daniel Stekloff [this message]
2004-03-23 19:24 ` Daniel Stekloff
2004-03-23 20:57 ` Carl-Daniel Hailfinger
2004-03-24 1:32 ` Greg KH
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=200403231119.10323.dsteklof@us.ibm.com \
--to=dsteklof@us.ibm.com \
--cc=linux-hotplug@vger.kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).