zdb: add missing cleanup for early return

Reviewed-by: Brian Behlendorf <behlendorf1@llnl.gov>
Reviewed-by: Don Brady <don.brady@klarasystems.com>
Reviewed-by: Alexander Motin <mav@FreeBSD.org>
Signed-off-by: Ameer Hamza <ahamza@ixsystems.com>
Closes #16152
This commit is contained in:
Ameer Hamza 2024-05-09 19:31:57 +05:00 committed by GitHub
parent 2dff7527d4
commit a0f3c8aaf1
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
1 changed files with 53 additions and 25 deletions

View File

@ -120,6 +120,9 @@ static int flagbits[256];
static uint64_t max_inflight_bytes = 256 * 1024 * 1024; /* 256MB */ static uint64_t max_inflight_bytes = 256 * 1024 * 1024; /* 256MB */
static int leaked_objects = 0; static int leaked_objects = 0;
static range_tree_t *mos_refd_objs; 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 *, static void snprintf_blkptr_compact(char *, size_t, const blkptr_t *,
boolean_t); boolean_t);
@ -131,6 +134,7 @@ static int dump_bpobj_cb(void *arg, const blkptr_t *bp, boolean_t free,
static void zdb_print_blkptr(const blkptr_t *bp, int flags); static void zdb_print_blkptr(const blkptr_t *bp, int flags);
static void zdb_exit(int reason);
typedef struct sublivelist_verify_block_refcnt { typedef struct sublivelist_verify_block_refcnt {
/* block pointer entry in livelist being verified */ /* block pointer entry in livelist being verified */
@ -818,7 +822,7 @@ usage(void)
(void) fprintf(stderr, "Specify an option more than once (e.g. -bb) " (void) fprintf(stderr, "Specify an option more than once (e.g. -bb) "
"to make only that option verbose\n"); "to make only that option verbose\n");
(void) fprintf(stderr, "Default is to dump everything non-verbosely\n"); (void) fprintf(stderr, "Default is to dump everything non-verbosely\n");
exit(1); zdb_exit(1);
} }
static void static void
@ -849,7 +853,7 @@ fatal(const char *fmt, ...)
dump_debug_buffer(); dump_debug_buffer();
exit(1); zdb_exit(1);
} }
static void static void
@ -2276,7 +2280,7 @@ snprintf_zstd_header(spa_t *spa, char *blkbuf, size_t buflen,
buf = malloc(SPA_MAXBLOCKSIZE); buf = malloc(SPA_MAXBLOCKSIZE);
if (buf == NULL) { if (buf == NULL) {
(void) fprintf(stderr, "out of memory\n"); (void) fprintf(stderr, "out of memory\n");
exit(1); zdb_exit(1);
} }
decode_embedded_bp_compressed(bp, buf); decode_embedded_bp_compressed(bp, buf);
memcpy(&zstd_hdr, buf, sizeof (zstd_hdr)); memcpy(&zstd_hdr, buf, sizeof (zstd_hdr));
@ -3231,6 +3235,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. * print uid or gid information.
* For normal POSIX id just the id is printed in decimal format. * For normal POSIX id just the id is printed in decimal format.
@ -4161,32 +4182,32 @@ dump_cachefile(const char *cachefile)
if ((fd = open64(cachefile, O_RDONLY)) < 0) { if ((fd = open64(cachefile, O_RDONLY)) < 0) {
(void) printf("cannot open '%s': %s\n", cachefile, (void) printf("cannot open '%s': %s\n", cachefile,
strerror(errno)); strerror(errno));
exit(1); zdb_exit(1);
} }
if (fstat64(fd, &statbuf) != 0) { if (fstat64(fd, &statbuf) != 0) {
(void) printf("failed to stat '%s': %s\n", cachefile, (void) printf("failed to stat '%s': %s\n", cachefile,
strerror(errno)); strerror(errno));
exit(1); zdb_exit(1);
} }
if ((buf = malloc(statbuf.st_size)) == NULL) { if ((buf = malloc(statbuf.st_size)) == NULL) {
(void) fprintf(stderr, "failed to allocate %llu bytes\n", (void) fprintf(stderr, "failed to allocate %llu bytes\n",
(u_longlong_t)statbuf.st_size); (u_longlong_t)statbuf.st_size);
exit(1); zdb_exit(1);
} }
if (read(fd, buf, statbuf.st_size) != statbuf.st_size) { if (read(fd, buf, statbuf.st_size) != statbuf.st_size) {
(void) fprintf(stderr, "failed to read %llu bytes\n", (void) fprintf(stderr, "failed to read %llu bytes\n",
(u_longlong_t)statbuf.st_size); (u_longlong_t)statbuf.st_size);
exit(1); zdb_exit(1);
} }
(void) close(fd); (void) close(fd);
if (nvlist_unpack(buf, statbuf.st_size, &config, 0) != 0) { if (nvlist_unpack(buf, statbuf.st_size, &config, 0) != 0) {
(void) fprintf(stderr, "failed to unpack nvlist\n"); (void) fprintf(stderr, "failed to unpack nvlist\n");
exit(1); zdb_exit(1);
} }
free(buf); free(buf);
@ -5102,14 +5123,14 @@ dump_label(const char *dev)
if ((fd = open64(path, O_RDONLY)) < 0) { if ((fd = open64(path, O_RDONLY)) < 0) {
(void) printf("cannot open '%s': %s\n", path, strerror(errno)); (void) printf("cannot open '%s': %s\n", path, strerror(errno));
exit(1); zdb_exit(1);
} }
if (fstat64_blk(fd, &statbuf) != 0) { if (fstat64_blk(fd, &statbuf) != 0) {
(void) printf("failed to stat '%s': %s\n", path, (void) printf("failed to stat '%s': %s\n", path,
strerror(errno)); strerror(errno));
(void) close(fd); (void) close(fd);
exit(1); zdb_exit(1);
} }
if (S_ISBLK(statbuf.st_mode) && zfs_dev_flush(fd) != 0) if (S_ISBLK(statbuf.st_mode) && zfs_dev_flush(fd) != 0)
@ -8221,7 +8242,7 @@ dump_zpool(spa_t *spa)
if (rc != 0) { if (rc != 0) {
dump_debug_buffer(); dump_debug_buffer();
exit(rc); zdb_exit(rc);
} }
} }
@ -8825,18 +8846,18 @@ zdb_embedded_block(char *thing)
words + 12, words + 13, words + 14, words + 15); words + 12, words + 13, words + 14, words + 15);
if (err != 16) { if (err != 16) {
(void) fprintf(stderr, "invalid input format\n"); (void) fprintf(stderr, "invalid input format\n");
exit(1); zdb_exit(1);
} }
ASSERT3U(BPE_GET_LSIZE(&bp), <=, SPA_MAXBLOCKSIZE); ASSERT3U(BPE_GET_LSIZE(&bp), <=, SPA_MAXBLOCKSIZE);
buf = malloc(SPA_MAXBLOCKSIZE); buf = malloc(SPA_MAXBLOCKSIZE);
if (buf == NULL) { if (buf == NULL) {
(void) fprintf(stderr, "out of memory\n"); (void) fprintf(stderr, "out of memory\n");
exit(1); zdb_exit(1);
} }
err = decode_embedded_bp(&bp, buf, BPE_GET_LSIZE(&bp)); err = decode_embedded_bp(&bp, buf, BPE_GET_LSIZE(&bp));
if (err != 0) { if (err != 0) {
(void) fprintf(stderr, "decode failed: %u\n", err); (void) fprintf(stderr, "decode failed: %u\n", err);
exit(1); zdb_exit(1);
} }
zdb_dump_block_raw(buf, BPE_GET_LSIZE(&bp), 0); zdb_dump_block_raw(buf, BPE_GET_LSIZE(&bp), 0);
free(buf); free(buf);
@ -8863,8 +8884,6 @@ int
main(int argc, char **argv) main(int argc, char **argv)
{ {
int c; int c;
spa_t *spa = NULL;
objset_t *os = NULL;
int dump_all = 1; int dump_all = 1;
int verbose = 0; int verbose = 0;
int error = 0; int error = 0;
@ -9093,6 +9112,7 @@ main(int argc, char **argv)
spa_mode_readable_spacemaps = B_TRUE; spa_mode_readable_spacemaps = B_TRUE;
kernel_init(SPA_MODE_READ); kernel_init(SPA_MODE_READ);
kernel_init_done = B_TRUE;
if (dump_all) if (dump_all)
verbose = MAX(verbose, 1); verbose = MAX(verbose, 1);
@ -9116,19 +9136,23 @@ main(int argc, char **argv)
if (argc != 1) if (argc != 1)
usage(); usage();
zdb_embedded_block(argv[0]); zdb_embedded_block(argv[0]);
return (0); error = 0;
goto fini;
} }
if (argc < 1) { if (argc < 1) {
if (!dump_opt['e'] && dump_opt['C']) { if (!dump_opt['e'] && dump_opt['C']) {
dump_cachefile(spa_config_path); dump_cachefile(spa_config_path);
return (0); error = 0;
goto fini;
} }
usage(); usage();
} }
if (dump_opt['l']) if (dump_opt['l']) {
return (dump_label(argv[0])); error = dump_label(argv[0]);
goto fini;
}
if (dump_opt['X'] || dump_opt['F']) if (dump_opt['X'] || dump_opt['F'])
rewind = ZPOOL_DO_REWIND | rewind = ZPOOL_DO_REWIND |
@ -9183,7 +9207,8 @@ main(int argc, char **argv)
} else if (objset_str && !zdb_numeric(objset_str + 1) && } else if (objset_str && !zdb_numeric(objset_str + 1) &&
dump_opt['N']) { dump_opt['N']) {
printf("Supply a numeric objset ID with -N\n"); printf("Supply a numeric objset ID with -N\n");
exit(1); error = 1;
goto fini;
} }
} else { } else {
target_pool = target; target_pool = target;
@ -9240,7 +9265,8 @@ main(int argc, char **argv)
if (argc != 2) if (argc != 2)
usage(); usage();
dump_opt['v'] = verbose + 3; 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']) { if (dump_opt['r']) {
@ -9328,7 +9354,7 @@ main(int argc, char **argv)
fatal("can't dump '%s': %s", target, fatal("can't dump '%s': %s", target,
strerror(error)); strerror(error));
} }
return (error); goto fini;
} else { } else {
target_pool = strdup(target); target_pool = strdup(target);
if (strpbrk(target, "/@") != NULL) if (strpbrk(target, "/@") != NULL)
@ -9458,9 +9484,10 @@ retry_lookup:
free(checkpoint_target); free(checkpoint_target);
} }
fini:
if (os != NULL) { if (os != NULL) {
close_objset(os, FTAG); close_objset(os, FTAG);
} else { } else if (spa != NULL) {
spa_close(spa, FTAG); spa_close(spa, FTAG);
} }
@ -9468,7 +9495,8 @@ retry_lookup:
dump_debug_buffer(); dump_debug_buffer();
kernel_fini(); if (kernel_init_done)
kernel_fini();
return (error); return (error);
} }