[Bug 1215911] Re: wait-for-root fails to wait for plain /dev/sdaX partitions.
Tetsuo Handa
1215911 at bugs.launchpad.net
Fri Aug 23 12:37:53 UTC 2013
I confirmed that below patch fixes my problem.
---------- patch start ----------
--- a/src/wait-for-root.c
+++ b/src/wait-for-root.c
@@ -88,7 +88,9 @@ main (int argc,
/* When the device doesn't exist yet, or is still being processed
* by udev, use the monitor socket to wait it to be done.
*/
- while ((udev_device = udev_monitor_receive_device (udev_monitor)) != NULL) {
+ while (1) {
+ while ((udev_device = udev_monitor_receive_device (udev_monitor)) == NULL)
+ sleep (1);
if (matching_device (udev_device, devpath)) {
type = udev_device_get_property_value (udev_device, "ID_FS_TYPE");
if (type) {
---------- patch end ----------
But why need to handle udev_monitor_receive_device() errors?
I think that wait-for-root.c could be written as short as below code.
---------- simplified wait-for-root.c start ----------
#include <libudev.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <stdio.h>
#include <limits.h>
#include <signal.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
static void alarm_handler(int signum)
{
exit(1);
}
int main(int argc, char *argv[])
{
const char *devpath;
char path[PATH_MAX];
struct udev *udev;
if (argc != 3) {
fprintf(stderr, "Usage: %s DEVICE TIMEOUT\n", argv[0]);
exit(2);
}
devpath = argv[1];
if (!strncmp(devpath, "UUID=", 5))
snprintf(path, sizeof(path), "/dev/disk/by-uuid/%s", devpath + 5);
else if (!strncmp(devpath, "LABEL=", 6))
snprintf(path, sizeof(path), "/dev/disk/by-label/%s", devpath + 6);
else
snprintf(path, sizeof(path), "%s", devpath);
signal(SIGALRM, alarm_handler);
alarm(atoi(argv[2]));
udev = udev_new();
while (1) {
struct stat devstat;
const char *type;
struct udev_device *udev_device;
if (stat(path, &devstat) || !S_ISBLK(devstat.st_mode)) {
sleep(1);
continue;
}
udev_device = udev_device_new_from_devnum(udev, 'b', devstat.st_rdev);
if (!udev_device) {
sleep(1);
continue;
}
type = udev_device_get_property_value(udev_device, "ID_FS_TYPE");
if (type)
printf("%s\n", type);
udev_device_unref(udev_device);
if (type)
break;
}
udev_unref(udev);
exit(0);
}
---------- simplified wait-for-root.c end ----------
--
You received this bug notification because you are a member of Ubuntu
Foundations Bugs, which is subscribed to initramfs-tools in Ubuntu.
https://bugs.launchpad.net/bugs/1215911
Title:
wait-for-root fails to wait for plain /dev/sdaX partitions.
Status in “initramfs-tools” package in Ubuntu:
New
Bug description:
Moving the discussion from http://www.spinics.net/lists/hotplug/msg05769.html
to launchpad, for I think that this bug needs to be handled in initramfs-tools
package rather than in udev package.
----------
I'm experiencing random boot failures with wait-for-root utility in Ubuntu
12.04 ( ubuntu-12.04-server-amd64.iso ) on a HP ProLiant DL360p Gen8 server.
For example, wait-for-root waited for only 0.13 seconds before giving
up at
FSTYPE=$(wait-for-root "${ROOT}" ${ROOTDELAY:-30})
line in scripts/local in the initramfs, and immediately enters into
panic "ALERT! ${ROOT} does not exist. Dropping to a shell!"
line.
This is a race condition and manually entering "exit" from the panic prompt
boots the system normally. This is a critical bug for this environment because
it will randomly fail to perform unattended reboot (e.g. automatic reboot after
saving kdump).
----------
I examined main() in wait-for-root using debug fprintf() and it turned out that
udev_monitor_receive_device() is sometimes immediately returning NULL (although
wait-for-root is using blocking socket).
I examined udev_monitor_receive_device() in libudev.so.0 using debug fprintf()
and it turned out that recvmsg() in udev_monitor_receive_device() (which is in
libudev-monitor.c in udev package) is returning ENOBUFS error before recvmsg()
returns information of the root partition.
The wait-for-root utility in initramfs-tools package is not expecting recvmsg()
to return ENOBUFS error. But since ENOBUFS is an inevitable error, I think that
wait-for-root (i.e. the caller of udev_monitor_receive_device()) should handle
this error.
To manage notifications about this bug go to:
https://bugs.launchpad.net/ubuntu/+source/initramfs-tools/+bug/1215911/+subscriptions
More information about the foundations-bugs
mailing list