root / os-posix.c @ 5a37532d
History | View | Annotate | Download (8.5 kB)
1 | 86b645e7 | Jes Sorensen | /*
|
---|---|---|---|
2 | 86b645e7 | Jes Sorensen | * os-posix.c
|
3 | 86b645e7 | Jes Sorensen | *
|
4 | 86b645e7 | Jes Sorensen | * Copyright (c) 2003-2008 Fabrice Bellard
|
5 | 86b645e7 | Jes Sorensen | * Copyright (c) 2010 Red Hat, Inc.
|
6 | 86b645e7 | Jes Sorensen | *
|
7 | 86b645e7 | Jes Sorensen | * Permission is hereby granted, free of charge, to any person obtaining a copy
|
8 | 86b645e7 | Jes Sorensen | * of this software and associated documentation files (the "Software"), to deal
|
9 | 86b645e7 | Jes Sorensen | * in the Software without restriction, including without limitation the rights
|
10 | 86b645e7 | Jes Sorensen | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
11 | 86b645e7 | Jes Sorensen | * copies of the Software, and to permit persons to whom the Software is
|
12 | 86b645e7 | Jes Sorensen | * furnished to do so, subject to the following conditions:
|
13 | 86b645e7 | Jes Sorensen | *
|
14 | 86b645e7 | Jes Sorensen | * The above copyright notice and this permission notice shall be included in
|
15 | 86b645e7 | Jes Sorensen | * all copies or substantial portions of the Software.
|
16 | 86b645e7 | Jes Sorensen | *
|
17 | 86b645e7 | Jes Sorensen | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
18 | 86b645e7 | Jes Sorensen | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
19 | 86b645e7 | Jes Sorensen | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
20 | 86b645e7 | Jes Sorensen | * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
21 | 86b645e7 | Jes Sorensen | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
22 | 86b645e7 | Jes Sorensen | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
23 | 86b645e7 | Jes Sorensen | * THE SOFTWARE.
|
24 | 86b645e7 | Jes Sorensen | */
|
25 | 86b645e7 | Jes Sorensen | |
26 | 86b645e7 | Jes Sorensen | #include <unistd.h> |
27 | 86b645e7 | Jes Sorensen | #include <fcntl.h> |
28 | 86b645e7 | Jes Sorensen | #include <signal.h> |
29 | 8d963e6a | Jes Sorensen | #include <sys/types.h> |
30 | 8d963e6a | Jes Sorensen | #include <sys/wait.h> |
31 | 69e8b162 | Jes Sorensen | /*needed for MAP_POPULATE before including qemu-options.h */
|
32 | 69e8b162 | Jes Sorensen | #include <sys/mman.h> |
33 | 8847cfe8 | Jes Sorensen | #include <pwd.h> |
34 | cc4662f9 | Stefan Hajnoczi | #include <grp.h> |
35 | 6170540b | Jes Sorensen | #include <libgen.h> |
36 | 86b645e7 | Jes Sorensen | |
37 | 86b645e7 | Jes Sorensen | /* Needed early for CONFIG_BSD etc. */
|
38 | 86b645e7 | Jes Sorensen | #include "config-host.h" |
39 | 9c17d615 | Paolo Bonzini | #include "sysemu/sysemu.h" |
40 | 59a5264b | Jes Sorensen | #include "net/slirp.h" |
41 | 59a5264b | Jes Sorensen | #include "qemu-options.h" |
42 | 86b645e7 | Jes Sorensen | |
43 | ce798cf2 | Jes Sorensen | #ifdef CONFIG_LINUX
|
44 | ce798cf2 | Jes Sorensen | #include <sys/prctl.h> |
45 | 949d31e6 | Jes Sorensen | #endif
|
46 | 949d31e6 | Jes Sorensen | |
47 | 15fdaee3 | Nathan Whitehorn | #ifdef __FreeBSD__
|
48 | 15fdaee3 | Nathan Whitehorn | #include <sys/sysctl.h> |
49 | 15fdaee3 | Nathan Whitehorn | #endif
|
50 | 15fdaee3 | Nathan Whitehorn | |
51 | 8847cfe8 | Jes Sorensen | static struct passwd *user_pwd; |
52 | 0766379d | Jes Sorensen | static const char *chroot_dir; |
53 | eb505be1 | Jes Sorensen | static int daemonize; |
54 | eb505be1 | Jes Sorensen | static int fds[2]; |
55 | 8847cfe8 | Jes Sorensen | |
56 | fe98ac14 | Jes Sorensen | void os_setup_early_signal_handling(void) |
57 | 86b645e7 | Jes Sorensen | { |
58 | 86b645e7 | Jes Sorensen | struct sigaction act;
|
59 | 86b645e7 | Jes Sorensen | sigfillset(&act.sa_mask); |
60 | 86b645e7 | Jes Sorensen | act.sa_flags = 0;
|
61 | 86b645e7 | Jes Sorensen | act.sa_handler = SIG_IGN; |
62 | 86b645e7 | Jes Sorensen | sigaction(SIGPIPE, &act, NULL);
|
63 | 86b645e7 | Jes Sorensen | } |
64 | 8d963e6a | Jes Sorensen | |
65 | f64622c4 | Gleb Natapov | static void termsig_handler(int signal, siginfo_t *info, void *c) |
66 | 8d963e6a | Jes Sorensen | { |
67 | f64622c4 | Gleb Natapov | qemu_system_killed(info->si_signo, info->si_pid); |
68 | 8d963e6a | Jes Sorensen | } |
69 | 8d963e6a | Jes Sorensen | |
70 | 8d963e6a | Jes Sorensen | void os_setup_signal_handling(void) |
71 | 8d963e6a | Jes Sorensen | { |
72 | 8d963e6a | Jes Sorensen | struct sigaction act;
|
73 | 8d963e6a | Jes Sorensen | |
74 | 8d963e6a | Jes Sorensen | memset(&act, 0, sizeof(act)); |
75 | f64622c4 | Gleb Natapov | act.sa_sigaction = termsig_handler; |
76 | f64622c4 | Gleb Natapov | act.sa_flags = SA_SIGINFO; |
77 | 8d963e6a | Jes Sorensen | sigaction(SIGINT, &act, NULL);
|
78 | 8d963e6a | Jes Sorensen | sigaction(SIGHUP, &act, NULL);
|
79 | 8d963e6a | Jes Sorensen | sigaction(SIGTERM, &act, NULL);
|
80 | 8d963e6a | Jes Sorensen | } |
81 | 6170540b | Jes Sorensen | |
82 | 6170540b | Jes Sorensen | /* Find a likely location for support files using the location of the binary.
|
83 | 6170540b | Jes Sorensen | For installed binaries this will be "$bindir/../share/qemu". When
|
84 | 6170540b | Jes Sorensen | running from the build tree this will be "$bindir/../pc-bios". */
|
85 | 6170540b | Jes Sorensen | #define SHARE_SUFFIX "/share/qemu" |
86 | 6170540b | Jes Sorensen | #define BUILD_SUFFIX "/pc-bios" |
87 | 6170540b | Jes Sorensen | char *os_find_datadir(const char *argv0) |
88 | 6170540b | Jes Sorensen | { |
89 | 6170540b | Jes Sorensen | char *dir;
|
90 | 6170540b | Jes Sorensen | char *p = NULL; |
91 | 6170540b | Jes Sorensen | char *res;
|
92 | 6170540b | Jes Sorensen | char buf[PATH_MAX];
|
93 | 6170540b | Jes Sorensen | size_t max_len; |
94 | 6170540b | Jes Sorensen | |
95 | 6170540b | Jes Sorensen | #if defined(__linux__)
|
96 | 6170540b | Jes Sorensen | { |
97 | 6170540b | Jes Sorensen | int len;
|
98 | 6170540b | Jes Sorensen | len = readlink("/proc/self/exe", buf, sizeof(buf) - 1); |
99 | 6170540b | Jes Sorensen | if (len > 0) { |
100 | 6170540b | Jes Sorensen | buf[len] = 0;
|
101 | 6170540b | Jes Sorensen | p = buf; |
102 | 6170540b | Jes Sorensen | } |
103 | 6170540b | Jes Sorensen | } |
104 | 6170540b | Jes Sorensen | #elif defined(__FreeBSD__)
|
105 | 6170540b | Jes Sorensen | { |
106 | 6170540b | Jes Sorensen | static int mib[4] = {CTL_KERN, KERN_PROC, KERN_PROC_PATHNAME, -1}; |
107 | 6170540b | Jes Sorensen | size_t len = sizeof(buf) - 1; |
108 | 6170540b | Jes Sorensen | |
109 | 6170540b | Jes Sorensen | *buf = '\0';
|
110 | 66fe09ee | Blue Swirl | if (!sysctl(mib, ARRAY_SIZE(mib), buf, &len, NULL, 0) && |
111 | 6170540b | Jes Sorensen | *buf) { |
112 | 6170540b | Jes Sorensen | buf[sizeof(buf) - 1] = '\0'; |
113 | 6170540b | Jes Sorensen | p = buf; |
114 | 6170540b | Jes Sorensen | } |
115 | 6170540b | Jes Sorensen | } |
116 | 6170540b | Jes Sorensen | #endif
|
117 | 6170540b | Jes Sorensen | /* If we don't have any way of figuring out the actual executable
|
118 | 6170540b | Jes Sorensen | location then try argv[0]. */
|
119 | 6170540b | Jes Sorensen | if (!p) {
|
120 | 6170540b | Jes Sorensen | p = realpath(argv0, buf); |
121 | 6170540b | Jes Sorensen | if (!p) {
|
122 | 6170540b | Jes Sorensen | return NULL; |
123 | 6170540b | Jes Sorensen | } |
124 | 6170540b | Jes Sorensen | } |
125 | 6170540b | Jes Sorensen | dir = dirname(p); |
126 | 6170540b | Jes Sorensen | dir = dirname(dir); |
127 | 6170540b | Jes Sorensen | |
128 | 6170540b | Jes Sorensen | max_len = strlen(dir) + |
129 | 6170540b | Jes Sorensen | MAX(strlen(SHARE_SUFFIX), strlen(BUILD_SUFFIX)) + 1;
|
130 | 7267c094 | Anthony Liguori | res = g_malloc0(max_len); |
131 | 6170540b | Jes Sorensen | snprintf(res, max_len, "%s%s", dir, SHARE_SUFFIX);
|
132 | 6170540b | Jes Sorensen | if (access(res, R_OK)) {
|
133 | 6170540b | Jes Sorensen | snprintf(res, max_len, "%s%s", dir, BUILD_SUFFIX);
|
134 | 6170540b | Jes Sorensen | if (access(res, R_OK)) {
|
135 | 7267c094 | Anthony Liguori | g_free(res); |
136 | 6170540b | Jes Sorensen | res = NULL;
|
137 | 6170540b | Jes Sorensen | } |
138 | 6170540b | Jes Sorensen | } |
139 | 6170540b | Jes Sorensen | |
140 | 6170540b | Jes Sorensen | return res;
|
141 | 6170540b | Jes Sorensen | } |
142 | 6170540b | Jes Sorensen | #undef SHARE_SUFFIX
|
143 | 6170540b | Jes Sorensen | #undef BUILD_SUFFIX
|
144 | 59a5264b | Jes Sorensen | |
145 | ce798cf2 | Jes Sorensen | void os_set_proc_name(const char *s) |
146 | ce798cf2 | Jes Sorensen | { |
147 | ce798cf2 | Jes Sorensen | #if defined(PR_SET_NAME)
|
148 | ce798cf2 | Jes Sorensen | char name[16]; |
149 | ce798cf2 | Jes Sorensen | if (!s)
|
150 | ce798cf2 | Jes Sorensen | return;
|
151 | 3eadc68e | Jim Meyering | pstrcpy(name, sizeof(name), s);
|
152 | ce798cf2 | Jes Sorensen | /* Could rewrite argv[0] too, but that's a bit more complicated.
|
153 | ce798cf2 | Jes Sorensen | This simple way is enough for `top'. */
|
154 | ce798cf2 | Jes Sorensen | if (prctl(PR_SET_NAME, name)) {
|
155 | ce798cf2 | Jes Sorensen | perror("unable to change process name");
|
156 | ce798cf2 | Jes Sorensen | exit(1);
|
157 | ce798cf2 | Jes Sorensen | } |
158 | ce798cf2 | Jes Sorensen | #else
|
159 | ce798cf2 | Jes Sorensen | fprintf(stderr, "Change of process name not supported by your OS\n");
|
160 | ce798cf2 | Jes Sorensen | exit(1);
|
161 | ce798cf2 | Jes Sorensen | #endif
|
162 | ce798cf2 | Jes Sorensen | } |
163 | ce798cf2 | Jes Sorensen | |
164 | 59a5264b | Jes Sorensen | /*
|
165 | 59a5264b | Jes Sorensen | * Parse OS specific command line options.
|
166 | 59a5264b | Jes Sorensen | * return 0 if option handled, -1 otherwise
|
167 | 59a5264b | Jes Sorensen | */
|
168 | 59a5264b | Jes Sorensen | void os_parse_cmd_args(int index, const char *optarg) |
169 | 59a5264b | Jes Sorensen | { |
170 | 59a5264b | Jes Sorensen | switch (index) {
|
171 | 59a5264b | Jes Sorensen | #ifdef CONFIG_SLIRP
|
172 | 59a5264b | Jes Sorensen | case QEMU_OPTION_smb:
|
173 | 59a5264b | Jes Sorensen | if (net_slirp_smb(optarg) < 0) |
174 | 59a5264b | Jes Sorensen | exit(1);
|
175 | 59a5264b | Jes Sorensen | break;
|
176 | 59a5264b | Jes Sorensen | #endif
|
177 | 8847cfe8 | Jes Sorensen | case QEMU_OPTION_runas:
|
178 | 8847cfe8 | Jes Sorensen | user_pwd = getpwnam(optarg); |
179 | 8847cfe8 | Jes Sorensen | if (!user_pwd) {
|
180 | 8847cfe8 | Jes Sorensen | fprintf(stderr, "User \"%s\" doesn't exist\n", optarg);
|
181 | 8847cfe8 | Jes Sorensen | exit(1);
|
182 | 8847cfe8 | Jes Sorensen | } |
183 | 8847cfe8 | Jes Sorensen | break;
|
184 | 0766379d | Jes Sorensen | case QEMU_OPTION_chroot:
|
185 | 0766379d | Jes Sorensen | chroot_dir = optarg; |
186 | 0766379d | Jes Sorensen | break;
|
187 | eb505be1 | Jes Sorensen | case QEMU_OPTION_daemonize:
|
188 | eb505be1 | Jes Sorensen | daemonize = 1;
|
189 | eb505be1 | Jes Sorensen | break;
|
190 | 70678b82 | Anthony Liguori | #if defined(CONFIG_LINUX)
|
191 | 70678b82 | Anthony Liguori | case QEMU_OPTION_enablefips:
|
192 | 70678b82 | Anthony Liguori | fips_set_state(true);
|
193 | 70678b82 | Anthony Liguori | break;
|
194 | 70678b82 | Anthony Liguori | #endif
|
195 | 59a5264b | Jes Sorensen | } |
196 | 59a5264b | Jes Sorensen | } |
197 | 8847cfe8 | Jes Sorensen | |
198 | e06eb601 | Jes Sorensen | static void change_process_uid(void) |
199 | 8847cfe8 | Jes Sorensen | { |
200 | 8847cfe8 | Jes Sorensen | if (user_pwd) {
|
201 | 8847cfe8 | Jes Sorensen | if (setgid(user_pwd->pw_gid) < 0) { |
202 | 8847cfe8 | Jes Sorensen | fprintf(stderr, "Failed to setgid(%d)\n", user_pwd->pw_gid);
|
203 | 8847cfe8 | Jes Sorensen | exit(1);
|
204 | 8847cfe8 | Jes Sorensen | } |
205 | cc4662f9 | Stefan Hajnoczi | if (initgroups(user_pwd->pw_name, user_pwd->pw_gid) < 0) { |
206 | cc4662f9 | Stefan Hajnoczi | fprintf(stderr, "Failed to initgroups(\"%s\", %d)\n",
|
207 | cc4662f9 | Stefan Hajnoczi | user_pwd->pw_name, user_pwd->pw_gid); |
208 | cc4662f9 | Stefan Hajnoczi | exit(1);
|
209 | cc4662f9 | Stefan Hajnoczi | } |
210 | 8847cfe8 | Jes Sorensen | if (setuid(user_pwd->pw_uid) < 0) { |
211 | 8847cfe8 | Jes Sorensen | fprintf(stderr, "Failed to setuid(%d)\n", user_pwd->pw_uid);
|
212 | 8847cfe8 | Jes Sorensen | exit(1);
|
213 | 8847cfe8 | Jes Sorensen | } |
214 | 8847cfe8 | Jes Sorensen | if (setuid(0) != -1) { |
215 | 8847cfe8 | Jes Sorensen | fprintf(stderr, "Dropping privileges failed\n");
|
216 | 8847cfe8 | Jes Sorensen | exit(1);
|
217 | 8847cfe8 | Jes Sorensen | } |
218 | 8847cfe8 | Jes Sorensen | } |
219 | 8847cfe8 | Jes Sorensen | } |
220 | 0766379d | Jes Sorensen | |
221 | e06eb601 | Jes Sorensen | static void change_root(void) |
222 | 0766379d | Jes Sorensen | { |
223 | 0766379d | Jes Sorensen | if (chroot_dir) {
|
224 | 0766379d | Jes Sorensen | if (chroot(chroot_dir) < 0) { |
225 | 0766379d | Jes Sorensen | fprintf(stderr, "chroot failed\n");
|
226 | 0766379d | Jes Sorensen | exit(1);
|
227 | 0766379d | Jes Sorensen | } |
228 | 0766379d | Jes Sorensen | if (chdir("/")) { |
229 | 0766379d | Jes Sorensen | perror("not able to chdir to /");
|
230 | 0766379d | Jes Sorensen | exit(1);
|
231 | 0766379d | Jes Sorensen | } |
232 | 0766379d | Jes Sorensen | } |
233 | 0766379d | Jes Sorensen | |
234 | 0766379d | Jes Sorensen | } |
235 | eb505be1 | Jes Sorensen | |
236 | eb505be1 | Jes Sorensen | void os_daemonize(void) |
237 | eb505be1 | Jes Sorensen | { |
238 | eb505be1 | Jes Sorensen | if (daemonize) {
|
239 | eb505be1 | Jes Sorensen | pid_t pid; |
240 | eb505be1 | Jes Sorensen | |
241 | eb505be1 | Jes Sorensen | if (pipe(fds) == -1) |
242 | eb505be1 | Jes Sorensen | exit(1);
|
243 | eb505be1 | Jes Sorensen | |
244 | eb505be1 | Jes Sorensen | pid = fork(); |
245 | eb505be1 | Jes Sorensen | if (pid > 0) { |
246 | eb505be1 | Jes Sorensen | uint8_t status; |
247 | eb505be1 | Jes Sorensen | ssize_t len; |
248 | eb505be1 | Jes Sorensen | |
249 | eb505be1 | Jes Sorensen | close(fds[1]);
|
250 | eb505be1 | Jes Sorensen | |
251 | eb505be1 | Jes Sorensen | again:
|
252 | eb505be1 | Jes Sorensen | len = read(fds[0], &status, 1); |
253 | eb505be1 | Jes Sorensen | if (len == -1 && (errno == EINTR)) |
254 | eb505be1 | Jes Sorensen | goto again;
|
255 | eb505be1 | Jes Sorensen | |
256 | eb505be1 | Jes Sorensen | if (len != 1) |
257 | eb505be1 | Jes Sorensen | exit(1);
|
258 | eb505be1 | Jes Sorensen | else if (status == 1) { |
259 | eb505be1 | Jes Sorensen | fprintf(stderr, "Could not acquire pidfile: %s\n", strerror(errno));
|
260 | eb505be1 | Jes Sorensen | exit(1);
|
261 | eb505be1 | Jes Sorensen | } else
|
262 | eb505be1 | Jes Sorensen | exit(0);
|
263 | eb505be1 | Jes Sorensen | } else if (pid < 0) |
264 | eb505be1 | Jes Sorensen | exit(1);
|
265 | eb505be1 | Jes Sorensen | |
266 | eb505be1 | Jes Sorensen | close(fds[0]);
|
267 | eb505be1 | Jes Sorensen | qemu_set_cloexec(fds[1]);
|
268 | eb505be1 | Jes Sorensen | |
269 | eb505be1 | Jes Sorensen | setsid(); |
270 | eb505be1 | Jes Sorensen | |
271 | eb505be1 | Jes Sorensen | pid = fork(); |
272 | eb505be1 | Jes Sorensen | if (pid > 0) |
273 | eb505be1 | Jes Sorensen | exit(0);
|
274 | eb505be1 | Jes Sorensen | else if (pid < 0) |
275 | eb505be1 | Jes Sorensen | exit(1);
|
276 | eb505be1 | Jes Sorensen | |
277 | eb505be1 | Jes Sorensen | umask(027);
|
278 | eb505be1 | Jes Sorensen | |
279 | eb505be1 | Jes Sorensen | signal(SIGTSTP, SIG_IGN); |
280 | eb505be1 | Jes Sorensen | signal(SIGTTOU, SIG_IGN); |
281 | eb505be1 | Jes Sorensen | signal(SIGTTIN, SIG_IGN); |
282 | eb505be1 | Jes Sorensen | } |
283 | eb505be1 | Jes Sorensen | } |
284 | eb505be1 | Jes Sorensen | |
285 | eb505be1 | Jes Sorensen | void os_setup_post(void) |
286 | eb505be1 | Jes Sorensen | { |
287 | eb505be1 | Jes Sorensen | int fd = 0; |
288 | eb505be1 | Jes Sorensen | |
289 | eb505be1 | Jes Sorensen | if (daemonize) {
|
290 | eb505be1 | Jes Sorensen | uint8_t status = 0;
|
291 | eb505be1 | Jes Sorensen | ssize_t len; |
292 | eb505be1 | Jes Sorensen | |
293 | eb505be1 | Jes Sorensen | again1:
|
294 | eb505be1 | Jes Sorensen | len = write(fds[1], &status, 1); |
295 | eb505be1 | Jes Sorensen | if (len == -1 && (errno == EINTR)) |
296 | eb505be1 | Jes Sorensen | goto again1;
|
297 | eb505be1 | Jes Sorensen | |
298 | eb505be1 | Jes Sorensen | if (len != 1) |
299 | eb505be1 | Jes Sorensen | exit(1);
|
300 | eb505be1 | Jes Sorensen | |
301 | eb505be1 | Jes Sorensen | if (chdir("/")) { |
302 | eb505be1 | Jes Sorensen | perror("not able to chdir to /");
|
303 | eb505be1 | Jes Sorensen | exit(1);
|
304 | eb505be1 | Jes Sorensen | } |
305 | eb505be1 | Jes Sorensen | TFR(fd = qemu_open("/dev/null", O_RDWR));
|
306 | eb505be1 | Jes Sorensen | if (fd == -1) |
307 | eb505be1 | Jes Sorensen | exit(1);
|
308 | eb505be1 | Jes Sorensen | } |
309 | eb505be1 | Jes Sorensen | |
310 | e06eb601 | Jes Sorensen | change_root(); |
311 | e06eb601 | Jes Sorensen | change_process_uid(); |
312 | eb505be1 | Jes Sorensen | |
313 | eb505be1 | Jes Sorensen | if (daemonize) {
|
314 | eb505be1 | Jes Sorensen | dup2(fd, 0);
|
315 | eb505be1 | Jes Sorensen | dup2(fd, 1);
|
316 | eb505be1 | Jes Sorensen | dup2(fd, 2);
|
317 | eb505be1 | Jes Sorensen | |
318 | eb505be1 | Jes Sorensen | close(fd); |
319 | eb505be1 | Jes Sorensen | } |
320 | eb505be1 | Jes Sorensen | } |
321 | eb505be1 | Jes Sorensen | |
322 | eb505be1 | Jes Sorensen | void os_pidfile_error(void) |
323 | eb505be1 | Jes Sorensen | { |
324 | eb505be1 | Jes Sorensen | if (daemonize) {
|
325 | eb505be1 | Jes Sorensen | uint8_t status = 1;
|
326 | eb505be1 | Jes Sorensen | if (write(fds[1], &status, 1) != 1) { |
327 | eb505be1 | Jes Sorensen | perror("daemonize. Writing to pipe\n");
|
328 | eb505be1 | Jes Sorensen | } |
329 | eb505be1 | Jes Sorensen | } else
|
330 | eb505be1 | Jes Sorensen | fprintf(stderr, "Could not acquire pid file: %s\n", strerror(errno));
|
331 | eb505be1 | Jes Sorensen | } |
332 | 9156d763 | Jes Sorensen | |
333 | 9156d763 | Jes Sorensen | void os_set_line_buffering(void) |
334 | 9156d763 | Jes Sorensen | { |
335 | 9156d763 | Jes Sorensen | setvbuf(stdout, NULL, _IOLBF, 0); |
336 | 9156d763 | Jes Sorensen | } |
337 | 949d31e6 | Jes Sorensen | |
338 | bc4a957c | Jes Sorensen | int qemu_create_pidfile(const char *filename) |
339 | bc4a957c | Jes Sorensen | { |
340 | bc4a957c | Jes Sorensen | char buffer[128]; |
341 | bc4a957c | Jes Sorensen | int len;
|
342 | bc4a957c | Jes Sorensen | int fd;
|
343 | bc4a957c | Jes Sorensen | |
344 | bc4a957c | Jes Sorensen | fd = qemu_open(filename, O_RDWR | O_CREAT, 0600);
|
345 | bc4a957c | Jes Sorensen | if (fd == -1) { |
346 | bc4a957c | Jes Sorensen | return -1; |
347 | bc4a957c | Jes Sorensen | } |
348 | bc4a957c | Jes Sorensen | if (lockf(fd, F_TLOCK, 0) == -1) { |
349 | 1bbd1592 | Markus Armbruster | close(fd); |
350 | bc4a957c | Jes Sorensen | return -1; |
351 | bc4a957c | Jes Sorensen | } |
352 | 953ffe0f | Andreas Färber | len = snprintf(buffer, sizeof(buffer), FMT_pid "\n", getpid()); |
353 | bc4a957c | Jes Sorensen | if (write(fd, buffer, len) != len) {
|
354 | 1bbd1592 | Markus Armbruster | close(fd); |
355 | bc4a957c | Jes Sorensen | return -1; |
356 | bc4a957c | Jes Sorensen | } |
357 | bc4a957c | Jes Sorensen | |
358 | 93dd748b | Laszlo Ersek | /* keep pidfile open & locked forever */
|
359 | bc4a957c | Jes Sorensen | return 0; |
360 | bc4a957c | Jes Sorensen | } |
361 | 995ee2bf | Hitoshi Mitake | |
362 | 995ee2bf | Hitoshi Mitake | bool is_daemonized(void) |
363 | 995ee2bf | Hitoshi Mitake | { |
364 | 995ee2bf | Hitoshi Mitake | return daemonize;
|
365 | 995ee2bf | Hitoshi Mitake | } |
366 | 888a6bc6 | Satoru Moriya | |
367 | 888a6bc6 | Satoru Moriya | int os_mlock(void) |
368 | 888a6bc6 | Satoru Moriya | { |
369 | 888a6bc6 | Satoru Moriya | int ret = 0; |
370 | 888a6bc6 | Satoru Moriya | |
371 | 888a6bc6 | Satoru Moriya | ret = mlockall(MCL_CURRENT | MCL_FUTURE); |
372 | 888a6bc6 | Satoru Moriya | if (ret < 0) { |
373 | 888a6bc6 | Satoru Moriya | perror("mlockall");
|
374 | 888a6bc6 | Satoru Moriya | } |
375 | 888a6bc6 | Satoru Moriya | |
376 | 888a6bc6 | Satoru Moriya | return ret;
|
377 | 888a6bc6 | Satoru Moriya | } |