]> git.ipfire.org Git - thirdparty/systemd.git/blame - src/remount-fs/remount-fs.c
tree-wide: introduce new safe_fork() helper and port everything over
[thirdparty/systemd.git] / src / remount-fs / remount-fs.c
CommitLineData
53e1b683 1/* SPDX-License-Identifier: LGPL-2.1+ */
449ddb2d
LP
2/***
3 This file is part of systemd.
4
5 Copyright 2010 Lennart Poettering
6
7 systemd is free software; you can redistribute it and/or modify it
5430f7f2
LP
8 under the terms of the GNU Lesser General Public License as published by
9 the Free Software Foundation; either version 2.1 of the License, or
449ddb2d
LP
10 (at your option) any later version.
11
12 systemd is distributed in the hope that it will be useful, but
13 WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
5430f7f2 15 Lesser General Public License for more details.
449ddb2d 16
5430f7f2 17 You should have received a copy of the GNU Lesser General Public License
449ddb2d
LP
18 along with systemd; If not, see <http://www.gnu.org/licenses/>.
19***/
20
449ddb2d 21#include <errno.h>
cf0fbc49 22#include <mntent.h>
449ddb2d 23#include <string.h>
b16fee15 24#include <sys/prctl.h>
449ddb2d
LP
25#include <sys/stat.h>
26#include <sys/wait.h>
cf0fbc49 27#include <unistd.h>
449ddb2d 28
4349cd7c 29#include "exit-status.h"
449ddb2d 30#include "log.h"
4349cd7c
LP
31#include "mount-setup.h"
32#include "mount-util.h"
9eb977db 33#include "path-util.h"
b16fee15 34#include "process-util.h"
24882e06 35#include "signal-util.h"
b16fee15 36#include "strv.h"
4349cd7c 37#include "util.h"
449ddb2d
LP
38
39/* Goes through /etc/fstab and remounts all API file systems, applying
40 * options that are in /etc/fstab that systemd might not have
41 * respected */
42
43int main(int argc, char *argv[]) {
b16fee15 44 _cleanup_hashmap_free_free_ Hashmap *pids = NULL;
5862d652 45 _cleanup_endmntent_ FILE *f = NULL;
449ddb2d 46 struct mntent* me;
b16fee15 47 int r;
449ddb2d
LP
48
49 if (argc > 1) {
50 log_error("This program takes no argument.");
22f4096c 51 return EXIT_FAILURE;
449ddb2d
LP
52 }
53
4cfa2c99 54 log_set_target(LOG_TARGET_AUTO);
449ddb2d
LP
55 log_parse_environment();
56 log_open();
57
4c12626c
LP
58 umask(0022);
59
9ffcff0e 60 f = setmntent("/etc/fstab", "re");
adb2ce5f 61 if (!f) {
b16fee15
LP
62 if (errno == ENOENT) {
63 r = 0;
64 goto finish;
65 }
e0295d26 66
b16fee15
LP
67 r = log_error_errno(errno, "Failed to open /etc/fstab: %m");
68 goto finish;
449ddb2d
LP
69 }
70
d5099efc 71 pids = hashmap_new(NULL);
adb2ce5f 72 if (!pids) {
b16fee15 73 r = log_oom();
449ddb2d
LP
74 goto finish;
75 }
76
449ddb2d
LP
77 while ((me = getmntent(f))) {
78 pid_t pid;
79 int k;
80 char *s;
81
b4efdf97 82 /* Remount the root fs, /usr and all API VFS */
2b93b027 83 if (!mount_point_is_api(me->mnt_dir) &&
b4efdf97
LP
84 !path_equal(me->mnt_dir, "/") &&
85 !path_equal(me->mnt_dir, "/usr"))
449ddb2d
LP
86 continue;
87
88 log_debug("Remounting %s", me->mnt_dir);
89
4c253ed1
LP
90 r = safe_fork("(remount)", FORK_RESET_SIGNALS|FORK_DEATHSIG, &pid);
91 if (r < 0) {
92 log_error_errno(r, "Failed to fork: %m");
b16fee15 93 goto finish;
449ddb2d 94 }
4c253ed1 95 if (r == 0) {
449ddb2d
LP
96 /* Child */
97
b16fee15 98 execv(MOUNT_PATH, STRV_MAKE(MOUNT_PATH, me->mnt_dir, "-o", "remount"));
449ddb2d 99
f00929ad 100 log_error_errno(errno, "Failed to execute " MOUNT_PATH ": %m");
22f4096c 101 _exit(EXIT_FAILURE);
449ddb2d
LP
102 }
103
104 /* Parent */
105
106 s = strdup(me->mnt_dir);
adb2ce5f 107 if (!s) {
b16fee15
LP
108 r = log_oom();
109 goto finish;
adb2ce5f
LP
110 }
111
4a0b58c4 112 k = hashmap_put(pids, PID_TO_PTR(pid), s);
adb2ce5f 113 if (k < 0) {
b16fee15
LP
114 free(s);
115 r = log_oom();
116 goto finish;
449ddb2d
LP
117 }
118 }
119
b16fee15 120 r = 0;
449ddb2d 121 while (!hashmap_isempty(pids)) {
b92bea5d 122 siginfo_t si = {};
449ddb2d
LP
123 char *s;
124
449ddb2d
LP
125 if (waitid(P_ALL, 0, &si, WEXITED) < 0) {
126
127 if (errno == EINTR)
128 continue;
129
b16fee15
LP
130 r = log_error_errno(errno, "waitid() failed: %m");
131 goto finish;
449ddb2d
LP
132 }
133
4a0b58c4 134 s = hashmap_remove(pids, PID_TO_PTR(si.si_pid));
adb2ce5f 135 if (s) {
1f0958f6 136 if (!is_clean_exit(si.si_code, si.si_status, EXIT_CLEAN_COMMAND, NULL)) {
449ddb2d 137 if (si.si_code == CLD_EXITED)
f00929ad 138 log_error(MOUNT_PATH " for %s exited with exit status %i.", s, si.si_status);
449ddb2d 139 else
f00929ad 140 log_error(MOUNT_PATH " for %s terminated by signal %s.", s, signal_to_string(si.si_status));
449ddb2d 141
b16fee15 142 r = -ENOEXEC;
449ddb2d
LP
143 }
144
145 free(s);
146 }
147 }
148
149finish:
b16fee15 150 return r < 0 ? EXIT_FAILURE : EXIT_SUCCESS;
449ddb2d 151}