Ejemplo n.º 1
0
/* Create a task, set its name and run it. */
static int
run_task(struct lib_context *lc, struct raid_set *rs, char *table, int type, char *name)
{
	/*
	 * DM_UUID_LEN is defined in dm-ioctl.h as 129 characters;
	 * though not all 129 must be used (md uses just 16 from 
	 * a quick review of md.c. 
	 * We will be using: (len vol grp name)
	 */
	char uuid[DM_UUID_LEN];
	int ret;
	struct dm_task *dmt;

	_init_dm();
	ret = (dmt = dm_task_create(type)) && dm_task_set_name(dmt, name);
	if (ret && table)
		ret = parse_table(lc, dmt, table);

	if (ret) {
		if (DM_DEVICE_CREATE == type) {
			ret = dmraid_uuid(lc, rs, uuid, DM_UUID_LEN, name) &&
				dm_task_set_uuid(dmt, uuid) && dm_task_run(dmt);
		} else
			ret = dm_task_run(dmt);
	}

	_exit_dm(dmt);
	return ret;
}
Ejemplo n.º 2
0
Archivo: dm.c Proyecto: radii/dmsteg
int dm_mount_aspect(substrate_t *substrate, u64 header_offset, u8 *header_key, char *name)
{
	char *params;
	struct dm_task *task;
	task = dm_task_create(DM_DEVICE_CREATE);
	if(!task) {
		die("dm_task_create");
	}
	if(!dm_task_set_name(task, name)) {
		die("dm_task_set_name");
	}
	if(!dm_task_set_uuid(task, name)) {
		die("dm_task_set_uuid");
	}
	params = steg_malloc(strlen(substrate->filename) + 4096);
	sprintf(params, "%s %zu ", substrate->filename, header_offset);
	sprint_hex(params + strlen(params), header_key, KEY_BYTES);
	if(!dm_task_add_target(task, 0, substrate->bytes, "steg", params)) {
		die("dm_task_add_target");
	}
	if(!dm_task_run(task)) {
		die("dm_task_run");
	}
	dm_task_destroy(task);
	steg_free(params);
	return 0;
}
Ejemplo n.º 3
0
int dm_addmap(int task, const char *name, const char *target,
	      const char *params, uint64_t size, int ro, const char *uuid,
	      int part, mode_t mode, uid_t uid, gid_t gid)
{
	int r = 0;
	struct dm_task *dmt;
	char *prefixed_uuid = NULL;
#ifdef LIBDM_API_COOKIE
	uint32_t cookie = 0;
	uint16_t udev_flags = 0;
#endif

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

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

	if (!dm_task_add_target (dmt, 0, size, target, params))
		goto addout;

	if (ro && !dm_task_set_ro (dmt))
			goto addout;

	if (task == DM_DEVICE_CREATE && uuid) {
		prefixed_uuid = make_prefixed_uuid(part, uuid);
		if (prefixed_uuid == NULL)
			goto addout;
		if (!dm_task_set_uuid(dmt, prefixed_uuid))
			goto addout;
	}

	if (!dm_task_set_mode(dmt, mode))
		goto addout;
	if (!dm_task_set_uid(dmt, uid))
		goto addout;
	if (!dm_task_set_gid(dmt, gid))
		goto addout;

	dm_task_no_open_count(dmt);

#ifdef LIBDM_API_COOKIE
	if (!udev_sync)
		udev_flags = DM_UDEV_DISABLE_LIBRARY_FALLBACK;
	if (task == DM_DEVICE_CREATE &&
	    !dm_task_set_cookie(dmt, &cookie, udev_flags))
		goto addout;
#endif
	r = dm_task_run (dmt);
#ifdef LIBDM_API_COOKIE
	if (task == DM_DEVICE_CREATE)
			dm_udev_wait(cookie);
#endif
addout:
	dm_task_destroy (dmt);
	free(prefixed_uuid);

	return r;
}
Ejemplo n.º 4
0
static int _dm_create(int task, int wait,
                      const char *name, const char *uuid,
                      uint64_t start, uint64_t length,
                      const char *target, const char *table,
                      struct era_dm_info *info)
{
	struct dm_task *dmt;
	uint32_t cookie = 0;
	int rc;

