qrexec: add startup notification

Avoid race conditions with services ordered shortly after qrexec start.
Make systemd know when qrexec-agent is really ready to serve.

Fixes QubesOS/qubes-issues#3985
This commit is contained in:
Marek Marczykowski-Górecki 2018-12-08 12:32:56 +01:00
parent 8216e40007
commit 426f322c58
No known key found for this signature in database
GPG Key ID: 063938BA42CFA724
2 changed files with 41 additions and 0 deletions

View File

@ -309,6 +309,42 @@ void handle_vchan_error(const char *op)
exit(1); exit(1);
} }
int my_sd_notify(int unset_environment, const char *state) {
struct sockaddr_un addr;
int fd;
int ret = -1;
addr.sun_family = AF_UNIX;
strncpy(addr.sun_path, getenv("NOTIFY_SOCKET"), sizeof(addr.sun_path)-1);
addr.sun_path[sizeof(addr.sun_path)-1] = '\0';
if (addr.sun_path[0] == '@')
addr.sun_path[0] = '\0';
if (unset_environment)
unsetenv("NOTIFY_SOCKET");
fd = socket(AF_UNIX, SOCK_DGRAM, 0);
if (fd == -1) {
perror("sd_notify socket");
return -1;
}
if (connect(fd, &addr, sizeof(addr)) == -1) {
perror("sd_notify connect");
goto out;
}
if (send(fd, state, strlen(state), 0) == -1) {
perror("sd_notify send");
goto out;
}
ret = 0;
out:
close(fd);
return ret;
}
void init() void init()
{ {
mode_t old_umask; mode_t old_umask;
@ -326,6 +362,10 @@ void init()
/* wait for qrexec daemon */ /* wait for qrexec daemon */
while (!libvchan_is_open(ctrl_vchan)) while (!libvchan_is_open(ctrl_vchan))
libvchan_wait(ctrl_vchan); libvchan_wait(ctrl_vchan);
if (getenv("NOTIFY_SOCKET")) {
my_sd_notify(1, "READY=1");
}
} }
void wake_meminfo_writer() void wake_meminfo_writer()

View File

@ -3,6 +3,7 @@ Description=Qubes remote exec agent
After=xendriverdomain.service After=xendriverdomain.service
[Service] [Service]
Type=notify
ExecStartPre=/bin/sh -c '[ -e /dev/xen/evtchn ] || modprobe xen_evtchn' ExecStartPre=/bin/sh -c '[ -e /dev/xen/evtchn ] || modprobe xen_evtchn'
ExecStart=/usr/lib/qubes/qrexec-agent ExecStart=/usr/lib/qubes/qrexec-agent