From: Richard W.M. Jones Date: Tue, 22 Mar 2011 11:15:21 +0000 (+0000) Subject: umount-all: Use /proc/mounts instead of output of 'mount' command. X-Git-Tag: 1.9.13~6 X-Git-Url: http://git.annexia.org/?a=commitdiff_plain;h=490560439061398d47873484a55fb823be29b285;p=libguestfs.git umount-all: Use /proc/mounts instead of output of 'mount' command. The particular issue is that ntfs-3g (or FUSE?) no longer appears to update /etc/mtab, which meant that umount-all was not unmounting these partitions. But parsing /proc/mounts is simpler and more robust in any case. --- diff --git a/daemon/mount.c b/daemon/mount.c index a915b44..fd0f6b2 100644 --- a/daemon/mount.c +++ b/daemon/mount.c @@ -298,50 +298,40 @@ compare_longest_first (const void *vp1, const void *vp2) int do_umount_all (void) { - char *out, *err; - int i, r; + FILE *fp; + struct mntent *m; char **mounts = NULL; int size = 0, alloc = 0; - char *p, *p2, *p3, *pend; - char matching[5 + sysroot_len]; - - r = command (&out, &err, "mount", NULL); - if (r == -1) { - reply_with_error ("mount: %s", err); - free (out); - free (err); - return -1; - } - - free (err); + char *err; + int i, r; - /* Lines have the format: - * /dev/foo on /mountpoint type ... + /* NB: Eventually we should aim to parse /proc/self/mountinfo, but + * that requires custom parsing code. */ - snprintf (matching, 5 + sysroot_len, " on %s", sysroot); + fp = setmntent ("/proc/mounts", "r"); + if (fp == NULL) { + perror ("/proc/mounts"); + exit (EXIT_FAILURE); + } - p = out; - while (p) { - pend = strchr (p, '\n'); - if (pend) { - *pend = '\0'; - pend++; + while ((m = getmntent (fp)) != NULL) { + /* Allow a mount directory like "/sysroot". */ + if (sysroot_len > 0 && STREQ (m->mnt_dir, sysroot)) { + if (add_string (&mounts, &size, &alloc, m->mnt_dir) == -1) { + endmntent (fp); + return -1; + } } - - p2 = strstr (p, matching); - if (p2 != NULL) { - p2 += 4; - p3 = p2 + strcspn (p2, " "); - *p3 = '\0'; - if (add_string (&mounts, &size, &alloc, p2) == -1) { - free (out); + /* Or allow a mount directory like "/sysroot/...". */ + if (STRPREFIX (m->mnt_dir, sysroot) && m->mnt_dir[sysroot_len] == '/') { + if (add_string (&mounts, &size, &alloc, m->mnt_dir) == -1) { + endmntent (fp); return -1; } } - - p = pend; } - free (out); + + endmntent (fp); qsort (mounts, size, sizeof (char *), compare_longest_first);