int dm_event_unregister_handler(const struct dm_event_handler *dmevh)
{
	int ret = 1, err;
	const char *uuid;
	struct dm_task *dmt;
	struct dm_event_daemon_message msg = { 0, 0, NULL };

	if (!(dmt = _get_device_info(dmevh))) {
		stack;
		return 0;
	}

	uuid = dm_task_get_uuid(dmt);

	if ((err = _do_event(DM_EVENT_CMD_UNREGISTER_FOR_EVENT, dmevh->dmeventd_path, &msg,
			    dmevh->dso, uuid, dmevh->mask, dmevh->timeout)) < 0) {
		log_error("%s: event deregistration failed: %s",
			  dm_task_get_name(dmt),
			  msg.data ? msg.data : strerror(-err));
		ret = 0;
	}

	dm_free(msg.data);

	dm_task_destroy(dmt);

	return ret;
}
Beispiel #2
0
char *
dm_mapname(int major, int minor)
{
	char * response = NULL;
	const char *map;
	struct dm_task *dmt;
	int r;
	int loop = MAX_WAIT * LOOPS_PER_SEC;

	if (!(dmt = dm_task_create(DM_DEVICE_STATUS)))
		return NULL;

	if (!dm_task_set_major(dmt, major) ||
	    !dm_task_set_minor(dmt, minor))
		goto bad;

	dm_task_no_open_count(dmt);

	/*
	 * device map might not be ready when we get here from
	 * daemon uev_trigger -> uev_add_map
	 */
	while (--loop) {
		r = dm_task_run(dmt);

		if (r)
			break;

		usleep(1000 * 1000 / LOOPS_PER_SEC);
	}

	if (!r) {
		condlog(0, "%i:%i: timeout fetching map name", major, minor);
		goto bad;
	}

	map = dm_task_get_name(dmt);
	if (map && strlen(map))
		response = STRDUP((char *)dm_task_get_name(dmt));

	dm_task_destroy(dmt);
	return response;
bad:
	dm_task_destroy(dmt);
	condlog(0, "%i:%i: error fetching map name", major, minor);
	return NULL;
}
Beispiel #3
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;
}
/*
 * Returns 0 if handler found; error (-ENOMEM, -ENOENT) otherwise.
 */
