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