git: 7dfadd78ba3c - main - hastd: Add a stop control message
- Go to: [ bottom of page ] [ top of archives ] [ this month ]
Date: Sat, 05 Sep 2026 15:44:45 UTC
The branch main has been updated by des:
URL: https://cgit.FreeBSD.org/src/commit/?id=7dfadd78ba3c4608c3631fb5008de77ea1e29e88
commit 7dfadd78ba3c4608c3631fb5008de77ea1e29e88
Author: Dag-Erling Smørgrav <des@FreeBSD.org>
AuthorDate: 2026-09-05 15:44:09 +0000
Commit: Dag-Erling Smørgrav <des@FreeBSD.org>
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