The branch main has been updated by des: URL: https://cgit.FreeBSD.org/src/commit/?id=7dfadd78ba3c4608c3631fb5008de77ea1e29e88
commit 7dfadd78ba3c4608c3631fb5008de77ea1e29e88 Author: Dag-Erling Smørgrav <[email protected]> AuthorDate: 2026-09-05 15:44:09 +0000 Commit: Dag-Erling Smørgrav <[email protected]> CommitDate: 2026-09-05 15:44:35 +0000 hastd: Add a stop control message Add a stop control message which causes hastd to clean up and terminate. Reviewed by: kevans Differential Revision: https://reviews.freebsd.org/D59344 --- sbin/hastctl/hastctl.c | 14 ++++++++++++++ sbin/hastd/control.c | 17 +++++++++++++++++ sbin/hastd/hast.h | 1 + sbin/hastd/hastd.c | 12 ++++++++---- 4 files changed, 40 insertions(+), 4 deletions(-) diff --git a/sbin/hastctl/hastctl.c b/sbin/hastctl/hastctl.c index fe37dcaa1b58..229af1dae74d 100644 --- a/sbin/hastctl/hastctl.c +++ b/sbin/hastctl/hastctl.c @@ -59,6 +59,7 @@ enum { CMD_ROLE, CMD_STATUS, CMD_DUMP, + CMD_STOP, CMD_LIST }; @@ -430,6 +431,9 @@ main(int argc, char *argv[]) } else if (strcmp(argv[1], "dump") == 0) { cmd = CMD_DUMP; optstr = "c:dh"; + } else if (strcmp(argv[1], "stop") == 0) { + cmd = CMD_STOP; + optstr = "c:dh"; } else usage(); @@ -524,6 +528,13 @@ main(int argc, char *argv[]) nv_add_string(nv, argv[ii], "resource%d", ii); } break; + case CMD_STOP: + /* Stop hastd. */ + if (argc > 0) + usage(); + nv = nv_alloc(); + nv_add_uint8(nv, HASTCTL_CMD_STOP, "cmd"); + break; default: PJDLOG_ABORT("Impossible command!"); } @@ -574,6 +585,9 @@ main(int argc, char *argv[]) case CMD_STATUS: error = control_status(nv); break; + case CMD_STOP: + error = 0; + break; default: PJDLOG_ABORT("Impossible command!"); } diff --git a/sbin/hastd/control.c b/sbin/hastd/control.c index 0a9befcc4358..7b13cc71f2c9 100644 --- a/sbin/hastd/control.c +++ b/sbin/hastd/control.c @@ -300,6 +300,15 @@ control_status(struct hastd_config *cfg, struct nv *nvout, control_status_worker(res, nvout, no); } +static void +control_stop(struct hastd_config *cfg, struct nv *nvout) +{ + pjdlog_info("Stop message received."); + (void)cfg; + (void)nvout; + sigexit_received = true; +} + void control_handle(struct hastd_config *cfg) { @@ -341,6 +350,14 @@ control_handle(struct hastd_config *cfg) error = 0; + /* The stop command does not expect any arguments. */ + if (cmd == HASTCTL_CMD_STOP) { + control_stop(cfg, nvout); + if (nv_error(nvout) != 0) + goto close; + goto fail; + } + str = nv_get_string(nvin, "resource0"); if (str == NULL) { pjdlog_error("Control header is missing 'resource0' field."); diff --git a/sbin/hastd/hast.h b/sbin/hastd/hast.h index d0f9dd874c56..a91993fc398e 100644 --- a/sbin/hastd/hast.h +++ b/sbin/hastd/hast.h @@ -66,6 +66,7 @@ #define HASTCTL_CMD_UNKNOWN 0 #define HASTCTL_CMD_SETROLE 1 #define HASTCTL_CMD_STATUS 2 +#define HASTCTL_CMD_STOP 3 #define HAST_ROLE_UNDEF 0 #define HAST_ROLE_INIT 1 diff --git a/sbin/hastd/hastd.c b/sbin/hastd/hastd.c index c62b85fd1925..5d90ddc8aff9 100644 --- a/sbin/hastd/hastd.c +++ b/sbin/hastd/hastd.c @@ -724,7 +724,6 @@ terminate_workers(void) { struct hast_resource *res; - pjdlog_info("Termination signal received, exiting."); TAILQ_FOREACH(res, &cfg->hc_resources, hr_next) { if (res->hr_workerpid == 0) continue; @@ -1044,10 +1043,8 @@ check_signals(void) switch (signo) { case SIGINT: case SIGTERM: + pjdlog_info("Termination signal received."); sigexit_received = true; - terminate_workers(); - proto_close(cfg->hc_controlconn); - exit(EX_OK); break; case SIGCHLD: child_exit(); @@ -1077,6 +1074,8 @@ main_loop(void) for (;;) { check_signals(); + if (sigexit_received) + break; /* Setup descriptors for select(2). */ FD_ZERO(&rfds); @@ -1135,6 +1134,8 @@ main_loop(void) * info about terminated workers in the meantime. */ check_signals(); + if (sigexit_received) + break; if (FD_ISSET(proto_descriptor(cfg->hc_controlconn), &rfds)) control_handle(cfg); @@ -1170,6 +1171,9 @@ main_loop(void) } } } + terminate_workers(); + proto_close(cfg->hc_controlconn); + exit(EX_OK); } static void
