]> git.proxmox.com Git - mirror_qemu.git/blame - util/osdep.c
iotests: make qemu_io_log() check return codes by default
[mirror_qemu.git] / util / osdep.c
CommitLineData
ea88812f
FB
1/*
2 * QEMU low level functions
5fafdf24 3 *
ea88812f 4 * Copyright (c) 2003 Fabrice Bellard
5fafdf24 5 *
ea88812f
FB
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 */
aafd7584 24#include "qemu/osdep.h"
ebb3d49c 25#include "qapi/error.h"
f348b6d1 26#include "qemu/cutils.h"
1de7afc9 27#include "qemu/sockets.h"
d49b6836 28#include "qemu/error-report.h"
b85ea5fa 29#include "qemu/madvise.h"
f2241d16 30#include "qemu/mprotect.h"
15e09912 31#include "qemu/hw-version.h"
83c9089e 32#include "monitor/monitor.h"
03ff3ca3 33
0f66998f
PM
34static bool fips_enabled = false;
35
d494352c 36static const char *hw_version = QEMU_HW_VERSION;
93bfef4c 37
128aa589
PB
38int socket_set_cork(int fd, int v)
39{
40#if defined(SOL_TCP) && defined(TCP_CORK)
e7b79428 41 return setsockopt(fd, SOL_TCP, TCP_CORK, &v, sizeof(v));
128aa589
PB
42#else
43 return 0;
44#endif
45}
46
bf1c852a
MK
47int socket_set_nodelay(int fd)
48{
49 int v = 1;
e7b79428 50 return setsockopt(fd, IPPROTO_TCP, TCP_NODELAY, &v, sizeof(v));
bf1c852a
MK
51}
52
e78815a5
AF
53int qemu_madvise(void *addr, size_t len, int advice)
54{
55 if (advice == QEMU_MADV_INVALID) {
56 errno = EINVAL;
57 return -1;
58 }
59#if defined(CONFIG_MADVISE)
60 return madvise(addr, len, advice);
61#elif defined(CONFIG_POSIX_MADVISE)
62 return posix_madvise(addr, len, advice);
63#else
64 errno = EINVAL;
65 return -1;
66#endif
67}
68
5fa64b31
EC
69static int qemu_mprotect__osdep(void *addr, size_t size, int prot)
70{
8e3b0cbb
MAL
71 g_assert(!((uintptr_t)addr & ~qemu_real_host_page_mask()));
72 g_assert(!(size & ~qemu_real_host_page_mask()));
5fa64b31
EC
73
74#ifdef _WIN32
75 DWORD old_protect;
76
77 if (!VirtualProtect(addr, size, prot, &old_protect)) {
cf0c76cd
PMD
78 g_autofree gchar *emsg = g_win32_error_message(GetLastError());
79 error_report("%s: VirtualProtect failed: %s", __func__, emsg);
5fa64b31
EC
80 return -1;
81 }
82 return 0;
83#else
84 if (mprotect(addr, size, prot)) {
85 error_report("%s: mprotect failed: %s", __func__, strerror(errno));
86 return -1;
87 }
88 return 0;
89#endif
90}
91
d7107fc0
RH
92int qemu_mprotect_rw(void *addr, size_t size)
93{
94#ifdef _WIN32
95 return qemu_mprotect__osdep(addr, size, PAGE_READWRITE);
96#else
97 return qemu_mprotect__osdep(addr, size, PROT_READ | PROT_WRITE);
98#endif
99}
100
5fa64b31
EC
101int qemu_mprotect_rwx(void *addr, size_t size)
102{
103#ifdef _WIN32
104 return qemu_mprotect__osdep(addr, size, PAGE_EXECUTE_READWRITE);
105#else
106 return qemu_mprotect__osdep(addr, size, PROT_READ | PROT_WRITE | PROT_EXEC);
107#endif
108}
109
110int qemu_mprotect_none(void *addr, size_t size)
111{
112#ifdef _WIN32
113 return qemu_mprotect__osdep(addr, size, PAGE_NOACCESS);
114#else
115 return qemu_mprotect__osdep(addr, size, PROT_NONE);
116#endif
117}
118
adb696f3 119#ifndef _WIN32
ca749954
FZ
120
121static int fcntl_op_setlk = -1;
122static int fcntl_op_getlk = -1;
123
adb696f3
CB
124/*
125 * Dups an fd and sets the flags
126 */
60efffa4 127int qemu_dup_flags(int fd, int flags)
adb696f3
CB
128{
129 int ret;
130 int serrno;
131 int dup_flags;
adb696f3 132
761d1ddf 133 ret = qemu_dup(fd);
adb696f3
CB
134 if (ret == -1) {
135 goto fail;
136 }
137
138 dup_flags = fcntl(ret, F_GETFL);
139 if (dup_flags == -1) {
140 goto fail;
141 }
142
143 if ((flags & O_SYNC) != (dup_flags & O_SYNC)) {
144 errno = EINVAL;
145 goto fail;
146 }
147
148 /* Set/unset flags that we can with fcntl */
3b6eda2f 149 if (fcntl(ret, F_SETFL, flags) == -1) {
adb696f3
CB
150 goto fail;
151 }
152
153 /* Truncate the file in the cases that open() would truncate it */
154 if (flags & O_TRUNC ||
155 ((flags & (O_CREAT | O_EXCL)) == (O_CREAT | O_EXCL))) {
156 if (ftruncate(ret, 0) == -1) {
157 goto fail;
158 }
159 }
160
161 return ret;
162
163fail:
164 serrno = errno;
165 if (ret != -1) {
166 close(ret);
167 }
168 errno = serrno;
169 return -1;
170}
0100fbbe 171
761d1ddf
FZ
172int qemu_dup(int fd)
173{
174 int ret;
175#ifdef F_DUPFD_CLOEXEC
176 ret = fcntl(fd, F_DUPFD_CLOEXEC, 0);
177#else
178 ret = dup(fd);
179 if (ret != -1) {
180 qemu_set_cloexec(ret);
181 }
182#endif
183 return ret;
184}
185
0100fbbe
PB
186static int qemu_parse_fdset(const char *param)
187{
188 return qemu_parse_fd(param);
189}
13461fdb 190
ca749954
FZ
191static void qemu_probe_lock_ops(void)
192{
193 if (fcntl_op_setlk == -1) {
194#ifdef F_OFD_SETLK
195 int fd;
196 int ret;
197 struct flock fl = {
198 .l_whence = SEEK_SET,
199 .l_start = 0,
200 .l_len = 0,
201 .l_type = F_WRLCK,
202 };
203
204 fd = open("/dev/null", O_RDWR);
205 if (fd < 0) {
206 fprintf(stderr,
207 "Failed to open /dev/null for OFD lock probing: %s\n",
208 strerror(errno));
209 fcntl_op_setlk = F_SETLK;
210 fcntl_op_getlk = F_GETLK;
211 return;
212 }
213 ret = fcntl(fd, F_OFD_GETLK, &fl);
214 close(fd);
215 if (!ret) {
216 fcntl_op_setlk = F_OFD_SETLK;
217 fcntl_op_getlk = F_OFD_GETLK;
218 } else {
219 fcntl_op_setlk = F_SETLK;
220 fcntl_op_getlk = F_GETLK;
221 }
222#else
223 fcntl_op_setlk = F_SETLK;
224 fcntl_op_getlk = F_GETLK;
225#endif
226 }
227}
228
229bool qemu_has_ofd_lock(void)
230{
231 qemu_probe_lock_ops();
232#ifdef F_OFD_SETLK
233 return fcntl_op_setlk == F_OFD_SETLK;
234#else
235 return false;
236#endif
237}
238
13461fdb
FZ
239static int qemu_lock_fcntl(int fd, int64_t start, int64_t len, int fl_type)
240{
13461fdb
FZ
241 int ret;
242 struct flock fl = {
243 .l_whence = SEEK_SET,
244 .l_start = start,
245 .l_len = len,
246 .l_type = fl_type,
247 };
ca749954 248 qemu_probe_lock_ops();
f86428a1
FZ
249 do {
250 ret = fcntl(fd, fcntl_op_setlk, &fl);
251 } while (ret == -1 && errno == EINTR);
13461fdb 252 return ret == -1 ? -errno : 0;
13461fdb
FZ
253}
254
255int qemu_lock_fd(int fd, int64_t start, int64_t len, bool exclusive)
256{
257 return qemu_lock_fcntl(fd, start, len, exclusive ? F_WRLCK : F_RDLCK);
258}
259
260int qemu_unlock_fd(int fd, int64_t start, int64_t len)
261{
262 return qemu_lock_fcntl(fd, start, len, F_UNLCK);
263}
264
265int qemu_lock_fd_test(int fd, int64_t start, int64_t len, bool exclusive)
266{
13461fdb
FZ
267 int ret;
268 struct flock fl = {
269 .l_whence = SEEK_SET,
270 .l_start = start,
271 .l_len = len,
272 .l_type = exclusive ? F_WRLCK : F_RDLCK,
273 };
ca749954
FZ
274 qemu_probe_lock_ops();
275 ret = fcntl(fd, fcntl_op_getlk, &fl);
13461fdb
FZ
276 if (ret == -1) {
277 return -errno;
278 } else {
279 return fl.l_type == F_UNLCK ? 0 : -EAGAIN;
280 }
13461fdb 281}
adb696f3 282#endif
03ff3ca3 283
c2069ff6
DB
284static int qemu_open_cloexec(const char *name, int flags, mode_t mode)
285{
286 int ret;
287#ifdef O_CLOEXEC
288 ret = open(name, flags | O_CLOEXEC, mode);
289#else
290 ret = open(name, flags, mode);
291 if (ret >= 0) {
292 qemu_set_cloexec(ret);
293 }
294#endif
295 return ret;
296}
297
40ff6d7e
KW
298/*
299 * Opens a file with FD_CLOEXEC set
300 */
bf93d2ad 301static int
ebb3d49c 302qemu_open_internal(const char *name, int flags, mode_t mode, Error **errp)
40ff6d7e
KW
303{
304 int ret;
40ff6d7e 305
adb696f3
CB
306#ifndef _WIN32
307 const char *fdset_id_str;
308
309 /* Attempt dup of fd from fd set */
310 if (strstart(name, "/dev/fdset/", &fdset_id_str)) {
311 int64_t fdset_id;
60efffa4 312 int dupfd;
adb696f3
CB
313
314 fdset_id = qemu_parse_fdset(fdset_id_str);
315 if (fdset_id == -1) {
ebb3d49c 316 error_setg(errp, "Could not parse fdset %s", name);
adb696f3
CB
317 errno = EINVAL;
318 return -1;
319 }
320
60efffa4 321 dupfd = monitor_fdset_dup_fd_add(fdset_id, flags);
adb696f3 322 if (dupfd == -1) {
ebb3d49c
DB
323 error_setg_errno(errp, errno, "Could not dup FD for %s flags %x",
324 name, flags);
adb696f3
CB
325 return -1;
326 }
327
adb696f3
CB
328 return dupfd;
329 }
330#endif
331
bf93d2ad
DB
332 ret = qemu_open_cloexec(name, flags, mode);
333
ebb3d49c
DB
334 if (ret == -1) {
335 const char *action = flags & O_CREAT ? "create" : "open";
661b3e81
DB
336#ifdef O_DIRECT
337 /* Give more helpful error message for O_DIRECT */
338 if (errno == EINVAL && (flags & O_DIRECT)) {
339 ret = open(name, flags & ~O_DIRECT, mode);
340 if (ret != -1) {
341 close(ret);
342 error_setg(errp, "Could not %s '%s': "
343 "filesystem does not support O_DIRECT",
344 action, name);
345 errno = EINVAL; /* restore first open()'s errno */
346 return -1;
347 }
348 }
349#endif /* O_DIRECT */
ebb3d49c
DB
350 error_setg_errno(errp, errno, "Could not %s '%s'",
351 action, name);
352 }
353
bf93d2ad
DB
354 return ret;
355}
356
40ff6d7e 357
c490af57
DB
358int qemu_open(const char *name, int flags, Error **errp)
359{
360 assert(!(flags & O_CREAT));
361
362 return qemu_open_internal(name, flags, 0, errp);
363}
364
365
366int qemu_create(const char *name, int flags, mode_t mode, Error **errp)
367{
368 assert(!(flags & O_CREAT));
369
370 return qemu_open_internal(name, flags | O_CREAT, mode, errp);
371}
372
373
bf93d2ad
DB
374int qemu_open_old(const char *name, int flags, ...)
375{
376 va_list ap;
377 mode_t mode = 0;
378 int ret;
379
380 va_start(ap, flags);
381 if (flags & O_CREAT) {
40ff6d7e 382 mode = va_arg(ap, int);
40ff6d7e 383 }
bf93d2ad 384 va_end(ap);
40ff6d7e 385
ebb3d49c 386 ret = qemu_open_internal(name, flags, mode, NULL);
40ff6d7e 387
a5813077
SH
388#ifdef O_DIRECT
389 if (ret == -1 && errno == EINVAL && (flags & O_DIRECT)) {
390 error_report("file system may not support O_DIRECT");
391 errno = EINVAL; /* in case it was clobbered */
392 }
393#endif /* O_DIRECT */
394
40ff6d7e
KW
395 return ret;
396}
397
2e1e79da
CB
398int qemu_close(int fd)
399{
adb696f3
CB
400 int64_t fdset_id;
401
402 /* Close fd that was dup'd from an fdset */
403 fdset_id = monitor_fdset_dup_fd_find(fd);
404 if (fdset_id != -1) {
405 int ret;
406
407 ret = close(fd);
408 if (ret == 0) {
409 monitor_fdset_dup_fd_remove(fd);
410 }
411
412 return ret;
413 }
414
2e1e79da
CB
415 return close(fd);
416}
417
ee13240e
MAL
418/*
419 * Delete a file from the filesystem, unless the filename is /dev/fdset/...
420 *
421 * Returns: On success, zero is returned. On error, -1 is returned,
422 * and errno is set appropriately.
423 */
424int qemu_unlink(const char *name)
425{
426 if (g_str_has_prefix(name, "/dev/fdset/")) {
427 return 0;
428 }
429
430 return unlink(name);
431}
432
7b5f699d
KS
433/*
434 * A variant of write(2) which handles partial write.
435 *
436 * Return the number of bytes transferred.
437 * Set errno if fewer than `count' bytes are written.
1298cb68
JQ
438 *
439 * This function don't work with non-blocking fd's.
8cc360b9 440 * Any of the possibilities with non-blocking fd's is bad:
1298cb68
JQ
441 * - return a short write (then name is wrong)
442 * - busy wait adding (errno == EAGAIN) to the loop
7b5f699d
KS
443 */
444ssize_t qemu_write_full(int fd, const void *buf, size_t count)
445{
446 ssize_t ret = 0;
447 ssize_t total = 0;
448
449 while (count) {
450 ret = write(fd, buf, count);
451 if (ret < 0) {
452 if (errno == EINTR)
453 continue;
454 break;
455 }
456
457 count -= ret;
458 buf += ret;
459 total += ret;
460 }
461
462 return total;
463}
464
40ff6d7e
KW
465/*
466 * Opens a socket with FD_CLOEXEC set
467 */
468int qemu_socket(int domain, int type, int protocol)
469{
470 int ret;
471
472#ifdef SOCK_CLOEXEC
473 ret = socket(domain, type | SOCK_CLOEXEC, protocol);
3a03bfa5
AP
474 if (ret != -1 || errno != EINVAL) {
475 return ret;
476 }
477#endif
40ff6d7e
KW
478 ret = socket(domain, type, protocol);
479 if (ret >= 0) {
480 qemu_set_cloexec(ret);
481 }
40ff6d7e
KW
482
483 return ret;
484}
485
486/*
487 * Accept a connection and set FD_CLOEXEC
488 */
489int qemu_accept(int s, struct sockaddr *addr, socklen_t *addrlen)
490{
491 int ret;
492
493#ifdef CONFIG_ACCEPT4
494 ret = accept4(s, addr, addrlen, SOCK_CLOEXEC);
347ed55c 495 if (ret != -1 || errno != ENOSYS) {
3a03bfa5
AP
496 return ret;
497 }
498#endif
40ff6d7e
KW
499 ret = accept(s, addr, addrlen);
500 if (ret >= 0) {
501 qemu_set_cloexec(ret);
502 }
40ff6d7e
KW
503
504 return ret;
505}
993295fe 506
35c2c8dc 507void qemu_set_hw_version(const char *version)
93bfef4c 508{
35c2c8dc 509 hw_version = version;
93bfef4c
CV
510}
511
35c2c8dc 512const char *qemu_hw_version(void)
93bfef4c 513{
35c2c8dc 514 return hw_version;
93bfef4c 515}
0f66998f
PM
516
517void fips_set_state(bool requested)
518{
519#ifdef __linux__
520 if (requested) {
521 FILE *fds = fopen("/proc/sys/crypto/fips_enabled", "r");
522 if (fds != NULL) {
523 fips_enabled = (fgetc(fds) == '1');
524 fclose(fds);
525 }
526 }
527#else
528 fips_enabled = false;
529#endif /* __linux__ */
530
531#ifdef _FIPS_DEBUG
532 fprintf(stderr, "FIPS mode %s (requested %s)\n",
7d37435b
PB
533 (fips_enabled ? "enabled" : "disabled"),
534 (requested ? "enabled" : "disabled"));
0f66998f
PM
535#endif
536}
537
538bool fips_get_state(void)
539{
540 return fips_enabled;
541}
0100fbbe 542
d3bf825e
MAL
543#ifdef _WIN32
544static void socket_cleanup(void)
545{
546 WSACleanup();
547}
548#endif
549
550int socket_init(void)
551{
552#ifdef _WIN32
553 WSADATA Data;
554 int ret, err;
555
556 ret = WSAStartup(MAKEWORD(2, 2), &Data);
557 if (ret != 0) {
558 err = WSAGetLastError();
559 fprintf(stderr, "WSAStartup: %d\n", err);
560 return -1;
561 }
562 atexit(socket_cleanup);
563#endif
564 return 0;
565}
9adea5f7 566
ae2990c2 567
9adea5f7
PB
568#ifndef CONFIG_IOVEC
569/* helper function for iov_send_recv() */
570static ssize_t
571readv_writev(int fd, const struct iovec *iov, int iov_cnt, bool do_write)
572{
573 unsigned i = 0;
574 ssize_t ret = 0;
575 while (i < iov_cnt) {
576 ssize_t r = do_write
577 ? write(fd, iov[i].iov_base, iov[i].iov_len)
578 : read(fd, iov[i].iov_base, iov[i].iov_len);
579 if (r > 0) {
580 ret += r;
581 } else if (!r) {
582 break;
583 } else if (errno == EINTR) {
584 continue;
585 } else {
586 /* else it is some "other" error,
587 * only return if there was no data processed. */
588 if (ret == 0) {
589 ret = -1;
590 }
591 break;
592 }
593 i++;
594 }
595 return ret;
596}
597
598ssize_t
599readv(int fd, const struct iovec *iov, int iov_cnt)
600{
601 return readv_writev(fd, iov, iov_cnt, false);
602}
603
604ssize_t
605writev(int fd, const struct iovec *iov, int iov_cnt)
606{
607 return readv_writev(fd, iov, iov_cnt, true);
608}
609#endif
282468c7
MAL
610
611/*
612 * Make sure data goes on disk, but if possible do not bother to
613 * write out the inode just for timestamp updates.
614 *
615 * Unfortunately even in 2009 many operating systems do not support
616 * fdatasync and have to fall back to fsync.
617 */
618int qemu_fdatasync(int fd)
619{
620#ifdef CONFIG_FDATASYNC
621 return fdatasync(fd);
622#else
623 return fsync(fd);
624#endif
625}