diff options
author | ek110237 <none@none> | 2007-01-18 14:25:26 -0800 |
---|---|---|
committer | ek110237 <none@none> | 2007-01-18 14:25:26 -0800 |
commit | 55434c770c89aa1b84474f2559a106803511aba0 (patch) | |
tree | 0b264887f9fd7111732d95873d02a27dc5c4e8c0 /usr/src/lib/libzfs/common/libzfs_pool.c | |
parent | bf7c2d400a7b538aed6f356c7107284378a19fa8 (diff) | |
download | illumos-joyent-55434c770c89aa1b84474f2559a106803511aba0.tar.gz |
6410433 'zpool status -v' would be more useful with filenames
6504702 zdb -dddv <poolname> chokes on xattrs
6506506 spa_history.c: LE_64(reclen) needs to be cast to uint64_t in case of 32-bit big-endian kernel
Diffstat (limited to 'usr/src/lib/libzfs/common/libzfs_pool.c')
-rw-r--r-- | usr/src/lib/libzfs/common/libzfs_pool.c | 177 |
1 files changed, 67 insertions, 110 deletions
diff --git a/usr/src/lib/libzfs/common/libzfs_pool.c b/usr/src/lib/libzfs/common/libzfs_pool.c index 87e8105e98..8466cd7573 100644 --- a/usr/src/lib/libzfs/common/libzfs_pool.c +++ b/usr/src/lib/libzfs/common/libzfs_pool.c @@ -277,12 +277,6 @@ zpool_close(zpool_handle_t *zhp) nvlist_free(zhp->zpool_config); if (zhp->zpool_old_config) nvlist_free(zhp->zpool_old_config); - if (zhp->zpool_error_log) { - int i; - for (i = 0; i < zhp->zpool_error_count; i++) - nvlist_free(zhp->zpool_error_log[i]); - free(zhp->zpool_error_log); - } free(zhp); } @@ -1573,19 +1567,12 @@ zbookmark_compare(const void *a, const void *b) * caller. */ int -zpool_get_errlog(zpool_handle_t *zhp, nvlist_t ***list, size_t *nelem) +zpool_get_errlog(zpool_handle_t *zhp, nvlist_t **nverrlistp) { zfs_cmd_t zc = { 0 }; uint64_t count; zbookmark_t *zb = NULL; - libzfs_handle_t *hdl = zhp->zpool_hdl; - int i, j; - - if (zhp->zpool_error_log != NULL) { - *list = zhp->zpool_error_log; - *nelem = zhp->zpool_error_count; - return (0); - } + int i; /* * Retrieve the raw error list from the kernel. If the number of errors @@ -1626,123 +1613,45 @@ zpool_get_errlog(zpool_handle_t *zhp, nvlist_t ***list, size_t *nelem) zb = ((zbookmark_t *)(uintptr_t)zc.zc_nvlist_dst) + zc.zc_nvlist_dst_size; count -= zc.zc_nvlist_dst_size; - zc.zc_nvlist_dst = 0ULL; qsort(zb, count, sizeof (zbookmark_t), zbookmark_compare); - /* - * Count the number of unique elements - */ - j = 0; - for (i = 0; i < count; i++) { - if (i > 0 && memcmp(&zb[i - 1], &zb[i], - sizeof (zbookmark_t)) == 0) - continue; - j++; - } - - /* - * If the user has only requested the number of items, return it now - * without bothering with the extra work. - */ - if (list == NULL) { - *nelem = j; - free((void *)(uintptr_t)zc.zc_nvlist_dst); - return (0); - } - - zhp->zpool_error_count = j; + verify(nvlist_alloc(nverrlistp, 0, KM_SLEEP) == 0); /* - * Allocate an array of nvlists to hold the results + * Fill in the nverrlistp with nvlist's of dataset and object numbers. */ - if ((zhp->zpool_error_log = zfs_alloc(zhp->zpool_hdl, - j * sizeof (nvlist_t *))) == NULL) { - free((void *)(uintptr_t)zc.zc_nvlist_dst); - return (-1); - } - - /* - * Fill in the results with names from the kernel. - */ - j = 0; for (i = 0; i < count; i++) { - char buf[64]; nvlist_t *nv; if (i > 0 && memcmp(&zb[i - 1], &zb[i], sizeof (zbookmark_t)) == 0) continue; - if (zcmd_alloc_dst_nvlist(hdl, &zc, 0) != 0) + if (nvlist_alloc(&nv, NV_UNIQUE_NAME, KM_SLEEP) != 0) + goto nomem; + if (nvlist_add_uint64(nv, ZPOOL_ERR_DATASET, + zb[i].zb_objset) != 0) { + nvlist_free(nv); goto nomem; - - zc.zc_bookmark = zb[i]; - for (;;) { - if (ioctl(zhp->zpool_hdl->libzfs_fd, - ZFS_IOC_BOOKMARK_NAME, &zc) != 0) { - if (errno == ENOMEM) { - if (zcmd_expand_dst_nvlist(hdl, &zc) - != 0) { - zcmd_free_nvlists(&zc); - goto nomem; - } - - continue; - } else { - if (nvlist_alloc(&nv, NV_UNIQUE_NAME, - 0) != 0) - goto nomem; - - zhp->zpool_error_log[j] = nv; - (void) snprintf(buf, sizeof (buf), - "%llx", (longlong_t) - zb[i].zb_objset); - if (nvlist_add_string(nv, - ZPOOL_ERR_DATASET, buf) != 0) - goto nomem; - (void) snprintf(buf, sizeof (buf), - "%llx", (longlong_t) - zb[i].zb_object); - if (nvlist_add_string(nv, - ZPOOL_ERR_OBJECT, buf) != 0) - goto nomem; - (void) snprintf(buf, sizeof (buf), - "lvl=%u blkid=%llu", - (int)zb[i].zb_level, - (long long)zb[i].zb_blkid); - if (nvlist_add_string(nv, - ZPOOL_ERR_RANGE, buf) != 0) - goto nomem; - } - } else { - if (zcmd_read_dst_nvlist(hdl, &zc, - &zhp->zpool_error_log[j]) != 0) { - zcmd_free_nvlists(&zc); - goto nomem; - } - } - - break; } - - zcmd_free_nvlists(&zc); - - j++; + if (nvlist_add_uint64(nv, ZPOOL_ERR_OBJECT, + zb[i].zb_object) != 0) { + nvlist_free(nv); + goto nomem; + } + if (nvlist_add_nvlist(*nverrlistp, "ejk", nv) != 0) { + nvlist_free(nv); + goto nomem; + } + nvlist_free(nv); } - *list = zhp->zpool_error_log; - *nelem = zhp->zpool_error_count; free((void *)(uintptr_t)zc.zc_nvlist_dst); - return (0); nomem: free((void *)(uintptr_t)zc.zc_nvlist_dst); - for (i = 0; i < zhp->zpool_error_count; i++) - nvlist_free(zhp->zpool_error_log[i]); - free(zhp->zpool_error_log); - zhp->zpool_error_log = NULL; return (no_memory(zhp->zpool_hdl)); } @@ -1938,3 +1847,51 @@ zpool_get_history(zpool_handle_t *zhp, nvlist_t **nvhisp) return (err); } + +void +zpool_obj_to_path(zpool_handle_t *zhp, uint64_t dsobj, uint64_t obj, + char *pathname, size_t len) +{ + zfs_cmd_t zc = { 0 }; + boolean_t mounted = B_FALSE; + char *mntpnt = NULL; + char dsname[MAXNAMELEN]; + + if (dsobj == 0) { + /* special case for the MOS */ + (void) snprintf(pathname, len, "<metadata>:<0x%llx>", obj); + return; + } + + /* get the dataset's name */ + (void) strlcpy(zc.zc_name, zhp->zpool_name, sizeof (zc.zc_name)); + zc.zc_obj = dsobj; + if (ioctl(zhp->zpool_hdl->libzfs_fd, + ZFS_IOC_DSOBJ_TO_DSNAME, &zc) != 0) { + /* just write out a path of two object numbers */ + (void) snprintf(pathname, len, "<0x%llx>:<0x%llx>", + dsobj, obj); + return; + } + (void) strlcpy(dsname, zc.zc_value, sizeof (dsname)); + + /* find out if the dataset is mounted */ + mounted = is_mounted(zhp->zpool_hdl, dsname, &mntpnt); + + /* get the corrupted object's path */ + (void) strlcpy(zc.zc_name, dsname, sizeof (zc.zc_name)); + zc.zc_obj = obj; + if (ioctl(zhp->zpool_hdl->libzfs_fd, ZFS_IOC_OBJ_TO_PATH, + &zc) == 0) { + if (mounted) { + (void) snprintf(pathname, len, "%s%s", mntpnt, + zc.zc_value); + } else { + (void) snprintf(pathname, len, "%s:%s", + dsname, zc.zc_value); + } + } else { + (void) snprintf(pathname, len, "%s:<0x%llx>", dsname, obj); + } + free(mntpnt); +} |