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