1*0c06d385Sjwpoduska /* 2*0c06d385Sjwpoduska * CDDL HEADER START 3*0c06d385Sjwpoduska * 4*0c06d385Sjwpoduska * The contents of this file are subject to the terms of the 5*0c06d385Sjwpoduska * Common Development and Distribution License, Version 1.0 only 6*0c06d385Sjwpoduska * (the "License"). You may not use this file except in compliance 7*0c06d385Sjwpoduska * with the License. 8*0c06d385Sjwpoduska * 9*0c06d385Sjwpoduska * You can obtain a copy of the license at http://smartos.org/CDDL 10*0c06d385Sjwpoduska * 11*0c06d385Sjwpoduska * See the License for the specific language governing permissions 12*0c06d385Sjwpoduska * and limitations under the License. 13*0c06d385Sjwpoduska * 14*0c06d385Sjwpoduska * When distributing Covered Code, include this CDDL HEADER in each 15*0c06d385Sjwpoduska * file. 16*0c06d385Sjwpoduska * 17*0c06d385Sjwpoduska * If applicable, add the following below this CDDL HEADER, with the 18*0c06d385Sjwpoduska * fields enclosed by brackets "[]" replaced with your own identifying 19*0c06d385Sjwpoduska * information: Portions Copyright [yyyy] [name of copyright owner] 20*0c06d385Sjwpoduska * 21*0c06d385Sjwpoduska * CDDL HEADER END 22*0c06d385Sjwpoduska * 23*0c06d385Sjwpoduska * Copyright 2020 Joyent, Inc. 24*0c06d385Sjwpoduska * 25*0c06d385Sjwpoduska */ 26*0c06d385Sjwpoduska 27*0c06d385Sjwpoduska #include <err.h> 28*0c06d385Sjwpoduska #include <errno.h> 29*0c06d385Sjwpoduska #include <stdio.h> 30*0c06d385Sjwpoduska #include <stdlib.h> 31*0c06d385Sjwpoduska #include <string.h> 32*0c06d385Sjwpoduska #include <unistd.h> 33*0c06d385Sjwpoduska #include <sys/debug.h> 34*0c06d385Sjwpoduska #include <sys/sysmacros.h> 35*0c06d385Sjwpoduska #include <sys/types.h> 36*0c06d385Sjwpoduska #include <libsysevent.h> 37*0c06d385Sjwpoduska #include <sys/sysevent/eventdefs.h> 38*0c06d385Sjwpoduska 39*0c06d385Sjwpoduska FILE *out; 40*0c06d385Sjwpoduska 41*0c06d385Sjwpoduska static void 42*0c06d385Sjwpoduska process_event(sysevent_t *ev) 43*0c06d385Sjwpoduska { 44*0c06d385Sjwpoduska char *class = NULL; 45*0c06d385Sjwpoduska char *subclass = NULL; 46*0c06d385Sjwpoduska 47*0c06d385Sjwpoduska /* get sysevent metadata and add to the nvlist */ 48*0c06d385Sjwpoduska class = sysevent_get_class_name(ev); 49*0c06d385Sjwpoduska subclass = sysevent_get_subclass_name(ev); 50*0c06d385Sjwpoduska 51*0c06d385Sjwpoduska if (class == NULL || subclass == NULL) 52*0c06d385Sjwpoduska errx(EXIT_FAILURE, "failed to retrieve sysevent metadata"); 53*0c06d385Sjwpoduska 54*0c06d385Sjwpoduska VERIFY0(strcmp(class, EC_ZFS)); 55*0c06d385Sjwpoduska VERIFY0(strcmp(subclass, ESC_ZFS_RESILVER_START)); 56*0c06d385Sjwpoduska 57*0c06d385Sjwpoduska flockfile(out); 58*0c06d385Sjwpoduska (void) fprintf(out, "Received %s.%s event\n", class, subclass); 59*0c06d385Sjwpoduska (void) fflush(out); 60*0c06d385Sjwpoduska funlockfile(out); 61*0c06d385Sjwpoduska } 62*0c06d385Sjwpoduska 63*0c06d385Sjwpoduska static void 64*0c06d385Sjwpoduska child_fatal(int fd, const char *msg, ...) 65*0c06d385Sjwpoduska { 66*0c06d385Sjwpoduska va_list ap; 67*0c06d385Sjwpoduska int fail = EXIT_FAILURE; 68*0c06d385Sjwpoduska 69*0c06d385Sjwpoduska va_start(ap, msg); 70*0c06d385Sjwpoduska (void) vfprintf(stderr, msg, ap); 71*0c06d385Sjwpoduska va_end(ap); 72*0c06d385Sjwpoduska (void) fputc('\n', stderr); 73*0c06d385Sjwpoduska 74*0c06d385Sjwpoduska (void) write(fd, &fail, sizeof (fail)); 75*0c06d385Sjwpoduska (void) close(fd); 76*0c06d385Sjwpoduska exit(EXIT_FAILURE); 77*0c06d385Sjwpoduska } 78*0c06d385Sjwpoduska 79*0c06d385Sjwpoduska static void 80*0c06d385Sjwpoduska do_child(int fd) 81*0c06d385Sjwpoduska { 82*0c06d385Sjwpoduska const char *subclasses[] = { 83*0c06d385Sjwpoduska ESC_ZFS_RESILVER_START, 84*0c06d385Sjwpoduska }; 85*0c06d385Sjwpoduska sysevent_handle_t *handle; 86*0c06d385Sjwpoduska int ret = 0; 87*0c06d385Sjwpoduska 88*0c06d385Sjwpoduska if ((handle = sysevent_bind_handle(process_event)) == NULL) { 89*0c06d385Sjwpoduska child_fatal(fd, "sysevent_bind_handle() failed: %s", 90*0c06d385Sjwpoduska strerror(errno)); 91*0c06d385Sjwpoduska } 92*0c06d385Sjwpoduska 93*0c06d385Sjwpoduska if (sysevent_subscribe_event(handle, EC_ZFS, subclasses, 94*0c06d385Sjwpoduska ARRAY_SIZE(subclasses)) != 0) { 95*0c06d385Sjwpoduska child_fatal(fd, "failed to subscribe to sysevents: %s", 96*0c06d385Sjwpoduska strerror(errno)); 97*0c06d385Sjwpoduska } 98*0c06d385Sjwpoduska 99*0c06d385Sjwpoduska (void) write(fd, &ret, sizeof (ret)); 100*0c06d385Sjwpoduska (void) close(fd); 101*0c06d385Sjwpoduska 102*0c06d385Sjwpoduska /* leave stderr open so any errors get captured by test harness */ 103*0c06d385Sjwpoduska (void) fclose(stdin); 104*0c06d385Sjwpoduska (void) fclose(stdout); 105*0c06d385Sjwpoduska 106*0c06d385Sjwpoduska for (;;) 107*0c06d385Sjwpoduska (void) pause(); 108*0c06d385Sjwpoduska } 109*0c06d385Sjwpoduska 110*0c06d385Sjwpoduska int 111*0c06d385Sjwpoduska main(int argc, char **argv) 112*0c06d385Sjwpoduska { 113*0c06d385Sjwpoduska pid_t child; 114*0c06d385Sjwpoduska int fds[2]; 115*0c06d385Sjwpoduska int ret = 0; 116*0c06d385Sjwpoduska 117*0c06d385Sjwpoduska if (argc < 2) { 118*0c06d385Sjwpoduska (void) fprintf(stderr, "Usage: %s outfile\n", argv[0]); 119*0c06d385Sjwpoduska exit(EXIT_FAILURE); 120*0c06d385Sjwpoduska } 121*0c06d385Sjwpoduska 122*0c06d385Sjwpoduska if ((out = fopen(argv[1], "w")) == NULL) 123*0c06d385Sjwpoduska err(EXIT_FAILURE, "unable to open %s", argv[1]); 124*0c06d385Sjwpoduska 125*0c06d385Sjwpoduska VERIFY0(pipe(fds)); 126*0c06d385Sjwpoduska 127*0c06d385Sjwpoduska switch (child = fork()) { 128*0c06d385Sjwpoduska case -1: 129*0c06d385Sjwpoduska err(EXIT_FAILURE, "unable to fork"); 130*0c06d385Sjwpoduska case 0: 131*0c06d385Sjwpoduska do_child(fds[1]); 132*0c06d385Sjwpoduska break; 133*0c06d385Sjwpoduska default: 134*0c06d385Sjwpoduska break; 135*0c06d385Sjwpoduska } 136*0c06d385Sjwpoduska 137*0c06d385Sjwpoduska (void) close(fds[1]); 138*0c06d385Sjwpoduska 139*0c06d385Sjwpoduska if (read(fds[0], &ret, sizeof (ret)) < 0) 140*0c06d385Sjwpoduska err(EXIT_FAILURE, "failure waiting on child"); 141*0c06d385Sjwpoduska 142*0c06d385Sjwpoduska if (ret != 0) 143*0c06d385Sjwpoduska return (ret); 144*0c06d385Sjwpoduska 145*0c06d385Sjwpoduska (void) close(fds[0]); 146*0c06d385Sjwpoduska (void) printf("%d\n", child); 147*0c06d385Sjwpoduska return (0); 148*0c06d385Sjwpoduska } 149