#include <string.h>
#include <sys/mount.h>
#include <sys/swap.h>
-#include <unistd.h>
#include <linux/loop.h>
#include <linux/dm-ioctl.h>
}
static int mount_points_list_get(MountPoint **head) {
- FILE *proc_self_mountinfo;
- char *path, *p;
+ _cleanup_fclose_ FILE *proc_self_mountinfo = NULL;
unsigned int i;
- int r;
assert(head);
- if (!(proc_self_mountinfo = fopen("/proc/self/mountinfo", "re")))
+ proc_self_mountinfo = fopen("/proc/self/mountinfo", "re");
+ if (!proc_self_mountinfo)
return -errno;
for (i = 1;; i++) {
- int k;
+ _cleanup_free_ char *path = NULL;
+ char *p = NULL;
MountPoint *m;
+ int k;
- path = p = NULL;
-
- if ((k = fscanf(proc_self_mountinfo,
- "%*s " /* (1) mount id */
- "%*s " /* (2) parent id */
- "%*s " /* (3) major:minor */
- "%*s " /* (4) root */
- "%ms " /* (5) mount point */
- "%*s" /* (6) mount options */
- "%*[^-]" /* (7) optional fields */
- "- " /* (8) separator */
- "%*s " /* (9) file system type */
- "%*s" /* (10) mount source */
- "%*s" /* (11) mount options 2 */
- "%*[^\n]", /* some rubbish at the end */
- &path)) != 1) {
+ k = fscanf(proc_self_mountinfo,
+ "%*s " /* (1) mount id */
+ "%*s " /* (2) parent id */
+ "%*s " /* (3) major:minor */
+ "%*s " /* (4) root */
+ "%ms " /* (5) mount point */
+ "%*s" /* (6) mount options */
+ "%*[^-]" /* (7) optional fields */
+ "- " /* (8) separator */
+ "%*s " /* (9) file system type */
+ "%*s" /* (10) mount source */
+ "%*s" /* (11) mount options 2 */
+ "%*[^\n]", /* some rubbish at the end */
+ &path);
+ if (k != 1) {
if (k == EOF)
break;
log_warning("Failed to parse /proc/self/mountinfo:%u.", i);
-
- free(path);
continue;
}
p = cunescape(path);
- free(path);
-
- if (!p) {
- r = -ENOMEM;
- goto finish;
- }
+ if (!p)
+ return -ENOMEM;
/* Ignore mount points we can't unmount because they
* are API or because we are keeping them open (like
- * /dev/console) */
+ * /dev/console). Also, ignore all mounts below API
+ * file systems, since they are likely virtual too,
+ * and hence not worth spending time on. Also, in
+ * unprivileged containers we might lack the rights to
+ * unmount these things, hence don't bother. */
if (mount_point_is_api(p) ||
mount_point_ignore(p) ||
- path_equal(p, "/dev/console")) {
+ path_startswith(p, "/dev") ||
+ path_startswith(p, "/sys") ||
+ path_startswith(p, "/proc")) {
free(p);
continue;
}
- if (!(m = new0(MountPoint, 1))) {
+ m = new0(MountPoint, 1);
+ if (!m) {
free(p);
- r = -ENOMEM;
- goto finish;
+ return -ENOMEM;
}
m->path = p;
LIST_PREPEND(mount_point, *head, m);
}
- r = 0;
-
-finish:
- fclose(proc_self_mountinfo);
-
- return r;
+ return 0;
}
static int swap_list_get(MountPoint **head) {
- FILE *proc_swaps;
+ _cleanup_fclose_ FILE *proc_swaps = NULL;
unsigned int i;
- int r;
assert(head);
free(dev);
if (!d) {
- r = -ENOMEM;
- goto finish;
+ return -ENOMEM;
}
if (!(swap = new0(MountPoint, 1))) {
free(d);
- r = -ENOMEM;
- goto finish;
+ return -ENOMEM;
}
swap->path = d;
LIST_PREPEND(mount_point, *head, swap);
}
- r = 0;
-
-finish:
- fclose(proc_swaps);
-
- return r;
+ return 0;
}
static int loopback_list_get(MountPoint **head) {
mount_point_free(head, m);
} else if (log_error) {
- log_warning("Could not unmount %s: %m", m->path);
+ log_warning_errno(errno, "Could not unmount %s: %m", m->path);
n_failed++;
}
}
mount_point_free(head, m);
} else {
- log_warning("Could not deactivate swap %s: %m", m->path);
+ log_warning_errno(errno, "Could not deactivate swap %s: %m", m->path);
n_failed++;
}
}
mount_point_free(head, m);
} else {
- log_warning("Could not detach loopback %s: %m", m->path);
+ log_warning_errno(errno, "Could not detach loopback %s: %m", m->path);
n_failed++;
}
}
mount_point_free(head, m);
} else {
- log_warning("Could not detach DM %s: %m", m->path);
+ log_warning_errno(errno, "Could not detach DM %s: %m", m->path);
n_failed++;
}
}