Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
freebsd
GitHub Repository: freebsd/freebsd-src
Path: blob/main/sys/contrib/openzfs/lib/libzutil/zutil_pool.c
48378 views
1
// SPDX-License-Identifier: CDDL-1.0
2
/*
3
* CDDL HEADER START
4
*
5
* The contents of this file are subject to the terms of the
6
* Common Development and Distribution License (the "License").
7
* You may not use this file except in compliance with the License.
8
*
9
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10
* or https://opensource.org/licenses/CDDL-1.0.
11
* See the License for the specific language governing permissions
12
* and limitations under the License.
13
*
14
* When distributing Covered Code, include this CDDL HEADER in each
15
* file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16
* If applicable, add the following below this CDDL HEADER, with the
17
* fields enclosed by brackets "[]" replaced with your own identifying
18
* information: Portions Copyright [yyyy] [name of copyright owner]
19
*
20
* CDDL HEADER END
21
*/
22
23
/*
24
* Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
25
*/
26
27
#include <stdio.h>
28
#include <stdlib.h>
29
#include <string.h>
30
#include <sys/nvpair.h>
31
#include <sys/fs/zfs.h>
32
#include <math.h>
33
34
#include <libzutil.h>
35
36
static void
37
dump_ddt_stat(const ddt_stat_t *dds, int h)
38
{
39
char refcnt[6];
40
char blocks[6], lsize[6], psize[6], dsize[6];
41
char ref_blocks[6], ref_lsize[6], ref_psize[6], ref_dsize[6];
42
43
if (dds == NULL || dds->dds_blocks == 0)
44
return;
45
46
if (h == -1)
47
(void) strcpy(refcnt, "Total");
48
else
49
zfs_nicenum(1ULL << h, refcnt, sizeof (refcnt));
50
51
zfs_nicenum(dds->dds_blocks, blocks, sizeof (blocks));
52
zfs_nicebytes(dds->dds_lsize, lsize, sizeof (lsize));
53
zfs_nicebytes(dds->dds_psize, psize, sizeof (psize));
54
zfs_nicebytes(dds->dds_dsize, dsize, sizeof (dsize));
55
zfs_nicenum(dds->dds_ref_blocks, ref_blocks, sizeof (ref_blocks));
56
zfs_nicebytes(dds->dds_ref_lsize, ref_lsize, sizeof (ref_lsize));
57
zfs_nicebytes(dds->dds_ref_psize, ref_psize, sizeof (ref_psize));
58
zfs_nicebytes(dds->dds_ref_dsize, ref_dsize, sizeof (ref_dsize));
59
60
(void) printf("%6s %6s %5s %5s %5s %6s %5s %5s %5s\n",
61
refcnt,
62
blocks, lsize, psize, dsize,
63
ref_blocks, ref_lsize, ref_psize, ref_dsize);
64
}
65
66
/*
67
* Print the DDT histogram and the column totals.
68
*/
69
void
70
zpool_dump_ddt(const ddt_stat_t *dds_total, const ddt_histogram_t *ddh)
71
{
72
int h;
73
74
(void) printf("\n");
75
76
(void) printf("bucket "
77
" allocated "
78
" referenced \n");
79
(void) printf("______ "
80
"______________________________ "
81
"______________________________\n");
82
83
(void) printf("%6s %6s %5s %5s %5s %6s %5s %5s %5s\n",
84
"refcnt",
85
"blocks", "LSIZE", "PSIZE", "DSIZE",
86
"blocks", "LSIZE", "PSIZE", "DSIZE");
87
88
(void) printf("%6s %6s %5s %5s %5s %6s %5s %5s %5s\n",
89
"------",
90
"------", "-----", "-----", "-----",
91
"------", "-----", "-----", "-----");
92
93
for (h = 0; h < 64; h++)
94
dump_ddt_stat(&ddh->ddh_stat[h], h);
95
96
dump_ddt_stat(dds_total, -1);
97
98
(void) printf("\n");
99
}
100
101
/*
102
* Process the buffer of nvlists, unpacking and storing each nvlist record
103
* into 'records'. 'leftover' is set to the number of bytes that weren't
104
* processed as there wasn't a complete record.
105
*/
106
int
107
zpool_history_unpack(char *buf, uint64_t bytes_read, uint64_t *leftover,
108
nvlist_t ***records, uint_t *numrecords)
109
{
110
uint64_t reclen;
111
nvlist_t *nv;
112
int i;
113
void *tmp;
114
115
while (bytes_read > sizeof (reclen)) {
116
117
/* get length of packed record (stored as little endian) */
118
for (i = 0, reclen = 0; i < sizeof (reclen); i++)
119
reclen += (uint64_t)(((uchar_t *)buf)[i]) << (8*i);
120
121
if (bytes_read < sizeof (reclen) + reclen)
122
break;
123
124
/* unpack record */
125
int err = nvlist_unpack(buf + sizeof (reclen), reclen, &nv, 0);
126
if (err != 0)
127
return (err);
128
bytes_read -= sizeof (reclen) + reclen;
129
buf += sizeof (reclen) + reclen;
130
131
/* add record to nvlist array */
132
(*numrecords)++;
133
if (ISP2(*numrecords + 1)) {
134
tmp = realloc(*records,
135
*numrecords * 2 * sizeof (nvlist_t *));
136
if (tmp == NULL) {
137
nvlist_free(nv);
138
(*numrecords)--;
139
return (ENOMEM);
140
}
141
*records = tmp;
142
}
143
(*records)[*numrecords - 1] = nv;
144
}
145
146
*leftover = bytes_read;
147
return (0);
148
}
149
150
/*
151
* Floating point sleep(). Allows you to pass in a floating point value for
152
* seconds.
153
*/
154
void
155
fsleep(float sec)
156
{
157
struct timespec req;
158
req.tv_sec = floor(sec);
159
req.tv_nsec = (sec - (float)req.tv_sec) * NANOSEC;
160
nanosleep(&req, NULL);
161
}
162
163
/*
164
* Get environment variable 'env' and return it as an integer.
165
* If 'env' is not set, then return 'default_val' instead.
166
*/
167
int
168
zpool_getenv_int(const char *env, int default_val)
169
{
170
char *str;
171
int val;
172
str = getenv(env);
173
if ((str == NULL) || sscanf(str, "%d", &val) != 1 ||
174
val < 0) {
175
val = default_val;
176
}
177
return (val);
178
}
179
180