Hello,

If I'm not mistaken, the intent way back in the early stages of systemd was to 
eliminate /etc/fstab and use .mount files exclusively.  Since it was never 
fully implemented I took the prerogative to make it work on my systems.
I've been using the setup for quite some time and it works without problem.

1. if /etc/fstab is missing, systemd must remount / based on the options
in /etc/systemd/system/-.mount.

2.  If /etc/fstab is missing, systemd must create a valid fstab (in this case 
/run/fstab) so that fsck runs properly.

The attached patches address those issues.

--- ./units/systemd-remount-fs.service.in.orig	2013-08-13 14:02:52.824756395 -0600
+++ ./units/systemd-remount-fs.service.in	2013-09-24 13:34:56.514061876 -0600
@@ -14,7 +14,6 @@ Conflicts=shutdown.target
 After=systemd-readahead-collect.service systemd-readahead-replay.service systemd-fsck-root.service
 Before=local-fs-pre.target local-fs.target shutdown.target
 Wants=local-fs-pre.target
-ConditionPathExists=/etc/fstab
 
 [Service]
 Type=oneshot
--- ./src/remount-fs/remount-fs.c.orig	2013-09-24 13:34:56.485062277 -0600
+++ ./src/remount-fs/remount-fs.c	2013-09-24 13:34:56.530061656 -0600
@@ -38,6 +38,61 @@
  * options that are in /etc/fstab that systemd might not have
  * respected */
 
