Skip to content

Commit

Permalink
Merge pull request #241 from truenas/NAS-129592-dragonfish
Browse files Browse the repository at this point in the history
NAS-129592 / 24.04.2 / [stable/dragonfish] Sync with zfs-2.2.5-staging
  • Loading branch information
amotin committed Jun 14, 2024
2 parents e4631d0 + 14c22d4 commit 2e68614
Show file tree
Hide file tree
Showing 5 changed files with 127 additions and 30 deletions.
142 changes: 113 additions & 29 deletions cmd/zdb/zdb.c
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,7 @@

#include <libnvpair.h>
#include <libzutil.h>
#include <libzfs_core.h>

#include "zdb.h"

Expand Down Expand Up @@ -168,6 +169,9 @@ static int flagbits[256];
static uint64_t max_inflight_bytes = 256 * 1024 * 1024; /* 256MB */
static int leaked_objects = 0;
static range_tree_t *mos_refd_objs;
static spa_t *spa;
static objset_t *os;
static boolean_t kernel_init_done;

static void snprintf_blkptr_compact(char *, size_t, const blkptr_t *,
boolean_t);
Expand Down Expand Up @@ -234,6 +238,7 @@ typedef struct sublivelist_verify_block {
} sublivelist_verify_block_t;

static void zdb_print_blkptr(const blkptr_t *bp, int flags);
static void zdb_exit(int reason);

typedef struct sublivelist_verify_block_refcnt {
/* block pointer entry in livelist being verified */
Expand Down Expand Up @@ -920,7 +925,7 @@ usage(void)
(void) fprintf(stderr, "Specify an option more than once (e.g. -bb) "
"to make only that option verbose\n");
(void) fprintf(stderr, "Default is to dump everything non-verbosely\n");
exit(1);
zdb_exit(1);
}

static void
Expand Down Expand Up @@ -951,7 +956,7 @@ fatal(const char *fmt, ...)

dump_debug_buffer();

exit(1);
zdb_exit(1);
}

static void
Expand Down Expand Up @@ -2376,7 +2381,7 @@ snprintf_zstd_header(spa_t *spa, char *blkbuf, size_t buflen,
buf = malloc(SPA_MAXBLOCKSIZE);
if (buf == NULL) {
(void) fprintf(stderr, "out of memory\n");
exit(1);
zdb_exit(1);
}
decode_embedded_bp_compressed(bp, buf);
memcpy(&zstd_hdr, buf, sizeof (zstd_hdr));
Expand Down Expand Up @@ -3331,6 +3336,23 @@ fuid_table_destroy(void)
}
}

static void
zdb_exit(int reason)
{
if (os != NULL) {
close_objset(os, FTAG);
} else if (spa != NULL) {
spa_close(spa, FTAG);
}

fuid_table_destroy();

if (kernel_init_done)
kernel_fini();

exit(reason);
}

