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