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