diff -aNru mountall-1.0/debian/changelog mountall-1.0.zenvoid.0/debian/changelog --- mountall-1.0/debian/changelog 2009-10-26 10:30:44.000000000 +0100 +++ mountall-1.0.zenvoid.0/debian/changelog 2009-11-22 17:46:51.000000000 +0100 @@ -1,3 +1,12 @@ +mountall (1.0.zenvoid.0) karmic; urgency=low + + * Workarounds for missing /proc/self/mountinfo. It happens when booting an + old unsupported kernel version. Sometimes those outdated kernels are + required, specially on embedded devices, unfortunatelly. + * Avoid pipe2 syscall for compatibility with kernel < 2.6.27. + + -- Roberto Gordo Saez Sun, 22 Nov 2009 17:45:04 +0100 + mountall (1.0) karmic; urgency=low [ Kees Cook ] diff -aNru mountall-1.0/src/mountall.c mountall-1.0.zenvoid.0/src/mountall.c --- mountall-1.0/src/mountall.c 2009-10-26 10:07:26.000000000 +0100 +++ mountall-1.0.zenvoid.0/src/mountall.c 2009-11-22 17:44:06.000000000 +0100 @@ -466,6 +466,15 @@ static int tmptime = -1; +/** + * old_kernel: + * + * TRUE when an old unsupported kernel version is detected. + * Activates workarounds for missing /proc/self/mountinfo. + **/ +static int old_kernel = FALSE; + + static void dequote (char *str) { @@ -915,7 +924,7 @@ mnt = find_mount (mountpoint); if (mnt - && strcmp (type, "swap")) { + && (! type || strcmp (type, "swap"))) { update_mount (mnt, device, -1, type, NULL, NULL); if (mnt->mount_opts) @@ -935,6 +944,79 @@ } static void +parse_mounts_file (FILE *mountinfo, + int reparsed) +{ + nih_local char *buf = NULL; + size_t bufsz; + + nih_assert (mountinfo != NULL); + + nih_debug ("updating mounts"); + + bufsz = 4096; + buf = NIH_MUST (nih_alloc (NULL, bufsz)); + + while (fgets (buf, bufsz, mountinfo) != NULL) { + char * saveptr; + char * ptr; + char * mountpoint; + char * type; + char * device; + char * mount_opts; + Mount *mnt; + + while ((! strchr (buf, '\n')) && (! feof (mountinfo))) { + buf = NIH_MUST (nih_realloc (buf, NULL, bufsz + 4096)); + fgets (buf + bufsz - 1, 4097, mountinfo); + bufsz += 4096; + } + + /* device */ + device = strtok_r (buf, " \t\n", &saveptr); + if (! device) + continue; + if ((! strcmp (device, "/dev/root")) + || (! strcmp (device, "none")) + || (! strcmp (device, "rootfs"))) + device = NULL; + + /* mountpoint */ + mountpoint = strtok_r (NULL, " \t\n", &saveptr); + if (! mountpoint) + continue; + + /* type */ + type = strtok_r (NULL, " \t\n", &saveptr); + if (! type) + continue; + if (! strcmp (type, "rootfs")) + type = NULL; + + /* mount opts */ + mount_opts = strtok_r (NULL, " \t\n", &saveptr); + if (! mount_opts) + continue; + + mnt = find_mount (mountpoint); + if (mnt && (! type || strcmp (type, "swap"))) { + update_mount (mnt, device, -1, type, NULL, NULL); + + if (mnt->mount_opts) + nih_unref (mnt->mount_opts, mounts); + } else { + mnt = new_mount (mountpoint, device, FALSE, type, NULL, NULL); + } + + mnt->mount_opts = NIH_MUST (nih_sprintf (mounts, "%s", mount_opts)); + if (reparsed && (! mnt->mounted)) { + mounted (mnt); + } else { + mnt->mounted = TRUE; + } + } +} +static void mountinfo_watcher (void * data, NihIoWatch *watch, NihIoEvents events) @@ -949,7 +1031,10 @@ nih_debug ("mountinfo changed, reparsing"); - parse_mountinfo_file (mountinfo, TRUE); + if (old_kernel) + parse_mounts_file (mountinfo, TRUE); + else + parse_mountinfo_file (mountinfo, TRUE); } void @@ -963,19 +1048,30 @@ mountinfo = fopen ("/proc/self/mountinfo", "r"); } if (! mountinfo) { - nih_fatal ("%s: %s", "/proc/self/mountinfo", - strerror (errno)); - delayed_exit (EXIT_MOUNT); - return; + nih_warn ("%s: %s", "/proc/self/mountinfo", + strerror (errno)); + + mountinfo = fopen ("/proc/mounts", "r"); + if (! mountinfo) { + nih_fatal ("%s: %s", "/proc/mounts", + strerror (errno)); + delayed_exit (EXIT_MOUNT); + return; + } + + nih_warn ("Activating workarounds for unsupported kernel"); + old_kernel = TRUE; } - parse_mountinfo_file (mountinfo, FALSE); + if (old_kernel) + parse_mounts_file (mountinfo, FALSE); + else + parse_mountinfo_file (mountinfo, FALSE); NIH_MUST (nih_io_add_watch (NULL, fileno (mountinfo), NIH_IO_EXCEPT, mountinfo_watcher, NULL)); } - void parse_filesystems (void) { @@ -1544,7 +1640,9 @@ nih_assert (args != NULL); nih_assert (args[0] != NULL); - NIH_ZERO (pipe2 (fds, O_CLOEXEC)); + NIH_ZERO (pipe (fds)); + fcntl(fds[0], F_SETFD, FD_CLOEXEC); + fcntl(fds[1], F_SETFD, FD_CLOEXEC); fflush (stdout); fflush (stderr); @@ -2212,7 +2310,9 @@ nih_info ("checking %s", mnt->mountpoint); /* Create a pipe to receive progress indication */ - NIH_ZERO (pipe2 (fds, O_CLOEXEC)); + NIH_ZERO (pipe (fds)); + fcntl(fds[0], F_SETFD, FD_CLOEXEC); + fcntl(fds[1], F_SETFD, FD_CLOEXEC); flags = fcntl (fds[1], F_GETFD); if ((flags < 0)