mirror of
https://github.com/swaywm/sway.git
synced 2024-12-26 06:57:15 +01:00
add --ready-fd to signal readiness
This adds a new commandline option, --ready-fd, to send a notification when sway is ready to run. This allows a process supervisor to notice sway's startup is complete which allows, for example, the session manager to start Wayland programs in the right order. Without this signal, users have to go through horrible hacks to order services. For example, I've been using `NotifyAccess=all` in the `sway.service` file and `exec systemd-notify --ready` in my sway config to emulate this. Problem is it's racy and error-prone. A particularly nasty bug triggered by `NotifyAccess=all` is when `podman` starts and then terminates a container. In that context, `conmon(8)` ends up notifying systemd it's the session master and takes over thee `MainPID` field in systemd. When it dies, systemd believes the session is over and proceeds to kill the entire session. This is explained in more details in: https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=1039857 This might not actually be the right place to do this in the sway startup sequence, that said. We call `server_run` right after, and maybe somewhere below that would be a better place. But `server_run` only calls `wl_display_run` and that's part of the core wayland library, so that seems a little too far down. I'm not sure Wayland itself is a place to do this, so for now I'm scratching my own itch and doing this in Sway itself. Note that this approach was taken instead of using the proper `sd_notify` library call, as that approach was refused in #7659. The `--ready-fd` approach was accepted in swaywm/swaylock#281 so it is hoped it will be seen as acceptable here. An alternative implementation would be to instead check the `NOTIFY_SOCKET` environment variable and use that, if present. That variable is used by systemd and at least the s6 supervisor to receive readiness notifications, so it might be less disruptive.
This commit is contained in:
parent
c5fd8c050f
commit
5eb8da6461
1 changed files with 18 additions and 1 deletions
19
sway/main.c
19
sway/main.c
|
@ -201,6 +201,7 @@ static const struct option long_options[] = {
|
||||||
{"verbose", no_argument, NULL, 'V'},
|
{"verbose", no_argument, NULL, 'V'},
|
||||||
{"get-socketpath", no_argument, NULL, 'p'},
|
{"get-socketpath", no_argument, NULL, 'p'},
|
||||||
{"unsupported-gpu", no_argument, NULL, 'u'},
|
{"unsupported-gpu", no_argument, NULL, 'u'},
|
||||||
|
{"ready-fd", required_argument, NULL, 'R'},
|
||||||
{0, 0, 0, 0}
|
{0, 0, 0, 0}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -214,17 +215,19 @@ static const char usage[] =
|
||||||
" -v, --version Show the version number and quit.\n"
|
" -v, --version Show the version number and quit.\n"
|
||||||
" -V, --verbose Enables more verbose logging.\n"
|
" -V, --verbose Enables more verbose logging.\n"
|
||||||
" --get-socketpath Gets the IPC socket path and prints it, then exits.\n"
|
" --get-socketpath Gets the IPC socket path and prints it, then exits.\n"
|
||||||
|
" -R --ready-fd <fd> Send readiness notification to the given file descriptor.\n"
|
||||||
"\n";
|
"\n";
|
||||||
|
|
||||||
int main(int argc, char **argv) {
|
int main(int argc, char **argv) {
|
||||||
static bool verbose = false, debug = false, validate = false;
|
static bool verbose = false, debug = false, validate = false;
|
||||||
|
|
||||||
char *config_path = NULL;
|
char *config_path = NULL;
|
||||||
|
int ready_fd;
|
||||||
|
|
||||||
int c;
|
int c;
|
||||||
while (1) {
|
while (1) {
|
||||||
int option_index = 0;
|
int option_index = 0;
|
||||||
c = getopt_long(argc, argv, "hCdD:vVc:", long_options, &option_index);
|
c = getopt_long(argc, argv, "hCdD:vVc:R:", long_options, &option_index);
|
||||||
if (c == -1) {
|
if (c == -1) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -265,6 +268,9 @@ int main(int argc, char **argv) {
|
||||||
exit(EXIT_FAILURE);
|
exit(EXIT_FAILURE);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
case 'R': // --ready-fd
|
||||||
|
ready_fd = strtol(optarg, NULL, 10);
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
fprintf(stderr, "%s", usage);
|
fprintf(stderr, "%s", usage);
|
||||||
exit(EXIT_FAILURE);
|
exit(EXIT_FAILURE);
|
||||||
|
@ -371,6 +377,17 @@ int main(int argc, char **argv) {
|
||||||
swaynag_show(&config->swaynag_config_errors);
|
swaynag_show(&config->swaynag_config_errors);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (ready_fd >= 0) {
|
||||||
|
// s6 wants a newline and ignores any text before that, systemd wants
|
||||||
|
// READY=1, so use the least common denominator
|
||||||
|
const char ready_str[] = "READY=1\n";
|
||||||
|
if (write(ready_fd, ready_str, strlen(ready_str)) != (ssize_t) strlen(ready_str)) {
|
||||||
|
sway_log(SWAY_INFO, "Failed to send readiness notification");
|
||||||
|
}
|
||||||
|
close(ready_fd);
|
||||||
|
ready_fd = -1;
|
||||||
|
}
|
||||||
|
|
||||||
server_run(&server);
|
server_run(&server);
|
||||||
|
|
||||||
shutdown:
|
shutdown:
|
||||||
|
|
Loading…
Reference in a new issue