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 err;
  27
  28    s = getenv("LISTEN_PID");
  29    if (s == NULL) {
  30        return 0;
  31    }
  32    err = qemu_strtoul(s, NULL, 10, &pid);
  33    if (err) {
  34        return 0;
  35    }
  36    if (pid != getpid()) {
  37        return 0;
  38    }
  39
  40    s = getenv("LISTEN_FDS");
  41    if (s == NULL) {
  42        return 0;
  43    }
  44    err = qemu_strtoul(s, NULL, 10, &nr_fds);
  45    if (err) {
  46        return 0;
  47    }
  48    assert(nr_fds <= UINT_MAX);
  49
  50    /* So these are not passed to any child processes we might start. */
  51    unsetenv("LISTEN_FDS");
  52    unsetenv("LISTEN_PID");
  53
  54    /* So the file descriptors don't leak into child processes. */
  55    for (i = 0; i < nr_fds; ++i) {
  56        fd = FIRST_SOCKET_ACTIVATION_FD + i;
  57        if (fcntl(fd, F_SETFD, FD_CLOEXEC) == -1) {
  58            /* If we cannot set FD_CLOEXEC then it probably means the file
  59             * descriptor is invalid, so socket activation has gone wrong
  60             * and we should exit.
  61             */
  62            error_report("Socket activation failed: "
  63                         "invalid file descriptor fd = %d: %m",
  64                         fd);
  65            exit(EXIT_FAILURE);
  66        }
  67    }
  68
  69    return (unsigned int) nr_fds;
  70}
  71
  72#else /* !_WIN32 */
  73unsigned int check_socket_activation(void)
  74{
  75    return 0;
  76}
  77#endif
  78