2 This file is part of systemd.
4 Copyright 2010 Lennart Poettering
6 systemd is free software; you can redistribute it and/or modify it
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
9 (at your option) any later version.
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
14 Lesser General Public License for more details.
16 You should have received a copy of the GNU Lesser General Public License
17 along with systemd; If not, see <http://www.gnu.org/licenses/>.
23 #include <sys/prctl.h>
28 #include "exit-status.h"
30 #include "mount-setup.h"
31 #include "mount-util.h"
32 #include "path-util.h"
33 #include "process-util.h"
34 #include "signal-util.h"
38 /* Goes through /etc/fstab and remounts all API file systems, applying
39 * options that are in /etc/fstab that systemd might not have
42 int main(int argc
, char *argv
[]) {
43 _cleanup_hashmap_free_free_ Hashmap
*pids
= NULL
;
44 _cleanup_endmntent_
FILE *f
= NULL
;
49 log_error("This program takes no argument.");
53 log_set_target(LOG_TARGET_AUTO
);
54 log_parse_environment();
59 f
= setmntent("/etc/fstab", "re");
61 if (errno
== ENOENT
) {
66 r
= log_error_errno(errno
, "Failed to open /etc/fstab: %m");
70 pids
= hashmap_new(NULL
);
76 while ((me
= getmntent(f
))) {
81 /* Remount the root fs, /usr and all API VFS */
82 if (!mount_point_is_api(me
->mnt_dir
) &&
83 !path_equal(me
->mnt_dir
, "/") &&
84 !path_equal(me
->mnt_dir
, "/usr"))
87 log_debug("Remounting %s", me
->mnt_dir
);
91 r
= log_error_errno(errno
, "Failed to fork: %m");
98 (void) reset_all_signal_handlers();
99 (void) reset_signal_mask();
100 (void) prctl(PR_SET_PDEATHSIG
, SIGTERM
);
102 execv(MOUNT_PATH
, STRV_MAKE(MOUNT_PATH
, me
->mnt_dir
, "-o", "remount"));
104 log_error_errno(errno
, "Failed to execute " MOUNT_PATH
": %m");
110 s
= strdup(me
->mnt_dir
);
116 k
= hashmap_put(pids
, PID_TO_PTR(pid
), s
);
125 while (!hashmap_isempty(pids
)) {
129 if (waitid(P_ALL
, 0, &si
, WEXITED
) < 0) {
134 r
= log_error_errno(errno
, "waitid() failed: %m");
138 s
= hashmap_remove(pids
, PID_TO_PTR(si
.si_pid
));
140 if (!is_clean_exit(si
.si_code
, si
.si_status
, EXIT_CLEAN_COMMAND
, NULL
)) {
141 if (si
.si_code
== CLD_EXITED
)
142 log_error(MOUNT_PATH
" for %s exited with exit status %i.", s
, si
.si_status
);
144 log_error(MOUNT_PATH
" for %s terminated by signal %s.", s
, signal_to_string(si
.si_status
));
154 return r
< 0 ? EXIT_FAILURE
: EXIT_SUCCESS
;