]> git.proxmox.com Git - qemu.git/blob - osdep.c
fix live migration
[qemu.git] / osdep.c
1 /*
2 * QEMU low level functions
3 *
4 * Copyright (c) 2003 Fabrice Bellard
5 *
6 * Permission is hereby granted, free of charge, to any person obtaining a copy
7 * of this software and associated documentation files (the "Software"), to deal
8 * in the Software without restriction, including without limitation the rights
9 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 * copies of the Software, and to permit persons to whom the Software is
11 * furnished to do so, subject to the following conditions:
12 *
13 * The above copyright notice and this permission notice shall be included in
14 * all copies or substantial portions of the Software.
15 *
16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
19 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22 * THE SOFTWARE.
23 */
24 #include <stdlib.h>
25 #include <stdio.h>
26 #include <stdarg.h>
27 #include <stdbool.h>
28 #include <string.h>
29 #include <errno.h>
30 #include <unistd.h>
31 #include <fcntl.h>
32
33 /* Needed early for CONFIG_BSD etc. */
34 #include "config-host.h"
35
36 #if defined(CONFIG_MADVISE) || defined(CONFIG_POSIX_MADVISE)
37 #include <sys/mman.h>
38 #endif
39
40 #ifdef CONFIG_SOLARIS
41 #include <sys/types.h>
42 #include <sys/statvfs.h>
43 /* See MySQL bug #7156 (http://bugs.mysql.com/bug.php?id=7156) for
44 discussion about Solaris header problems */
45 extern int madvise(caddr_t, size_t, int);
46 #endif
47
48 #include "qemu-common.h"
49 #include "trace.h"
50 #include "qemu_socket.h"
51 #include "monitor.h"
52
53 static bool fips_enabled = false;
54
55 static const char *qemu_version = QEMU_VERSION;
56
57 static int default_fdset_get_fd(int64_t fdset_id, int flags)
58 {
59 return -1;
60 }
61 QEMU_WEAK_ALIAS(monitor_fdset_get_fd, default_fdset_get_fd);
62 #define monitor_fdset_get_fd \
63 QEMU_WEAK_REF(monitor_fdset_get_fd, default_fdset_get_fd)
64
65 static int default_fdset_dup_fd_add(int64_t fdset_id, int dup_fd)
66 {
67 return -1;
68 }
69 QEMU_WEAK_ALIAS(monitor_fdset_dup_fd_add, default_fdset_dup_fd_add);
70 #define monitor_fdset_dup_fd_add \
71 QEMU_WEAK_REF(monitor_fdset_dup_fd_add, default_fdset_dup_fd_add)
72
73 static int default_fdset_dup_fd_remove(int dup_fd)
74 {
75 return -1;
76 }
77 QEMU_WEAK_ALIAS(monitor_fdset_dup_fd_remove, default_fdset_dup_fd_remove);
78 #define monitor_fdset_dup_fd_remove \
79 QEMU_WEAK_REF(monitor_fdset_dup_fd_remove, default_fdset_dup_fd_remove)
80
81 static int default_fdset_dup_fd_find(int dup_fd)
82 {
83 return -1;
84 }
85 QEMU_WEAK_ALIAS(monitor_fdset_dup_fd_find, default_fdset_dup_fd_find);
86 #define monitor_fdset_dup_fd_find \
87 QEMU_WEAK_REF(monitor_fdset_dup_fd_remove, default_fdset_dup_fd_find)
88
89 int socket_set_cork(int fd, int v)
90 {
91 #if defined(SOL_TCP) && defined(TCP_CORK)
92 return setsockopt(fd, SOL_TCP, TCP_CORK, &v, sizeof(v));
93 #else
94 return 0;
95 #endif
96 }
97
98 int qemu_madvise(void *addr, size_t len, int advice)
99 {
100 if (advice == QEMU_MADV_INVALID) {
101 errno = EINVAL;
102 return -1;
103 }
104 #if defined(CONFIG_MADVISE)
105 return madvise(addr, len, advice);
106 #elif defined(CONFIG_POSIX_MADVISE)
107 return posix_madvise(addr, len, advice);
108 #else
109 errno = EINVAL;
110 return -1;
111 #endif
112 }
113
114 #ifndef _WIN32
115 /*
116 * Dups an fd and sets the flags
117 */
118 static int qemu_dup_flags(int fd, int flags)
119 {
120 int ret;
121 int serrno;
122 int dup_flags;
123
124 #ifdef F_DUPFD_CLOEXEC
125 ret = fcntl(fd, F_DUPFD_CLOEXEC, 0);
126 #else
127 ret = dup(fd);
128 if (ret != -1) {
129 qemu_set_cloexec(ret);
130 }
131 #endif
132 if (ret == -1) {
133 goto fail;
134 }
135
136 dup_flags = fcntl(ret, F_GETFL);
137 if (dup_flags == -1) {
138 goto fail;
139 }
140
141 if ((flags & O_SYNC) != (dup_flags & O_SYNC)) {
142 errno = EINVAL;
143 goto fail;
144 }
145
146 /* Set/unset flags that we can with fcntl */
147 if (fcntl(ret, F_SETFL, flags) == -1) {
148 goto fail;
149 }
150
151 /* Truncate the file in the cases that open() would truncate it */
152 if (flags & O_TRUNC ||
153 ((flags & (O_CREAT | O_EXCL)) == (O_CREAT | O_EXCL))) {
154 if (ftruncate(ret, 0) == -1) {
155 goto fail;
156 }
157 }
158
159 return ret;
160
161 fail:
162 serrno = errno;
163 if (ret != -1) {
164 close(ret);
165 }
166 errno = serrno;
167 return -1;
168 }
169
170 static int qemu_parse_fdset(const char *param)
171 {
172 return qemu_parse_fd(param);
173 }
174 #endif
175
176 /*
177 * Opens a file with FD_CLOEXEC set
178 */
179 int qemu_open(const char *name, int flags, ...)
180 {
181 int ret;
182 int mode = 0;
183
184 #ifndef _WIN32
185 const char *fdset_id_str;
186
187 /* Attempt dup of fd from fd set */
188 if (strstart(name, "/dev/fdset/", &fdset_id_str)) {
189 int64_t fdset_id;
190 int fd, dupfd;
191
192 fdset_id = qemu_parse_fdset(fdset_id_str);
193 if (fdset_id == -1) {
194 errno = EINVAL;
195 return -1;
196 }
197
198 fd = monitor_fdset_get_fd(fdset_id, flags);
199 if (fd == -1) {
200 return -1;
201 }
202
203 dupfd = qemu_dup_flags(fd, flags);
204 if (dupfd == -1) {
205 return -1;
206 }
207
208 ret = monitor_fdset_dup_fd_add(fdset_id, dupfd);
209 if (ret == -1) {
210 close(dupfd);
211 errno = EINVAL;
212 return -1;
213 }
214
215 return dupfd;
216 }
217 #endif
218
219 if (flags & O_CREAT) {
220 va_list ap;
221
222 va_start(ap, flags);
223 mode = va_arg(ap, int);
224 va_end(ap);
225 }
226
227 #ifdef O_CLOEXEC
228 ret = open(name, flags | O_CLOEXEC, mode);
229 #else
230 ret = open(name, flags, mode);
231 if (ret >= 0) {
232 qemu_set_cloexec(ret);
233 }
234 #endif
235
236 return ret;
237 }
238
239 int qemu_close(int fd)
240 {
241 int64_t fdset_id;
242
243 /* Close fd that was dup'd from an fdset */
244 fdset_id = monitor_fdset_dup_fd_find(fd);
245 if (fdset_id != -1) {
246 int ret;
247
248 ret = close(fd);
249 if (ret == 0) {
250 monitor_fdset_dup_fd_remove(fd);
251 }
252
253 return ret;
254 }
255
256 return close(fd);
257 }
258
259 /*
260 * A variant of write(2) which handles partial write.
261 *
262 * Return the number of bytes transferred.
263 * Set errno if fewer than `count' bytes are written.
264 *
265 * This function don't work with non-blocking fd's.
266 * Any of the possibilities with non-bloking fd's is bad:
267 * - return a short write (then name is wrong)
268 * - busy wait adding (errno == EAGAIN) to the loop
269 */
270 ssize_t qemu_write_full(int fd, const void *buf, size_t count)
271 {
272 ssize_t ret = 0;
273 ssize_t total = 0;
274
275 while (count) {
276 ret = write(fd, buf, count);
277 if (ret < 0) {
278 if (errno == EINTR)
279 continue;
280 break;
281 }
282
283 count -= ret;
284 buf += ret;
285 total += ret;
286 }
287
288 return total;
289 }
290
291 /*
292 * Opens a socket with FD_CLOEXEC set
293 */
294 int qemu_socket(int domain, int type, int protocol)
295 {
296 int ret;
297
298 #ifdef SOCK_CLOEXEC
299 ret = socket(domain, type | SOCK_CLOEXEC, protocol);
300 if (ret != -1 || errno != EINVAL) {
301 return ret;
302 }
303 #endif
304 ret = socket(domain, type, protocol);
305 if (ret >= 0) {
306 qemu_set_cloexec(ret);
307 }
308
309 return ret;
310 }
311
312 /*
313 * Accept a connection and set FD_CLOEXEC
314 */
315 int qemu_accept(int s, struct sockaddr *addr, socklen_t *addrlen)
316 {
317 int ret;
318
319 #ifdef CONFIG_ACCEPT4
320 ret = accept4(s, addr, addrlen, SOCK_CLOEXEC);
321 if (ret != -1 || errno != ENOSYS) {
322 return ret;
323 }
324 #endif
325 ret = accept(s, addr, addrlen);
326 if (ret >= 0) {
327 qemu_set_cloexec(ret);
328 }
329
330 return ret;
331 }
332
333 /*
334 * A variant of send(2) which handles partial write.
335 *
336 * Return the number of bytes transferred, which is only
337 * smaller than `count' if there is an error.
338 *
339 * This function won't work with non-blocking fd's.
340 * Any of the possibilities with non-bloking fd's is bad:
341 * - return a short write (then name is wrong)
342 * - busy wait adding (errno == EAGAIN) to the loop
343 */
344 ssize_t qemu_send_full(int fd, const void *buf, size_t count, int flags)
345 {
346 ssize_t ret = 0;
347 ssize_t total = 0;
348
349 while (count) {
350 ret = send(fd, buf, count, flags);
351 if (ret < 0) {
352 if (errno == EINTR) {
353 continue;
354 }
355 break;
356 }
357
358 count -= ret;
359 buf += ret;
360 total += ret;
361 }
362
363 return total;
364 }
365
366 /*
367 * A variant of recv(2) which handles partial write.
368 *
369 * Return the number of bytes transferred, which is only
370 * smaller than `count' if there is an error.
371 *
372 * This function won't work with non-blocking fd's.
373 * Any of the possibilities with non-bloking fd's is bad:
374 * - return a short write (then name is wrong)
375 * - busy wait adding (errno == EAGAIN) to the loop
376 */
377 ssize_t qemu_recv_full(int fd, void *buf, size_t count, int flags)
378 {
379 ssize_t ret = 0;
380 ssize_t total = 0;
381
382 while (count) {
383 ret = qemu_recv(fd, buf, count, flags);
384 if (ret <= 0) {
385 if (ret < 0 && errno == EINTR) {
386 continue;
387 }
388 break;
389 }
390
391 count -= ret;
392 buf += ret;
393 total += ret;
394 }
395
396 return total;
397 }
398
399 void qemu_set_version(const char *version)
400 {
401 qemu_version = version;
402 }
403
404 const char *qemu_get_version(void)
405 {
406 return qemu_version;
407 }
408
409 void fips_set_state(bool requested)
410 {
411 #ifdef __linux__
412 if (requested) {
413 FILE *fds = fopen("/proc/sys/crypto/fips_enabled", "r");
414 if (fds != NULL) {
415 fips_enabled = (fgetc(fds) == '1');
416 fclose(fds);
417 }
418 }
419 #else
420 fips_enabled = false;
421 #endif /* __linux__ */
422
423 #ifdef _FIPS_DEBUG
424 fprintf(stderr, "FIPS mode %s (requested %s)\n",
425 (fips_enabled ? "enabled" : "disabled"),
426 (requested ? "enabled" : "disabled"));
427 #endif
428 }
429
430 bool fips_get_state(void)
431 {
432 return fips_enabled;
433 }
434