]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - sbin/hastd/event.c
Optionally bind ktls threads to NUMA domains
[FreeBSD/FreeBSD.git] / sbin / hastd / event.c
1 /*-
2  * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
3  *
4  * Copyright (c) 2010 Pawel Jakub Dawidek <pjd@FreeBSD.org>
5  * All rights reserved.
6  *
7  * Redistribution and use in source and binary forms, with or without
8  * modification, are permitted provided that the following conditions
9  * are met:
10  * 1. Redistributions of source code must retain the above copyright
11  *    notice, this list of conditions and the following disclaimer.
12  * 2. Redistributions in binary form must reproduce the above copyright
13  *    notice, this list of conditions and the following disclaimer in the
14  *    documentation and/or other materials provided with the distribution.
15  *
16  * THIS SOFTWARE IS PROVIDED BY THE AUTHORS AND CONTRIBUTORS ``AS IS'' AND
17  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE
20  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
21  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
22  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
23  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
24  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
25  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
26  * SUCH DAMAGE.
27  */
28
29 #include <sys/cdefs.h>
30 __FBSDID("$FreeBSD$");
31
32 #include <errno.h>
33
34 #include "hast.h"
35 #include "hast_proto.h"
36 #include "hooks.h"
37 #include "nv.h"
38 #include "pjdlog.h"
39 #include "proto.h"
40 #include "subr.h"
41
42 #include "event.h"
43
44 void
45 event_send(const struct hast_resource *res, int event)
46 {
47         struct nv *nvin, *nvout;
48         int error;
49
50         PJDLOG_ASSERT(res != NULL);
51         PJDLOG_ASSERT(event >= EVENT_MIN && event <= EVENT_MAX);
52
53         nvin = nvout = NULL;
54
55         /*
56          * Prepare and send event to parent process.
57          */
58         nvout = nv_alloc();
59         nv_add_uint8(nvout, (uint8_t)event, "event");
60         error = nv_error(nvout);
61         if (error != 0) {
62                 pjdlog_common(LOG_ERR, 0, error,
63                     "Unable to prepare event header");
64                 goto done;
65         }
66         if (hast_proto_send(res, res->hr_event, nvout, NULL, 0) == -1) {
67                 pjdlog_errno(LOG_ERR, "Unable to send event header");
68                 goto done;
69         }
70         if (hast_proto_recv_hdr(res->hr_event, &nvin) == -1) {
71                 pjdlog_errno(LOG_ERR, "Unable to receive event header");
72                 goto done;
73         }
74         /*
75          * Do nothing with the answer. We only wait for it to be sure not
76          * to exit too quickly after sending an event and exiting immediately.
77          */
78 done:
79         if (nvin != NULL)
80                 nv_free(nvin);
81         if (nvout != NULL)
82                 nv_free(nvout);
83 }
84
85 int
86 event_recv(const struct hast_resource *res)
87 {
88         struct nv *nvin, *nvout;
89         const char *evstr;
90         uint8_t event;
91         int error;
92
93         PJDLOG_ASSERT(res != NULL);
94
95         nvin = nvout = NULL;
96
97         if (hast_proto_recv_hdr(res->hr_event, &nvin) == -1) {
98                 /*
99                  * First error log as debug. This is because worker process
100                  * most likely exited.
101                  */
102                 pjdlog_common(LOG_DEBUG, 1, errno,
103                     "Unable to receive event header");
104                 goto fail;
105         }
106
107         event = nv_get_uint8(nvin, "event");
108         if (event == EVENT_NONE) {
109                 pjdlog_error("Event header is missing 'event' field.");
110                 goto fail;
111         }
112
113         switch (event) {
114         case EVENT_CONNECT:
115                 evstr = "connect";
116                 break;
117         case EVENT_DISCONNECT:
118                 evstr = "disconnect";
119                 break;
120         case EVENT_SYNCSTART:
121                 evstr = "syncstart";
122                 break;
123         case EVENT_SYNCDONE:
124                 evstr = "syncdone";
125                 break;
126         case EVENT_SYNCINTR:
127                 evstr = "syncintr";
128                 break;
129         case EVENT_SPLITBRAIN:
130                 evstr = "split-brain";
131                 break;
132         default:
133                 pjdlog_error("Event header contain invalid event number (%hhu).",
134                     event);
135                 goto fail;
136         }
137
138         pjdlog_prefix_set("[%s] (%s) ", res->hr_name, role2str(res->hr_role));
139         hook_exec(res->hr_exec, evstr, res->hr_name, NULL);
140         pjdlog_prefix_set("%s", "");
141
142         nvout = nv_alloc();
143         nv_add_int16(nvout, 0, "error");
144         error = nv_error(nvout);
145         if (error != 0) {
146                 pjdlog_common(LOG_ERR, 0, error,
147                     "Unable to prepare event header");
148                 goto fail;
149         }
150         if (hast_proto_send(res, res->hr_event, nvout, NULL, 0) == -1) {
151                 pjdlog_errno(LOG_ERR, "Unable to send event header");
152                 goto fail;
153         }
154         nv_free(nvin);
155         nv_free(nvout);
156         return (0);
157 fail:
158         if (nvin != NULL)
159                 nv_free(nvin);
160         if (nvout != NULL)
161                 nv_free(nvout);
162         return (-1);
163 }