diff options
author | Richard W.M. Jones <rjones@redhat.com> | 2011-03-22 11:15:21 +0000 |
---|---|---|
committer | Richard W.M. Jones <rjones@redhat.com> | 2011-03-22 11:15:34 +0000 |
commit | 490560439061398d47873484a55fb823be29b285 (patch) | |
tree | 78dbc30c6b08562f1f0d664b4455cfc04db6cac0 /daemon | |
parent | 1541f3a564f8ff14c1a63298120e4dc618ea3274 (diff) | |
download | libguestfs-490560439061398d47873484a55fb823be29b285.tar.gz libguestfs-490560439061398d47873484a55fb823be29b285.tar.xz libguestfs-490560439061398d47873484a55fb823be29b285.zip |
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.
Notes
Notes:
Labels: bugfix
Diffstat (limited to 'daemon')
-rw-r--r-- | daemon/mount.c | 58 |
1 files changed, 24 insertions, 34 deletions
diff --git a/daemon/mount.c b/daemon/mount.c index a915b440..fd0f6b29 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); |