Exemple #1
0
/*
 * Returns 'in use' details, if found, about a specific dev_name,
 * based on the caller(who). It is important to note that it is possible
 * for there to be more than one 'in use' statistic regarding a dev_name.
 * The **msg parameter returns a list of 'in use' details. This message
 * is formatted via gettext().
 */
int
dm_inuse(char *dev_name, char **msg, dm_who_type_t who, int *errp)
{
	nvlist_t *dev_stats = NULL;
	char *by, *data;
	nvpair_t *nvwhat = NULL;
	nvpair_t *nvdesc = NULL;
	int	found = 0;
	int	err;
	char	*dname = NULL;

	*errp = 0;
	*msg = NULL;

	/*
	 * If the user doesn't want to do in use checking, return.
	 */

	if (NOINUSE_SET)
		return (0);

	dname = getfullblkname(dev_name);
	/*
	 * If we cannot find the block name, we cannot check the device
	 * for in use statistics. So, return found, which is == 0.
	 */
	if (dname == NULL || *dname == '\0') {
		return (found);
	}

	/*
	 * Slice stats for swap devices are only returned if mounted
	 * (e.g. /tmp).  Other devices or files being used for swap
	 * are ignored, so we add a special check here to use swapctl(2)
	 * to perform in-use checking.
	 */
	if (ANY_ZPOOL_USE(who) && (err = dm_inuse_swap(dname, errp))) {

		/* on error, dm_inuse_swap sets errp */
		if (err < 0) {
			free(dname);
			return (err);
		}

		/* simulate a mounted swap device */
		(void) build_usage_string(dname, DM_USE_MOUNT, "swap", msg,
		    &found, errp);

		/* if this fails, dm_get_usage_string changed */
		ASSERT(found == 1);

		free(dname);
		return (found);
	}

	dm_get_slice_stats(dname, &dev_stats, errp);
	if (dev_stats == NULL) {
		/*
		 * If there is an error, but it isn't a no device found error
		 * return the error as recorded. Otherwise, with a full
		 * block name, we might not be able to get the slice
		 * associated, and will get an ENODEV error. For example,
		 * an SVM metadevice will return a value from getfullblkname()
		 * but libdiskmgt won't be able to find this device for
		 * statistics gathering. This is expected and we should not
		 * report errnoneous errors.
		 */
		if (*errp) {
			if (*errp == ENODEV) {
				*errp = 0;
			}
		}
		free(dname);
		return (found);
	}

	for (;;) {

		nvwhat = nvlist_next_nvpair(dev_stats, nvdesc);
		nvdesc = nvlist_next_nvpair(dev_stats, nvwhat);

		/*
		 * End of the list found.
		 */
		if (nvwhat == NULL || nvdesc == NULL) {
			break;
		}
		/*
		 * Otherwise, we check to see if this client(who) cares
		 * about this in use scenario
		 */

		ASSERT(strcmp(nvpair_name(nvwhat), DM_USED_BY) == 0);
		ASSERT(strcmp(nvpair_name(nvdesc), DM_USED_NAME) == 0);
		/*
		 * If we error getting the string value continue on
		 * to the next pair(if there is one)
		 */
		if (nvpair_value_string(nvwhat, &by)) {
			continue;
		}
		if (nvpair_value_string(nvdesc, &data)) {
			continue;
		}

		switch (who) {
			case DM_WHO_MKFS:
				/*
				 * mkfs is not in use for these cases.
				 * All others are in use.
				 */
				if (strcmp(by, DM_USE_LU) == 0 ||
				    strcmp(by, DM_USE_FS) == 0 ||
				    strcmp(by, DM_USE_EXPORTED_ZPOOL) == 0) {
					break;
				}
				if (build_usage_string(dname,
				    by, data, msg, &found, errp) != 0) {
					if (*errp) {
						goto out;
					}
				}
				break;
			case DM_WHO_SWAP:
				/*
				 * Not in use for this.
				 */
				if (strcmp(by, DM_USE_DUMP) == 0 ||
				    strcmp(by, DM_USE_FS) == 0 ||
				    strcmp(by, DM_USE_EXPORTED_ZPOOL) == 0) {
					break;
				}
				if (strcmp(by, DM_USE_LU) == 0 &&
				    strcmp(data, "-") == 0) {
					break;
				}
				if (strcmp(by, DM_USE_VFSTAB) == 0 &&
				    strcmp(data, "") == 0) {
					break;
				}
				if (build_usage_string(dname,
				    by, data, msg, &found, errp) != 0) {
					if (*errp) {
						goto out;
					}
				}
				break;
			case DM_WHO_DUMP:
				/*
				 * Not in use for this.
				 */
				if ((strcmp(by, DM_USE_MOUNT) == 0 &&
				    strcmp(data, "swap") == 0) ||
				    strcmp(by, DM_USE_DUMP) == 0 ||
				    strcmp(by, DM_USE_FS) == 0 ||
				    strcmp(by, DM_USE_EXPORTED_ZPOOL) == 0) {
					break;
				}
				if (build_usage_string(dname,
				    by, data, msg, &found, errp)) {
					if (*errp) {
						goto out;
					}
				}
				break;

			case DM_WHO_FORMAT:
				if (strcmp(by, DM_USE_FS) == 0 ||
				    strcmp(by, DM_USE_EXPORTED_ZPOOL) == 0)
					break;
				if (build_usage_string(dname,
				    by, data, msg, &found, errp) != 0) {
					if (*errp) {
						goto out;
					}
				}
				break;

			case DM_WHO_ZPOOL_FORCE:
				if (strcmp(by, DM_USE_FS) == 0 ||
				    strcmp(by, DM_USE_EXPORTED_ZPOOL) == 0)
					break;
				/* FALLTHROUGH */
			case DM_WHO_ZPOOL:
				if (build_usage_string(dname,
				    by, data, msg, &found, errp) != 0) {
					if (*errp)
						goto out;
				}
				break;

			case DM_WHO_ZPOOL_SPARE:
				if (strcmp(by, DM_USE_SPARE_ZPOOL) != 0) {
					if (build_usage_string(dname, by,
					    data, msg, &found, errp) != 0) {
						if (*errp)
							goto out;
					}
				}
				break;

			default:
				/*
				 * nothing found in use for this client
				 * of libdiskmgt. Default is 'not in use'.
				 */
				break;
		}
	}
out:
	if (dname != NULL)
		free(dname);
	if (dev_stats != NULL)
		nvlist_free(dev_stats);

	return (found);
}
Exemple #2
0
/*
 * Returns 'in use' details, if found, about a specific dev_name,
 * based on the caller(who). It is important to note that it is possible
 * for there to be more than one 'in use' statistic regarding a dev_name.
 * The **msg parameter returns a list of 'in use' details. This message
 * is formatted via gettext().
 */
