[systemd-devel] [systemd 2/2] Adding unmount function to be used in shutdown

Fabiano Fidencio fidencio at profusion.mobi
Tue Sep 21 16:17:06 PDT 2010


This function will unmount all filesystem (and those which fail
will be remounted read-only).
Filesystems are being read from /proc/self/mountinfo.
---
 src/shutdownd.c |   73 +++++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 files changed, 73 insertions(+), 0 deletions(-)

diff --git a/src/shutdownd.c b/src/shutdownd.c
index 72a2801..d47b160 100644
--- a/src/shutdownd.c
+++ b/src/shutdownd.c
@@ -23,6 +23,7 @@
 #include <sys/poll.h>
 #include <sys/types.h>
 #include <sys/timerfd.h>
+#include <sys/mount.h>
 #include <assert.h>
 #include <string.h>
 #include <errno.h>
@@ -36,6 +37,78 @@
 #include "sd-daemon.h"
 #include "utmp-wtmp.h"
 
+static int umount_proc_self_mountinfo(void) {
+        FILE *proc_self_mountinfo;
+        int r;
+        char *device, *path, *d, *p;
+
+        if (!(proc_self_mountinfo = fopen("/proc/self/mountinfo", "re")))
+                return -errno;
+
+        for (;;) {
+                int k;
+
+                device = path = d = 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) seperator */
+                                "%*s "       /* (9) file system type */
+                                "%ms"        /* (10) mount source */
+                                "%*s"        /* (11) mount options 2 */
+                                "%*[^\n]",   /* some rubbish at the end */
+                                &path,
+                                &device)) != 2) {
+
+                        if (k == EOF)
+                                break;
+
+                        r = -EBADMSG;
+                        goto finish;
+                }
+
+                if (!(d = cunescape(device)) ||
+                    !(p = cunescape(path))) {
+                        r = -ENOMEM;
+                        goto finish;
+                }
+
+                if ((r = umount(p) < 0))
+                        if ((r = umount2(p, MNT_FORCE)) < 0) {
+                                log_warning("umount: forced umount of %s failed! Trying to remount read-only.\n", p);
+                                if ((r = mount(d, p, NULL, MS_MGC_VAL|MS_REMOUNT|MS_RDONLY, NULL)) < 0)
+                                        log_error("umount: Cannot remount %s read-only\n", d);
+                                else
+                                        log_warning("umount: %s busy - remounted read-only\n", d);
+                        } else
+                                log_warning("umount: %s was umounted succesfully\n", p);
+                else
+                        log_warning("umount: %s was umounted succesfully\n", p);
+
+                free(device);
+                free(path);
+                free(d);
+                free(p);
+        }
+
+        r = 0;
+
+finish:
+        free(device);
+        free(path);
+        free(d);
+        free(p);
+        fclose(proc_self_mountinfo);
+
+        return r;
+}
+
 static int read_packet(int fd, struct shutdownd_command *_c) {
         struct msghdr msghdr;
         struct iovec iovec;
-- 
1.7.2.3



More information about the systemd-devel mailing list