Esempio n. 1
0
int dm_device_remove_all(uint64_t *dev)
{
	struct bl_dm_tree *p;
	struct dm_tree_node *node;
	const char *uuid;
	int ret = 0;
	uint32_t major, minor;
	uint64_t bl_dev;

	memcpy(&major, dev, sizeof(uint32_t));
	memcpy(&minor, (void *)dev + sizeof(uint32_t), sizeof(uint32_t));
	bl_dev = MKDEV(major, minor);
	p = find_bl_dm_tree(bl_dev);
	if (!p)
		return ret;

	node = dm_tree_find_node(p->tree, MAJOR(bl_dev), MINOR(bl_dev));
	if (!node)
		return ret;

	uuid = dm_tree_node_get_uuid(node);
	if (!uuid)
		return ret;

	dm_device_remove(bl_dev);
	ret = dm_tree_deactivate_children(node, uuid, strlen(uuid));
	dm_task_update_nodes();
	bl_dm_remove_tree(bl_dev);

	return ret;
}
Esempio n. 2
0
static int dm_device_remove(uint64_t dev)
{
	struct dm_task *dmt;
	struct dm_names *dmnames;
	char *name = NULL;
	int ret = 0;

	/* Look for dev_name via dev, if dev_name could be transferred here,
	   we could jump to DM_DEVICE_REMOVE directly */

	dmt = dm_task_create(DM_DEVICE_LIST);
	if (!dmt) {
		BL_LOG_ERR("dm_task creation failed\n");
		goto out;
	}

	ret = dm_task_run(dmt);
	if (!ret) {
		BL_LOG_ERR("dm_task_run failed\n");
		goto out;
	}

	dmnames = dm_task_get_names(dmt);
	if (!dmnames || !dmnames->dev) {
		BL_LOG_ERR("dm_task_get_names failed\n");
		goto out;
	}

	while (dmnames) {
		if (dmnames->dev == dev) {
			name = strdup(dmnames->name);
			break;
		}
		dmnames = (void *)dmnames + dmnames->next;
	}

	if (!name) {
		BL_LOG_ERR("Could not find device\n");
		goto out;
	}

	dm_task_update_nodes();

 out:
	if (dmt)
		dm_task_destroy(dmt);

	/* Start to remove device */
	if (name) {
		ret = dm_device_remove_byname(name);
		free(name);
	}

	return ret;
}
Esempio n. 3
0
static int dm_device_remove_byname(const char *dev_name)
{
	struct dm_task *dmt;
	int ret = 0;

	BL_LOG_INFO("%s: %s\n", __func__, dev_name);

	dmt = dm_task_create(DM_DEVICE_REMOVE);
	if (!dmt)
		return 0;

	ret = dm_task_set_name(dmt, dev_name) && dm_task_run(dmt);

	dm_task_update_nodes();
	dm_task_destroy(dmt);

	return ret;
}
Esempio n. 4
0
/*
 * Create device via device mapper
 * return 0 when creation failed
 * return dev no for created device
 */
