]> git.ipfire.org Git - thirdparty/systemd.git/blame - src/remount-fs/remount-fs.c
gpt-auto-generator: exit immediately if in container
[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>
23#include <fcntl.h>
24#include <errno.h>
25#include <string.h>
26#include <sys/stat.h>
27#include <sys/wait.h>
28#include <mntent.h>
29
30#include "log.h"
31#include "util.h"
9eb977db 32#include "path-util.h"
449ddb2d
LP
33#include "set.h"
34#include "mount-setup.h"
9a57c629 35#include "exit-status.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;
449ddb2d
LP
43 FILE *f = NULL;
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) {
e0295d26
LP
60 if (errno == ENOENT) {
61 ret = EXIT_SUCCESS;
62 goto finish;
63 }
64
449ddb2d
LP
65 log_error("Failed to open /etc/fstab: %m");
66 goto finish;
67 }
68
adb2ce5f
LP
69 pids = hashmap_new(trivial_hash_func, trivial_compare_func);
70 if (!pids) {
449ddb2d
LP
71 log_error("Failed to allocate set");
72 goto finish;
73 }
74
22f4096c 75 ret = EXIT_SUCCESS;
449ddb2d
LP
76
77 while ((me = getmntent(f))) {
78 pid_t pid;
79 int k;
80 char *s;
81
b4efdf97 82 /* Remount the root fs, /usr and all API VFS */
2b93b027 83 if (!mount_point_is_api(me->mnt_dir) &&
b4efdf97
LP
84 !path_equal(me->mnt_dir, "/") &&
85 !path_equal(me->mnt_dir, "/usr"))
449ddb2d
LP
86 continue;
87
88 log_debug("Remounting %s", me->mnt_dir);
89
adb2ce5f
LP
90 pid = fork();
91 if (pid < 0) {
449ddb2d 92 log_error("Failed to fork: %m");
adb2ce5f 93 ret = EXIT_FAILURE;
449ddb2d
LP
94 continue;
95 }
96
97 if (pid == 0) {
98 const char *arguments[5];
99 /* Child */
100
101 arguments[0] = "/bin/mount";
102 arguments[1] = me->mnt_dir;
103 arguments[2] = "-o";
104 arguments[3] = "remount";
105 arguments[4] = NULL;
106
107 execv("/bin/mount", (char **) arguments);
108
109 log_error("Failed to execute /bin/mount: %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) {
449ddb2d 125 log_error("Failed to add PID to set: %s", strerror(-k));
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
140 log_error("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
LP
148 if (si.si_code == CLD_EXITED)
149 log_error("/bin/mount for %s exited with exit status %i.", s, si.si_status);
150 else
151 log_error("/bin/mount for %s terminated by signal %s.", s, signal_to_string(si.si_status));
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
165 if (f)
166 endmntent(f);
167
168 return ret;
169}