+static void remount(Hashmap *pids, int *pret, const char *mnt_dir, const char *mnt_options)
+{
+        pid_t pid;
+        int k;
+        char *s;
+
+        /* Remount the root fs, /usr and all API VFS */
+        if (!mount_point_is_api(mnt_dir) &&
+            !path_equal(mnt_dir, "/") &&
+            !path_equal(mnt_dir, "/usr"))
+                return;
+
+        log_debug("Remounting %s", mnt_dir);
+
+        pid = fork();
+        if (pid < 0) {
+                log_error("Failed to fork: %m");
+                *pret = EXIT_FAILURE;
+                return;
+        }
+
+        if (pid == 0) {
+                const char *arguments[5];
+                /* Child */
+
+                arguments[0] = "/usr/bin/mount";
+                arguments[1] = mnt_dir;
+                arguments[2] = "-o";
+                arguments[3] = mnt_options;
+                arguments[4] = NULL;
+
+                execv("/usr/bin/mount", (char **) arguments);
+
+                log_error("Failed to execute /usr/bin/mount: %m");
+                _exit(EXIT_FAILURE);
+        }
+
+        /* Parent */
+
+        s = strdup(mnt_dir);
+        if (!s) {
+                log_oom();
+                *pret = EXIT_FAILURE;
+                return;
+        }
+
+
+        k = hashmap_put(pids, UINT_TO_PTR(pid), s);
+        if (k < 0) {
+                log_error("Failed to add PID to set: %s", strerror(-k));
+                *pret = EXIT_FAILURE;
+                return;
+        }
+}
+
 int main(int argc, char *argv[]) {
         int ret = EXIT_FAILURE;
         FILE *f = NULL;
@@ -56,12 +111,7 @@ int main(int argc, char *argv[]) {
         umask(0022);
 
         f = setmntent("/etc/fstab", "r");
-        if (!f) {
-                if (errno == ENOENT) {
-                        ret = EXIT_SUCCESS;
-                        goto finish;
-                }
-
+        if (!f && (errno != ENOENT)) {
                 log_error("Failed to open /etc/fstab: %m");
                 goto finish;
         }
@@ -74,57 +124,38 @@ int main(int argc, char *argv[]) {
 
         ret = EXIT_SUCCESS;
 
-        while ((me = getmntent(f))) {
-                pid_t pid;
-                int k;
-                char *s;
-
-                /* Remount the root fs, /usr and all API VFS */
-                if (!mount_point_is_api(me->mnt_dir) &&
-                    !path_equal(me->mnt_dir, "/") &&
-                    !path_equal(me->mnt_dir, "/usr"))
-                        continue;
-
-                log_debug("Remounting %s", me->mnt_dir);
-
-                pid = fork();
-                if (pid < 0) {
-                        log_error("Failed to fork: %m");
-                        ret = EXIT_FAILURE;
-                        continue;
-                }
-
-                if (pid == 0) {
-                        const char *arguments[5];
-                        /* Child */
-
-                        arguments[0] = "/usr/bin/mount";
-                        arguments[1] = me->mnt_dir;
-                        arguments[2] = "-o";
-                        arguments[3] = "remount";
-                        arguments[4] = NULL;
-
-                        execv("/usr/bin/mount", (char **) arguments);
+        if ( ! f ) {
+                f = fopen("/etc/systemd/system/-.mount", "r");
 
-                        log_error("Failed to execute /usr/bin/mount: %m");
-                        _exit(EXIT_FAILURE);
+                if ( f ) {
+                        char *line = NULL;
+                        size_t len = 0;
+                        ssize_t read;
+
+                        while ((read = getline(&line, &len, f)) != -1) {
+                                if ( ! strncmp("Options=", line, 8) ) {
+                                        char *nl = strrchr(line, '\n');
+
+                                        if ( nl )
+                                                *nl = 0;
+
+                                        char *options = malloc(strlen(line + 8) + sizeof("remount,rw,"));
+                                        strcpy(options, "remount,rw,");
+                                        strcat(options, line + 8);
+                                        remount(pids, &ret, "/", options);
+                                        free((void*)options);
+                                        break;
+                                }
+                        }
+
+                        free((void*)line);
+                        fclose(f);
+                        f = NULL;
                 }
-
-                /* Parent */
-
-                s = strdup(me->mnt_dir);
-                if (!s) {
-                        log_oom();
-                        ret = EXIT_FAILURE;
-                        continue;
-                }
-
-
-                k = hashmap_put(pids, UINT_TO_PTR(pid), s);
-                if (k < 0) {
-                        log_error("Failed to add PID to set: %s", strerror(-k));
-                        ret = EXIT_FAILURE;
-                        continue;
+        }
+        else {
+                while ((me = getmntent(f))) {
+                        remount(pids, &ret, me->mnt_dir, "remount");
                 }
         }
 
--- ./src/core/mount.c.orig	2013-06-12 15:58:11.970500795 -0600
+++ ./src/core/mount.c	2013-06-12 16:00:00.491514455 -0600
@@ -21,6 +21,7 @@
 
 #include <errno.h>
 #include <stdio.h>
+#include <string.h>
 #include <mntent.h>
 #include <sys/epoll.h>
 #include <signal.h>
@@ -336,6 +337,15 @@ static bool mount_is_bind(MountParameter
         return false;
 }
 
+static bool mount_is_local_partition(MountParameters *p) {
+        assert(p);
+
+        return !strncmp(p->what, "/dev/sd", 7)
+                || !strncmp(p->what, "/dev/hd", 7)
+                || !strncmp(p->what, "/dev/disk/", 10)
+                || !strncmp(p->what, "/dev/mmc", 8);
+}
+
 static bool needs_quota(MountParameters *p) {
         assert(p);
 
@@ -378,6 +388,9 @@ static int mount_add_device_links(Mount
         if (r < 0)
                 return r;
 
+        if((p->passno == 0) && mount_is_local_partition(p))
+                p->passno = 2;
+
         if (p->passno > 0 &&
             UNIT(m)->manager->running_as == SYSTEMD_SYSTEM) {
                 char *name;
--- ./src/core/mount.c.orig	2012-11-11 15:11:42.648267131 -0700
+++ ./src/core/mount.c	2012-11-11 16:10:44.758031015 -0700
@@ -377,6 +377,13 @@ static int mount_add_device_links(Mount
         if((p->passno == 0) && mount_is_local_partition(p))
                 p->passno = 2;
 
+        if(mount_is_local_partition(p)) {
+                FILE *f = fopen("/run/fstab", "a");
+                const char *options = "default";
+                fprintf(f, "%s %s %s %s 1 2\n", p->what, m->where, p->fstype, options);
+                fclose(f);
+        }
+
         if (p->passno > 0 &&
             UNIT(m)->manager->running_as == SYSTEMD_SYSTEM) {
                 char *name;
--- ./src/fsck/fsck.c.orig	2012-11-11 15:33:15.855782319 -0700
+++ ./src/fsck/fsck.c	2012-11-11 16:26:53.065199360 -0700
@@ -348,7 +348,20 @@ int main(int argc, char *argv[]) {
                 /* Child */
                 if (progress_pipe[0] >= 0)
                         close_nointr_nofail(progress_pipe[0]);
-                execv(cmdline[0], (char**) cmdline);
+
+                {
+                        struct stat st;
+
+                        if ( stat("/etc/fstab", &st) && ! stat("/run/fstab", &st) ) {
+                                const char *env[2];
+                                env[0] = "FSTAB_FILE=/run/fstab";
+                                env[1] = 0;
+                                execvpe(cmdline[0], (char**) cmdline, (char**)env);
+                        } else {
+                                execv(cmdline[0], (char**) cmdline);
+                        }
+                }
+
                 _exit(8); /* Operational error */
         }
 
_______________________________________________
systemd-devel mailing list
[email protected]
http://lists.freedesktop.org/mailman/listinfo/systemd-devel

Reply via email to