If $NOTIFY_SOCKET environment variable is present and its
value starts with / or @ and fits in struct sockaddr_unix,
use it to send READY=1 message to a session manager like
systemd. This allows qemu to be used in a systemd Type=notify
service.
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
---
os-posix.c | 36 ++++++++++++++++++++++++++++++++++++
1 file changed, 36 insertions(+)
diff --git a/os-posix.c b/os-posix.c
index 52925c23d3..ab27252115 100644
--- a/os-posix.c
+++ b/os-posix.c
@@ -282,6 +282,41 @@ void os_setup_limits(void)
}
}
+static void sd_notify_ready(void)
+{
+#ifdef CONFIG_LINUX
+ static const char message[] = "READY=1";
+ static const char sock_env[] = "NOTIFY_SOCKET";
+
+ struct sockaddr_un sun;
+ int sock;
+ const char *sock_path;
+
+ sock_path = getenv(sock_env);
+ if (!sock_path ||
+ (*sock_path != '/' && *sock_path != '@') ||
+ strlen(sock_path) >= sizeof(sun.sun_path)) {
+ return;
+ }
+
+ memset(&sun, 0, sizeof(sun));
+ sun.sun_family = AF_UNIX;
+ strcpy(sun.sun_path, sock_path);
+ if (*sock_path == '@') {
+ sun.sun_path[0] = '\0';
+ }
+
+ sock = socket(AF_UNIX, SOCK_DGRAM, 0);
+ if (sock >= 0) {
+ /* ignore errors */
+ sendto(sock, message, sizeof(message) - 1, 0,
+ (struct sockaddr *)&sun, sizeof(sun));
+ close(sock);
+ }
+ unsetenv(sock_env);
+#endif
+}
+
void os_setup_post(void)
{
int fd = 0;
@@ -297,6 +332,7 @@ void os_setup_post(void)
}
}
+ sd_notify_ready();
change_root();
change_process_uid();
--
2.47.3