+ if (where[0] == '/')
+ path_kill_slashes(where);
+
+ r = mount_add_one(m, what, where, false);
+ free(what);
+ free(where);
+
+ if (r < 0)
+ goto finish;
+ }
+
+ r = 0;
+finish:
+
+ endmntent(f);
+ return r;
+}
+
+static int mount_load_proc_self_mountinfo(Manager *m) {
+ FILE *f;
+ int r;
+
+ assert(m);
+
+ if (!(f = fopen("/proc/self/mountinfo", "r")))
+ return -errno;
+
+ for (;;) {
+ int k;
+ char *device, *path, *d, *p;
+
+ if ((k = fscanf(f,
+ "%*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) seperator */
+ "%*s " /* (9) file system type */
+ "%ms" /* (10) mount source */
+ "%*[^\n]", /* some rubbish at the end */
+ &path,
+ &device)) != 2) {
+
+ if (k == EOF) {
+ if (feof(f))
+ break;
+
+ r = -errno;
+ goto finish;
+ }
+
+ r = -EBADMSG;
+ goto finish;
+ }
+
+ if (!(d = cunescape(device))) {
+ free(device);
+ free(path);
+ r = -ENOMEM;
+ goto finish;
+ }
+ free(device);
+
+ if (!(p = cunescape(path))) {
+ free(d);
+ free(path);
+ r = -ENOMEM;
+ goto finish;
+ }
+ free(path);
+
+ r = mount_add_one(m, d, p, true);
+ free(d);
+ free(p);
+
+ if (r < 0)
+ goto finish;
+ }
+
+ r = 0;
+
+finish:
+ fclose(f);
+
+ return r;
+}
+
+static int mount_enumerate(Manager *m) {
+ int r;
+ assert(m);
+
+ if ((r = mount_load_etc_fstab(m)) < 0)
+ goto fail;
+
+ if ((r = mount_load_proc_self_mountinfo(m)) < 0)
+ goto fail;
+
+ return 0;
+
+fail:
+ mount_shutdown(m);
+ return r;