Beispiel #1
0
int ploop_discard(struct ploop_disk_images_data *di,
		struct ploop_discard_param *param)
{
	int ret;
	char dev[PATH_MAX];
	char mnt[PATH_MAX];
	int mounted = 0;

	if (ploop_lock_dd(di))
		return SYSEXIT_LOCK;

	ret = ploop_find_dev(di->runtime->component_name,
			di->images[0]->file, dev, sizeof(dev));
	if (ret == -1) {
		ploop_unlock_dd(di);
		return SYSEXIT_LOCK;
	} else if (ret == 0) {
		if (ploop_get_mnt_by_dev(dev, mnt, sizeof(mnt))) {
			ploop_err(0, "Unable to find mount point for %s", dev);
			ploop_unlock_dd(di);
			return SYSEXIT_PARAM;
		}
	} else {
		struct ploop_mount_param mount_param = {};

		if (!param->automount) {
			ploop_err(0, "Unable to discard: image is not mounted");
			ploop_unlock_dd(di);
			return SYSEXIT_PARAM;
		}
		ret = auto_mount_image(di, &mount_param);
		if (ret) {
			ploop_unlock_dd(di);
			return ret;
		}
		mounted = 1;
		snprintf(dev, sizeof(dev), "%s", mount_param.device);
		snprintf(mnt, sizeof(mnt), "%s", mount_param.target);

		free_mount_param(&mount_param);
	}
	ploop_unlock_dd(di);

	ret = do_ploop_discard(di, dev, mnt, param->minlen_b,
			param->to_free, param->stop);

	if (mounted && ploop_lock_dd(di) == 0) {
		ploop_umount(dev, di);
		ploop_unlock_dd(di);
	}

	return ret;
}
Beispiel #2
0
int ploop_create_temporary_snapshot(struct ploop_disk_images_data *di,
		struct ploop_tsnapshot_param *param, int *holder_fd)
{
	int ret;
	struct ploop_mount_param mount_param = { .ro = 1, };
	char component_name[PLOOP_COOKIE_SIZE];

	if (di == NULL || param == NULL)
		return SYSEXIT_PARAM;

	if (param->guid == NULL) {
		ploop_err(0, "Snapshot guid is not specified");
		return SYSEXIT_PARAM;
	}

	if (param->component_name == NULL) {
		ploop_err(0, "Component name is not specified");
		return SYSEXIT_PARAM;
	}

	if (ploop_lock_dd(di))
		return SYSEXIT_LOCK;

	ret = do_create_snapshot(di, param->guid, param->snap_dir, 1);
	if (ret)
		goto err_unlock;

	/* FIXME: should be processed from 'struct ploop_mount_param' only ?? */
	char *t = di->runtime->component_name;
	snprintf(component_name, sizeof(component_name), "%s%s",
			holder_fd == NULL ? TSNAPSHOT_MOUNT_LOCK_MARK : "",
			param->component_name);
	di->runtime->component_name = component_name;

	mount_param.guid = param->guid;
	mount_param.target = param->target;
	ret = mount_image(di, &mount_param);
	di->runtime->component_name = t;

	if (ret)
		goto err_merge;

	strncpy(param->device, mount_param.device, sizeof(param->device));
	param->device[sizeof(param->device) - 1] = '\0';

	if (holder_fd != NULL) {
		ret = open_snap_holder(param->device, holder_fd);
		if (ret)
			goto err;
	}

	ploop_unlock_dd(di);

	return 0;

err:
	ploop_umount(mount_param.device, di);

err_merge:
	ploop_merge_snapshot_by_guid(di, di->top_guid, NULL);

err_unlock:
	ploop_unlock_dd(di);

	return ret;
}

int is_device_inuse(const char *dev)
{
	int count;
	char fname[PATH_MAX];
	char cookie[PLOOP_COOKIE_SIZE] = "";

	if (ploop_get_attr(dev, "open_count", &count))
		return 1;

	/* detect if snapshot locked by ploop mount */
	snprintf(fname, sizeof(fname), "/sys/block/%s/pstate/cookie",
			memcmp(dev, "/dev/", 5) == 0 ? dev + 5 : dev);
	if (read_line_quiet(fname, cookie, sizeof(cookie)))
		return 1;

	if (!strncmp(cookie, TSNAPSHOT_MOUNT_LOCK_MARK,
				sizeof(TSNAPSHOT_MOUNT_LOCK_MARK)-1))
		return 1;

	/* snap holder + mount */
	if (count >= 2)
		return 1;

	/* if there single reference we should detect is holder is alive */
	if (count == 1 && ploop_get_mnt_by_dev(dev, fname, sizeof(fname)) != 0)
		return 1;

	return 0;
}
Beispiel #3
0
static int plooptool_umount(int argc, char **argv)
{
	int i, ret;
	char *mnt = NULL;
	char device[PATH_MAX];
	struct {
		char * device;
	} umountopts = { };
	const char *component_name = NULL;

	while ((i = getopt(argc, argv, "d:m:c:")) != EOF) {
		switch (i) {
		case 'd':
			umountopts.device = optarg;
			break;
		case 'm':
			mnt = optarg;
			break;
		case 'c':
			component_name = optarg;
			break;
		default:
			usage_umount();
			return SYSEXIT_PARAM;
		}
	}

	argc -= optind;
	argv += optind;

	if (argc != 1 && !umountopts.device && !mnt) {
		usage_umount();
		return SYSEXIT_PARAM;
	}

	if (umountopts.device != NULL) {
		int len = strlen(umountopts.device);

		/* if partition is provided, strip it */
		if (strcmp(umountopts.device + len - 2, "p1") == 0 &&
				isdigit(umountopts.device[len - 3]))
			umountopts.device[len - 2] = '\0';

		ret = ploop_umount(umountopts.device, NULL);
	}else if (mnt != NULL) {
		if (ploop_get_dev_by_mnt(mnt, device, sizeof(device))) {
			fprintf(stderr, "Unable to find ploop device by %s\n",
					mnt);
			return SYSEXIT_PARAM;
		}
		ret = ploop_umount(device, NULL);
	} else if (is_xml_fname(argv[0])) {
		struct ploop_disk_images_data *di;
		ret = ploop_open_dd(&di, argv[0]);
		if (ret)
			return ret;

		if (component_name != NULL)
			ploop_set_component_name(di, component_name);

		ret = ploop_umount_image(di);

		ploop_close_dd(di);
	} else {
		if (ploop_find_dev(component_name, argv[0], device, sizeof(device)) != 0) {
			fprintf(stderr, "Image %s is not mounted\n", argv[0]);
			return SYSEXIT_PARAM;
		}
		ret = ploop_umount(device, NULL);
	}

	return ret;
}