Example #1
0
void
_npf_config_error(nl_config_t *ncf, nl_error_t *ne)
{
	memset(ne, 0, sizeof(*ne));
	prop_dictionary_get_int32(ncf->ncf_err, "id", &ne->ne_id);
	prop_dictionary_get_cstring(ncf->ncf_err,
	    "source-file", &ne->ne_source_file);
	prop_dictionary_get_uint32(ncf->ncf_err,
	    "source-line", &ne->ne_source_line);
	prop_dictionary_get_int32(ncf->ncf_err,
	    "code-error", &ne->ne_ncode_error);
	prop_dictionary_get_int32(ncf->ncf_err,
	    "code-errat", &ne->ne_ncode_errat);
}
Example #2
0
/*
 * Load new table/tables to device.
 * Call apropriate target init routine open all physical pdev's and
 * link them to device. For other targets mirror, strip, snapshot
 * etc. also add dependency devices to upcalls list.
 *
 * Load table to inactive slot table are switched in dm_device_resume_ioctl.
 * This simulates Linux behaviour better there should not be any difference.
 *
 */
int
dm_table_load_ioctl(prop_dictionary_t dm_dict)
{
	dm_dev_t *dmv;
	dm_table_entry_t *table_en, *last_table;
	dm_table_t *tbl;
	dm_target_t *target;

	prop_object_iterator_t iter;
	prop_array_t cmd_array;
	prop_dictionary_t target_dict;

	const char *name, *uuid, *type;

	uint32_t flags, ret, minor;

	char *str;

	ret = 0;
	flags = 0;
	name = NULL;
	uuid = NULL;
	dmv = NULL;
	last_table = NULL;
	str = NULL;

	/*
	 * char *xml; xml = prop_dictionary_externalize(dm_dict);
	 * printf("%s\n",xml);
	 */

	prop_dictionary_get_cstring_nocopy(dm_dict, DM_IOCTL_NAME, &name);
	prop_dictionary_get_cstring_nocopy(dm_dict, DM_IOCTL_UUID, &uuid);
	prop_dictionary_get_uint32(dm_dict, DM_IOCTL_FLAGS, &flags);
	prop_dictionary_get_uint32(dm_dict, DM_IOCTL_MINOR, &minor);

	cmd_array = prop_dictionary_get(dm_dict, DM_IOCTL_CMD_DATA);
	iter = prop_array_iterator(cmd_array);
	dm_dbg_print_flags(flags);

	if ((dmv = dm_dev_lookup(name, uuid, minor)) == NULL) {
		DM_REMOVE_FLAG(flags, DM_EXISTS_FLAG);
		return ENOENT;
	}
	aprint_debug("Loading table to device: %s--%d\n", name,
	    dmv->table_head.cur_active_table);

	/*
	 * I have to check if this table slot is not used by another table list.
	 * if it is used I should free them.
	 */
	if (dmv->flags & DM_INACTIVE_PRESENT_FLAG)
		dm_table_destroy(&dmv->table_head, DM_TABLE_INACTIVE);

	dm_dbg_print_flags(dmv->flags);
	tbl = dm_table_get_entry(&dmv->table_head, DM_TABLE_INACTIVE);

	aprint_debug("dmv->name = %s\n", dmv->name);

	prop_dictionary_set_uint32(dm_dict, DM_IOCTL_MINOR, dmv->minor);

	while ((target_dict = prop_object_iterator_next(iter)) != NULL) {
		prop_dictionary_get_cstring_nocopy(target_dict,
		    DM_TABLE_TYPE, &type);
		/*
		 * If we want to deny table with 2 or more different
		 * target we should do it here
		 */
		if (((target = dm_target_lookup(type)) == NULL) &&
		    ((target = dm_target_autoload(type)) == NULL)) {
			dm_table_release(&dmv->table_head, DM_TABLE_INACTIVE);
			dm_dev_unbusy(dmv);
			return ENOENT;
		}
		if ((table_en = kmalloc(sizeof(dm_table_entry_t),
			    M_DM, M_WAITOK)) == NULL) {
			dm_table_release(&dmv->table_head, DM_TABLE_INACTIVE);
			dm_dev_unbusy(dmv);
			dm_target_unbusy(target);
			return ENOMEM;
		}
		prop_dictionary_get_uint64(target_dict, DM_TABLE_START,
		    &table_en->start);
		prop_dictionary_get_uint64(target_dict, DM_TABLE_LENGTH,
		    &table_en->length);

		aprint_debug("dm_ioctl.c... table_en->start = %ju, "
			     "table_en->length = %ju\n",
			     (uintmax_t)table_en->start,
			     (uintmax_t)table_en->length);

		table_en->target = target;
		table_en->dm_dev = dmv;
		table_en->target_config = NULL;

		/*
		 * There is a parameter string after dm_target_spec
		 * structure which  points to /dev/wd0a 284 part of
		 * table. String str points to this text. This can be
		 * null and therefore it should be checked before we try to
		 * use it.
		 */
		prop_dictionary_get_cstring(target_dict,
		    DM_TABLE_PARAMS, &str);

		if (SLIST_EMPTY(tbl))
			/* insert this table to head */
			SLIST_INSERT_HEAD(tbl, table_en, next);
		else
			SLIST_INSERT_AFTER(last_table, table_en, next);

		/*
		 * Params string is different for every target,
		 * therfore I have to pass it to target init
		 * routine and parse parameters there.
		 */
		aprint_debug("DM: str passed in is: %s", str);
		if ((ret = target->init(dmv, &table_en->target_config,
			    str)) != 0) {

			dm_table_release(&dmv->table_head, DM_TABLE_INACTIVE);
			dm_table_destroy(&dmv->table_head, DM_TABLE_INACTIVE);
			kfree(str, M_TEMP);

			dm_dev_unbusy(dmv);
			dm_target_unbusy(target);
			return ret;
		}
		last_table = table_en;
		kfree(str, M_TEMP);
	}
	prop_object_iterator_release(iter);

	DM_ADD_FLAG(flags, DM_INACTIVE_PRESENT_FLAG);
	atomic_set_int(&dmv->flags, DM_INACTIVE_PRESENT_FLAG);

	dm_table_release(&dmv->table_head, DM_TABLE_INACTIVE);

	dm_dev_unbusy(dmv);
#if 0
	dmsetdiskinfo(dmv->diskp, &dmv->table_head);
#endif
	return 0;
}
/* Parse given dm task structure to proplib dictionary.  */
static int _flatten(struct dm_task *dmt, prop_dictionary_t dm_dict)
{
	prop_array_t cmd_array;
	prop_dictionary_t target_spec;

	struct target *t;

	size_t len;
	char type[DM_MAX_TYPE_NAME];

	uint32_t major, flags;
	int count = 0;
	char *str = NULL;
	const int (*version)[3];

	flags = 0;
	version = &_cmd_data_v4[dmt->type].version;

	cmd_array = prop_array_create();

	for (t = dmt->head; t; t = t->next) {
		target_spec = prop_dictionary_create();

		prop_dictionary_set_uint64(target_spec,DM_TABLE_START,t->start);
		prop_dictionary_set_uint64(target_spec,DM_TABLE_LENGTH,t->length);

		strlcpy(type,t->type,DM_MAX_TYPE_NAME);

		prop_dictionary_set_cstring(target_spec,DM_TABLE_TYPE,type);
		prop_dictionary_set_cstring(target_spec,DM_TABLE_PARAMS,t->params);

		prop_dictionary_get_cstring(target_spec,
		    DM_TABLE_PARAMS, (char **) &str);

		prop_array_set(cmd_array,count,target_spec);

		prop_object_release(target_spec);

		count++;
	}


	if (count && (dmt->sector || dmt->message)) {
		log_error("targets and message are incompatible");
		return -1;
	}

	if (count && dmt->newname) {
		log_error("targets and newname are incompatible");
		return -1;
	}

	if (count && dmt->geometry) {
		log_error("targets and geometry are incompatible");
		return -1;
	}

	if (dmt->newname && (dmt->sector || dmt->message)) {
		log_error("message and newname are incompatible");
		return -1;
	}

	if (dmt->newname && dmt->geometry) {
		log_error("geometry and newname are incompatible");
		return -1;
	}

	if (dmt->geometry && (dmt->sector || dmt->message)) {
		log_error("geometry and message are incompatible");
		return -1;
	}

	if (dmt->sector && !dmt->message) {
		log_error("message is required with sector");
		return -1;
	}

	if (dmt->newname)
		len += strlen(dmt->newname) + 1;

	if (dmt->message)
		len += sizeof(struct dm_target_msg) + strlen(dmt->message) + 1;

	if (dmt->geometry)
		len += strlen(dmt->geometry) + 1;

	nbsd_dmi_add_version((*version), dm_dict);

	nbsd_get_dm_major(&major, DM_BLOCK_MAJOR);
	/* 
	 * Only devices with major which is equal to netbsd dm major 
	 * dm devices in NetBSD can't have more majors then one assigned to dm.
	 */
	if (dmt->major != major && dmt->major != -1)
		return -1;

	if (dmt->minor >= 0) {
		flags |= DM_PERSISTENT_DEV_FLAG;

		prop_dictionary_set_uint32(dm_dict, DM_IOCTL_MINOR, dmt->minor);
	}

	/* Set values to dictionary. */
	if (dmt->dev_name)
		prop_dictionary_set_cstring(dm_dict, DM_IOCTL_NAME, dmt->dev_name);

	if (dmt->uuid)
		prop_dictionary_set_cstring(dm_dict, DM_IOCTL_UUID, dmt->uuid);

	if (dmt->type == DM_DEVICE_SUSPEND)
		flags |= DM_SUSPEND_FLAG;
	if (dmt->no_flush)
		flags |= DM_NOFLUSH_FLAG;
	if (dmt->read_only)
		flags |= DM_READONLY_FLAG;
	if (dmt->skip_lockfs)
		flags |= DM_SKIP_LOCKFS_FLAG;

	if (dmt->query_inactive_table) {
		if (_dm_version_minor < 16)
			log_warn("WARNING: Inactive table query unsupported "
				 "by kernel.  It will use live table.");
		flags |= DM_QUERY_INACTIVE_TABLE_FLAG;
	}

	prop_dictionary_set_uint32(dm_dict, DM_IOCTL_FLAGS, flags);

	prop_dictionary_set_uint32(dm_dict, DM_IOCTL_EVENT, dmt->event_nr);

	if (dmt->newname)
		prop_array_set_cstring(cmd_array, 0, dmt->newname);

	/* Add array for all COMMAND specific data. */
	prop_dictionary_set(dm_dict, DM_IOCTL_CMD_DATA, cmd_array);
	prop_object_release(cmd_array);

	return 0;
}