usr/src/cmd/ztest/ztest.c
changeset 7768 7d2fd61355d7
parent 7762 067dd33ef32c
child 7793 4dbbc0a3f135
equal deleted inserted replaced
7767:905db6a104b6 7768:7d2fd61355d7
   603 	return (raidz);
   603 	return (raidz);
   604 }
   604 }
   605 
   605 
   606 static nvlist_t *
   606 static nvlist_t *
   607 make_vdev_mirror(char *path, char *aux, size_t size, uint64_t ashift,
   607 make_vdev_mirror(char *path, char *aux, size_t size, uint64_t ashift,
   608 	int log, int r, int m)
   608 	int r, int m)
   609 {
   609 {
   610 	nvlist_t *mirror, **child;
   610 	nvlist_t *mirror, **child;
   611 	int c;
   611 	int c;
   612 
   612 
   613 	if (m < 1)
   613 	if (m < 1)
   621 	VERIFY(nvlist_alloc(&mirror, NV_UNIQUE_NAME, 0) == 0);
   621 	VERIFY(nvlist_alloc(&mirror, NV_UNIQUE_NAME, 0) == 0);
   622 	VERIFY(nvlist_add_string(mirror, ZPOOL_CONFIG_TYPE,
   622 	VERIFY(nvlist_add_string(mirror, ZPOOL_CONFIG_TYPE,
   623 	    VDEV_TYPE_MIRROR) == 0);
   623 	    VDEV_TYPE_MIRROR) == 0);
   624 	VERIFY(nvlist_add_nvlist_array(mirror, ZPOOL_CONFIG_CHILDREN,
   624 	VERIFY(nvlist_add_nvlist_array(mirror, ZPOOL_CONFIG_CHILDREN,
   625 	    child, m) == 0);
   625 	    child, m) == 0);
   626 	VERIFY(nvlist_add_uint64(mirror, ZPOOL_CONFIG_IS_LOG, log) == 0);
       
   627 
   626 
   628 	for (c = 0; c < m; c++)
   627 	for (c = 0; c < m; c++)
   629 		nvlist_free(child[c]);
   628 		nvlist_free(child[c]);
   630 
   629 
   631 	umem_free(child, m * sizeof (nvlist_t *));
   630 	umem_free(child, m * sizeof (nvlist_t *));
   642 
   641 
   643 	ASSERT(t > 0);
   642 	ASSERT(t > 0);
   644 
   643 
   645 	child = umem_alloc(t * sizeof (nvlist_t *), UMEM_NOFAIL);
   644 	child = umem_alloc(t * sizeof (nvlist_t *), UMEM_NOFAIL);
   646 
   645 
   647 	for (c = 0; c < t; c++)
   646 	for (c = 0; c < t; c++) {
   648 		child[c] = make_vdev_mirror(path, aux, size, ashift, log, r, m);
   647 		child[c] = make_vdev_mirror(path, aux, size, ashift, r, m);
       
   648 		VERIFY(nvlist_add_uint64(child[c], ZPOOL_CONFIG_IS_LOG,
       
   649 		    log) == 0);
       
   650 	}
   649 
   651 
   650 	VERIFY(nvlist_alloc(&root, NV_UNIQUE_NAME, 0) == 0);
   652 	VERIFY(nvlist_alloc(&root, NV_UNIQUE_NAME, 0) == 0);
   651 	VERIFY(nvlist_add_string(root, ZPOOL_CONFIG_TYPE, VDEV_TYPE_ROOT) == 0);
   653 	VERIFY(nvlist_add_string(root, ZPOOL_CONFIG_TYPE, VDEV_TYPE_ROOT) == 0);
   652 	VERIFY(nvlist_add_nvlist_array(root, aux ? aux : ZPOOL_CONFIG_CHILDREN,
   654 	VERIFY(nvlist_add_nvlist_array(root, aux ? aux : ZPOOL_CONFIG_CHILDREN,
   653 	    child, t) == 0);
   655 	    child, t) == 0);
   829 
   831 
   830 	spa_close(spa, FTAG);
   832 	spa_close(spa, FTAG);
   831 	(void) rw_unlock(&ztest_shared->zs_name_lock);
   833 	(void) rw_unlock(&ztest_shared->zs_name_lock);
   832 }
   834 }
   833 
   835 
       
   836 static vdev_t *
       
   837 vdev_lookup_by_path(vdev_t *vd, const char *path)
       
   838 {
       
   839 	vdev_t *mvd;
       
   840 
       
   841 	if (vd->vdev_path != NULL && strcmp(path, vd->vdev_path) == 0)
       
   842 		return (vd);
       
   843 
       
   844 	for (int c = 0; c < vd->vdev_children; c++)
       
   845 		if ((mvd = vdev_lookup_by_path(vd->vdev_child[c], path)) !=
       
   846 		    NULL)
       
   847 			return (mvd);
       
   848 
       
   849 	return (NULL);
       
   850 }
       
   851 
   834 /*
   852 /*
   835  * Verify that vdev_add() works as expected.
   853  * Verify that vdev_add() works as expected.
   836  */
   854  */
   837 void
   855 void
   838 ztest_vdev_add_remove(ztest_args_t *za)
   856 ztest_vdev_add_remove(ztest_args_t *za)
   873  */
   891  */
   874 void
   892 void
   875 ztest_vdev_aux_add_remove(ztest_args_t *za)
   893 ztest_vdev_aux_add_remove(ztest_args_t *za)
   876 {
   894 {
   877 	spa_t *spa = za->za_spa;
   895 	spa_t *spa = za->za_spa;
       
   896 	vdev_t *rvd = spa->spa_root_vdev;
   878 	spa_aux_vdev_t *sav;
   897 	spa_aux_vdev_t *sav;
   879 	char *aux;
   898 	char *aux;
   880 	uint64_t guid = 0;
   899 	uint64_t guid = 0;
   881 	int error;
   900 	int error;
   882 
   901 
   883 	if (ztest_random(3) == 0) {
   902 	if (ztest_random(2) == 0) {
   884 		sav = &spa->spa_spares;
   903 		sav = &spa->spa_spares;
   885 		aux = ZPOOL_CONFIG_SPARES;
   904 		aux = ZPOOL_CONFIG_SPARES;
   886 	} else {
   905 	} else {
   887 		sav = &spa->spa_l2cache;
   906 		sav = &spa->spa_l2cache;
   888 		aux = ZPOOL_CONFIG_L2CACHE;
   907 		aux = ZPOOL_CONFIG_L2CACHE;
   909 			    zopt_pool, aux, ztest_shared->zs_vdev_aux);
   928 			    zopt_pool, aux, ztest_shared->zs_vdev_aux);
   910 			for (c = 0; c < sav->sav_count; c++)
   929 			for (c = 0; c < sav->sav_count; c++)
   911 				if (strcmp(sav->sav_vdevs[c]->vdev_path,
   930 				if (strcmp(sav->sav_vdevs[c]->vdev_path,
   912 				    path) == 0)
   931 				    path) == 0)
   913 					break;
   932 					break;
   914 			if (c == sav->sav_count)
   933 			if (c == sav->sav_count &&
       
   934 			    vdev_lookup_by_path(rvd, path) == NULL)
   915 				break;
   935 				break;
   916 			ztest_shared->zs_vdev_aux++;
   936 			ztest_shared->zs_vdev_aux++;
   917 		}
   937 		}
   918 	}
   938 	}
   919 
   939 
   921 
   941 
   922 	if (guid == 0) {
   942 	if (guid == 0) {
   923 		/*
   943 		/*
   924 		 * Add a new device.
   944 		 * Add a new device.
   925 		 */
   945 		 */
   926 		nvlist_t *nvroot = make_vdev_root(NULL, aux, zopt_vdev_size, 0,
   946 		nvlist_t *nvroot = make_vdev_root(NULL, aux,
   927 		    0, 0, 0, 1);
   947 		    (zopt_vdev_size * 5) / 4, 0, 0, 0, 0, 1);
   928 		error = spa_vdev_add(spa, nvroot);
   948 		error = spa_vdev_add(spa, nvroot);
   929 		if (error != 0)
   949 		if (error != 0)
   930 			fatal(0, "spa_vdev_add(%p) = %d", nvroot, error);
   950 			fatal(0, "spa_vdev_add(%p) = %d", nvroot, error);
   931 		nvlist_free(nvroot);
   951 		nvlist_free(nvroot);
   932 	} else {
   952 	} else {
   944 	}
   964 	}
   945 
   965 
   946 	(void) mutex_unlock(&ztest_shared->zs_vdev_lock);
   966 	(void) mutex_unlock(&ztest_shared->zs_vdev_lock);
   947 }
   967 }
   948 
   968 
   949 static vdev_t *
       
   950 vdev_lookup_by_path(vdev_t *vd, const char *path)
       
   951 {
       
   952 	int c;
       
   953 	vdev_t *mvd;
       
   954 
       
   955 	if (vd->vdev_path != NULL) {
       
   956 		if (vd->vdev_wholedisk == 1) {
       
   957 			/*
       
   958 			 * For whole disks, the internal path has 's0', but the
       
   959 			 * path passed in by the user doesn't.
       
   960 			 */
       
   961 			if (strlen(path) == strlen(vd->vdev_path) - 2 &&
       
   962 			    strncmp(path, vd->vdev_path, strlen(path)) == 0)
       
   963 				return (vd);
       
   964 		} else if (strcmp(path, vd->vdev_path) == 0) {
       
   965 			return (vd);
       
   966 		}
       
   967 	}
       
   968 
       
   969 	for (c = 0; c < vd->vdev_children; c++)
       
   970 		if ((mvd = vdev_lookup_by_path(vd->vdev_child[c], path)) !=
       
   971 		    NULL)
       
   972 			return (mvd);
       
   973 
       
   974 	return (NULL);
       
   975 }
       
   976 
       
   977 /*
   969 /*
   978  * Verify that we can attach and detach devices.
   970  * Verify that we can attach and detach devices.
   979  */
   971  */
   980 void
   972 void
   981 ztest_vdev_attach_detach(ztest_args_t *za)
   973 ztest_vdev_attach_detach(ztest_args_t *za)
   982 {
   974 {
   983 	spa_t *spa = za->za_spa;
   975 	spa_t *spa = za->za_spa;
       
   976 	spa_aux_vdev_t *sav = &spa->spa_spares;
   984 	vdev_t *rvd = spa->spa_root_vdev;
   977 	vdev_t *rvd = spa->spa_root_vdev;
   985 	vdev_t *oldvd, *newvd, *pvd;
   978 	vdev_t *oldvd, *newvd, *pvd;
   986 	nvlist_t *root;
   979 	nvlist_t *root;
   987 	uint64_t leaves = MAX(zopt_mirrors, 1) * zopt_raidz;
   980 	uint64_t leaves = MAX(zopt_mirrors, 1) * zopt_raidz;
   988 	uint64_t leaf, top;
   981 	uint64_t leaf, top;
   989 	uint64_t ashift = ztest_get_ashift();
   982 	uint64_t ashift = ztest_get_ashift();
       
   983 	uint64_t oldguid;
   990 	size_t oldsize, newsize;
   984 	size_t oldsize, newsize;
   991 	char oldpath[MAXPATHLEN], newpath[MAXPATHLEN];
   985 	char oldpath[MAXPATHLEN], newpath[MAXPATHLEN];
   992 	int replacing;
   986 	int replacing;
       
   987 	int newvd_is_spare = B_FALSE;
       
   988 	int oldvd_is_log;
   993 	int error, expected_error;
   989 	int error, expected_error;
   994 
   990 
   995 	(void) mutex_lock(&ztest_shared->zs_vdev_lock);
   991 	(void) mutex_lock(&ztest_shared->zs_vdev_lock);
   996 
   992 
   997 	spa_config_enter(spa, SCL_VDEV, FTAG, RW_READER);
   993 	spa_config_enter(spa, SCL_VDEV, FTAG, RW_READER);
  1010 	 * Pick a random leaf within it.
  1006 	 * Pick a random leaf within it.
  1011 	 */
  1007 	 */
  1012 	leaf = ztest_random(leaves);
  1008 	leaf = ztest_random(leaves);
  1013 
  1009 
  1014 	/*
  1010 	/*
  1015 	 * Generate the path to this leaf.  The filename will end with 'a'.
  1011 	 * Locate this vdev.
  1016 	 * We'll alternate replacements with a filename that ends with 'b'.
  1012 	 */
  1017 	 */
  1013 	oldvd = rvd->vdev_child[top];
  1018 	(void) snprintf(oldpath, sizeof (oldpath),
  1014 	if (zopt_mirrors >= 1)
  1019 	    ztest_dev_template, zopt_dir, zopt_pool, top * leaves + leaf);
  1015 		oldvd = oldvd->vdev_child[leaf / zopt_raidz];
  1020 
  1016 	if (zopt_raidz > 1)
  1021 	bcopy(oldpath, newpath, MAXPATHLEN);
  1017 		oldvd = oldvd->vdev_child[leaf % zopt_raidz];
  1022 
  1018 
  1023 	/*
  1019 	/*
  1024 	 * If the 'a' file isn't part of the pool, the 'b' file must be.
  1020 	 * If we're already doing an attach or replace, oldvd may be a
  1025 	 */
  1021 	 * mirror vdev -- in which case, pick a random child.
  1026 	if (vdev_lookup_by_path(rvd, oldpath) == NULL)
  1022 	 */
  1027 		oldpath[strlen(oldpath) - 1] = 'b';
  1023 	while (oldvd->vdev_children != 0) {
  1028 	else
  1024 		ASSERT(oldvd->vdev_children == 2);
  1029 		newpath[strlen(newpath) - 1] = 'b';
  1025 		oldvd = oldvd->vdev_child[ztest_random(2)];
  1030 
  1026 	}
  1031 	/*
  1027 
  1032 	 * Now oldpath represents something that's already in the pool,
  1028 	oldguid = oldvd->vdev_guid;
  1033 	 * and newpath is the thing we'll try to attach.
  1029 	oldsize = vdev_get_rsize(oldvd);
  1034 	 */
  1030 	oldvd_is_log = oldvd->vdev_top->vdev_islog;
  1035 	oldvd = vdev_lookup_by_path(rvd, oldpath);
  1031 	(void) strcpy(oldpath, oldvd->vdev_path);
  1036 	newvd = vdev_lookup_by_path(rvd, newpath);
       
  1037 	ASSERT(oldvd != NULL);
       
  1038 	pvd = oldvd->vdev_parent;
  1032 	pvd = oldvd->vdev_parent;
  1039 
  1033 
  1040 	/*
  1034 	/*
  1041 	 * Make newsize a little bigger or smaller than oldsize.
  1035 	 * For the new vdev, choose with equal probability between the two
  1042 	 * If it's smaller, the attach should fail.
  1036 	 * standard paths (ending in either 'a' or 'b') or a random hot spare.
  1043 	 * If it's larger, and we're doing a replace,
  1037 	 */
  1044 	 * we should get dynamic LUN growth when we're done.
  1038 	if (sav->sav_count != 0 && ztest_random(3) == 0) {
  1045 	 */
  1039 		newvd = sav->sav_vdevs[ztest_random(sav->sav_count)];
  1046 	oldsize = vdev_get_rsize(oldvd);
  1040 		newvd_is_spare = B_TRUE;
  1047 	newsize = 10 * oldsize / (9 + ztest_random(3));
  1041 		(void) strcpy(newpath, newvd->vdev_path);
       
  1042 	} else {
       
  1043 		(void) snprintf(newpath, sizeof (newpath), ztest_dev_template,
       
  1044 		    zopt_dir, zopt_pool, top * leaves + leaf);
       
  1045 		if (ztest_random(2) == 0)
       
  1046 			newpath[strlen(newpath) - 1] = 'b';
       
  1047 		newvd = vdev_lookup_by_path(rvd, newpath);
       
  1048 	}
       
  1049 
       
  1050 	if (newvd) {
       
  1051 		newsize = vdev_get_rsize(newvd);
       
  1052 	} else {
       
  1053 		/*
       
  1054 		 * Make newsize a little bigger or smaller than oldsize.
       
  1055 		 * If it's smaller, the attach should fail.
       
  1056 		 * If it's larger, and we're doing a replace,
       
  1057 		 * we should get dynamic LUN growth when we're done.
       
  1058 		 */
       
  1059 		newsize = 10 * oldsize / (9 + ztest_random(3));
       
  1060 	}
  1048 
  1061 
  1049 	/*
  1062 	/*
  1050 	 * If pvd is not a mirror or root, the attach should fail with ENOTSUP,
  1063 	 * If pvd is not a mirror or root, the attach should fail with ENOTSUP,
  1051 	 * unless it's a replace; in that case any non-replacing parent is OK.
  1064 	 * unless it's a replace; in that case any non-replacing parent is OK.
  1052 	 *
  1065 	 *
  1053 	 * If newvd is already part of the pool, it should fail with EBUSY.
  1066 	 * If newvd is already part of the pool, it should fail with EBUSY.
  1054 	 *
  1067 	 *
  1055 	 * If newvd is too small, it should fail with EOVERFLOW.
  1068 	 * If newvd is too small, it should fail with EOVERFLOW.
  1056 	 */
  1069 	 */
  1057 	if (newvd != NULL)
  1070 	if (pvd->vdev_ops != &vdev_mirror_ops &&
       
  1071 	    pvd->vdev_ops != &vdev_root_ops && (!replacing ||
       
  1072 	    pvd->vdev_ops == &vdev_replacing_ops ||
       
  1073 	    pvd->vdev_ops == &vdev_spare_ops))
       
  1074 		expected_error = ENOTSUP;
       
  1075 	else if (newvd_is_spare && (!replacing || oldvd_is_log))
       
  1076 		expected_error = ENOTSUP;
       
  1077 	else if (newvd == oldvd)
       
  1078 		expected_error = replacing ? 0 : EBUSY;
       
  1079 	else if (vdev_lookup_by_path(rvd, newpath) != NULL)
  1058 		expected_error = EBUSY;
  1080 		expected_error = EBUSY;
  1059 	else if (pvd->vdev_ops != &vdev_mirror_ops &&
       
  1060 	    pvd->vdev_ops != &vdev_root_ops &&
       
  1061 	    (!replacing || pvd->vdev_ops == &vdev_replacing_ops))
       
  1062 		expected_error = ENOTSUP;
       
  1063 	else if (newsize < oldsize)
  1081 	else if (newsize < oldsize)
  1064 		expected_error = EOVERFLOW;
  1082 		expected_error = EOVERFLOW;
  1065 	else if (ashift > oldvd->vdev_top->vdev_ashift)
  1083 	else if (ashift > oldvd->vdev_top->vdev_ashift)
  1066 		expected_error = EDOM;
  1084 		expected_error = EDOM;
  1067 	else
  1085 	else
  1073 	 * Build the nvlist describing newpath.
  1091 	 * Build the nvlist describing newpath.
  1074 	 */
  1092 	 */
  1075 	root = make_vdev_root(newpath, NULL, newvd == NULL ? newsize : 0,
  1093 	root = make_vdev_root(newpath, NULL, newvd == NULL ? newsize : 0,
  1076 	    ashift, 0, 0, 0, 1);
  1094 	    ashift, 0, 0, 0, 1);
  1077 
  1095 
  1078 	error = spa_vdev_attach(spa, oldvd->vdev_guid, root, replacing);
  1096 	error = spa_vdev_attach(spa, oldguid, root, replacing);
  1079 
  1097 
  1080 	nvlist_free(root);
  1098 	nvlist_free(root);
  1081 
  1099 
  1082 	/*
  1100 	/*
  1083 	 * If our parent was the replacing vdev, but the replace completed,
  1101 	 * If our parent was the replacing vdev, but the replace completed,