	if (!(dmt = dm_task_create(task)))
		return -1;

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

	if (uuid && !dm_task_set_uuid(dmt, uuid))
		goto out;

	if (target && !dm_task_add_target(dmt, start, length, target, table))
		goto out;

	if (wait && !dm_task_set_cookie(dmt, &cookie, 0))
		goto out;

	rc = dm_task_run(dmt);

	if (wait)
		(void) dm_udev_wait(cookie);

	if (rc && info)
	{
		struct dm_info dmi;

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

		info->target_count = dmi.target_count;
		info->open_count = dmi.open_count;
		info->suspended = dmi.suspended;
		info->exists = dmi.exists;
		info->major = dmi.major;
		info->minor = dmi.minor;
	}

	dm_task_destroy(dmt);

	return rc ? 0 : -1;
out:
	dm_task_destroy(dmt);
	return -1;
}
/* Get uuid of a device */
static struct dm_task *_get_device_info(const struct dm_event_handler *dmevh)
{
	struct dm_task *dmt;
	struct dm_info info;

	if (!(dmt = dm_task_create(DM_DEVICE_INFO))) {
		log_error("_get_device_info: dm_task creation for info failed");
		return NULL;
	}

	if (dmevh->uuid)
		dm_task_set_uuid(dmt, dmevh->uuid);
	else if (dmevh->dev_name)
		dm_task_set_name(dmt, dmevh->dev_name);
	else if (dmevh->major && dmevh->minor) {
		dm_task_set_major(dmt, dmevh->major);
		dm_task_set_minor(dmt, dmevh->minor);
        }

	/* FIXME Add name or uuid or devno to messages */
	if (!dm_task_run(dmt)) {
		log_error("_get_device_info: dm_task_run() failed");
		goto failed;
	}

	if (!dm_task_get_info(dmt, &info)) {
		log_error("_get_device_info: failed to get info for device");
		goto failed;
	}

	if (!info.exists) {
		log_error("_get_device_info: device not found");
		goto failed;
	}

	return dmt;

failed:
	dm_task_destroy(dmt);
	return NULL;
}
Ejemplo n.º 6
0
/*
 * Low level device-layer operations.
 */