/*
* print uid or gid information.
* For normal POSIX id just the id is printed in decimal format.
Expand Down Expand Up @@ -4256,32 +4278,32 @@ dump_cachefile(const char *cachefile)
if ((fd = open64(cachefile, O_RDONLY)) < 0) {
(void) printf("cannot open '%s': %s\n", cachefile,
strerror(errno));
exit(1);
zdb_exit(1);
}

if (fstat64(fd, &statbuf) != 0) {
(void) printf("failed to stat '%s': %s\n", cachefile,
strerror(errno));
exit(1);
zdb_exit(1);
}

if ((buf = malloc(statbuf.st_size)) == NULL) {
(void) fprintf(stderr, "failed to allocate %llu bytes\n",
(u_longlong_t)statbuf.st_size);
exit(1);
zdb_exit(1);
}

if (read(fd, buf, statbuf.st_size) != statbuf.st_size) {
(void) fprintf(stderr, "failed to read %llu bytes\n",
(u_longlong_t)statbuf.st_size);
exit(1);
zdb_exit(1);
}

(void) close(fd);

if (nvlist_unpack(buf, statbuf.st_size, &config, 0) != 0) {
(void) fprintf(stderr, "failed to unpack nvlist\n");
exit(1);
zdb_exit(1);
}

free(buf);
Expand Down Expand Up @@ -5197,14 +5219,14 @@ dump_label(const char *dev)

if ((fd = open64(path, O_RDONLY)) < 0) {
(void) printf("cannot open '%s': %s\n", path, strerror(errno));
exit(1);
zdb_exit(1);
}

if (fstat64_blk(fd, &statbuf) != 0) {
(void) printf("failed to stat '%s': %s\n", path,
strerror(errno));
(void) close(fd);
exit(1);
zdb_exit(1);
}

if (S_ISBLK(statbuf.st_mode) && zfs_dev_flush(fd) != 0)
Expand Down Expand Up @@ -8300,7 +8322,7 @@ dump_zpool(spa_t *spa)

if (rc != 0) {
dump_debug_buffer();
exit(rc);
zdb_exit(rc);
}
}

Expand Down Expand Up @@ -8879,18 +8901,18 @@ zdb_embedded_block(char *thing)
words + 12, words + 13, words + 14, words + 15);
if (err != 16) {
(void) fprintf(stderr, "invalid input format\n");
exit(1);
zdb_exit(1);
}
ASSERT3U(BPE_GET_LSIZE(&bp), <=, SPA_MAXBLOCKSIZE);
buf = malloc(SPA_MAXBLOCKSIZE);
if (buf == NULL) {
(void) fprintf(stderr, "out of memory\n");
exit(1);
zdb_exit(1);
}
err = decode_embedded_bp(&bp, buf, BPE_GET_LSIZE(&bp));
if (err != 0) {
(void) fprintf(stderr, "decode failed: %u\n", err);
exit(1);
zdb_exit(1);
}
zdb_dump_block_raw(buf, BPE_GET_LSIZE(&bp), 0);
free(buf);
Expand All @@ -8917,8 +8939,6 @@ int
main(int argc, char **argv)
{
int c;
spa_t *spa = NULL;
objset_t *os = NULL;
int dump_all = 1;
int verbose = 0;
int error = 0;
Expand All @@ -8934,6 +8954,9 @@ main(int argc, char **argv)
char *spa_config_path_env, *objset_str;
boolean_t target_is_spa = B_TRUE, dataset_lookup = B_FALSE;
nvlist_t *cfg = NULL;
boolean_t force_import = B_FALSE;
boolean_t config_path_console = B_FALSE;
char pbuf[MAXPATHLEN];

dprintf_setup(&argc, argv);

Expand Down Expand Up @@ -9087,6 +9110,7 @@ main(int argc, char **argv)
}
break;
case 'U':
config_path_console = B_TRUE;
spa_config_path = optarg;
if (spa_config_path[0] != '/') {
(void) fprintf(stderr,
Expand Down Expand Up @@ -9146,8 +9170,6 @@ main(int argc, char **argv)
*/
spa_mode_readable_spacemaps = B_TRUE;

kernel_init(SPA_MODE_READ);

if (dump_all)
verbose = MAX(verbose, 1);

Expand All @@ -9166,23 +9188,74 @@ main(int argc, char **argv)
if (argc < 2 && dump_opt['R'])
usage();

target = argv[0];

/*
* Automate cachefile
*/
if (!spa_config_path_env && !config_path_console && target &&
libzfs_core_init() == 0) {
char *pname = strdup(target);
const char *value;
nvlist_t *pnvl = NULL;
nvlist_t *vnvl;

if (strpbrk(pname, "/@") != NULL)
*strpbrk(pname, "/@") = '\0';

if (pname && lzc_get_props(pname, &pnvl) == 0) {
if (nvlist_lookup_nvlist(pnvl, "cachefile",
&vnvl) == 0) {
value = fnvlist_lookup_string(vnvl,
ZPROP_VALUE);
} else {
value = "-";
}
strlcpy(pbuf, value, sizeof (pbuf));
if (pbuf[0] != '\0') {
if (pbuf[0] == '/') {
if (access(pbuf, F_OK) == 0)
spa_config_path = pbuf;
else
force_import = B_TRUE;
} else if ((strcmp(pbuf, "-") == 0 &&
access(ZPOOL_CACHE, F_OK) != 0) ||
strcmp(pbuf, "none") == 0) {
force_import = B_TRUE;
}
}
nvlist_free(vnvl);
}

free(pname);
nvlist_free(pnvl);
libzfs_core_fini();
}

kernel_init(SPA_MODE_READ);
kernel_init_done = B_TRUE;

if (dump_opt['E']) {
if (argc != 1)
usage();
zdb_embedded_block(argv[0]);
return (0);
error = 0;
goto fini;
}

if (argc < 1) {
if (!dump_opt['e'] && dump_opt['C']) {
dump_cachefile(spa_config_path);
return (0);
error = 0;
goto fini;
}
usage();
}

if (dump_opt['l'])
return (dump_label(argv[0]));
if (dump_opt['l']) {
error = dump_label(argv[0]);
goto fini;
}

if (dump_opt['X'] || dump_opt['F'])
rewind = ZPOOL_DO_REWIND |
Expand All @@ -9198,7 +9271,6 @@ main(int argc, char **argv)
fatal("internal error: %s", strerror(ENOMEM));

