1 /* 2 * os-posix-lib.c 3 * 4 * Copyright (c) 2003-2008 Fabrice Bellard 5 * Copyright (c) 2010 Red Hat, Inc. 6 * 7 * QEMU library functions on POSIX which are shared between QEMU and 8 * the QEMU tools. 9 * 10 * Permission is hereby granted, free of charge, to any person obtaining a copy 11 * of this software and associated documentation files (the "Software"), to deal 12 * in the Software without restriction, including without limitation the rights 13 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 14 * copies of the Software, and to permit persons to whom the Software is 15 * furnished to do so, subject to the following conditions: 16 * 17 * The above copyright notice and this permission notice shall be included in 18 * all copies or substantial portions of the Software. 19 * 20 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 21 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 22 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 23 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 24 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 25 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 26 * THE SOFTWARE. 27 */ 28 29 /* The following block of code temporarily renames the daemon() function so the 30 compiler does not see the warning associated with it in stdlib.h on OSX */ 31 #ifdef __APPLE__ 32 #define daemon qemu_fake_daemon_function 33 #include <stdlib.h> 34 #undef daemon 35 extern int daemon(int, int); 36 #endif 37 38 #if defined(__linux__) && (defined(__x86_64__) || defined(__arm__)) 39 /* Use 2 MiB alignment so transparent hugepages can be used by KVM. 40 Valgrind does not support alignments larger than 1 MiB, 41 therefore we need special code which handles running on Valgrind. */ 42 # define QEMU_VMALLOC_ALIGN (512 * 4096) 43 #elif defined(__linux__) && defined(__s390x__) 44 /* Use 1 MiB (segment size) alignment so gmap can be used by KVM. */ 45 # define QEMU_VMALLOC_ALIGN (256 * 4096) 46 #else 47 # define QEMU_VMALLOC_ALIGN getpagesize() 48 #endif 49 #define HUGETLBFS_MAGIC 0x958458f6 50 51 #include <termios.h> 52 #include <unistd.h> 53 #include <termios.h> 54 55 #include <glib/gprintf.h> 56 57 #include "config-host.h" 58 #include "sysemu/sysemu.h" 59 #include "trace.h" 60 #include "qemu/sockets.h" 61 #include <sys/mman.h> 62 #include <libgen.h> 63 #include <setjmp.h> 64 #include <sys/signal.h> 65 66 #ifdef CONFIG_LINUX 67 #include <sys/syscall.h> 68 #include <sys/vfs.h> 69 #endif 70 71 #ifdef __FreeBSD__ 72 #include <sys/sysctl.h> 73 #endif 74 75 int qemu_get_thread_id(void) 76 { 77 #if defined(__linux__) 78 return syscall(SYS_gettid); 79 #else 80 return getpid(); 81 #endif 82 } 83 84 int qemu_daemon(int nochdir, int noclose) 85 { 86 return daemon(nochdir, noclose); 87 } 88 89 void *qemu_oom_check(void *ptr) 90 { 91 if (ptr == NULL) { 92 fprintf(stderr, "Failed to allocate memory: %s\n", strerror(errno)); 93 abort(); 94 } 95 return ptr; 96 } 97 98 void *qemu_try_memalign(size_t alignment, size_t size) 99 { 100 void *ptr; 101 102 if (alignment < sizeof(void*)) { 103 alignment = sizeof(void*); 104 } 105 106 #if defined(_POSIX_C_SOURCE) && !defined(__sun__) 107 int ret; 108 ret = posix_memalign(&ptr, alignment, size); 109 if (ret != 0) { 110 errno = ret; 111 ptr = NULL; 112 } 113 #elif defined(CONFIG_BSD) 114 ptr = valloc(size); 115 #else 116 ptr = memalign(alignment, size); 117 #endif 118 trace_qemu_memalign(alignment, size, ptr); 119 return ptr; 120 } 121 122 void *qemu_memalign(size_t alignment, size_t size) 123 { 124 return qemu_oom_check(qemu_try_memalign(alignment, size)); 125 } 126 127 /* alloc shared memory pages */ 128 void *qemu_anon_ram_alloc(size_t size, uint64_t *alignment) 129 { 130 size_t align = QEMU_VMALLOC_ALIGN; 131 size_t total = size + align - getpagesize(); 132 void *ptr = mmap(0, total, PROT_READ | PROT_WRITE, 133 MAP_ANONYMOUS | MAP_PRIVATE, -1, 0); 134 size_t offset = QEMU_ALIGN_UP((uintptr_t)ptr, align) - (uintptr_t)ptr; 135 136 if (ptr == MAP_FAILED) { 137 return NULL; 138 } 139 140 if (alignment) { 141 *alignment = align; 142 } 143 ptr += offset; 144 total -= offset; 145 146 if (offset > 0) { 147 munmap(ptr - offset, offset); 148 } 149 if (total > size) { 150 munmap(ptr + size, total - size); 151 } 152 153 trace_qemu_anon_ram_alloc(size, ptr); 154 return ptr; 155 } 156 157 void qemu_vfree(void *ptr) 158 { 159 trace_qemu_vfree(ptr); 160 free(ptr); 161 } 162 163 void qemu_anon_ram_free(void *ptr, size_t size) 164 { 165 trace_qemu_anon_ram_free(ptr, size); 166 if (ptr) { 167 munmap(ptr, size); 168 } 169 } 170 171 void qemu_set_block(int fd) 172 { 173 int f; 174 f = fcntl(fd, F_GETFL); 175 fcntl(fd, F_SETFL, f & ~O_NONBLOCK); 176 } 177 178 void qemu_set_nonblock(int fd) 179 { 180 int f; 181 f = fcntl(fd, F_GETFL); 182 fcntl(fd, F_SETFL, f | O_NONBLOCK); 183 } 184 185 int socket_set_fast_reuse(int fd) 186 { 187 int val = 1, ret; 188 189 ret = setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, 190 (const char *)&val, sizeof(val)); 191 192 assert(ret == 0); 193 194 return ret; 195 } 196 197 void qemu_set_cloexec(int fd) 198 { 199 int f; 200 f = fcntl(fd, F_GETFD); 201 fcntl(fd, F_SETFD, f | FD_CLOEXEC); 202 } 203 204 /* 205 * Creates a pipe with FD_CLOEXEC set on both file descriptors 206 */ 207 int qemu_pipe(int pipefd[2]) 208 { 209 int ret; 210 211 #ifdef CONFIG_PIPE2 212 ret = pipe2(pipefd, O_CLOEXEC); 213 if (ret != -1 || errno != ENOSYS) { 214 return ret; 215 } 216 #endif 217 ret = pipe(pipefd); 218 if (ret == 0) { 219 qemu_set_cloexec(pipefd[0]); 220 qemu_set_cloexec(pipefd[1]); 221 } 222 223 return ret; 224 } 225 226 int qemu_utimens(const char *path, const struct timespec *times) 227 { 228 struct timeval tv[2], tv_now; 229 struct stat st; 230 int i; 231 #ifdef CONFIG_UTIMENSAT 232 int ret; 233 234 ret = utimensat(AT_FDCWD, path, times, AT_SYMLINK_NOFOLLOW); 235 if (ret != -1 || errno != ENOSYS) { 236 return ret; 237 } 238 #endif 239 /* Fallback: use utimes() instead of utimensat() */ 240 241 /* happy if special cases */ 242 if (times[0].tv_nsec == UTIME_OMIT && times[1].tv_nsec == UTIME_OMIT) { 243 return 0; 244 } 245 if (times[0].tv_nsec == UTIME_NOW && times[1].tv_nsec == UTIME_NOW) { 246 return utimes(path, NULL); 247 } 248 249 /* prepare for hard cases */ 250 if (times[0].tv_nsec == UTIME_NOW || times[1].tv_nsec == UTIME_NOW) { 251 gettimeofday(&tv_now, NULL); 252 } 253 if (times[0].tv_nsec == UTIME_OMIT || times[1].tv_nsec == UTIME_OMIT) { 254 stat(path, &st); 255 } 256 257 for (i = 0; i < 2; i++) { 258 if (times[i].tv_nsec == UTIME_NOW) { 259 tv[i].tv_sec = tv_now.tv_sec; 260 tv[i].tv_usec = tv_now.tv_usec; 261 } else if (times[i].tv_nsec == UTIME_OMIT) { 262 tv[i].tv_sec = (i == 0) ? st.st_atime : st.st_mtime; 263 tv[i].tv_usec = 0; 264 } else { 265 tv[i].tv_sec = times[i].tv_sec; 266 tv[i].tv_usec = times[i].tv_nsec / 1000; 267 } 268 } 269 270 return utimes(path, &tv[0]); 271 } 272 273 char * 274 qemu_get_local_state_pathname(const char *relative_pathname) 275 { 276 return g_strdup_printf("%s/%s", CONFIG_QEMU_LOCALSTATEDIR, 277 relative_pathname); 278 } 279 280 void qemu_set_tty_echo(int fd, bool echo) 281 { 282 struct termios tty; 283 284 tcgetattr(fd, &tty); 285 286 if (echo) { 287 tty.c_lflag |= ECHO | ECHONL | ICANON | IEXTEN; 288 } else { 289 tty.c_lflag &= ~(ECHO | ECHONL | ICANON | IEXTEN); 290 } 291 292 tcsetattr(fd, TCSANOW, &tty); 293 } 294 295 static char exec_dir[PATH_MAX]; 296 297 void qemu_init_exec_dir(const char *argv0) 298 { 299 char *dir; 300 char *p = NULL; 301 char buf[PATH_MAX]; 302 303 assert(!exec_dir[0]); 304 305 #if defined(__linux__) 306 { 307 int len; 308 len = readlink("/proc/self/exe", buf, sizeof(buf) - 1); 309 if (len > 0) { 310 buf[len] = 0; 311 p = buf; 312 } 313 } 314 #elif defined(__FreeBSD__) 315 { 316 static int mib[4] = {CTL_KERN, KERN_PROC, KERN_PROC_PATHNAME, -1}; 317 size_t len = sizeof(buf) - 1; 318 319 *buf = '\0'; 320 if (!sysctl(mib, ARRAY_SIZE(mib), buf, &len, NULL, 0) && 321 *buf) { 322 buf[sizeof(buf) - 1] = '\0'; 323 p = buf; 324 } 325 } 326 #endif 327 /* If we don't have any way of figuring out the actual executable 328 location then try argv[0]. */ 329 if (!p) { 330 if (!argv0) { 331 return; 332 } 333 p = realpath(argv0, buf); 334 if (!p) { 335 return; 336 } 337 } 338 dir = dirname(p); 339 340 pstrcpy(exec_dir, sizeof(exec_dir), dir); 341 } 342 343 char *qemu_get_exec_dir(void) 344 { 345 return g_strdup(exec_dir); 346 } 347 348 static sigjmp_buf sigjump; 349 350 static void sigbus_handler(int signal) 351 { 352 siglongjmp(sigjump, 1); 353 } 354 355 static size_t fd_getpagesize(int fd) 356 { 357 #ifdef CONFIG_LINUX 358 struct statfs fs; 359 int ret; 360 361 if (fd != -1) { 362 do { 363 ret = fstatfs(fd, &fs); 364 } while (ret != 0 && errno == EINTR); 365 366 if (ret == 0 && fs.f_type == HUGETLBFS_MAGIC) { 367 return fs.f_bsize; 368 } 369 } 370 #endif 371 372 return getpagesize(); 373 } 374 375 void os_mem_prealloc(int fd, char *area, size_t memory) 376 { 377 int ret; 378 struct sigaction act, oldact; 379 sigset_t set, oldset; 380 381 memset(&act, 0, sizeof(act)); 382 act.sa_handler = &sigbus_handler; 383 act.sa_flags = 0; 384 385 ret = sigaction(SIGBUS, &act, &oldact); 386 if (ret) { 387 perror("os_mem_prealloc: failed to install signal handler"); 388 exit(1); 389 } 390 391 /* unblock SIGBUS */ 392 sigemptyset(&set); 393 sigaddset(&set, SIGBUS); 394 pthread_sigmask(SIG_UNBLOCK, &set, &oldset); 395 396 if (sigsetjmp(sigjump, 1)) { 397 fprintf(stderr, "os_mem_prealloc: Insufficient free host memory " 398 "pages available to allocate guest RAM\n"); 399 exit(1); 400 } else { 401 int i; 402 size_t hpagesize = fd_getpagesize(fd); 403 size_t numpages = DIV_ROUND_UP(memory, hpagesize); 404 405 /* MAP_POPULATE silently ignores failures */ 406 for (i = 0; i < numpages; i++) { 407 memset(area + (hpagesize * i), 0, 1); 408 } 409 410 ret = sigaction(SIGBUS, &oldact, NULL); 411 if (ret) { 412 perror("os_mem_prealloc: failed to reinstall signal handler"); 413 exit(1); 414 } 415 416 pthread_sigmask(SIG_SETMASK, &oldset, NULL); 417 } 418 } 419 420 421 static struct termios oldtty; 422 423 static void term_exit(void) 424 { 425 tcsetattr(0, TCSANOW, &oldtty); 426 } 427 428 static void term_init(void) 429 { 430 struct termios tty; 431 432 tcgetattr(0, &tty); 433 oldtty = tty; 434 435 tty.c_iflag &= ~(IGNBRK|BRKINT|PARMRK|ISTRIP 436 |INLCR|IGNCR|ICRNL|IXON); 437 tty.c_oflag |= OPOST; 438 tty.c_lflag &= ~(ECHO|ECHONL|ICANON|IEXTEN); 439 tty.c_cflag &= ~(CSIZE|PARENB); 440 tty.c_cflag |= CS8; 441 tty.c_cc[VMIN] = 1; 442 tty.c_cc[VTIME] = 0; 443 444 tcsetattr(0, TCSANOW, &tty); 445 446 atexit(term_exit); 447 } 448 449 int qemu_read_password(char *buf, int buf_size) 450 { 451 uint8_t ch; 452 int i, ret; 453 454 printf("password: "); 455 fflush(stdout); 456 term_init(); 457 i = 0; 458 for (;;) { 459 ret = read(0, &ch, 1); 460 if (ret == -1) { 461 if (errno == EAGAIN || errno == EINTR) { 462 continue; 463 } else { 464 break; 465 } 466 } else if (ret == 0) { 467 ret = -1; 468 break; 469 } else { 470 if (ch == '\r' || 471 ch == '\n') { 472 ret = 0; 473 break; 474 } 475 if (i < (buf_size - 1)) { 476 buf[i++] = ch; 477 } 478 } 479 } 480 term_exit(); 481 buf[i] = '\0'; 482 printf("\n"); 483 return ret; 484 } 485