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

Reply via email to