event.c revision 229945
1128707Sru/*- 2128707Sru * Copyright (c) 2010 Pawel Jakub Dawidek <pjd@FreeBSD.org> 3128707Sru * All rights reserved. 4128707Sru * 5128707Sru * Redistribution and use in source and binary forms, with or without 6128707Sru * modification, are permitted provided that the following conditions 7128707Sru * are met: 8128707Sru * 1. Redistributions of source code must retain the above copyright 9128707Sru * notice, this list of conditions and the following disclaimer. 10128707Sru * 2. Redistributions in binary form must reproduce the above copyright 11128707Sru * notice, this list of conditions and the following disclaimer in the 12128707Sru * documentation and/or other materials provided with the distribution. 13128707Sru * 14128707Sru * THIS SOFTWARE IS PROVIDED BY THE AUTHORS AND CONTRIBUTORS ``AS IS'' AND 15128707Sru * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 16128707Sru * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 17125932Sru * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE 18129240Sru * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 19129240Sru * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 20125932Sru * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 21125932Sru * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 22125932Sru * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 23125932Sru * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 24125932Sru * SUCH DAMAGE. 25125932Sru */ 26125932Sru 27242562Savg#include <sys/cdefs.h> 28125932Sru__FBSDID("$FreeBSD: head/sbin/hastd/event.c 229945 2012-01-10 22:39:07Z pjd $"); 29220337Srdivacky 30220337Srdivacky#include <errno.h> 31129240Sru 32129240Sru#include "hast.h" 33129240Sru#include "hast_proto.h" 34220337Srdivacky#include "hooks.h" 35129240Sru#include "nv.h" 36220337Srdivacky#include "pjdlog.h" 37129240Sru#include "proto.h" 38129240Sru#include "subr.h" 39129240Sru 40129240Sru#include "event.h" 41129240Sru 42129240Sruvoid 43242907Sdimevent_send(const struct hast_resource *res, int event) 44125932Sru{ 45242562Savg struct nv *nvin, *nvout; 46125932Sru int error; 47242907Sdim 48242562Savg PJDLOG_ASSERT(res != NULL); 49242562Savg PJDLOG_ASSERT(event >= EVENT_MIN && event <= EVENT_MAX); 50242562Savg 51242562Savg nvin = nvout = NULL; 52242562Savg 53242562Savg /* 54125932Sru * Prepare and send event to parent process. 55128707Sru */ 56125932Sru nvout = nv_alloc(); 57220337Srdivacky nv_add_uint8(nvout, (uint8_t)event, "event"); 58220337Srdivacky error = nv_error(nvout); 59129240Sru if (error != 0) { 60129240Sru pjdlog_common(LOG_ERR, 0, error, 61129240Sru "Unable to prepare event header"); 62129240Sru goto done; 63129240Sru } 64129240Sru if (hast_proto_send(res, res->hr_event, nvout, NULL, 0) == -1) { 65220337Srdivacky pjdlog_errno(LOG_ERR, "Unable to send event header"); 66129240Sru goto done; 67129240Sru } 68220337Srdivacky if (hast_proto_recv_hdr(res->hr_event, &nvin) == -1) { 69125932Sru pjdlog_errno(LOG_ERR, "Unable to receive event header"); 70128707Sru goto done; 71125932Sru } 72129240Sru /* 73129240Sru * Do nothing with the answer. We only wait for it to be sure not 74129240Sru * to exit too quickly after sending an event and exiting immediately. 75129240Sru */ 76129240Srudone: 77125932Sru if (nvin != NULL) 78128707Sru nv_free(nvin); 79125932Sru if (nvout != NULL) 80129240Sru nv_free(nvout); 81129240Sru} 82129240Sru 83129240Sruint 84129240Sruevent_recv(const struct hast_resource *res) 85{ 86 struct nv *nvin, *nvout; 87 const char *evstr; 88 uint8_t event; 89 int error; 90 91 PJDLOG_ASSERT(res != NULL); 92 93 nvin = nvout = NULL; 94 95 if (hast_proto_recv_hdr(res->hr_event, &nvin) == -1) { 96 /* 97 * First error log as debug. This is because worker process 98 * most likely exited. 99 */ 100 pjdlog_common(LOG_DEBUG, 1, errno, 101 "Unable to receive event header"); 102 goto fail; 103 } 104 105 event = nv_get_uint8(nvin, "event"); 106 if (event == EVENT_NONE) { 107 pjdlog_error("Event header is missing 'event' field."); 108 goto fail; 109 } 110 111 switch (event) { 112 case EVENT_CONNECT: 113 evstr = "connect"; 114 break; 115 case EVENT_DISCONNECT: 116 evstr = "disconnect"; 117 break; 118 case EVENT_SYNCSTART: 119 evstr = "syncstart"; 120 break; 121 case EVENT_SYNCDONE: 122 evstr = "syncdone"; 123 break; 124 case EVENT_SYNCINTR: 125 evstr = "syncintr"; 126 break; 127 case EVENT_SPLITBRAIN: 128 evstr = "split-brain"; 129 break; 130 default: 131 pjdlog_error("Event header contain invalid event number (%hhu).", 132 event); 133 goto fail; 134 } 135 136 pjdlog_prefix_set("[%s] (%s) ", res->hr_name, role2str(res->hr_role)); 137 hook_exec(res->hr_exec, evstr, res->hr_name, NULL); 138 pjdlog_prefix_set("%s", ""); 139 140 nvout = nv_alloc(); 141 nv_add_int16(nvout, 0, "error"); 142 error = nv_error(nvout); 143 if (error != 0) { 144 pjdlog_common(LOG_ERR, 0, error, 145 "Unable to prepare event header"); 146 goto fail; 147 } 148 if (hast_proto_send(res, res->hr_event, nvout, NULL, 0) == -1) { 149 pjdlog_errno(LOG_ERR, "Unable to send event header"); 150 goto fail; 151 } 152 nv_free(nvin); 153 nv_free(nvout); 154 return (0); 155fail: 156 if (nvin != NULL) 157 nv_free(nvin); 158 if (nvout != NULL) 159 nv_free(nvout); 160 return (-1); 161} 162