Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
freebsd
GitHub Repository: freebsd/freebsd-src
Path: blob/main/sys/contrib/openzfs/tests/zfs-tests/cmd/ereports.c
48529 views
1
// SPDX-License-Identifier: CDDL-1.0
2
/*
3
* CDDL HEADER START
4
*
5
* This file and its contents are supplied under the terms of the
6
* Common Development and Distribution License ("CDDL"), version 1.0.
7
* You may only use this file in accordance with the terms of version
8
* 1.0 of the CDDL.
9
*
10
* A full copy of the text of the CDDL should have accompanied this
11
* source. A copy of the CDDL is also available via the Internet at
12
* http://www.illumos.org/license/CDDL.
13
*
14
* CDDL HEADER END
15
*/
16
17
/*
18
* Copyright (c) 2020 by Delphix. All rights reserved.
19
*/
20
21
#include <assert.h>
22
#include <fcntl.h>
23
#include <stdio.h>
24
#include <libzfs.h>
25
#include <sys/zfs_ioctl.h>
26
#include <sys/nvpair.h>
27
#include <sys/fm/protocol.h>
28
#include <sys/fm/fs/zfs.h>
29
30
/*
31
* Command to output io and checksum ereport values, one per line.
32
* Used by zpool_events_duplicates.ksh to check for duplicate events.
33
*
34
* example output line:
35
*
36
* checksum "error_pool" 0x856dd01ce52e336 0x000034 0x000400 0x000a402c00
37
* 0x000004 0x000000 0x000000 0x000000 0x000001
38
*/
39
40
/*
41
* Our ereport duplicate criteria
42
*
43
* When the class and all of these values match, then an ereport is
44
* considered to be a duplicate.
45
*/
46
static const char *const criteria_name[] = {
47
FM_EREPORT_PAYLOAD_ZFS_POOL,
48
FM_EREPORT_PAYLOAD_ZFS_VDEV_GUID,
49
FM_EREPORT_PAYLOAD_ZFS_ZIO_ERR,
50
FM_EREPORT_PAYLOAD_ZFS_ZIO_SIZE,
51
FM_EREPORT_PAYLOAD_ZFS_ZIO_OFFSET,
52
FM_EREPORT_PAYLOAD_ZFS_ZIO_TYPE,
53
FM_EREPORT_PAYLOAD_ZFS_ZIO_PRIORITY,
54
55
/* logical zio criteriai (optional) */
56
FM_EREPORT_PAYLOAD_ZFS_ZIO_OBJSET,
57
FM_EREPORT_PAYLOAD_ZFS_ZIO_OBJECT,
58
FM_EREPORT_PAYLOAD_ZFS_ZIO_BLKID,
59
FM_EREPORT_PAYLOAD_ZFS_ZIO_LEVEL,
60
};
61
62
#define CRITERIA_NAMES_COUNT ARRAY_SIZE(criteria_name)
63
64
static void
65
print_ereport_line(nvlist_t *nvl)
66
{
67
const char *class;
68
int last = CRITERIA_NAMES_COUNT - 1;
69
70
/*
71
* For the test case context, we only want to see 'io' and
72
* 'checksum' subclass. We skip 'data' to minimize the output.
73
*/
74
if (nvlist_lookup_string(nvl, FM_CLASS, &class) != 0 ||
75
strstr(class, "ereport.fs.zfs.") == NULL ||
76
strcmp(class, "ereport.fs.zfs.data") == 0) {
77
return;
78
}
79
80
(void) printf("%s\t", class + strlen("ereport.fs.zfs."));
81
82
for (int i = 0; i < CRITERIA_NAMES_COUNT; i++) {
83
nvpair_t *nvp;
84
uint32_t i32 = 0;
85
uint64_t i64 = 0;
86
const char *str = NULL;
87
88
if (nvlist_lookup_nvpair(nvl, criteria_name[i], &nvp) != 0) {
89
/* print a proxy for optional criteria */
90
(void) printf("--------");
91
(void) printf("%c", i == last ? '\n' : '\t');
92
continue;
93
}
94
95
switch (nvpair_type(nvp)) {
96
case DATA_TYPE_STRING:
97
(void) nvpair_value_string(nvp, &str);
98
(void) printf("\"%s\"", str ? str : "<NULL>");
99
break;
100
101
case DATA_TYPE_INT32:
102
(void) nvpair_value_int32(nvp, (void *)&i32);
103
(void) printf("0x%06x", i32);
104
break;
105
106
case DATA_TYPE_UINT32:
107
(void) nvpair_value_uint32(nvp, &i32);
108
(void) printf("0x%06x", i32);
109
break;
110
111
case DATA_TYPE_INT64:
112
(void) nvpair_value_int64(nvp, (void *)&i64);
113
(void) printf("0x%06llx", (u_longlong_t)i64);
114
break;
115
116
case DATA_TYPE_UINT64:
117
(void) nvpair_value_uint64(nvp, &i64);
118
if (strcmp(FM_EREPORT_PAYLOAD_ZFS_ZIO_OFFSET,
119
criteria_name[i]) == 0)
120
(void) printf("0x%010llx", (u_longlong_t)i64);
121
else
122
(void) printf("0x%06llx", (u_longlong_t)i64);
123
break;
124
default:
125
(void) printf("<unknown>");
126
break;
127
}
128
(void) printf("%c", i == last ? '\n' : '\t');
129
}
130
}
131
132
static void
133
ereports_dump(libzfs_handle_t *zhdl, int zevent_fd)
134
{
135
nvlist_t *nvl;
136
int ret, dropped;
137
138
while (1) {
139
ret = zpool_events_next(zhdl, &nvl, &dropped, ZEVENT_NONBLOCK,
140
zevent_fd);
141
if (ret || nvl == NULL)
142
break;
143
if (dropped > 0)
144
(void) fprintf(stdout, "dropped %d events\n", dropped);
145
print_ereport_line(nvl);
146
(void) fflush(stdout);
147
nvlist_free(nvl);
148
}
149
}
150
151
int
152
main(void)
153
{
154
libzfs_handle_t *hdl;
155
int fd;
156
157
hdl = libzfs_init();
158
if (hdl == NULL) {
159
(void) fprintf(stderr, "libzfs_init: %s\n", strerror(errno));
160
exit(2);
161
}
162
fd = open(ZFS_DEV, O_RDWR);
163
if (fd < 0) {
164
(void) fprintf(stderr, "open: %s\n", strerror(errno));
165
libzfs_fini(hdl);
166
exit(2);
167
}
168
169
ereports_dump(hdl, fd);
170
171
(void) close(fd);
172
libzfs_fini(hdl);
173
174
return (0);
175
}
176
177