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); }
/* * 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; }