1 /* SPDX-License-Identifier: LGPL-2.1-or-later */
11 #include "exit-status.h"
12 #include "fstab-util.h"
14 #include "main-func.h"
15 #include "mount-setup.h"
16 #include "mount-util.h"
17 #include "path-util.h"
18 #include "process-util.h"
19 #include "signal-util.h"
22 /* Goes through /etc/fstab and remounts all API file systems, applying options that are in /etc/fstab that systemd
23 * might not have respected */
25 static int track_pid(Hashmap
**h
, const char *path
, pid_t pid
) {
26 _cleanup_free_
char *c
= NULL
;
31 assert(pid_is_valid(pid
));
37 r
= hashmap_ensure_put(h
, NULL
, PID_TO_PTR(pid
), c
);
41 return log_error_errno(r
, "Failed to store pid " PID_FMT
, pid
);
47 static int do_remount(const char *path
, bool force_rw
, Hashmap
**pids
) {
51 log_debug("Remounting %s...", path
);
53 r
= safe_fork(force_rw
? "(remount-rw)" : "(remount)",
54 FORK_RESET_SIGNALS
|FORK_DEATHSIG_SIGTERM
|FORK_RLIMIT_NOFILE_SAFE
|FORK_LOG
, &pid
);
63 force_rw
? "remount,rw" : "remount"));
64 log_error_errno(errno
, "Failed to execute " MOUNT_PATH
": %m");
69 return track_pid(pids
, path
, pid
);
72 static int remount_by_fstab(Hashmap
**ret_pids
) {
73 _cleanup_hashmap_free_free_ Hashmap
*pids
= NULL
;
74 _cleanup_endmntent_
FILE *f
= NULL
;
75 bool has_root
= false;
84 f
= setmntent(fstab_path(), "re");
87 return log_error_errno(errno
, "Failed to open %s: %m", fstab_path());
92 while ((me
= getmntent(f
))) {
93 /* Remount the root fs, /usr, and all API VFSs */
94 if (!mount_point_is_api(me
->mnt_dir
) &&
95 !PATH_IN_SET(me
->mnt_dir
, "/", "/usr"))
98 if (path_equal(me
->mnt_dir
, "/"))
101 r
= do_remount(me
->mnt_dir
, false, &pids
);
106 *ret_pids
= TAKE_PTR(pids
);
110 static int run(int argc
, char *argv
[]) {
111 _cleanup_hashmap_free_free_ Hashmap
*pids
= NULL
;
117 return log_error_errno(SYNTHETIC_ERRNO(EINVAL
),
118 "This program takes no arguments.");
122 r
= remount_by_fstab(&pids
);
126 /* The $SYSTEMD_REMOUNT_ROOT_RW environment variable is set by systemd-gpt-auto-generator to tell us
127 * whether to remount things. We honour it only if there's no explicit line in /etc/fstab configured
128 * which takes precedence. */
130 r
= getenv_bool("SYSTEMD_REMOUNT_ROOT_RW");
131 if (r
< 0 && r
!= -ENXIO
)
132 log_warning_errno(r
, "Failed to parse $SYSTEMD_REMOUNT_ROOT_RW, ignoring: %m");
135 r
= do_remount("/", true, &pids
);
142 while (!hashmap_isempty(pids
)) {
143 _cleanup_free_
char *s
= NULL
;
146 if (waitid(P_ALL
, 0, &si
, WEXITED
) < 0) {
150 return log_error_errno(errno
, "waitid() failed: %m");
153 s
= hashmap_remove(pids
, PID_TO_PTR(si
.si_pid
));
155 !is_clean_exit(si
.si_code
, si
.si_status
, EXIT_CLEAN_COMMAND
, NULL
)) {
156 if (si
.si_code
== CLD_EXITED
)
157 log_error(MOUNT_PATH
" for %s exited with exit status %i.", s
, si
.si_status
);
159 log_error(MOUNT_PATH
" for %s terminated by signal %s.", s
, signal_to_string(si
.si_status
));
168 DEFINE_MAIN_FUNCTION(run
);