Control socket activation
This branch provides reasonable configs for full systemd socket activation for kresd.
Merge request reports
Activity
Added 7 commits:
- efa731c3...5426e206 - 4 commits from branch
knot:master
- f431416d - allow control socket to be specified by systemd supervision
- d176afeb - systemd rules for closely-supervised knot-resolver service
- c1ab798f - update documentation to explain systemd socket-activation configuration
Toggle commit list- efa731c3...5426e206 - 4 commits from branch
335 335 uv_pipe_open(&pipe, 0); 336 336 uv_read_start((uv_stream_t*) &pipe, tty_alloc, tty_read); 337 337 } else { 338 (void) mkdir("tty", S_IRWXU|S_IRWXG); 339 sock_file = afmt("tty/%ld", getpid()); 340 if (sock_file) { 341 uv_pipe_bind(&pipe, sock_file); 342 uv_listen((uv_stream_t *) &pipe, 16, tty_accept); 338 int pipe_ret = -1; 339 if (control_fd != -1) { 457 464 458 465 #ifdef HAS_SYSTEMD 459 466 /* Accept passed sockets from systemd supervisor. */ 460 int sd_nsocks = sd_listen_fds(0); 467 char **socket_names = NULL; 468 int sd_nsocks = sd_listen_fds_with_names(0, &socket_names); 461 469 for (int i = 0; i < sd_nsocks; ++i) { 462 470 int fd = SD_LISTEN_FDS_START + i; 463 array_push(fd_set, fd); 471 /* when run under systemd supervision, do not use interactive mode */ 472 g_interactive = false; 473 if (forks != 1) { 474 kr_log_error("[system] when run under systemd-style supervision, " 475 "use single-process only (bad: --fork=%d).\n", forks); Err how does systemd work when you want to start multiple forks? Toy supervisor in scripts can do this perfectly fine because it communicates bound sockets through env variable and all workers are free to use them. systemd passes pipe so I guess it wouldn't be happy if all workers asked for the same socket set, but there should be a way to do that.
Edited by Marek VavrusaI think systemd can bind a set of supervised daemons to the same ports. I'd implement this with a systemd generator, but in practice i think that's likely to be overkill for most implementations.
I can provide an example set of generator unit files if that's something you want, but i figured it'd be nice to start more simply.
The idea is that you just use one fork. While the generators would be a nice feature we can provide in future, I think we don't need to cover all use cases. This would be to start kresd in full unprivileged mode using systemd, and if the sysadmin wants anything more complicated he would need to do his own provisioning anyway.
457 464 458 465 #ifdef HAS_SYSTEMD 459 466 /* Accept passed sockets from systemd supervisor. */ 460 int sd_nsocks = sd_listen_fds(0); 467 char **socket_names = NULL; 468 int sd_nsocks = sd_listen_fds_with_names(0, &socket_names); 461 469 for (int i = 0; i < sd_nsocks; ++i) { 462 470 int fd = SD_LISTEN_FDS_START + i; 463 array_push(fd_set, fd); 471 /* when run under systemd supervision, do not use interactive mode */ 472 g_interactive = false; 473 if (forks != 1) { 474 kr_log_error("[system] when run under systemd-style supervision, " 475 "use single-process only (bad: --fork=%d).\n", forks); 476 return EXIT_FAILURE; ---eh? i don't think so -- it free()s it later in the patch, no? ---
Edited to add: oh, i see what you mean, in the failure case. In this case, the daemon is going to exit anyway, so i hadn't spent the extra cycles to clean up the RAM. but i can do that in a future revision if you prefer.
Edited by Daniel Kahn Gillmor
463 array_push(fd_set, fd); 471 /* when run under systemd supervision, do not use interactive mode */ 472 g_interactive = false; 473 if (forks != 1) { 474 kr_log_error("[system] when run under systemd-style supervision, " 475 "use single-process only (bad: --fork=%d).\n", forks); 476 return EXIT_FAILURE; 477 } 478 if (!strcasecmp("control",socket_names[i])) { 479 control_fd = fd; 480 } else { 481 array_push(fd_set, fd); 482 } 483 free(socket_names[i]); 464 484 } 485 free(socket_names); It'd be probably nicer to write a cleanup routine and free the array members and then the array and reuse it in thesolved.return
above.Edited by Marek Vavrusa
Added 9 commits:
Toggle commit listmentioned in commit 7dddb6c0
- systemd/knot-resolver.service 0 → 100644
1 [Unit] 2 Description=Knot DNS Resolver daemon 3 ## This is a socket-activated service: 4 RefuseManualStart=true 5 6 [Service] 7 Type=notify 8 WorkingDirectory=/run/knot-resolver/cache 9 ExecStart=/usr/sbin/kresd 10 User=knot-resolver 11 Restart=on-failure 12 13 [Install] 14 WantedBy=sockets.target I think this line is a mistake. mea culpa! I've just opened !433 (merged) to correct it.
Thanks for catching it, @vcunat.
The thanks should go elsewhere.