]>
Commit | Line | Data |
---|---|---|
e89f1295 DB |
1 | /* |
2 | * CDDL HEADER START | |
3 | * | |
4 | * The contents of this file are subject to the terms of the | |
5 | * Common Development and Distribution License (the "License"). | |
6 | * You may not use this file except in compliance with the License. | |
7 | * | |
8 | * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE | |
9 | * or http://www.opensolaris.org/os/licensing. | |
10 | * See the License for the specific language governing permissions | |
11 | * and limitations under the License. | |
12 | * | |
13 | * When distributing Covered Code, include this CDDL HEADER in each | |
14 | * file and include the License file at usr/src/OPENSOLARIS.LICENSE. | |
15 | * If applicable, add the following below this CDDL HEADER, with the | |
16 | * fields enclosed by brackets "[]" replaced with your own identifying | |
17 | * information: Portions Copyright [yyyy] [name of copyright owner] | |
18 | * | |
19 | * CDDL HEADER END | |
20 | */ | |
21 | ||
22 | /* | |
23 | * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved. | |
24 | */ | |
25 | ||
26 | #include <stdio.h> | |
27 | #include <stdlib.h> | |
28 | #include <string.h> | |
29 | #include <sys/nvpair.h> | |
30 | #include <sys/fs/zfs.h> | |
31 | ||
32 | #include <libzutil.h> | |
33 | ||
34 | static void | |
35 | dump_ddt_stat(const ddt_stat_t *dds, int h) | |
36 | { | |
37 | char refcnt[6]; | |
38 | char blocks[6], lsize[6], psize[6], dsize[6]; | |
39 | char ref_blocks[6], ref_lsize[6], ref_psize[6], ref_dsize[6]; | |
40 | ||
41 | if (dds == NULL || dds->dds_blocks == 0) | |
42 | return; | |
43 | ||
44 | if (h == -1) | |
45 | (void) strcpy(refcnt, "Total"); | |
46 | else | |
47 | zfs_nicenum(1ULL << h, refcnt, sizeof (refcnt)); | |
48 | ||
49 | zfs_nicenum(dds->dds_blocks, blocks, sizeof (blocks)); | |
50 | zfs_nicebytes(dds->dds_lsize, lsize, sizeof (lsize)); | |
51 | zfs_nicebytes(dds->dds_psize, psize, sizeof (psize)); | |
52 | zfs_nicebytes(dds->dds_dsize, dsize, sizeof (dsize)); | |
53 | zfs_nicenum(dds->dds_ref_blocks, ref_blocks, sizeof (ref_blocks)); | |
54 | zfs_nicebytes(dds->dds_ref_lsize, ref_lsize, sizeof (ref_lsize)); | |
55 | zfs_nicebytes(dds->dds_ref_psize, ref_psize, sizeof (ref_psize)); | |
56 | zfs_nicebytes(dds->dds_ref_dsize, ref_dsize, sizeof (ref_dsize)); | |
57 | ||
58 | (void) printf("%6s %6s %5s %5s %5s %6s %5s %5s %5s\n", | |
59 | refcnt, | |
60 | blocks, lsize, psize, dsize, | |
61 | ref_blocks, ref_lsize, ref_psize, ref_dsize); | |
62 | } | |
63 | ||
64 | /* | |
65 | * Print the DDT histogram and the column totals. | |
66 | */ | |
67 | void | |
68 | zpool_dump_ddt(const ddt_stat_t *dds_total, const ddt_histogram_t *ddh) | |
69 | { | |
70 | int h; | |
71 | ||
72 | (void) printf("\n"); | |
73 | ||
74 | (void) printf("bucket " | |
75 | " allocated " | |
76 | " referenced \n"); | |
77 | (void) printf("______ " | |
78 | "______________________________ " | |
79 | "______________________________\n"); | |
80 | ||
81 | (void) printf("%6s %6s %5s %5s %5s %6s %5s %5s %5s\n", | |
82 | "refcnt", | |
83 | "blocks", "LSIZE", "PSIZE", "DSIZE", | |
84 | "blocks", "LSIZE", "PSIZE", "DSIZE"); | |
85 | ||
86 | (void) printf("%6s %6s %5s %5s %5s %6s %5s %5s %5s\n", | |
87 | "------", | |
88 | "------", "-----", "-----", "-----", | |
89 | "------", "-----", "-----", "-----"); | |
90 | ||
91 | for (h = 0; h < 64; h++) | |
92 | dump_ddt_stat(&ddh->ddh_stat[h], h); | |
93 | ||
94 | dump_ddt_stat(dds_total, -1); | |
95 | ||
96 | (void) printf("\n"); | |
97 | } | |
98 | ||
99 | /* | |
100 | * Process the buffer of nvlists, unpacking and storing each nvlist record | |
101 | * into 'records'. 'leftover' is set to the number of bytes that weren't | |
102 | * processed as there wasn't a complete record. | |
103 | */ | |
104 | int | |
105 | zpool_history_unpack(char *buf, uint64_t bytes_read, uint64_t *leftover, | |
106 | nvlist_t ***records, uint_t *numrecords) | |
107 | { | |
108 | uint64_t reclen; | |
109 | nvlist_t *nv; | |
110 | int i; | |
111 | void *tmp; | |
112 | ||
113 | while (bytes_read > sizeof (reclen)) { | |
114 | ||
115 | /* get length of packed record (stored as little endian) */ | |
116 | for (i = 0, reclen = 0; i < sizeof (reclen); i++) | |
117 | reclen += (uint64_t)(((uchar_t *)buf)[i]) << (8*i); | |
118 | ||
119 | if (bytes_read < sizeof (reclen) + reclen) | |
120 | break; | |
121 | ||
122 | /* unpack record */ | |
123 | if (nvlist_unpack(buf + sizeof (reclen), reclen, &nv, 0) != 0) | |
124 | return (ENOMEM); | |
125 | bytes_read -= sizeof (reclen) + reclen; | |
126 | buf += sizeof (reclen) + reclen; | |
127 | ||
128 | /* add record to nvlist array */ | |
129 | (*numrecords)++; | |
130 | if (ISP2(*numrecords + 1)) { | |
131 | tmp = realloc(*records, | |
132 | *numrecords * 2 * sizeof (nvlist_t *)); | |
133 | if (tmp == NULL) { | |
134 | nvlist_free(nv); | |
135 | (*numrecords)--; | |
136 | return (ENOMEM); | |
137 | } | |
138 | *records = tmp; | |
139 | } | |
140 | (*records)[*numrecords - 1] = nv; | |
141 | } | |
142 | ||
143 | *leftover = bytes_read; | |
144 | return (0); | |
145 | } |