qemu/util/oslib-posix.c
<<
>>
Prefs
   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#include "qemu/osdep.h"
  30#include <termios.h>
  31#include <termios.h>
  32
  33#include <glib/gprintf.h>
  34
  35#include "sysemu/sysemu.h"
  36#include "trace.h"
  37#include "qapi/error.h"
  38#include "qemu/sockets.h"
  39#include <libgen.h>
  40#include <sys/signal.h>
  41#include "qemu/cutils.h"
  42
  43#ifdef CONFIG_LINUX
  44#include <sys/syscall.h>
  45#endif
  46
  47#ifdef __FreeBSD__
  48#include <sys/sysctl.h>
  49#endif
  50
  51#include "qemu/mmap-alloc.h"
  52
  53int qemu_get_thread_id(void)
  54{
  55#if defined(__linux__)
  56    return syscall(SYS_gettid);
  57#else
  58    return getpid();
  59#endif
  60}
  61
  62int qemu_daemon(int nochdir, int noclose)
  63{
  64    return daemon(nochdir, noclose);
  65}
  66
  67void *qemu_oom_check(void *ptr)
  68{
  69    if (ptr == NULL) {
  70        fprintf(stderr, "Failed to allocate memory: %s\n", strerror(errno));
  71        abort();
  72    }
  73    return ptr;
  74}
  75
  76void *qemu_try_memalign(size_t alignment, size_t size)
  77{
  78    void *ptr;
  79
  80    if (alignment < sizeof(void*)) {
  81        alignment = sizeof(void*);
  82    }
  83
  84#if defined(_POSIX_C_SOURCE) && !defined(__sun__)
  85    int ret;
  86    ret = posix_memalign(&ptr, alignment, size);
  87    if (ret != 0) {
  88        errno = ret;
  89        ptr = NULL;
  90    }
  91#elif defined(CONFIG_BSD)
  92    ptr = valloc(size);
  93#else
  94    ptr = memalign(alignment, size);
  95#endif
  96    trace_qemu_memalign(alignment, size, ptr);
  97    return ptr;
  98}
  99
 100void *qemu_memalign(size_t alignment, size_t size)
 101{
 102    return qemu_oom_check(qemu_try_memalign(alignment, size));
 103}
 104
 105/* alloc shared memory pages */
 106void *qemu_anon_ram_alloc(size_t size, uint64_t *alignment)
 107{
 108    size_t align = QEMU_VMALLOC_ALIGN;
 109    void *ptr = qemu_ram_mmap(-1, size, align, false);
 110
 111    if (ptr == MAP_FAILED) {
 112        return NULL;
 113    }
 114
 115    if (alignment) {
 116        *alignment = align;
 117    }
 118
 119    trace_qemu_anon_ram_alloc(size, ptr);
 120    return ptr;
 121}
 122
 123void qemu_vfree(void *ptr)
 124{
 125    trace_qemu_vfree(ptr);
 126    free(ptr);
 127}
 128
 129void qemu_anon_ram_free(void *ptr, size_t size)
 130{
 131    trace_qemu_anon_ram_free(ptr, size);
 132    qemu_ram_munmap(ptr, size);
 133}
 134
 135void qemu_set_block(int fd)
 136{
 137    int f;
 138    f = fcntl(fd, F_GETFL);
 139    fcntl(fd, F_SETFL, f & ~O_NONBLOCK);
 140}
 141
 142void qemu_set_nonblock(int fd)
 143{
 144    int f;
 145    f = fcntl(fd, F_GETFL);
 146    fcntl(fd, F_SETFL, f | O_NONBLOCK);
 147}
 148
 149int socket_set_fast_reuse(int fd)
 150{
 151    int val = 1, ret;
 152
 153    ret = setsockopt(fd, SOL_SOCKET, SO_REUSEADDR,
 154                     (const char *)&val, sizeof(val));
 155
 156    assert(ret == 0);
 157
 158    return ret;
 159}
 160
 161void qemu_set_cloexec(int fd)
 162{
 163    int f;
 164    f = fcntl(fd, F_GETFD);
 165    fcntl(fd, F_SETFD, f | FD_CLOEXEC);
 166}
 167
 168/*
 169 * Creates a pipe with FD_CLOEXEC set on both file descriptors
 170 */
 171int qemu_pipe(int pipefd[2])
 172{
 173    int ret;
 174
 175#ifdef CONFIG_PIPE2
 176    ret = pipe2(pipefd, O_CLOEXEC);
 177    if (ret != -1 || errno != ENOSYS) {
 178        return ret;
 179    }
 180#endif
 181    ret = pipe(pipefd);
 182    if (ret == 0) {
 183        qemu_set_cloexec(pipefd[0]);
 184        qemu_set_cloexec(pipefd[1]);
 185    }
 186
 187    return ret;
 188}
 189
 190int qemu_utimens(const char *path, const struct timespec *times)
 191{
 192    struct timeval tv[2], tv_now;
 193    struct stat st;
 194    int i;
 195#ifdef CONFIG_UTIMENSAT
 196    int ret;
 197
 198    ret = utimensat(AT_FDCWD, path, times, AT_SYMLINK_NOFOLLOW);
 199    if (ret != -1 || errno != ENOSYS) {
 200        return ret;
 201    }
 202#endif
 203    /* Fallback: use utimes() instead of utimensat() */
 204
 205    /* happy if special cases */
 206    if (times[0].tv_nsec == UTIME_OMIT && times[1].tv_nsec == UTIME_OMIT) {
 207        return 0;
 208    }
 209    if (times[0].tv_nsec == UTIME_NOW && times[1].tv_nsec == UTIME_NOW) {
 210        return utimes(path, NULL);
 211    }
 212
 213    /* prepare for hard cases */
 214    if (times[0].tv_nsec == UTIME_NOW || times[1].tv_nsec == UTIME_NOW) {
 215        gettimeofday(&tv_now, NULL);
 216    }
 217    if (times[0].tv_nsec == UTIME_OMIT || times[1].tv_nsec == UTIME_OMIT) {
 218        stat(path, &st);
 219    }
 220
 221    for (i = 0; i < 2; i++) {
 222        if (times[i].tv_nsec == UTIME_NOW) {
 223            tv[i].tv_sec = tv_now.tv_sec;
 224            tv[i].tv_usec = tv_now.tv_usec;
 225        } else if (times[i].tv_nsec == UTIME_OMIT) {
 226            tv[i].tv_sec = (i == 0) ? st.st_atime : st.st_mtime;
 227            tv[i].tv_usec = 0;
 228        } else {
 229            tv[i].tv_sec = times[i].tv_sec;
 230            tv[i].tv_usec = times[i].tv_nsec / 1000;
 231        }
 232    }
 233
 234    return utimes(path, &tv[0]);
 235}
 236
 237char *
 238qemu_get_local_state_pathname(const char *relative_pathname)
 239{
 240    return g_strdup_printf("%s/%s", CONFIG_QEMU_LOCALSTATEDIR,
 241                           relative_pathname);
 242}
 243
 244void qemu_set_tty_echo(int fd, bool echo)
 245{
 246    struct termios tty;
 247
 248    tcgetattr(fd, &tty);
 249
 250    if (echo) {
 251        tty.c_lflag |= ECHO | ECHONL | ICANON | IEXTEN;
 252    } else {
 253        tty.c_lflag &= ~(ECHO | ECHONL | ICANON | IEXTEN);
 254    }
 255
 256    tcsetattr(fd, TCSANOW, &tty);
 257}
 258
 259static char exec_dir[PATH_MAX];
 260
 261void qemu_init_exec_dir(const char *argv0)
 262{
 263    char *dir;
 264    char *p = NULL;
 265    char buf[PATH_MAX];
 266
 267    assert(!exec_dir[0]);
 268
 269#if defined(__linux__)
 270    {
 271        int len;
 272        len = readlink("/proc/self/exe", buf, sizeof(buf) - 1);
 273        if (len > 0) {
 274            buf[len] = 0;
 275            p = buf;
 276        }
 277    }
 278#elif defined(__FreeBSD__)
 279    {
 280        static int mib[4] = {CTL_KERN, KERN_PROC, KERN_PROC_PATHNAME, -1};
 281        size_t len = sizeof(buf) - 1;
 282
 283        *buf = '\0';
 284        if (!sysctl(mib, ARRAY_SIZE(mib), buf, &len, NULL, 0) &&
 285            *buf) {
 286            buf[sizeof(buf) - 1] = '\0';
 287            p = buf;
 288        }
 289    }
 290#endif
 291    /* If we don't have any way of figuring out the actual executable
 292       location then try argv[0].  */
 293    if (!p) {
 294        if (!argv0) {
 295            return;
 296        }
 297        p = realpath(argv0, buf);
 298        if (!p) {
 299            return;
 300        }
 301    }
 302    dir = g_path_get_dirname(p);
 303
 304    pstrcpy(exec_dir, sizeof(exec_dir), dir);
 305
 306    g_free(dir);
 307}
 308
 309char *qemu_get_exec_dir(void)
 310{
 311    return g_strdup(exec_dir);
 312}
 313
 314static sigjmp_buf sigjump;
 315
 316static void sigbus_handler(int signal)
 317{
 318    siglongjmp(sigjump, 1);
 319}
 320
 321void os_mem_prealloc(int fd, char *area, size_t memory, Error **errp)
 322{
 323    int ret;
 324    struct sigaction act, oldact;
 325    sigset_t set, oldset;
 326
 327    memset(&act, 0, sizeof(act));
 328    act.sa_handler = &sigbus_handler;
 329    act.sa_flags = 0;
 330
 331    ret = sigaction(SIGBUS, &act, &oldact);
 332    if (ret) {
 333        error_setg_errno(errp, errno,
 334            "os_mem_prealloc: failed to install signal handler");
 335        return;
 336    }
 337
 338    /* unblock SIGBUS */
 339    sigemptyset(&set);
 340    sigaddset(&set, SIGBUS);
 341    pthread_sigmask(SIG_UNBLOCK, &set, &oldset);
 342
 343    if (sigsetjmp(sigjump, 1)) {
 344        error_setg(errp, "os_mem_prealloc: Insufficient free host memory "
 345            "pages available to allocate guest RAM\n");
 346    } else {
 347        int i;
 348        size_t hpagesize = qemu_fd_getpagesize(fd);
 349        size_t numpages = DIV_ROUND_UP(memory, hpagesize);
 350
 351        /* MAP_POPULATE silently ignores failures */
 352        for (i = 0; i < numpages; i++) {
 353            memset(area + (hpagesize * i), 0, 1);
 354        }
 355    }
 356
 357    ret = sigaction(SIGBUS, &oldact, NULL);
 358    if (ret) {
 359        /* Terminate QEMU since it can't recover from error */
 360        perror("os_mem_prealloc: failed to reinstall signal handler");
 361        exit(1);
 362    }
 363    pthread_sigmask(SIG_SETMASK, &oldset, NULL);
 364}
 365
 366
 367static struct termios oldtty;
 368
 369static void term_exit(void)
 370{
 371    tcsetattr(0, TCSANOW, &oldtty);
 372}
 373
 374static void term_init(void)
 375{
 376    struct termios tty;
 377
 378    tcgetattr(0, &tty);
 379    oldtty = tty;
 380
 381    tty.c_iflag &= ~(IGNBRK|BRKINT|PARMRK|ISTRIP
 382                          |INLCR|IGNCR|ICRNL|IXON);
 383    tty.c_oflag |= OPOST;
 384    tty.c_lflag &= ~(ECHO|ECHONL|ICANON|IEXTEN);
 385    tty.c_cflag &= ~(CSIZE|PARENB);
 386    tty.c_cflag |= CS8;
 387    tty.c_cc[VMIN] = 1;
 388    tty.c_cc[VTIME] = 0;
 389
 390    tcsetattr(0, TCSANOW, &tty);
 391
 392    atexit(term_exit);
 393}
 394
 395int qemu_read_password(char *buf, int buf_size)
 396{
 397    uint8_t ch;
 398    int i, ret;
 399
 400    printf("password: ");
 401    fflush(stdout);
 402    term_init();
 403    i = 0;
 404    for (;;) {
 405        ret = read(0, &ch, 1);
 406        if (ret == -1) {
 407            if (errno == EAGAIN || errno == EINTR) {
 408                continue;
 409            } else {
 410                break;
 411            }
 412        } else if (ret == 0) {
 413            ret = -1;
 414            break;
 415        } else {
 416            if (ch == '\r' ||
 417                ch == '\n') {
 418                ret = 0;
 419                break;
 420            }
 421            if (i < (buf_size - 1)) {
 422                buf[i++] = ch;
 423            }
 424        }
 425    }
 426    term_exit();
 427    buf[i] = '\0';
 428    printf("\n");
 429    return ret;
 430}
 431
 432
 433pid_t qemu_fork(Error **errp)
 434{
 435    sigset_t oldmask, newmask;
 436    struct sigaction sig_action;
 437    int saved_errno;
 438    pid_t pid;
 439
 440    /*
 441     * Need to block signals now, so that child process can safely
 442     * kill off caller's signal handlers without a race.
 443     */
 444    sigfillset(&newmask);
 445    if (pthread_sigmask(SIG_SETMASK, &newmask, &oldmask) != 0) {
 446        error_setg_errno(errp, errno,
 447                         "cannot block signals");
 448        return -1;
 449    }
 450
 451    pid = fork();
 452    saved_errno = errno;
 453
 454    if (pid < 0) {
 455        /* attempt to restore signal mask, but ignore failure, to
 456         * avoid obscuring the fork failure */
 457        (void)pthread_sigmask(SIG_SETMASK, &oldmask, NULL);
 458        error_setg_errno(errp, saved_errno,
 459                         "cannot fork child process");
 460        errno = saved_errno;
 461        return -1;
 462    } else if (pid) {
 463        /* parent process */
 464
 465        /* Restore our original signal mask now that the child is
 466         * safely running. Only documented failures are EFAULT (not
 467         * possible, since we are using just-grabbed mask) or EINVAL
 468         * (not possible, since we are using correct arguments).  */
 469        (void)pthread_sigmask(SIG_SETMASK, &oldmask, NULL);
 470    } else {
 471        /* child process */
 472        size_t i;
 473
 474        /* Clear out all signal handlers from parent so nothing
 475         * unexpected can happen in our child once we unblock
 476         * signals */
 477        sig_action.sa_handler = SIG_DFL;
 478        sig_action.sa_flags = 0;
 479        sigemptyset(&sig_action.sa_mask);
 480
 481        for (i = 1; i < NSIG; i++) {
 482            /* Only possible errors are EFAULT or EINVAL The former
 483             * won't happen, the latter we expect, so no need to check
 484             * return value */
 485            (void)sigaction(i, &sig_action, NULL);
 486        }
 487
 488        /* Unmask all signals in child, since we've no idea what the
 489         * caller's done with their signal mask and don't want to
 490         * propagate that to children */
 491        sigemptyset(&newmask);
 492        if (pthread_sigmask(SIG_SETMASK, &newmask, NULL) != 0) {
 493            Error *local_err = NULL;
 494            error_setg_errno(&local_err, errno,
 495                             "cannot unblock signals");
 496            error_report_err(local_err);
 497            _exit(1);
 498        }
 499    }
 500    return pid;
 501}
 502