Path: blob/main/sys/contrib/openzfs/lib/libzutil/zutil_pool.c
48378 views
// SPDX-License-Identifier: CDDL-1.01/*2* CDDL HEADER START3*4* The contents of this file are subject to the terms of the5* 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.LICENSE9* or https://opensource.org/licenses/CDDL-1.0.10* See the License for the specific language governing permissions11* and limitations under the License.12*13* When distributing Covered Code, include this CDDL HEADER in each14* file and include the License file at usr/src/OPENSOLARIS.LICENSE.15* If applicable, add the following below this CDDL HEADER, with the16* fields enclosed by brackets "[]" replaced with your own identifying17* information: Portions Copyright [yyyy] [name of copyright owner]18*19* CDDL HEADER END20*/2122/*23* Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.24*/2526#include <stdio.h>27#include <stdlib.h>28#include <string.h>29#include <sys/nvpair.h>30#include <sys/fs/zfs.h>31#include <math.h>3233#include <libzutil.h>3435static void36dump_ddt_stat(const ddt_stat_t *dds, int h)37{38char refcnt[6];39char blocks[6], lsize[6], psize[6], dsize[6];40char ref_blocks[6], ref_lsize[6], ref_psize[6], ref_dsize[6];4142if (dds == NULL || dds->dds_blocks == 0)43return;4445if (h == -1)46(void) strcpy(refcnt, "Total");47else48zfs_nicenum(1ULL << h, refcnt, sizeof (refcnt));4950zfs_nicenum(dds->dds_blocks, blocks, sizeof (blocks));51zfs_nicebytes(dds->dds_lsize, lsize, sizeof (lsize));52zfs_nicebytes(dds->dds_psize, psize, sizeof (psize));53zfs_nicebytes(dds->dds_dsize, dsize, sizeof (dsize));54zfs_nicenum(dds->dds_ref_blocks, ref_blocks, sizeof (ref_blocks));55zfs_nicebytes(dds->dds_ref_lsize, ref_lsize, sizeof (ref_lsize));56zfs_nicebytes(dds->dds_ref_psize, ref_psize, sizeof (ref_psize));57zfs_nicebytes(dds->dds_ref_dsize, ref_dsize, sizeof (ref_dsize));5859(void) printf("%6s %6s %5s %5s %5s %6s %5s %5s %5s\n",60refcnt,61blocks, lsize, psize, dsize,62ref_blocks, ref_lsize, ref_psize, ref_dsize);63}6465/*66* Print the DDT histogram and the column totals.67*/68void69zpool_dump_ddt(const ddt_stat_t *dds_total, const ddt_histogram_t *ddh)70{71int h;7273(void) printf("\n");7475(void) printf("bucket "76" allocated "77" referenced \n");78(void) printf("______ "79"______________________________ "80"______________________________\n");8182(void) printf("%6s %6s %5s %5s %5s %6s %5s %5s %5s\n",83"refcnt",84"blocks", "LSIZE", "PSIZE", "DSIZE",85"blocks", "LSIZE", "PSIZE", "DSIZE");8687(void) printf("%6s %6s %5s %5s %5s %6s %5s %5s %5s\n",88"------",89"------", "-----", "-----", "-----",90"------", "-----", "-----", "-----");9192for (h = 0; h < 64; h++)93dump_ddt_stat(&ddh->ddh_stat[h], h);9495dump_ddt_stat(dds_total, -1);9697(void) printf("\n");98}99100/*101* Process the buffer of nvlists, unpacking and storing each nvlist record102* into 'records'. 'leftover' is set to the number of bytes that weren't103* processed as there wasn't a complete record.104*/105int106zpool_history_unpack(char *buf, uint64_t bytes_read, uint64_t *leftover,107nvlist_t ***records, uint_t *numrecords)108{109uint64_t reclen;110nvlist_t *nv;111int i;112void *tmp;113114while (bytes_read > sizeof (reclen)) {115116/* get length of packed record (stored as little endian) */117for (i = 0, reclen = 0; i < sizeof (reclen); i++)118reclen += (uint64_t)(((uchar_t *)buf)[i]) << (8*i);119120if (bytes_read < sizeof (reclen) + reclen)121break;122123/* unpack record */124int err = nvlist_unpack(buf + sizeof (reclen), reclen, &nv, 0);125if (err != 0)126return (err);127bytes_read -= sizeof (reclen) + reclen;128buf += sizeof (reclen) + reclen;129130/* add record to nvlist array */131(*numrecords)++;132if (ISP2(*numrecords + 1)) {133tmp = realloc(*records,134*numrecords * 2 * sizeof (nvlist_t *));135if (tmp == NULL) {136nvlist_free(nv);137(*numrecords)--;138return (ENOMEM);139}140*records = tmp;141}142(*records)[*numrecords - 1] = nv;143}144145*leftover = bytes_read;146return (0);147}148149/*150* Floating point sleep(). Allows you to pass in a floating point value for151* seconds.152*/153void154fsleep(float sec)155{156struct timespec req;157req.tv_sec = floor(sec);158req.tv_nsec = (sec - (float)req.tv_sec) * NANOSEC;159nanosleep(&req, NULL);160}161162/*163* Get environment variable 'env' and return it as an integer.164* If 'env' is not set, then return 'default_val' instead.165*/166int167zpool_getenv_int(const char *env, int default_val)168{169char *str;170int val;171str = getenv(env);172if ((str == NULL) || sscanf(str, "%d", &val) != 1 ||173val < 0) {174val = default_val;175}176return (val);177}178179180