]> git.ipfire.org Git - thirdparty/systemd.git/blame - src/remount-fs/remount-fs.c
tree-wide: drop 'This file is part of systemd' blurb
[thirdparty/systemd.git] / src / remount-fs / remount-fs.c
CommitLineData
53e1b683 1/* SPDX-License-Identifier: LGPL-2.1+ */
449ddb2d 2/***
449ddb2d 3 Copyright 2010 Lennart Poettering
449ddb2d
LP
4***/
5
449ddb2d 6#include <errno.h>
cf0fbc49 7#include <mntent.h>
449ddb2d 8#include <string.h>
b16fee15 9#include <sys/prctl.h>
449ddb2d
LP
10#include <sys/stat.h>
11#include <sys/wait.h>
cf0fbc49 12#include <unistd.h>
449ddb2d 13
4349cd7c 14#include "exit-status.h"
449ddb2d 15#include "log.h"
4349cd7c
LP
16#include "mount-setup.h"
17#include "mount-util.h"
9eb977db 18#include "path-util.h"
b16fee15 19#include "process-util.h"
24882e06 20#include "signal-util.h"
b16fee15 21#include "strv.h"
4349cd7c 22#include "util.h"
449ddb2d
LP
23
24/* Goes through /etc/fstab and remounts all API file systems, applying
25 * options that are in /etc/fstab that systemd might not have
26 * respected */
27
28int main(int argc, char *argv[]) {
b16fee15 29 _cleanup_hashmap_free_free_ Hashmap *pids = NULL;
5862d652 30 _cleanup_endmntent_ FILE *f = NULL;
449ddb2d 31 struct mntent* me;
b16fee15 32 int r;
449ddb2d
LP
33
34 if (argc > 1) {
35 log_error("This program takes no argument.");
22f4096c 36 return EXIT_FAILURE;
449ddb2d
LP
37 }
38
4cfa2c99 39 log_set_target(LOG_TARGET_AUTO);
449ddb2d
LP
40 log_parse_environment();
41 log_open();
42
4c12626c
LP
43 umask(0022);
44
9ffcff0e 45 f = setmntent("/etc/fstab", "re");
adb2ce5f 46 if (!f) {
b16fee15
LP
47 if (errno == ENOENT) {
48 r = 0;
49 goto finish;
50 }
e0295d26 51
b16fee15
LP
52 r = log_error_errno(errno, "Failed to open /etc/fstab: %m");
53 goto finish;
449ddb2d
LP
54 }
55
d5099efc 56 pids = hashmap_new(NULL);
adb2ce5f 57 if (!pids) {
b16fee15 58 r = log_oom();
449ddb2d
LP
59 goto finish;
60 }
61
449ddb2d
LP
62 while ((me = getmntent(f))) {
63 pid_t pid;
64 int k;
65 char *s;
66
b4efdf97 67 /* Remount the root fs, /usr and all API VFS */
2b93b027 68 if (!mount_point_is_api(me->mnt_dir) &&
b4efdf97
LP
69 !path_equal(me->mnt_dir, "/") &&
70 !path_equal(me->mnt_dir, "/usr"))
449ddb2d
LP
71 continue;
72
73 log_debug("Remounting %s", me->mnt_dir);
74
b6e1fff1
LP
75 r = safe_fork("(remount)", FORK_RESET_SIGNALS|FORK_DEATHSIG|FORK_LOG, &pid);
76 if (r < 0)
b16fee15 77 goto finish;
4c253ed1 78 if (r == 0) {
449ddb2d
LP
79 /* Child */
80
b16fee15 81 execv(MOUNT_PATH, STRV_MAKE(MOUNT_PATH, me->mnt_dir, "-o", "remount"));
449ddb2d 82
f00929ad 83 log_error_errno(errno, "Failed to execute " MOUNT_PATH ": %m");
22f4096c 84 _exit(EXIT_FAILURE);
449ddb2d
LP
85 }
86
87 /* Parent */
88
89 s = strdup(me->mnt_dir);
adb2ce5f 90 if (!s) {
b16fee15
LP
91 r = log_oom();
92 goto finish;
adb2ce5f
LP
93 }
94
4a0b58c4 95 k = hashmap_put(pids, PID_TO_PTR(pid), s);
adb2ce5f 96 if (k < 0) {
b16fee15
LP
97 free(s);
98 r = log_oom();
99 goto finish;
449ddb2d
LP
100 }
101 }
102
b16fee15 103 r = 0;
449ddb2d 104 while (!hashmap_isempty(pids)) {
b92bea5d 105 siginfo_t si = {};
449ddb2d
LP
106 char *s;
107
449ddb2d
LP
108 if (waitid(P_ALL, 0, &si, WEXITED) < 0) {
109
110 if (errno == EINTR)
111 continue;
112
b16fee15
LP
113 r = log_error_errno(errno, "waitid() failed: %m");
114 goto finish;
449ddb2d
LP
115 }
116
4a0b58c4 117 s = hashmap_remove(pids, PID_TO_PTR(si.si_pid));
adb2ce5f 118 if (s) {
1f0958f6 119 if (!is_clean_exit(si.si_code, si.si_status, EXIT_CLEAN_COMMAND, NULL)) {
449ddb2d 120 if (si.si_code == CLD_EXITED)
f00929ad 121 log_error(MOUNT_PATH " for %s exited with exit status %i.", s, si.si_status);
449ddb2d 122 else
f00929ad 123 log_error(MOUNT_PATH " for %s terminated by signal %s.", s, signal_to_string(si.si_status));
449ddb2d 124
b16fee15 125 r = -ENOEXEC;
449ddb2d
LP
126 }
127
128 free(s);
129 }
130 }
131
132finish:
b16fee15 133 return r < 0 ? EXIT_FAILURE : EXIT_SUCCESS;
449ddb2d 134}