]> git.ipfire.org Git - thirdparty/systemd.git/blame - src/remount-fs/remount-fs.c
util: split out signal-util.[ch] from 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
f00929ad 98 arguments[0] = MOUNT_PATH;
449ddb2d
LP
99 arguments[1] = me->mnt_dir;
100 arguments[2] = "-o";
101 arguments[3] = "remount";
102 arguments[4] = NULL;
103
f00929ad 104 execv(MOUNT_PATH, (char **) arguments);
449ddb2d 105
f00929ad 106 log_error_errno(errno, "Failed to execute " MOUNT_PATH ": %m");
22f4096c 107 _exit(EXIT_FAILURE);
449ddb2d
LP
108 }
109
110 /* Parent */
111
112 s = strdup(me->mnt_dir);
adb2ce5f 113 if (!s) {
0d0f0c50 114 log_oom();
adb2ce5f
LP
115 ret = EXIT_FAILURE;
116 continue;
117 }
118
449ddb2d 119
adb2ce5f
LP
120 k = hashmap_put(pids, UINT_TO_PTR(pid), s);
121 if (k < 0) {
da927ba9 122 log_error_errno(k, "Failed to add PID to set: %m");
22f4096c 123 ret = EXIT_FAILURE;
449ddb2d
LP
124 continue;
125 }
126 }
127
128 while (!hashmap_isempty(pids)) {
b92bea5d 129 siginfo_t si = {};
449ddb2d
LP
130 char *s;
131
449ddb2d
LP
132 if (waitid(P_ALL, 0, &si, WEXITED) < 0) {
133
134 if (errno == EINTR)
135 continue;
136
56f64d95 137 log_error_errno(errno, "waitid() failed: %m");
22f4096c 138 ret = EXIT_FAILURE;
449ddb2d
LP
139 break;
140 }
141
adb2ce5f
LP
142 s = hashmap_remove(pids, UINT_TO_PTR(si.si_pid));
143 if (s) {
96342de6 144 if (!is_clean_exit(si.si_code, si.si_status, NULL)) {
449ddb2d 145 if (si.si_code == CLD_EXITED)
f00929ad 146 log_error(MOUNT_PATH " for %s exited with exit status %i.", s, si.si_status);
449ddb2d 147 else
f00929ad 148 log_error(MOUNT_PATH " for %s terminated by signal %s.", s, signal_to_string(si.si_status));
449ddb2d 149
22f4096c 150 ret = EXIT_FAILURE;
449ddb2d
LP
151 }
152
153 free(s);
154 }
155 }
156
157finish:
158
159 if (pids)
160 hashmap_free_free(pids);
161
449ddb2d
LP
162 return ret;
163}