qemu/util/systemd.c
<<
>>
Prefs
   1/*
   2 * systemd socket activation support
   3 *
   4 * Copyright 2017 Red Hat, Inc. and/or its affiliates
   5 *
   6 * Authors:
   7 *  Richard W.M. Jones <rjones@redhat.com>
   8 *
   9 * This work is licensed under the terms of the GNU GPL, version 2 or later.
  10 * See the COPYING file in the top-level directory.
  11 */
  12
  13#include "qemu/osdep.h"
  14#include "qemu/systemd.h"
  15#include "qemu/cutils.h"
  16#include "qemu/error-report.h"
  17
  18#ifndef _WIN32
  19unsigned int check_socket_activation(void)
  20{
  21    const char *s;
  22    unsigned long pid;
  23    unsigned long nr_fds;
  24    unsigned int i;
  25    int fd;
  26    int f;
  27    int err;
  28
  29    s = getenv("LISTEN_PID");
  30    if (s == NULL) {
  31        return 0;
  32    }
  33    err = qemu_strtoul(s, NULL, 10, &pid);
  34    if (err) {
  35        return 0;
  36    }
  37    if (pid != getpid()) {
  38        return 0;
  39    }
  40
  41    s = getenv("LISTEN_FDS");
  42    if (s == NULL) {
  43        return 0;
  44    }
  45    err = qemu_strtoul(s, NULL, 10, &nr_fds);
  46    if (err) {
  47        return 0;
  48    }
  49    assert(nr_fds <= UINT_MAX);
  50
  51    /* So these are not passed to any child processes we might start. */
  52    unsetenv("LISTEN_FDS");
  53    unsetenv("LISTEN_PID");
  54
  55    /* So the file descriptors don't leak into child processes. */
  56    for (i = 0; i < nr_fds; ++i) {
  57        fd = FIRST_SOCKET_ACTIVATION_FD + i;
  58        f = fcntl(fd, F_GETFD);
  59        if (f == -1 || fcntl(fd, F_SETFD, f | FD_CLOEXEC) == -1) {
  60            /* If we cannot set FD_CLOEXEC then it probably means the file
  61             * descriptor is invalid, so socket activation has gone wrong
  62             * and we should exit.
  63             */
  64            error_report("Socket activation failed: "
  65                         "invalid file descriptor fd = %d: %s",
  66                         fd, g_strerror(errno));
  67            exit(EXIT_FAILURE);
  68        }
  69    }
  70
  71    return (unsigned int) nr_fds;
  72}
  73
  74#else /* !_WIN32 */
  75unsigned int check_socket_activation(void)
  76{
  77    return 0;
  78}
  79#endif
  80