usr/src/cmd/zdb/zdb.c
changeset 4627 c85631613c19
parent 4577 ed36b0e652bc
child 4787 602d3f97842c
equal deleted inserted replaced
4626:48725cf3692a 4627:c85631613c19
    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 };
  2068 	char *endstr;
  2197 	char *endstr;
  2069 	int dump_all = 1;
  2198 	int dump_all = 1;
  2070 	int verbose = 0;
  2199 	int verbose = 0;
  2071 	int error;
  2200 	int error;
  2072 	int flag, set;
  2201 	int flag, set;
       
  2202 	int exported = 0;
       
  2203 	char *vdev_dir = NULL;
  2073 
  2204 
  2074 	(void) setrlimit(RLIMIT_NOFILE, &rl);
  2205 	(void) setrlimit(RLIMIT_NOFILE, &rl);
  2075 	(void) enable_extended_FILE_stdio(-1, -1);
  2206 	(void) enable_extended_FILE_stdio(-1, -1);
  2076 
  2207 
  2077 	dprintf_setup(&argc, argv);
  2208 	dprintf_setup(&argc, argv);
  2078 
  2209 
  2079 	while ((c = getopt(argc, argv, "udibcsvCLO:B:UlR")) != -1) {
  2210 	while ((c = getopt(argc, argv, "udibcsvCLO:B:UlRep:")) != -1) {
  2080 		switch (c) {
  2211 		switch (c) {
  2081 		case 'u':
  2212 		case 'u':
  2082 		case 'd':
  2213 		case 'd':
  2083 		case 'i':
  2214 		case 'i':
  2084 		case 'b':
  2215 		case 'b':
  2137 			verbose++;
  2268 			verbose++;
  2138 			break;
  2269 			break;
  2139 		case 'U':
  2270 		case 'U':
  2140 			spa_config_dir = "/tmp";
  2271 			spa_config_dir = "/tmp";
  2141 			break;
  2272 			break;
       
  2273 		case 'e':
       
  2274 			exported = 1;
       
  2275 			break;
       
  2276 		case 'p':
       
  2277 			vdev_dir = optarg;
       
  2278 			break;
  2142 		default:
  2279 		default:
  2143 			usage();
  2280 			usage();
  2144 			break;
  2281 			break;
  2145 		}
  2282 		}
  2146 	}
  2283 	}
  2147 
  2284 
       
  2285 	if (vdev_dir != NULL && exported == 0)
       
  2286 		(void) fatal("-p option requires use of -e\n");
       
  2287 
  2148 	kernel_init(FREAD);
  2288 	kernel_init(FREAD);
       
  2289 	g_zfs = libzfs_init();
  2149 
  2290 
  2150 	/*
  2291 	/*
  2151 	 * Disable vdev caching.  If we don't do this, live pool traversal
  2292 	 * Disable vdev caching.  If we don't do this, live pool traversal
  2152 	 * won't make progress because it will never see disk updates.
  2293 	 * won't make progress because it will never see disk updates.
  2153 	 */
  2294 	 */
  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 
  2229 	} else {
  2384 	} else {
  2230 		dump_zpool(spa);
  2385 		dump_zpool(spa);
  2231 		spa_close(spa, FTAG);
  2386 		spa_close(spa, FTAG);
  2232 	}
  2387 	}
  2233 
  2388 
       
  2389 	libzfs_fini(g_zfs);
  2234 	kernel_fini();
  2390 	kernel_fini();
  2235 
  2391 
  2236 	return (0);
  2392 	return (0);
  2237 }
  2393 }