]>
Commit | Line | Data |
---|---|---|
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 | ||
42 | int 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 | ||
153 | finish: | |
b16fee15 | 154 | return r < 0 ? EXIT_FAILURE : EXIT_SUCCESS; |
449ddb2d | 155 | } |