X-Git-Url: http://www.chiark.greenend.org.uk/ucgi/~ianmdlvl/git?p=elogind.git;a=blobdiff_plain;f=src%2Fumount.c;h=95efa8204b2e9e9cb11e2cf07666d1556251354d;hp=4fd6b22ad78620e3585985b0a3f9a19989a827b3;hb=1968a360405e302d4d2c2abc03a3314f81375156;hpb=7fc942b29e7bdb9d6aa3123f53da6680edabd8f0 diff --git a/src/umount.c b/src/umount.c index 4fd6b22ad..95efa8204 100644 --- a/src/umount.c +++ b/src/umount.c @@ -37,6 +37,7 @@ typedef struct MountPoint { char *path; dev_t devnum; + bool skip_ro; LIST_FIELDS (struct MountPoint, mount_point); } MountPoint; @@ -71,6 +72,8 @@ static int mount_points_list_get(MountPoint **head) { for (i = 1;; i++) { int k; MountPoint *m; + char *root; + bool skip_ro; path = p = NULL; @@ -78,7 +81,7 @@ static int mount_points_list_get(MountPoint **head) { "%*s " /* (1) mount id */ "%*s " /* (2) parent id */ "%*s " /* (3) major:minor */ - "%*s " /* (4) root */ + "%ms " /* (4) root */ "%ms " /* (5) mount point */ "%*s" /* (6) mount options */ "%*[^-]" /* (7) optional fields */ @@ -87,7 +90,8 @@ static int mount_points_list_get(MountPoint **head) { "%*s" /* (10) mount source */ "%*s" /* (11) mount options 2 */ "%*[^\n]", /* some rubbish at the end */ - &path)) != 1) { + &root, + &path)) != 2) { if (k == EOF) break; @@ -97,6 +101,11 @@ static int mount_points_list_get(MountPoint **head) { continue; } + /* If we encounter a bind mount, don't try to remount + * the source dir too early */ + skip_ro = !streq(root, "/"); + free(root); + p = cunescape(path); free(path); @@ -117,6 +126,7 @@ static int mount_points_list_get(MountPoint **head) { } m->path = p; + m->skip_ro = skip_ro; LIST_PREPEND(MountPoint, mount_point, *head, m); } @@ -136,7 +146,7 @@ static int swap_list_get(MountPoint **head) { assert(head); if (!(proc_swaps = fopen("/proc/swaps", "re"))) - return -errno; + return (errno == ENOENT) ? 0 : -errno; (void) fscanf(proc_swaps, "%*s %*s %*s %*s %*s\n"); @@ -355,7 +365,7 @@ static int delete_loopback(const char *device) { int fd, r; if ((fd = open(device, O_RDONLY|O_CLOEXEC)) < 0) - return -errno; + return errno == ENOENT ? 0 : -errno; r = ioctl(fd, LOOP_CLR_FD, 0); close_nointr_nofail(fd); @@ -428,6 +438,11 @@ static int mount_points_list_remount_read_only(MountPoint **head, bool *changed) LIST_FOREACH_SAFE(mount_point, m, n, *head) { + if (m->skip_ro) { + n_failed++; + continue; + } + /* Trying to remount read-only */ if (mount(NULL, m->path, NULL, MS_MGC_VAL|MS_REMOUNT|MS_RDONLY, NULL) == 0) { if (changed)