static struct dm_task *_setup_task(const char *name, const char *uuid,
				   uint32_t *event_nr, int task,
				   uint32_t major, uint32_t minor)
{
	struct dm_task *dmt;

	if (!(dmt = dm_task_create(task)))
		return_NULL;

	if (name)
		dm_task_set_name(dmt, name);

	if (uuid && *uuid)
		dm_task_set_uuid(dmt, uuid);

	if (event_nr)
		dm_task_set_event_nr(dmt, *event_nr);

	if (major)
		dm_task_set_major_minor(dmt, major, minor, 1);

	return dmt;
}
Ejemplo n.º 7
0
/* Check, if a device exists. */
static int _fill_device_data(struct thread_status *ts)
{
	struct dm_task *dmt;
	struct dm_info dmi;

	if (!ts->device.uuid)
		return 0;

	ts->device.name = NULL;
	ts->device.major = ts->device.minor = 0;

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

	dm_task_set_uuid(dmt, ts->device.uuid);
	if (!dm_task_run(dmt))
		goto fail;

	ts->device.name = dm_strdup(dm_task_get_name(dmt));
	if (!ts->device.name)
		goto fail;

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

	ts->device.major = dmi.major;
	ts->device.minor = dmi.minor;

	dm_task_destroy(dmt);
	return 1;

      fail:
	dm_task_destroy(dmt);
	dm_free(ts->device.name);
	return 0;
}
static int _create_and_load_v4(struct dm_task *dmt)
{
	struct dm_task *task;
	int r;
	uint32_t cookie;

	/* Use new task struct to create the device */
	if (!(task = dm_task_create(DM_DEVICE_CREATE))) {
		log_error("Failed to create device-mapper task struct");
		_udev_complete(dmt);
		return 0;
	}

	/* Copy across relevant fields */
	if (dmt->dev_name && !dm_task_set_name(task, dmt->dev_name)) {
		dm_task_destroy(task);
		_udev_complete(dmt);
		return 0;
	}

	if (dmt->uuid && !dm_task_set_uuid(task, dmt->uuid)) {
		dm_task_destroy(task);
		_udev_complete(dmt);
		return 0;
	}

	task->major = dmt->major;
	task->minor = dmt->minor;
	task->uid = dmt->uid;
	task->gid = dmt->gid;
	task->mode = dmt->mode;
	/* FIXME: Just for udev_check in dm_task_run. Can we avoid this? */
	task->event_nr = dmt->event_nr & DM_UDEV_FLAGS_MASK;
	task->cookie_set = dmt->cookie_set;

	r = dm_task_run(task);
	dm_task_destroy(task);
	if (!r) {
		_udev_complete(dmt);
		return 0;
	}

	/* Next load the table */
	if (!(task = dm_task_create(DM_DEVICE_RELOAD))) {
		log_error("Failed to create device-mapper task struct");
		_udev_complete(dmt);
		r = 0;
		goto revert;
	}

	/* Copy across relevant fields */
	if (dmt->dev_name && !dm_task_set_name(task, dmt->dev_name)) {
		dm_task_destroy(task);
		_udev_complete(dmt);
		r = 0;
		goto revert;
	}

	task->read_only = dmt->read_only;
	task->head = dmt->head;
	task->tail = dmt->tail;

	r = dm_task_run(task);

	task->head = NULL;
	task->tail = NULL;
	dm_task_destroy(task);
	if (!r) {
		_udev_complete(dmt);
		goto revert;
	}

	/* Use the original structure last so the info will be correct */
	dmt->type = DM_DEVICE_RESUME;
	dm_free(dmt->uuid);
	dmt->uuid = NULL;

	r = dm_task_run(dmt);

	if (r)
		return r;

      revert:
 	dmt->type = DM_DEVICE_REMOVE;
	dm_free(dmt->uuid);
	dmt->uuid = NULL;

	/*
	 * Also udev-synchronize "remove" dm task that is a part of this revert!
	 * But only if the original dm task was supposed to be synchronized.
	 */
	if (dmt->cookie_set) {
		cookie = (dmt->event_nr & ~DM_UDEV_FLAGS_MASK) |
			 (DM_COOKIE_MAGIC << DM_UDEV_FLAGS_SHIFT);
		dm_task_set_cookie(dmt, &cookie,
				   (dmt->event_nr & DM_UDEV_FLAGS_MASK) >>
				    DM_UDEV_FLAGS_SHIFT);
	}
Ejemplo n.º 9
0
static int _first_status(int task,
                         const char *name,
                         const char *uuid,
                         uint64_t *start, uint64_t *length,
                         size_t target_size, char *target_ptr,
                         size_t params_size, char *params_ptr)
{
	uint64_t a, b;
	struct dm_task *dmt;
	struct dm_info dmi;
	char *tgt, *prm;
	int rc = -1;

	if (!(dmt = dm_task_create(task)))
		return -1;

	if (name && !dm_task_set_name(dmt, name))
		goto out;

	if (uuid && !dm_task_set_uuid(dmt, uuid))
		goto out;

	if (!dm_task_run(dmt))
		goto out;

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

	if (!dmi.exists)
	{
		error(0, "target %s does not exists",
		      name ? name : (uuid ? uuid : "<NULL>"));
		goto out;
	}

	(void)dm_get_next_target(dmt, NULL, &a, &b, &tgt, &prm);

	if (start)
		*start = a;

	if (length)
		*length = b;

	if (target_size > 0 && target_ptr)
	{
		if (strlen(tgt) >= target_size)
		{
			error(0, "too long target name");
			goto out;
		}

		strcpy(target_ptr, tgt);
	}

	if (params_size > 0 && params_ptr)
	{
		if (strlen(prm) >= params_size)
		{
			error(0, "too long target params");
			goto out;
		}

		strcpy(params_ptr, prm);
	}

	rc = 0;
out:
	dm_task_destroy(dmt);
	return rc;
}
Ejemplo n.º 10
0
int era_dm_info(const char *name,
                const char *uuid,
                struct era_dm_info *info,
                size_t name_size, char *name_ptr,
                size_t uuid_size, char *uuid_ptr)
{
	struct dm_task *dmt;
	struct dm_info dmi;
	int rc = -1;

	if (!(dmt = dm_task_create(DM_DEVICE_INFO)))
		return -1;

	if (name && !dm_task_set_name(dmt, name))
		goto out;

	if (uuid && !dm_task_set_uuid(dmt, uuid))
		goto out;

	if (!dm_task_run(dmt))
		goto out;

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

	if (info)
	{
		info->target_count = dmi.target_count;
		info->open_count = dmi.open_count;
		info->suspended = dmi.suspended;
		info->exists = dmi.exists;
		info->major = dmi.major;
		info->minor = dmi.minor;
	}

	if (dmi.exists && name_size > 0 && name_ptr)
	{
		const char *dm_name;
		size_t dm_name_len;

		dm_name = dm_task_get_name(dmt);
		if (!dm_name)
			goto out;

		dm_name_len = strlen(dm_name);
		if (dm_name_len >= name_size)
		{
			rc = dm_name_len + 1;
			goto out;
		}

		strcpy(name_ptr, dm_name);
	}

	if (dmi.exists && uuid_size > 0 && uuid_ptr)
	{
		const char *dm_uuid;
		size_t dm_uuid_len;

		dm_uuid = dm_task_get_uuid(dmt);
		if (!dm_uuid)
			goto out;

		dm_uuid_len = strlen(dm_uuid);
		if (dm_uuid_len >= uuid_size)
		{
			dm_task_destroy(dmt);
			return dm_uuid_len + 1;
		}

		strcpy(uuid_ptr, dm_uuid);
	}

	rc = 0;
out:
	dm_task_destroy(dmt);
	return rc;
}
Ejemplo n.º 11
0
static int
dm_addmap (int task, const char *target, struct multipath *mpp,
	   char * params, int ro) {
	int r = 0;
	struct dm_task *dmt;
	char *prefixed_uuid = NULL;
	uint32_t cookie = 0;

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

	if (!dm_task_set_name (dmt, mpp->alias))
		goto addout;

	if (!dm_task_add_target (dmt, 0, mpp->size, target, params))
		goto addout;

	if (ro)
		dm_task_set_ro(dmt);

	if (task == DM_DEVICE_CREATE) {
		if (strlen(mpp->wwid) > 0) {
			prefixed_uuid = MALLOC(UUID_PREFIX_LEN +
					       strlen(mpp->wwid) + 1);
			if (!prefixed_uuid) {
				condlog(0, "cannot create prefixed uuid : %s",
					strerror(errno));
				goto addout;
			}
			sprintf(prefixed_uuid, UUID_PREFIX "%s", mpp->wwid);
			if (!dm_task_set_uuid(dmt, prefixed_uuid))
				goto freeout;
		}
		dm_task_skip_lockfs(dmt);
#ifdef LIBDM_API_FLUSH
		dm_task_no_flush(dmt);
#endif
	}

	if (mpp->attribute_flags & (1 << ATTR_MODE) &&
	    !dm_task_set_mode(dmt, mpp->mode))
		goto freeout;
	if (mpp->attribute_flags & (1 << ATTR_UID) &&
	    !dm_task_set_uid(dmt, mpp->uid))
		goto freeout;
	if (mpp->attribute_flags & (1 << ATTR_GID) &&
	    !dm_task_set_gid(dmt, mpp->gid))
		goto freeout;
	condlog(4, "%s: %s [0 %llu %s %s]", mpp->alias,
		task == DM_DEVICE_RELOAD ? "reload" : "addmap", mpp->size,
		target, params);

	dm_task_no_open_count(dmt);

	if (task == DM_DEVICE_CREATE &&
	    !dm_task_set_cookie(dmt, &cookie,
				DM_UDEV_DISABLE_LIBRARY_FALLBACK))
		goto freeout;

	r = dm_task_run (dmt);

	if (task == DM_DEVICE_CREATE)
			dm_udev_wait(cookie);
freeout:
	if (prefixed_uuid)
		FREE(prefixed_uuid);

addout:
	dm_task_destroy (dmt);

	return r;
}
static int _reload_with_suppression_v4(struct dm_task *dmt)
{
	struct dm_task *task;
	struct target *t1, *t2;
	int r;

	/* New task to get existing table information */
	if (!(task = dm_task_create(DM_DEVICE_TABLE))) {
		log_error("Failed to create device-mapper task struct");
		return 0;
	}

	/* Copy across relevant fields */
	if (dmt->dev_name && !dm_task_set_name(task, dmt->dev_name)) {
		dm_task_destroy(task);
		return 0;
	}

	if (dmt->uuid && !dm_task_set_uuid(task, dmt->uuid)) {
		dm_task_destroy(task);
		return 0;
	}

	task->major = dmt->major;
	task->minor = dmt->minor;

	r = dm_task_run(task);

	if (!r) {
		dm_task_destroy(task);
		return r;
	}

	/* Store existing table size */
	t2 = task->head;
	while (t2 && t2->next)
		t2 = t2->next;
	dmt->existing_table_size = t2 ? t2->start + t2->length : 0;

	if ((task->dmi.v4->flags & DM_READONLY_FLAG) ? 1 : 0 != dmt->read_only)
		goto no_match;

	t1 = dmt->head;
	t2 = task->head;

	while (t1 && t2) {
		while (t2->params[strlen(t2->params) - 1] == ' ')
			t2->params[strlen(t2->params) - 1] = '\0';
		if ((t1->start != t2->start) ||
		    (t1->length != t2->length) ||
		    (strcmp(t1->type, t2->type)) ||
		    (strcmp(t1->params, t2->params)))
			goto no_match;
		t1 = t1->next;
		t2 = t2->next;
	}

	if (!t1 && !t2) {
		dmt->dmi.v4 = task->dmi.v4;
		task->dmi.v4 = NULL;
		dm_task_destroy(task);
		return 1;
	}

no_match:
	dm_task_destroy(task);

	/* Now do the original reload */
	dmt->suppress_identical_reload = 0;
	r = dm_task_run(dmt);

	return r;
}
/* Create new device and load table to it. */
static int _create_and_load_v4(struct dm_task *dmt)
{
	struct dm_task *task;
	int r;

	log_verbose("create and load called");

	/* Use new task struct to create the device */
	if (!(task = dm_task_create(DM_DEVICE_CREATE))) {
		log_error("Failed to create device-mapper task struct");
		return 0;
	}

	/* Copy across relevant fields */
	if (dmt->dev_name && !dm_task_set_name(task, dmt->dev_name)) {
		dm_task_destroy(task);
		return 0;
	}

	if (dmt->uuid && !dm_task_set_uuid(task, dmt->uuid)) {
		dm_task_destroy(task);
		return 0;
	}

	task->major = dmt->major;
	task->minor = dmt->minor;
	task->uid = dmt->uid;
	task->gid = dmt->gid;
	task->mode = dmt->mode;

	r = dm_task_run(task);
	dm_task_destroy(task);
	if (!r)
		return r;

	/* Next load the table */
	if (!(task = dm_task_create(DM_DEVICE_RELOAD))) {
		log_error("Failed to create device-mapper task struct");
		return 0;
	}

	/* Copy across relevant fields */
	if (dmt->dev_name && !dm_task_set_name(task, dmt->dev_name)) {
		dm_task_destroy(task);
		return 0;
	}

	task->read_only = dmt->read_only;
	task->head = dmt->head;
	task->tail = dmt->tail;

	r = dm_task_run(task);

	task->head = NULL;
	task->tail = NULL;
	dm_task_destroy(task);
	if (!r)
		goto revert;

	/* Use the original structure last so the info will be correct */
	dmt->type = DM_DEVICE_RESUME;
	dm_free(dmt->uuid);
	dmt->uuid = NULL;

	r = dm_task_run(dmt);

	if (r)
		return r;

      revert:
	dmt->type = DM_DEVICE_REMOVE;
	dm_free(dmt->uuid);
	dmt->uuid = NULL;

	if (!dm_task_run(dmt))
		log_error("Failed to revert device creation.");

	return r;
}
Ejemplo n.º 14
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;
}