static uint64_t
dm_device_create_mapped(const char *dev_name, struct bl_dm_table *p)
{
	struct dm_task *dmt;
	struct dm_info dminfo;
	int ret = 0;

	dmt = dm_task_create(DM_DEVICE_CREATE);
	if (!dmt) {
		BL_LOG_ERR("Create dm_task for %s failed\n", dev_name);
		return 0;
	}
	ret = dm_task_set_name(dmt, dev_name);
	if (!ret)
		goto err_out;

	while (p) {
		ret =
		    dm_task_add_target(dmt, p->offset, p->size, p->target_type,
				       p->params);
		if (!ret)
			goto err_out;
		p = p->next;
	}

	ret = dm_task_run(dmt) && dm_task_get_info(dmt, &dminfo)
	    && dminfo.exists;

	if (!ret)
		goto err_out;

	dm_task_update_nodes();

 err_out:
	dm_task_destroy(dmt);

	if (!ret) {
		BL_LOG_ERR("Create device %s failed\n", dev_name);
		return 0;
	}
	return MKDEV(dminfo.major, dminfo.minor);
}
Esempio n. 5
0
int dm_remove_device(const char *name, int force, uint64_t size)
{
	int r = -EINVAL;
	int retries = force ? RETRY_COUNT : 1;
	int error_target = 0;

	if (!name || (force && !size))
		return -EINVAL;

	do {
		r = _dm_simple(DM_DEVICE_REMOVE, name, 1) ? 0 : -EINVAL;
		if (--retries && r) {
			log_dbg("WARNING: other process locked internal device %s, %s.",
				name, retries ? "retrying remove" : "giving up");
			if (force && (crypt_get_debug_level() == CRYPT_LOG_DEBUG))
				debug_processes_using_device(name);
			sleep(1);
			if (force && !error_target) {
				/* If force flag is set, replace device with error, read-only target.
				 * it should stop processes from reading it and also removed underlying
				 * device from mapping, so it is usable again.
				 * Force flag should be used only for temporary devices, which are
				 * intended to work inside cryptsetup only!
				 * Anyway, if some process try to read temporary cryptsetup device,
				 * it is bug - no other process should try touch it (e.g. udev).
				 */
				_error_device(name, size);
				error_target = 1;
			}
		}
	} while (r == -EINVAL && retries);

	dm_task_update_nodes();

	return r;
}
Esempio n. 6
0
int dm_create_device(const char *name,
		     const char *device,
		     const char *cipher,
		     const char *type,
		     const char *uuid,
		     uint64_t size,
		     uint64_t skip,
		     uint64_t offset,
		     size_t key_size,
		     const char *key,
		     int read_only,
		     int reload)
{
	struct dm_task *dmt = NULL;
	struct dm_info dmi;
	char *params = NULL;
	char *error = NULL;
	char dev_uuid[DM_UUID_LEN] = {0};
	int r = -EINVAL;
	uint32_t read_ahead = 0;
	uint32_t cookie = 0;
	uint16_t udev_flags = 0;

	params = get_params(device, skip, offset, cipher, key_size, key);
	if (!params)
		goto out_no_removal;

	if (type && !strncmp(type, "TEMP", 4))
		udev_flags = CRYPT_TEMP_UDEV_FLAGS;

	/* All devices must have DM_UUID, only resize on old device is exception */
	if (reload) {
		if (!(dmt = dm_task_create(DM_DEVICE_RELOAD)))
			goto out_no_removal;

		if (!dm_task_set_name(dmt, name))
			goto out_no_removal;
	} else {
		dm_prepare_uuid(name, type, uuid, dev_uuid, sizeof(dev_uuid));

		if (!(dmt = dm_task_create(DM_DEVICE_CREATE)))
			goto out_no_removal;

		if (!dm_task_set_name(dmt, name))
			goto out_no_removal;

		if (!dm_task_set_uuid(dmt, dev_uuid))
			goto out_no_removal;

		if (_dm_use_udev() && !dm_task_set_cookie(dmt, &cookie, udev_flags))
			goto out_no_removal;
	}

	if (read_only && !dm_task_set_ro(dmt))
		goto out_no_removal;
	if (!dm_task_add_target(dmt, 0, size, DM_CRYPT_TARGET, params))
		goto out_no_removal;

#ifdef DM_READ_AHEAD_MINIMUM_FLAG
	if (_dev_read_ahead(device, &read_ahead) &&
	    !dm_task_set_read_ahead(dmt, read_ahead, DM_READ_AHEAD_MINIMUM_FLAG))
		goto out_no_removal;
#endif

	if (!dm_task_run(dmt))
		goto out_no_removal;

	if (reload) {
		dm_task_destroy(dmt);
		if (!(dmt = dm_task_create(DM_DEVICE_RESUME)))
			goto out;
		if (!dm_task_set_name(dmt, name))
			goto out;
		if (uuid && !dm_task_set_uuid(dmt, dev_uuid))
			goto out;
		if (_dm_use_udev() && !dm_task_set_cookie(dmt, &cookie, udev_flags))
			goto out;
		if (!dm_task_run(dmt))
			goto out;
	}

	if (!dm_task_get_info(dmt, &dmi))
		goto out;

	r = 0;
out:
	if (_dm_use_udev()) {
		(void)dm_udev_wait(cookie);
		cookie = 0;
	}

	if (r < 0 && !reload) {
		if (get_error())
			error = strdup(get_error());

		dm_remove_device(name, 0, 0);

		if (error) {
			set_error(error);
			free(error);
		}
	}

out_no_removal:
	if (cookie && _dm_use_udev())
		(void)dm_udev_wait(cookie);

	if (params)
		safe_free(params);
	if (dmt)
		dm_task_destroy(dmt);

	dm_task_update_nodes();
	return r;
}