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