49 #include <sys/stat.h> |
49 #include <sys/stat.h> |
50 #include <sys/resource.h> |
50 #include <sys/resource.h> |
51 #include <sys/dmu_traverse.h> |
51 #include <sys/dmu_traverse.h> |
52 #include <sys/zio_checksum.h> |
52 #include <sys/zio_checksum.h> |
53 #include <sys/zio_compress.h> |
53 #include <sys/zio_compress.h> |
|
54 #undef ZFS_MAXNAMELEN |
|
55 #undef verify |
|
56 #include <libzfs.h> |
54 |
57 |
55 const char cmdname[] = "zdb"; |
58 const char cmdname[] = "zdb"; |
56 uint8_t dump_opt[256]; |
59 uint8_t dump_opt[256]; |
57 |
60 |
58 typedef void object_viewer_t(objset_t *, uint64_t, void *data, size_t size); |
61 typedef void object_viewer_t(objset_t *, uint64_t, void *data, size_t size); |
60 extern void dump_intent_log(zilog_t *); |
63 extern void dump_intent_log(zilog_t *); |
61 uint64_t *zopt_object = NULL; |
64 uint64_t *zopt_object = NULL; |
62 int zopt_objects = 0; |
65 int zopt_objects = 0; |
63 int zdb_advance = ADVANCE_PRE; |
66 int zdb_advance = ADVANCE_PRE; |
64 zbookmark_t zdb_noread = { 0, 0, ZB_NO_LEVEL, 0 }; |
67 zbookmark_t zdb_noread = { 0, 0, ZB_NO_LEVEL, 0 }; |
|
68 libzfs_handle_t *g_zfs; |
65 |
69 |
66 /* |
70 /* |
67 * These libumem hooks provide a reasonable set of defaults for the allocator's |
71 * These libumem hooks provide a reasonable set of defaults for the allocator's |
68 * debugging facilities. |
72 * debugging facilities. |
69 */ |
73 */ |
81 |
85 |
82 static void |
86 static void |
83 usage(void) |
87 usage(void) |
84 { |
88 { |
85 (void) fprintf(stderr, |
89 (void) fprintf(stderr, |
86 "Usage: %s [-udibcsvLU] [-O order] [-B os:obj:level:blkid] " |
90 "Usage: %s [-udibcsvLUe] [-O order] [-B os:obj:level:blkid] " |
87 "dataset [object...]\n" |
91 "dataset [object...]\n" |
88 " %s -C [pool]\n" |
92 " %s -C [pool]\n" |
89 " %s -l dev\n" |
93 " %s -l dev\n" |
90 " %s -R vdev:offset:size:flags\n", |
94 " %s -R vdev:offset:size:flags\n" |
91 cmdname, cmdname, cmdname, cmdname); |
95 " %s [-p path_to_vdev_dir]\n", |
|
96 cmdname, cmdname, cmdname, cmdname, cmdname); |
92 |
97 |
93 (void) fprintf(stderr, " -u uberblock\n"); |
98 (void) fprintf(stderr, " -u uberblock\n"); |
94 (void) fprintf(stderr, " -d datasets\n"); |
99 (void) fprintf(stderr, " -d datasets\n"); |
95 (void) fprintf(stderr, " -C cached pool configuration\n"); |
100 (void) fprintf(stderr, " -C cached pool configuration\n"); |
96 (void) fprintf(stderr, " -i intent logs\n"); |
101 (void) fprintf(stderr, " -i intent logs\n"); |
105 (void) fprintf(stderr, " -U use zpool.cache in /tmp\n"); |
110 (void) fprintf(stderr, " -U use zpool.cache in /tmp\n"); |
106 (void) fprintf(stderr, " -B objset:object:level:blkid -- " |
111 (void) fprintf(stderr, " -B objset:object:level:blkid -- " |
107 "simulate bad block\n"); |
112 "simulate bad block\n"); |
108 (void) fprintf(stderr, " -R read and display block from a" |
113 (void) fprintf(stderr, " -R read and display block from a" |
109 "device\n"); |
114 "device\n"); |
|
115 (void) fprintf(stderr, " -e Pool is exported/destroyed\n"); |
|
116 (void) fprintf(stderr, " -p <Path to vdev dir> (use with -e)\n"); |
110 (void) fprintf(stderr, "Specify an option more than once (e.g. -bb) " |
117 (void) fprintf(stderr, "Specify an option more than once (e.g. -bb) " |
111 "to make only that option verbose\n"); |
118 "to make only that option verbose\n"); |
112 (void) fprintf(stderr, "Default is to dump everything non-verbosely\n"); |
119 (void) fprintf(stderr, "Default is to dump everything non-verbosely\n"); |
113 exit(1); |
120 exit(1); |
114 } |
121 } |
2056 out: |
2063 out: |
2057 umem_free(buf, size); |
2064 umem_free(buf, size); |
2058 free(dup); |
2065 free(dup); |
2059 } |
2066 } |
2060 |
2067 |
|
2068 static boolean_t |
|
2069 nvlist_string_match(nvlist_t *config, char *name, char *tgt) |
|
2070 { |
|
2071 char *s; |
|
2072 |
|
2073 verify(nvlist_lookup_string(config, name, &s) == 0); |
|
2074 return (strcmp(s, tgt) == 0); |
|
2075 } |
|
2076 |
|
2077 static boolean_t |
|
2078 nvlist_uint64_match(nvlist_t *config, char *name, uint64_t tgt) |
|
2079 { |
|
2080 uint64_t val; |
|
2081 |
|
2082 verify(nvlist_lookup_uint64(config, name, &val) == 0); |
|
2083 return (val == tgt); |
|
2084 } |
|
2085 |
|
2086 static boolean_t |
|
2087 vdev_child_guid_match(nvlist_t *vdev, uint64_t guid) |
|
2088 { |
|
2089 nvlist_t **child; |
|
2090 uint_t c, children; |
|
2091 |
|
2092 verify(nvlist_lookup_nvlist_array(vdev, ZPOOL_CONFIG_CHILDREN, |
|
2093 &child, &children) == 0); |
|
2094 for (c = 0; c < children; ++c) |
|
2095 if (nvlist_uint64_match(child[c], ZPOOL_CONFIG_GUID, guid)) |
|
2096 return (B_TRUE); |
|
2097 return (B_FALSE); |
|
2098 } |
|
2099 |
|
2100 static boolean_t |
|
2101 vdev_child_string_match(nvlist_t *vdev, char *tgt) |
|
2102 { |
|
2103 nvlist_t **child; |
|
2104 uint_t c, children; |
|
2105 |
|
2106 verify(nvlist_lookup_nvlist_array(vdev, ZPOOL_CONFIG_CHILDREN, |
|
2107 &child, &children) == 0); |
|
2108 for (c = 0; c < children; ++c) { |
|
2109 if (nvlist_string_match(child[c], ZPOOL_CONFIG_PATH, tgt) || |
|
2110 nvlist_string_match(child[c], ZPOOL_CONFIG_DEVID, tgt)) |
|
2111 return (B_TRUE); |
|
2112 } |
|
2113 return (B_FALSE); |
|
2114 } |
|
2115 |
|
2116 static boolean_t |
|
2117 vdev_guid_match(nvlist_t *config, uint64_t guid) |
|
2118 { |
|
2119 nvlist_t *nvroot; |
|
2120 |
|
2121 verify(nvlist_lookup_nvlist(config, ZPOOL_CONFIG_VDEV_TREE, |
|
2122 &nvroot) == 0); |
|
2123 |
|
2124 return (nvlist_uint64_match(nvroot, ZPOOL_CONFIG_GUID, guid) || |
|
2125 vdev_child_guid_match(nvroot, guid)); |
|
2126 } |
|
2127 |
|
2128 static boolean_t |
|
2129 vdev_string_match(nvlist_t *config, char *tgt) |
|
2130 { |
|
2131 nvlist_t *nvroot; |
|
2132 |
|
2133 verify(nvlist_lookup_nvlist(config, ZPOOL_CONFIG_VDEV_TREE, |
|
2134 &nvroot) == 0); |
|
2135 |
|
2136 return (vdev_child_string_match(nvroot, tgt)); |
|
2137 } |
|
2138 |
|
2139 static boolean_t |
|
2140 pool_match(nvlist_t *config, char *tgt) |
|
2141 { |
|
2142 uint64_t guid = strtoull(tgt, NULL, 0); |
|
2143 |
|
2144 if (guid != 0) { |
|
2145 return ( |
|
2146 nvlist_uint64_match(config, ZPOOL_CONFIG_POOL_GUID, guid) || |
|
2147 vdev_guid_match(config, guid)); |
|
2148 } else { |
|
2149 return ( |
|
2150 nvlist_string_match(config, ZPOOL_CONFIG_POOL_NAME, tgt) || |
|
2151 vdev_string_match(config, tgt)); |
|
2152 } |
|
2153 } |
|
2154 |
|
2155 static int |
|
2156 find_exported_zpool(char *pool_id, nvlist_t **configp, char *vdev_dir) |
|
2157 { |
|
2158 nvlist_t *pools; |
|
2159 int error = ENOENT; |
|
2160 nvlist_t *match = NULL; |
|
2161 |
|
2162 if (vdev_dir != NULL) |
|
2163 pools = zpool_find_import(g_zfs, 1, &vdev_dir); |
|
2164 else |
|
2165 pools = zpool_find_import(g_zfs, 0, NULL); |
|
2166 |
|
2167 if (pools != NULL) { |
|
2168 nvpair_t *elem = NULL; |
|
2169 |
|
2170 while ((elem = nvlist_next_nvpair(pools, elem)) != NULL) { |
|
2171 verify(nvpair_value_nvlist(elem, configp) == 0); |
|
2172 if (pool_match(*configp, pool_id)) { |
|
2173 if (match != NULL) { |
|
2174 (void) fatal( |
|
2175 "More than one matching pool - " |
|
2176 "specify guid/devid/device path."); |
|
2177 } else { |
|
2178 match = *configp; |
|
2179 error = 0; |
|
2180 } |
|
2181 } |
|
2182 } |
|
2183 } |
|
2184 |
|
2185 *configp = error ? NULL : match; |
|
2186 |
|
2187 return (error); |
|
2188 } |
|
2189 |
2061 int |
2190 int |
2062 main(int argc, char **argv) |
2191 main(int argc, char **argv) |
2063 { |
2192 { |
2064 int i, c; |
2193 int i, c; |
2065 struct rlimit rl = { 1024, 1024 }; |
2194 struct rlimit rl = { 1024, 1024 }; |
2198 } |
2339 } |
2199 |
2340 |
2200 if (dump_opt['C']) |
2341 if (dump_opt['C']) |
2201 dump_config(argv[0]); |
2342 dump_config(argv[0]); |
2202 |
2343 |
2203 if (strchr(argv[0], '/') != NULL) { |
2344 if (exported == 0) { |
2204 error = dmu_objset_open(argv[0], DMU_OST_ANY, |
2345 if (strchr(argv[0], '/') != NULL) { |
2205 DS_MODE_STANDARD | DS_MODE_READONLY, &os); |
2346 error = dmu_objset_open(argv[0], DMU_OST_ANY, |
|
2347 DS_MODE_STANDARD | DS_MODE_READONLY, &os); |
|
2348 } else { |
|
2349 error = spa_open(argv[0], &spa, FTAG); |
|
2350 } |
2206 } else { |
2351 } else { |
2207 error = spa_open(argv[0], &spa, FTAG); |
2352 /* |
|
2353 * Check to see if the name refers to an exported zpool |
|
2354 */ |
|
2355 nvlist_t *exported_conf = NULL; |
|
2356 |
|
2357 error = find_exported_zpool(argv[0], &exported_conf, vdev_dir); |
|
2358 if (error == 0) { |
|
2359 error = spa_import(argv[0], exported_conf, vdev_dir); |
|
2360 if (error == 0) |
|
2361 error = spa_open(argv[0], &spa, FTAG); |
|
2362 } |
2208 } |
2363 } |
2209 |
2364 |
2210 if (error) |
2365 if (error) |
2211 fatal("can't open %s: %s", argv[0], strerror(error)); |
2366 fatal("can't open %s: %s", argv[0], strerror(error)); |
2212 |
2367 |