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