]> git.ipfire.org Git - thirdparty/systemd.git/blame - src/remount-api-vfs.c
relicense to LGPLv2.1 (with exceptions)
[thirdparty/systemd.git] / src / remount-api-vfs.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"
32#include "set.h"
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;
449ddb2d
LP
42 FILE *f = NULL;
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) {
449ddb2d
LP
59 log_error("Failed to open /etc/fstab: %m");
60 goto finish;
61 }
62
adb2ce5f
LP
63 pids = hashmap_new(trivial_hash_func, trivial_compare_func);
64 if (!pids) {
449ddb2d
LP
65 log_error("Failed to allocate set");
66 goto finish;
67 }
68
22f4096c 69 ret = EXIT_SUCCESS;
449ddb2d
LP
70
71 while ((me = getmntent(f))) {
72 pid_t pid;
73 int k;
74 char *s;
75
76 if (!mount_point_is_api(me->mnt_dir))
77 continue;
78
79 log_debug("Remounting %s", me->mnt_dir);
80
adb2ce5f
LP
81 pid = fork();
82 if (pid < 0) {
449ddb2d 83 log_error("Failed to fork: %m");
adb2ce5f 84 ret = EXIT_FAILURE;
449ddb2d
LP
85 continue;
86 }
87
88 if (pid == 0) {
89 const char *arguments[5];
90 /* Child */
91
92 arguments[0] = "/bin/mount";
93 arguments[1] = me->mnt_dir;
94 arguments[2] = "-o";
95 arguments[3] = "remount";
96 arguments[4] = NULL;
97
98 execv("/bin/mount", (char **) arguments);
99
100 log_error("Failed to execute /bin/mount: %m");
22f4096c 101 _exit(EXIT_FAILURE);
449ddb2d
LP
102 }
103
104 /* Parent */
105
106 s = strdup(me->mnt_dir);
adb2ce5f
LP
107 if (!s) {
108 log_error("Out of memory.");
109 ret = EXIT_FAILURE;
110 continue;
111 }
112
449ddb2d 113
adb2ce5f
LP
114 k = hashmap_put(pids, UINT_TO_PTR(pid), s);
115 if (k < 0) {
449ddb2d 116 log_error("Failed to add PID to set: %s", strerror(-k));
22f4096c 117 ret = EXIT_FAILURE;
449ddb2d
LP
118 continue;
119 }
120 }
121
122 while (!hashmap_isempty(pids)) {
123 siginfo_t si;
124 char *s;
125
126 zero(si);
127 if (waitid(P_ALL, 0, &si, WEXITED) < 0) {
128
129 if (errno == EINTR)
130 continue;
131
132 log_error("waitid() failed: %m");
22f4096c 133 ret = EXIT_FAILURE;
449ddb2d
LP
134 break;
135 }
136
adb2ce5f
LP
137 s = hashmap_remove(pids, UINT_TO_PTR(si.si_pid));
138 if (s) {
449ddb2d
LP
139 if (!is_clean_exit(si.si_code, si.si_status)) {
140 if (si.si_code == CLD_EXITED)
141 log_error("/bin/mount for %s exited with exit status %i.", s, si.si_status);
142 else
143 log_error("/bin/mount for %s terminated by signal %s.", s, signal_to_string(si.si_status));
144
22f4096c 145 ret = EXIT_FAILURE;
449ddb2d
LP
146 }
147
148 free(s);
149 }
150 }
151
152finish:
153
154 if (pids)
155 hashmap_free_free(pids);
156
157 if (f)
158 endmntent(f);
159
160 return ret;
161}