diff options
author | John Levon <john.levon@joyent.com> | 2020-05-26 13:57:13 +0000 |
---|---|---|
committer | John Levon <john.levon@joyent.com> | 2020-05-26 13:57:13 +0000 |
commit | 5b2acc0949194447bba6e45a0fa44d0b5f42f208 (patch) | |
tree | 7ea9eb87bc68fee386dd39035ce715e87a0e673c /usr/src/test/zfs-tests/tests/functional/resilver/sysevent.c | |
parent | 8ca018083101bf1cb175869679bc123187fb1bab (diff) | |
parent | 2a1277d3064386cd5c4e372301007aa330bf1d5e (diff) | |
download | illumos-joyent-gcc9.tar.gz |
mergegcc9
Diffstat (limited to 'usr/src/test/zfs-tests/tests/functional/resilver/sysevent.c')
-rw-r--r-- | usr/src/test/zfs-tests/tests/functional/resilver/sysevent.c | 163 |
1 files changed, 163 insertions, 0 deletions
diff --git a/usr/src/test/zfs-tests/tests/functional/resilver/sysevent.c b/usr/src/test/zfs-tests/tests/functional/resilver/sysevent.c new file mode 100644 index 0000000000..62a8b2faa2 --- /dev/null +++ b/usr/src/test/zfs-tests/tests/functional/resilver/sysevent.c @@ -0,0 +1,163 @@ +/* + * CDDL HEADER START + * + * The contents of this file are subject to the terms of the + * Common Development and Distribution License, Version 1.0 only + * (the "License"). You may not use this file except in compliance + * with the License. + * + * You can obtain a copy of the license at http://smartos.org/CDDL + * + * See the License for the specific language governing permissions + * and limitations under the License. + * + * When distributing Covered Code, include this CDDL HEADER in each + * file. + * + * If applicable, add the following below this CDDL HEADER, with the + * fields enclosed by brackets "[]" replaced with your own identifying + * information: Portions Copyright [yyyy] [name of copyright owner] + * + * CDDL HEADER END + * + * Copyright 2020 Joyent, Inc. + * + */ + +#include <err.h> +#include <errno.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <unistd.h> +#include <sys/debug.h> +#include <sys/sysmacros.h> +#include <sys/types.h> +#include <libsysevent.h> +#include <sys/sysevent/eventdefs.h> + +FILE *out; + +static void +process_event(sysevent_t *ev) +{ + char *class = NULL; + char *subclass = NULL; + + /* get sysevent metadata and add to the nvlist */ + class = sysevent_get_class_name(ev); + subclass = sysevent_get_subclass_name(ev); + + if (class == NULL || subclass == NULL) + errx(EXIT_FAILURE, "failed to retrieve sysevent metadata"); + + VERIFY0(strcmp(class, EC_ZFS)); + + flockfile(out); + (void) fprintf(out, "Received %s.%s event\n", class, subclass); + (void) fflush(out); + funlockfile(out); +} + +static void +child_fatal(int fd, const char *msg, ...) +{ + va_list ap; + int fail = EXIT_FAILURE; + + va_start(ap, msg); + (void) vfprintf(stderr, msg, ap); + va_end(ap); + (void) fputc('\n', stderr); + + (void) write(fd, &fail, sizeof (fail)); + (void) close(fd); + exit(EXIT_FAILURE); +} + +static void +do_child(int fd, char * const subclasses[], size_t n) +{ + sysevent_handle_t *handle; + int ret = 0; + + if ((handle = sysevent_bind_handle(process_event)) == NULL) { + child_fatal(fd, "sysevent_bind_handle() failed: %s", + strerror(errno)); + } + + if (sysevent_subscribe_event(handle, EC_ZFS, + (const char **)subclasses, n) != 0) { + child_fatal(fd, "failed to subscribe to sysevents: %s", + strerror(errno)); + } + + (void) write(fd, &ret, sizeof (ret)); + (void) close(fd); + + /* leave stderr open so any errors get captured by test harness */ + (void) fclose(stdin); + (void) fclose(stdout); + + for (;;) + (void) pause(); +} + +static void +usage(const char *name) +{ + (void) fprintf(stderr, "Usage: %s [-o outfile] zfs_event...\n", name); + exit(2); +} + +int +main(int argc, char * const argv[]) +{ + const char *outfile = NULL; + pid_t child; + int fds[2]; + int ret = 0; + int c; + + while ((c = getopt(argc, argv, "o:")) != -1) { + switch (c) { + case 'o': + outfile = optarg; + break; + case '?': + (void) fprintf(stderr, "Invalid option -%c\n", optopt); + usage(argv[0]); + } + } + + if (outfile != NULL) { + if ((out = fopen(optarg, "w")) == NULL) + err(EXIT_FAILURE, "unable to open %s", optarg); + } else { + out = stdout; + } + + VERIFY0(pipe(fds)); + + switch (child = fork()) { + case -1: + err(EXIT_FAILURE, "unable to fork"); + case 0: + do_child(fds[1], argv + optind, (size_t)(argc - optind)); + break; + default: + break; + } + + (void) close(fds[1]); + + if (read(fds[0], &ret, sizeof (ret)) < 0) + err(EXIT_FAILURE, "failure waiting on child"); + + if (ret != 0) + return (ret); + + (void) close(fds[0]); + (void) printf("%d\n", child); + return (0); +} |