int
dm_inuse(char *dev_name, char **msg, dm_who_type_t who, int *errp)
{
	nvlist_t *dev_stats = NULL;
	char *by, *data;
	nvpair_t *nvwhat = NULL;
	nvpair_t *nvdesc = NULL;
	int	found = 0;

	*errp = 0;
	*msg = NULL;

	/*
	 * If the user doesn't want to do in use checking, return.
	 */

	if (NOINUSE_SET)
		return (0);
	
	dm_get_slice_stats(dev_name, &dev_stats, errp);
	if (dev_stats == NULL) {
		/*
		 * If there is an error, but it isn't a no device found error
		 * return the error as recorded. Otherwise, with a full
		 * block name, we might not be able to get the slice
		 * associated, and will get an ENODEV error. For example,
		 * an SVM metadevice will return a value from getfullblkname()
		 * but libdiskmgt won't be able to find this device for
		 * statistics gathering. This is expected and we should not
		 * report errnoneous errors.
		 */
		if (*errp) {
			if (*errp == ENODEV) {
				*errp = 0;
			}
		}
		//    free(dname);
		return (found);
	}

	for (;;) {

		nvwhat = nvlist_next_nvpair(dev_stats, nvdesc);
		nvdesc = nvlist_next_nvpair(dev_stats, nvwhat);

		/*
		 * End of the list found.
		 */
		if (nvwhat == NULL || nvdesc == NULL) {
			break;
		}
		/*
		 * Otherwise, we check to see if this client(who) cares
		 * about this in use scenario
		 */

		ASSERT(strcmp(nvpair_name(nvwhat), DM_USED_BY) == 0);
		ASSERT(strcmp(nvpair_name(nvdesc), DM_USED_NAME) == 0);
		/*
		 * If we error getting the string value continue on
		 * to the next pair(if there is one)
		 */
		if (nvpair_value_string(nvwhat, &by)) {
			continue;
		}
		if (nvpair_value_string(nvdesc, &data)) {
			continue;
		}

		switch (who) {

		case DM_WHO_ZPOOL_FORCE:
			if (strcmp(by, DM_USE_FS) == 0 ||
			strcmp(by, DM_USE_EXPORTED_ZPOOL) == 0 ||
			strcmp(by,  DM_USE_OS_PARTITION) == 0)
				break;
			/* FALLTHROUGH */
		case DM_WHO_ZPOOL:
			if (build_usage_string(dev_name,
			by, data, msg, &found, errp) != 0) {
				if (*errp)
					goto out;
			}
			break;

		case DM_WHO_ZPOOL_SPARE:
			if (strcmp(by, DM_USE_SPARE_ZPOOL) != 0) {
				if (build_usage_string(dev_name, by,
					data, msg, &found, errp) != 0) {
					if (*errp)
						goto out;
				}
			}
			break;

		default:
			/*
			 * nothing found in use for this client
			 * of libdiskmgt. Default is 'not in use'.
			 */
			break;
		}
	}
  out:
	nvlist_free(dev_stats);

	return (found);
}