]> git.ipfire.org Git - thirdparty/systemd.git/blame - src/remount-fs/remount-fs.c
util-lib: move fstab_node_to_udev_node() to fstab-util.[ch]
[thirdparty/systemd.git] / src / remount-fs / remount-fs.c
CommitLineData
449ddb2d
LP
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
5430f7f2
LP
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
449ddb2d
LP
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
5430f7f2 16 Lesser General Public License for more details.
449ddb2d 17
5430f7f2 18 You should have received a copy of the GNU Lesser General Public License
449ddb2d
LP
19 along with systemd; If not, see <http://www.gnu.org/licenses/>.
20***/
21
22#include <unistd.h>
449ddb2d
LP
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"
9eb977db 31#include "path-util.h"
24882e06 32#include "signal-util.h"
449ddb2d 33#include "mount-setup.h"
9a57c629 34#include "exit-status.h"
449ddb2d
LP
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
40int main(int argc, char *argv[]) {
22f4096c 41 int ret = EXIT_FAILURE;
5862d652 42 _cleanup_endmntent_ FILE *f = NULL;
449ddb2d
LP
43 struct mntent* me;
44 Hashmap *pids = NULL;
45
46 if (argc > 1) {
47 log_error("This program takes no argument.");
22f4096c 48 return EXIT_FAILURE;
449ddb2d
LP
49 }
50
4cfa2c99 51 log_set_target(LOG_TARGET_AUTO);
449ddb2d
LP
52 log_parse_environment();
53 log_open();
54
4c12626c
LP
55 umask(0022);
56
adb2ce5f
LP
57 f = setmntent("/etc/fstab", "r");
58 if (!f) {
5862d652
ZJS
59 if (errno == ENOENT)
60 return EXIT_SUCCESS;
e0295d26 61
56f64d95 62 log_error_errno(errno, "Failed to open /etc/fstab: %m");
5862d652 63 return EXIT_FAILURE;
449ddb2d
LP
64 }
65
d5099efc 66 pids = hashmap_new(NULL);
adb2ce5f 67 if (!pids) {
449ddb2d
LP
68 log_error("Failed to allocate set");
69 goto finish;
70 }
71
22f4096c 72 ret = EXIT_SUCCESS;
449ddb2d
LP
73
74 while ((me = getmntent(f))) {
75 pid_t pid;
76 int k;
77 char *s;
78
b4efdf97 79 /* Remount the root fs, /usr and all API VFS */
2b93b027 80 if (!mount_point_is_api(me->mnt_dir) &&
b4efdf97
LP
81 !path_equal(me->mnt_dir, "/") &&
82 !path_equal(me->mnt_dir, "/usr"))
449ddb2d
LP
83 continue;
84
85 log_debug("Remounting %s", me->mnt_dir);
86
adb2ce5f
LP
87 pid = fork();
88 if (pid < 0) {
56f64d95 89 log_error_errno(errno, "Failed to fork: %m");
adb2ce5f 90 ret = EXIT_FAILURE;
449ddb2d
LP
91 continue;
92 }
93
94 if (pid == 0) {
95 const char *arguments[5];
96 /* Child */
97
ce30c8dc
LP
98 (void) reset_all_signal_handlers();
99 (void) reset_signal_mask();
100
f00929ad 101 arguments[0] = MOUNT_PATH;
449ddb2d
LP
102 arguments[1] = me->mnt_dir;
103 arguments[2] = "-o";
104 arguments[3] = "remount";
105 arguments[4] = NULL;
106
f00929ad 107 execv(MOUNT_PATH, (char **) arguments);
449ddb2d 108
f00929ad 109 log_error_errno(errno, "Failed to execute " MOUNT_PATH ": %m");
22f4096c 110 _exit(EXIT_FAILURE);
449ddb2d
LP
111 }
112
113 /* Parent */
114
115 s = strdup(me->mnt_dir);
adb2ce5f 116 if (!s) {
0d0f0c50 117 log_oom();
adb2ce5f
LP
118 ret = EXIT_FAILURE;
119 continue;
120 }
121
449ddb2d 122
adb2ce5f
LP
123 k = hashmap_put(pids, UINT_TO_PTR(pid), s);
124 if (k < 0) {
da927ba9 125 log_error_errno(k, "Failed to add PID to set: %m");
22f4096c 126 ret = EXIT_FAILURE;
449ddb2d
LP
127 continue;
128 }
129 }
130
131 while (!hashmap_isempty(pids)) {
b92bea5d 132 siginfo_t si = {};
449ddb2d
LP
133 char *s;
134
449ddb2d
LP
135 if (waitid(P_ALL, 0, &si, WEXITED) < 0) {
136
137 if (errno == EINTR)
138 continue;
139
56f64d95 140 log_error_errno(errno, "waitid() failed: %m");
22f4096c 141 ret = EXIT_FAILURE;
449ddb2d
LP
142 break;
143 }
144
adb2ce5f
LP
145 s = hashmap_remove(pids, UINT_TO_PTR(si.si_pid));
146 if (s) {
96342de6 147 if (!is_clean_exit(si.si_code, si.si_status, NULL)) {
449ddb2d 148 if (si.si_code == CLD_EXITED)
f00929ad 149 log_error(MOUNT_PATH " for %s exited with exit status %i.", s, si.si_status);
449ddb2d 150 else
f00929ad 151 log_error(MOUNT_PATH " for %s terminated by signal %s.", s, signal_to_string(si.si_status));
449ddb2d 152
22f4096c 153 ret = EXIT_FAILURE;
449ddb2d
LP
154 }
155
156 free(s);
157 }
158 }
159
160finish:
161
162 if (pids)
163 hashmap_free_free(pids);
164
449ddb2d
LP
165 return ret;
166}