2
0

systemd.c 1.9 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980
  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. #include "qemu/osdep.h"
  13. #include "qemu/systemd.h"
  14. #include "qemu/cutils.h"
  15. #include "qemu/error-report.h"
  16. #ifndef _WIN32
  17. unsigned int check_socket_activation(void)
  18. {
  19. const char *s;
  20. unsigned long pid;
  21. unsigned long nr_fds;
  22. unsigned int i;
  23. int fd;
  24. int f;
  25. int err;
  26. s = getenv("LISTEN_PID");
  27. if (s == NULL) {
  28. return 0;
  29. }
  30. err = qemu_strtoul(s, NULL, 10, &pid);
  31. if (err) {
  32. return 0;
  33. }
  34. if (pid != getpid()) {
  35. return 0;
  36. }
  37. s = getenv("LISTEN_FDS");
  38. if (s == NULL) {
  39. return 0;
  40. }
  41. err = qemu_strtoul(s, NULL, 10, &nr_fds);
  42. if (err) {
  43. return 0;
  44. }
  45. assert(nr_fds <= UINT_MAX);
  46. /* So these are not passed to any child processes we might start. */
  47. unsetenv("LISTEN_FDS");
  48. unsetenv("LISTEN_PID");
  49. unsetenv("LISTEN_FDNAMES");
  50. /* So the file descriptors don't leak into child processes. */
  51. for (i = 0; i < nr_fds; ++i) {
  52. fd = FIRST_SOCKET_ACTIVATION_FD + i;
  53. f = fcntl(fd, F_GETFD);
  54. if (f == -1 || fcntl(fd, F_SETFD, f | FD_CLOEXEC) == -1) {
  55. /* If we cannot set FD_CLOEXEC then it probably means the file
  56. * descriptor is invalid, so socket activation has gone wrong
  57. * and we should exit.
  58. */
  59. error_report("Socket activation failed: "
  60. "invalid file descriptor fd = %d: %s",
  61. fd, g_strerror(errno));
  62. exit(EXIT_FAILURE);
  63. }
  64. }
  65. return (unsigned int) nr_fds;
  66. }
  67. #else /* !_WIN32 */
  68. unsigned int check_socket_activation(void)
  69. {
  70. return 0;
  71. }
  72. #endif