int dm_event_get_registered_device(struct dm_event_handler *dmevh, int next)
{
	int ret = 0;
	const char *uuid = NULL;
	char *reply_dso = NULL, *reply_uuid = NULL;
	enum dm_event_mask reply_mask = 0;
	struct dm_task *dmt = NULL;
	struct dm_event_daemon_message msg = { 0, 0, NULL };
	struct dm_info info;

	if (!(dmt = _get_device_info(dmevh))) {
		stack;
		return 0;
	}

	uuid = dm_task_get_uuid(dmt);

	if (!(ret = _do_event(next ? DM_EVENT_CMD_GET_NEXT_REGISTERED_DEVICE :
			     DM_EVENT_CMD_GET_REGISTERED_DEVICE, dmevh->dmeventd_path,
			      &msg, dmevh->dso, uuid, dmevh->mask, 0))) {
		/* FIXME this will probably horribly break if we get
		   ill-formatted reply */
		ret = _parse_message(&msg, &reply_dso, &reply_uuid, &reply_mask);
	} else {
		ret = -ENOENT;
		goto fail;
	}

	dm_task_destroy(dmt);
	dmt = NULL;

	dm_free(msg.data);
	msg.data = NULL;

	_dm_event_handler_clear_dev_info(dmevh);
	dmevh->uuid = dm_strdup(reply_uuid);
	if (!dmevh->uuid) {
		ret = -ENOMEM;
		goto fail;
	}

	if (!(dmt = _get_device_info(dmevh))) {
		ret = -ENXIO; /* dmeventd probably gave us bogus uuid back */
		goto fail;
	}

	dm_event_handler_set_dso(dmevh, reply_dso);
	dm_event_handler_set_event_mask(dmevh, reply_mask);

	dm_free(reply_dso);
	reply_dso = NULL;

	dm_free(reply_uuid);
	reply_uuid = NULL;

	dmevh->dev_name = dm_strdup(dm_task_get_name(dmt));
	if (!dmevh->dev_name) {
		ret = -ENOMEM;
		goto fail;
	}

	if (!dm_task_get_info(dmt, &info)) {
		ret = -1;
		goto fail;
	}

	dmevh->major = info.major;
	dmevh->minor = info.minor;

	dm_task_destroy(dmt);

	return ret;

 fail:
	dm_free(msg.data);
	dm_free(reply_dso);
	dm_free(reply_uuid);
	_dm_event_handler_clear_dev_info(dmevh);
	if (dmt)
		dm_task_destroy(dmt);
	return ret;
}
Beispiel #5
0
int device_is_usable(struct device *dev)
{
	struct dm_task *dmt;
	struct dm_info info;
	const char *name, *uuid;
	uint64_t start, length;
	char *target_type = NULL;
	char *params, *vgname = NULL, *lvname, *layer;
	void *next = NULL;
	int r = 0;

	if (!(dmt = dm_task_create(DM_DEVICE_STATUS))) {
		log_error("Failed to allocate dm_task struct to check dev status");
		return 0;
	}

	if (!dm_task_set_major_minor(dmt, MAJOR(dev->dev), MINOR(dev->dev), 1))
		goto_out;

	if (!dm_task_run(dmt)) {
		log_error("Failed to get state of mapped device");
		goto out;
	}

	if (!dm_task_get_info(dmt, &info))
		goto_out;

	if (!info.exists || info.suspended)
		goto out;

	name = dm_task_get_name(dmt);
	uuid = dm_task_get_uuid(dmt);

	/* FIXME Also check for mirror block_on_error and mpath no paths */
	/* For now, we exclude all mirrors */

	do {
		next = dm_get_next_target(dmt, next, &start, &length,
					  &target_type, &params);
		/* Skip if target type doesn't match */
		if (target_type && !strcmp(target_type, "mirror")) {
			log_debug("%s: Mirror device not usable.", dev_name(dev));
			goto out;
		}
	} while (next);

	/* FIXME Also check dependencies? */

	/* Check internal lvm devices */
	if (uuid && !strncmp(uuid, UUID_PREFIX, sizeof(UUID_PREFIX) - 1)) {
		if (!(vgname = dm_strdup(name)) ||
		    !dm_split_lvm_name(NULL, NULL, &vgname, &lvname, &layer))
			goto_out;

		if (lvname && (is_reserved_lvname(lvname) || *layer)) {
			log_debug("%s: Reserved internal LV device %s/%s%s%s not usable.",
				  dev_name(dev), vgname, lvname, *layer ? "-" : "", layer);
			goto out;
		}
	}

	r = 1;

      out:
	dm_free(vgname);
	dm_task_destroy(dmt);
	return r;
}
Beispiel #6
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;
}
Beispiel #7
0
	p[0] = '\0';
	syslog(LOG_INFO, "%s array, %s, is %s in-sync.",
	       raid_type, device, strcmp(resync_ratio, p+1) ? "not" : "now");

	return 0;
}

void process_event(struct dm_task *dmt,
		   enum dm_event_mask event __attribute__((unused)),
		   void **unused __attribute__((unused)))
{
	void *next = NULL;
	uint64_t start, length;
	char *target_type = NULL;
	char *params;
	const char *device = dm_task_get_name(dmt);

	dmeventd_lvm2_lock();

	do {
		next = dm_get_next_target(dmt, next, &start, &length,
					  &target_type, &params);

		if (!target_type) {
			syslog(LOG_INFO, "%s mapping lost.", device);
			continue;
		}

		if (strcmp(target_type, "raid")) {
			syslog(LOG_INFO, "%s has non-raid portion.", device);
			continue;