error = 0;
target = argv[0];

if (strpbrk(target, "/@") != NULL) {
size_t targetlen;
Expand Down Expand Up @@ -9237,15 +9309,24 @@ main(int argc, char **argv)
} else if (objset_str && !zdb_numeric(objset_str + 1) &&
dump_opt['N']) {
printf("Supply a numeric objset ID with -N\n");
exit(1);
error = 1;
goto fini;
}
} else {
target_pool = target;
}

if (dump_opt['e']) {
if (dump_opt['e'] || force_import) {
importargs_t args = { 0 };

/*
* If path is not provided, search in /dev
*/
if (searchdirs == NULL) {
searchdirs = umem_alloc(sizeof (char *), UMEM_NOFAIL);
searchdirs[nsearch++] = (char *)ZFS_DEVDIR;
}

args.paths = nsearch;
args.path = searchdirs;
args.can_be_active = B_TRUE;
Expand Down Expand Up @@ -9294,7 +9375,8 @@ main(int argc, char **argv)
if (argc != 2)
usage();
dump_opt['v'] = verbose + 3;
return (dump_path(argv[0], argv[1], NULL));
error = dump_path(argv[0], argv[1], NULL);
goto fini;
}

if (dump_opt['r']) {
Expand Down Expand Up @@ -9382,7 +9464,7 @@ main(int argc, char **argv)
fatal("can't dump '%s': %s", target,
strerror(error));
}
return (error);
goto fini;
} else {
target_pool = strdup(target);
if (strpbrk(target, "/@") != NULL)
Expand Down Expand Up @@ -9512,17 +9594,19 @@ main(int argc, char **argv)
free(checkpoint_target);
}

fini:
if (os != NULL) {
close_objset(os, FTAG);
} else {
} else if (spa != NULL) {
spa_close(spa, FTAG);
}

fuid_table_destroy();

dump_debug_buffer();

kernel_fini();
if (kernel_init_done)
kernel_fini();

return (error);
}
1 change: 1 addition & 0 deletions include/libzfs_core.h
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,7 @@ _LIBZFS_CORE_H int lzc_snaprange_space(const char *, const char *, uint64_t *);
_LIBZFS_CORE_H int lzc_hold(nvlist_t *, int, nvlist_t **);
_LIBZFS_CORE_H int lzc_release(nvlist_t *, nvlist_t **);
_LIBZFS_CORE_H int lzc_get_holds(const char *, nvlist_t **);
_LIBZFS_CORE_H int lzc_get_props(const char *, nvlist_t **);

enum lzc_send_flags {
LZC_SEND_FLAG_EMBED_DATA = 1 << 0,
Expand Down
6 changes: 6 additions & 0 deletions lib/libzfs_core/libzfs_core.abi
Original file line number Diff line number Diff line change
Expand Up @@ -167,6 +167,7 @@
<elf-symbol name='lzc_get_bookmarks' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
<elf-symbol name='lzc_get_bootenv' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
<elf-symbol name='lzc_get_holds' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
<elf-symbol name='lzc_get_props' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
<elf-symbol name='lzc_get_vdev_prop' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
<elf-symbol name='lzc_hold' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
<elf-symbol name='lzc_initialize' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
Expand Down Expand Up @@ -2611,6 +2612,11 @@
<parameter type-id='857bb57e' name='holdsp'/>
<return type-id='95e97e5e'/>
</function-decl>
<function-decl name='lzc_get_props' mangled-name='lzc_get_props' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='lzc_get_props'>
<parameter type-id='80f4b756' name='poolname'/>
<parameter type-id='857bb57e' name='props'/>
<return type-id='95e97e5e'/>
</function-decl>
<function-decl name='lzc_send_wrapper' mangled-name='lzc_send_wrapper' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='lzc_send_wrapper'>
<parameter type-id='2e711a2a' name='func'/>
<parameter type-id='95e97e5e' name='orig_fd'/>
Expand Down
6 changes: 6 additions & 0 deletions lib/libzfs_core/libzfs_core.c
Original file line number Diff line number Diff line change
Expand Up @@ -596,6 +596,12 @@ lzc_get_holds(const char *snapname, nvlist_t **holdsp)
return (lzc_ioctl(ZFS_IOC_GET_HOLDS, snapname, NULL, holdsp));
}

int
lzc_get_props(const char *poolname, nvlist_t **props)
{
return (lzc_ioctl(ZFS_IOC_POOL_GET_PROPS, poolname, NULL, props));
}

static unsigned int
max_pipe_buffer(int infd)
{
Expand Down

0 comments on commit 2e68614

Please sign in to comment.