Home | History | Annotate | Line # | Download | only in libdm
libdm_ioctl.c revision 1.3
      1 /*
      2  * Copyright (c) 2010 The NetBSD Foundation, Inc.
      3  * All rights reserved.
      4  *
      5  * This code is derived from software contributed to The NetBSD Foundation
      6  * by Adam Hamsik.
      7  *
      8  * Redistribution and use in source and binary forms, with or without
      9  * modification, are permitted provided that the following conditions
     10  * are met:
     11  * 1. Redistributions of source code must retain the above copyright
     12  *    notice, this list of conditions and the following disclaimer.
     13  * 2. Redistributions in binary form must reproduce the above copyright
     14  *    notice, this list of conditions and the following disclaimer in the
     15  *    documentation and/or other materials provided with the distribution.
     16  *
     17  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
     18  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
     19  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
     20  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
     21  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
     22  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
     23  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
     24  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
     25  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
     26  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
     27  * POSSIBILITY OF SUCH DAMAGE.
     28  */
     29 
     30 #include <sys/types.h>
     31 #include <sys/param.h>
     32 #include <sys/ioctl.h>
     33 
     34 #include <errno.h>
     35 #include <fcntl.h>
     36 #include <stdio.h>
     37 #include <stdlib.h>
     38 #include <string.h>
     39 #include <unistd.h>
     40 
     41 #include <prop/proplib.h>
     42 
     43 #include <dev/dm/netbsd-dm.h>
     44 
     45 #include "dm.h"
     46 
     47 /*
     48  * Libdm library works like interface between device-mapper driver and
     49  * NetBSD userspace. For start it uses same set of commands like linux
     50  * libdevmapper, but in later stage if we introduce NetBSD device-mapper
     51  * extensions we don't need to change libdevmapper.
     52  *
     53  * LIBDM basically creates one proplib dictionary with everything what is
     54  * needed to work with device-mapper devices.
     55  *
     56  * Basic element of libdm is libdm_task which contains version and command
     57  * string with another dictionary cmd.
     58  */
     59 
     60 struct libdm_cmd {
     61 	prop_array_t ldm_cmd;
     62 };
     63 
     64 struct libdm_iter {
     65 	prop_object_iterator_t ldm_obji;
     66 };
     67 
     68 struct libdm_task {
     69 	prop_dictionary_t ldm_task;
     70 };
     71 
     72 struct libdm_table {
     73 	prop_dictionary_t ldm_tbl;
     74 };
     75 
     76 struct libdm_target {
     77 	prop_dictionary_t ldm_trgt;
     78 };
     79 
     80 struct libdm_dev {
     81 	prop_dictionary_t ldm_dev;
     82 };
     83 
     84 struct cmd_version cmd_ver[] = {
     85 	{"version", {4, 0, 0}},
     86 	{"targets", {4, 0, 0}},
     87 	{"create", {4, 0, 0}},
     88 	{"info",   {4, 0, 0}},
     89 	{"mknodes",{4, 0, 0}},
     90 	{"names",  {4, 0, 0}},
     91 	{"suspend",{4, 0, 0}},
     92 	{"remove", {4, 0, 0}},
     93 	{"rename", {4, 0, 0}},
     94 	{"resume", {4, 0, 0}},
     95 	{"clear",  {4, 0, 0}},
     96 	{"deps",   {4, 0, 0}},
     97 	{"reload", {4, 0, 0}},
     98 	{"status", {4, 0, 0}},
     99 	{"table",  {4, 0, 0}},
    100 	/* NetBSD device-mapper command extension goes here */
    101 	{NULL, {0, 0, 0}}
    102 };
    103 
    104 /* /dev/mapper/control managing routines */
    105 static int libdm_control_open(const char *);
    106 static int libdm_control_close(int);
    107 
    108 static int
    109 libdm_control_open(const char *path)
    110 {
    111 	int fd;
    112 #ifdef RUMP_ACTION
    113 	if ((fd = rump_sys_open(path, O_RDWR)) < 0)
    114 		return -1;
    115 #else
    116 	if ((fd = open(path, O_RDWR)) < 0)
    117 		return -1;
    118 #endif
    119 	return fd;
    120 }
    121 
    122 static int
    123 libdm_control_close(int fd)
    124 {
    125 
    126 #ifdef RUMP_ACTION
    127 	return rump_sys_close(fd);
    128 #else
    129 	return close(fd);
    130 #endif
    131 }
    132 
    133 /* Destroy iterator for arrays such as version strings, cmd_data. */
    134 void
    135 libdm_iter_destroy(libdm_iter_t libdm_iter)
    136 {
    137 
    138 	prop_object_iterator_release(libdm_iter->ldm_obji);
    139 	free(libdm_iter);
    140 }
    141 
    142 /*
    143  * Issue ioctl call to kernel, releasing both dictionaries is
    144  * left on callers.
    145  */
    146 int
    147 libdm_task_run(libdm_task_t libdm_task)
    148 {
    149 	prop_dictionary_t dict;
    150 	int libdm_control_fd = -1;
    151 	int error;
    152 #ifdef RUMP_ACTION
    153 	struct plistref prefp;
    154 #endif
    155 	error = 0;
    156 
    157 	if (libdm_task == NULL)
    158 		return ENOENT;
    159 
    160 	if ((libdm_control_fd = libdm_control_open(DM_DEVICE_PATH)) < 0)
    161 		return errno;
    162 #ifdef RUMP_ACTION
    163 	prop_dictionary_externalize_to_pref(libdm_task->ldm_task,
    164 	    &prefp);
    165 
    166 	error = rump_sys_ioctl(libdm_control_fd, NETBSD_DM_IOCTL, &prefp);
    167 	if (error < 0) {
    168 		libdm_control_close(libdm_control_fd);
    169 
    170 		return error;
    171 	}
    172 	dict = prop_dictionary_internalize(prefp.pref_plist);
    173 #else
    174 	prop_dictionary_externalize_to_file(libdm_task->ldm_task, "/tmp/libdm_in");
    175 	error = prop_dictionary_sendrecv_ioctl(libdm_task->ldm_task,
    176 	    libdm_control_fd, NETBSD_DM_IOCTL, &dict);
    177 	if ( error != 0) {
    178 		libdm_control_close(libdm_control_fd);
    179 		return error;
    180 	}
    181 	prop_dictionary_externalize_to_file(dict, "/tmp/libdm_out");
    182 #endif
    183 
    184 	libdm_control_close(libdm_control_fd);
    185 	prop_object_retain(dict);
    186 	prop_object_release(libdm_task->ldm_task);
    187 	libdm_task->ldm_task = dict;
    188 
    189 	return EXIT_SUCCESS;
    190 }
    191 
    192 
    193 /* Create libdm General task structure */
    194 libdm_task_t
    195 libdm_task_create(const char *command)
    196 {
    197 	libdm_task_t task;
    198 	size_t i,len,slen;
    199 	prop_array_t ver;
    200 
    201 	task = NULL;
    202 
    203 	task = malloc(sizeof(*task));
    204 	if (task == NULL)
    205 		return NULL;
    206 
    207 	if ((task->ldm_task = prop_dictionary_create()) == NULL) {
    208 		free(task);
    209 		return NULL;
    210 	}
    211 
    212 	if ((prop_dictionary_set_cstring(task->ldm_task, DM_IOCTL_COMMAND,
    213 		    command)) == false) {
    214 		prop_object_release(task->ldm_task);
    215 		free(task);
    216 		return NULL;
    217 	}
    218 
    219 	len = strlen(command);
    220 
    221 	for (i = 0; cmd_ver[i].cmd != NULL; i++) {
    222 		slen = strlen(cmd_ver[i].cmd);
    223 
    224 		if (len != slen)
    225 			continue;
    226 
    227 		if ((strncmp(command, cmd_ver[i].cmd, slen)) == 0) {
    228 			ver = prop_array_create();
    229 			prop_array_add_uint32(ver, cmd_ver[i].version[0]);
    230 			prop_array_add_uint32(ver, cmd_ver[i].version[1]);
    231 			prop_array_add_uint32(ver, cmd_ver[i].version[2]);
    232 
    233 			prop_dictionary_set(task->ldm_task, DM_IOCTL_VERSION,
    234 			    ver);
    235 
    236 			prop_object_release(ver);
    237 			break;
    238 		}
    239 	}
    240 
    241 	return task;
    242 }
    243 
    244 void
    245 libdm_task_destroy(libdm_task_t libdm_task)
    246 {
    247 
    248 	if (libdm_task != NULL)
    249 		prop_object_release(libdm_task->ldm_task);
    250 	free(libdm_task);
    251 }
    252 
    253 /* Set device name */
    254 int
    255 libdm_task_set_name(const char *name, libdm_task_t libdm_task)
    256 {
    257 
    258 	if ((prop_dictionary_set_cstring(libdm_task->ldm_task,
    259 		    DM_IOCTL_NAME, name)) == false)
    260 		return ENOENT;
    261 
    262 	return 0;
    263 }
    264 
    265 /* Set device name */
    266 char *
    267 libdm_task_get_name(libdm_task_t libdm_task)
    268 {
    269 	char *name;
    270 
    271 	if (!prop_dictionary_get_cstring_nocopy(libdm_task->ldm_task,
    272 	    DM_IOCTL_NAME, (const char **)&name))
    273 		return NULL;
    274 
    275 	return name;
    276 }
    277 
    278 /* Set device uuid */
    279 int
    280 libdm_task_set_uuid(const char *uuid, libdm_task_t libdm_task)
    281 {
    282 
    283 	if ((prop_dictionary_set_cstring(libdm_task->ldm_task,
    284 	    DM_IOCTL_UUID, uuid)) == false)
    285 		return ENOENT;
    286 
    287 	return 0;
    288 }
    289 
    290 /* Set device name */
    291 char *
    292 libdm_task_get_uuid(libdm_task_t libdm_task)
    293 {
    294 	char *uuid;
    295 
    296 	if (!prop_dictionary_get_cstring_nocopy(libdm_task->ldm_task,
    297 	    DM_IOCTL_UUID, (const char **)&uuid))
    298 		return NULL;
    299 
    300 	return uuid;
    301 }
    302 
    303 /* Get command name */
    304 char *
    305 libdm_task_get_command(libdm_task_t libdm_task)
    306 {
    307 	char *command;
    308 
    309 	if (!prop_dictionary_get_cstring_nocopy(libdm_task->ldm_task,
    310 	    DM_IOCTL_COMMAND, (const char **)&command))
    311 		return NULL;
    312 
    313 	return command;
    314 }
    315 
    316 int32_t
    317 libdm_task_get_cmd_version(libdm_task_t libdm_task, uint32_t *ver, size_t size)
    318 {
    319 	prop_array_t prop_ver;
    320 	size_t i;
    321 
    322 	prop_ver = prop_dictionary_get(libdm_task->ldm_task,
    323 	    DM_IOCTL_VERSION);
    324 
    325 	i = prop_array_count(prop_ver);
    326 
    327 	if (i > size)
    328 		return -i;
    329 
    330 	for (i = 0; i < size; i++)
    331 		prop_array_get_uint32(prop_ver, i, &ver[i]);
    332 
    333 	return i;
    334 }
    335 
    336 /* Select device minor number. */
    337 int
    338 libdm_task_set_minor(uint32_t minor, libdm_task_t libdm_task)
    339 {
    340 
    341 	if ((prop_dictionary_set_uint32(libdm_task->ldm_task,
    342 	    DM_IOCTL_MINOR, minor)) == false)
    343 		return ENOENT;
    344 
    345 	return 0;
    346 }
    347 
    348 /* Select device minor number. */
    349 uint32_t
    350 libdm_task_get_minor(libdm_task_t libdm_task)
    351 {
    352 	uint32_t minor;
    353 
    354 	minor = 0;
    355 
    356 	(void)prop_dictionary_get_uint32(libdm_task->ldm_task,
    357 	    DM_IOCTL_MINOR, &minor);
    358 
    359 	return minor;
    360 }
    361 
    362 /* Set/Del DM_SUSPEND_FLAG for caller. */
    363 void
    364 libdm_task_set_suspend_flag(libdm_task_t libdm_task)
    365 {
    366 	uint32_t flags;
    367 
    368 	flags = 0;
    369 
    370 	(void)prop_dictionary_get_uint32(libdm_task->ldm_task,
    371 	    DM_IOCTL_FLAGS, &flags);
    372 
    373 	flags |= DM_SUSPEND_FLAG;
    374 
    375 	(void)prop_dictionary_set_uint32(libdm_task->ldm_task,
    376 	    DM_IOCTL_FLAGS, flags);
    377 }
    378 
    379 void
    380 libdm_task_del_suspend_flag(libdm_task_t libdm_task)
    381 {
    382 	uint32_t flags;
    383 
    384 	(void)prop_dictionary_get_uint32(libdm_task->ldm_task,
    385 	    DM_IOCTL_FLAGS, &flags);
    386 
    387 	flags &= ~DM_SUSPEND_FLAG;
    388 
    389 	(void)prop_dictionary_set_uint32(libdm_task->ldm_task,
    390 	    DM_IOCTL_FLAGS, flags);
    391 }
    392 
    393 /* Set/Del DM_STATUS_FLAG for caller. */
    394 void
    395 libdm_task_set_status_flag(libdm_task_t libdm_task)
    396 {
    397 	uint32_t flags;
    398 
    399 	flags = 0;
    400 
    401 	(void)prop_dictionary_get_uint32(libdm_task->ldm_task,
    402 	    DM_IOCTL_FLAGS, &flags);
    403 
    404 	flags |= DM_STATUS_TABLE_FLAG;
    405 
    406 	(void)prop_dictionary_set_uint32(libdm_task->ldm_task,
    407 	    DM_IOCTL_FLAGS, flags);
    408 }
    409 
    410 void
    411 libdm_task_del_status_flag(libdm_task_t libdm_task)
    412 {
    413 	uint32_t flags;
    414 
    415 	(void)prop_dictionary_get_uint32(libdm_task->ldm_task,
    416 	    DM_IOCTL_FLAGS, &flags);
    417 
    418 	flags &= ~DM_STATUS_TABLE_FLAG;
    419 
    420 	(void)prop_dictionary_set_uint32(libdm_task->ldm_task,
    421 	    DM_IOCTL_FLAGS, flags);
    422 }
    423 
    424 /* Set/Del DM_EXISTS_FLAG for caller. */
    425 void
    426 libdm_task_set_exists_flag(libdm_task_t libdm_task)
    427 {
    428 	uint32_t flags;
    429 
    430 	flags = 0;
    431 
    432 	(void)prop_dictionary_get_uint32(libdm_task->ldm_task,
    433 	    DM_IOCTL_FLAGS, &flags);
    434 
    435 	flags |= DM_EXISTS_FLAG;
    436 
    437 	(void)prop_dictionary_set_uint32(libdm_task->ldm_task,
    438 	    DM_IOCTL_FLAGS, flags);
    439 }
    440 
    441 void
    442 libdm_task_del_exists_flag(libdm_task_t libdm_task)
    443 {
    444 	uint32_t flags;
    445 
    446 	(void)prop_dictionary_get_uint32(libdm_task->ldm_task,
    447 	    DM_IOCTL_FLAGS, &flags);
    448 
    449 	flags &= ~DM_EXISTS_FLAG;
    450 
    451 	(void)prop_dictionary_set_uint32(libdm_task->ldm_task,
    452 	    DM_IOCTL_FLAGS, flags);
    453 }
    454 
    455 /* Set flags used by LVM this is shortcut and should not be used
    456    by anyone else. */
    457 void
    458 libdm_task_set_flags(libdm_task_t libdm_task, uint32_t flags)
    459 {
    460 
    461 	(void)prop_dictionary_set_uint32(libdm_task->ldm_task,
    462 	    DM_IOCTL_FLAGS, flags);
    463 }
    464 
    465 /* Get ioctl protocol status flags. */
    466 uint32_t
    467 libdm_task_get_flags(libdm_task_t libdm_task)
    468 {
    469 	uint32_t flags;
    470 
    471 	(void)prop_dictionary_get_uint32(libdm_task->ldm_task,
    472 	    DM_IOCTL_FLAGS, &flags);
    473 
    474 	return flags;
    475 }
    476 
    477 /* Set ioctl protocol status flags. */
    478 uint32_t
    479 libdm_task_get_target_num(libdm_task_t libdm_task)
    480 {
    481 	uint32_t count;
    482 
    483 	(void)prop_dictionary_get_uint32(libdm_task->ldm_task,
    484 	    DM_IOCTL_TARGET_COUNT, &count);
    485 
    486 	return count;
    487 }
    488 
    489 int32_t
    490 libdm_task_get_open_num(libdm_task_t libdm_task)
    491 {
    492 	int32_t count;
    493 
    494 	(void)prop_dictionary_get_int32(libdm_task->ldm_task,
    495 	    DM_IOCTL_OPEN, &count);
    496 
    497 	return count;
    498 }
    499 
    500 uint32_t
    501 libdm_task_get_event_num(libdm_task_t libdm_task)
    502 {
    503 	uint32_t event;
    504 
    505 	(void)prop_dictionary_get_uint32(libdm_task->ldm_task,
    506 	    DM_IOCTL_EVENT, &event);
    507 
    508 	return event;
    509 }
    510 
    511 /* Set cmd_data dictionary entry to task struct. */
    512 int
    513 libdm_task_set_cmd(libdm_cmd_t libdm_cmd, libdm_task_t libdm_task)
    514 {
    515 
    516 	if ((prop_dictionary_set(libdm_task->ldm_task,
    517 	    DM_IOCTL_CMD_DATA, libdm_cmd->ldm_cmd)) == false)
    518 		return ENOENT;
    519 
    520 	return 0;
    521 }
    522 
    523 /* Get cmd_data dictionary entry from task struct */
    524 libdm_cmd_t
    525 libdm_task_get_cmd(libdm_task_t libdm_task)
    526 {
    527 	libdm_cmd_t cmd;
    528 
    529 	cmd = malloc(sizeof(*cmd));
    530 
    531 	cmd->ldm_cmd = prop_dictionary_get(libdm_task->ldm_task,
    532 	    DM_IOCTL_CMD_DATA);
    533 
    534 	if (cmd->ldm_cmd == NULL) {
    535 		free(cmd);
    536 		return NULL;
    537 	}
    538 
    539 	/* Get a reference prop_dictionary_get will not get it */
    540 	prop_object_retain(cmd->ldm_cmd);
    541 
    542 	return cmd;
    543 }
    544 
    545 /* Command functions
    546  *
    547  * Functions for creation, destroing, set, get of command area of
    548  * ioctl dictionary.
    549  */
    550 libdm_cmd_t
    551 libdm_cmd_create(void)
    552 {
    553 	libdm_cmd_t cmd;
    554 
    555 	cmd = malloc(sizeof(*cmd));
    556 	if (cmd == NULL)
    557 		return NULL;
    558 
    559 	cmd->ldm_cmd =  prop_array_create();
    560 
    561 	return cmd;
    562 }
    563 
    564 void
    565 libdm_cmd_destroy(libdm_cmd_t libdm_cmd)
    566 {
    567 
    568 	prop_object_release(libdm_cmd->ldm_cmd);
    569 	free(libdm_cmd);
    570 }
    571 
    572 /* Create iterator object for caller this can be used to
    573    iterate through all members of cmd array. */
    574 libdm_iter_t
    575 libdm_cmd_iter_create(libdm_cmd_t libdm_cmd)
    576 {
    577 
    578 	libdm_iter_t iter;
    579 
    580 	iter = malloc(sizeof(*iter));
    581 	if (iter == NULL)
    582 		return NULL;
    583 
    584 	iter->ldm_obji = prop_array_iterator(libdm_cmd->ldm_cmd);
    585 
    586 	return iter;
    587 }
    588 
    589 int
    590 libdm_cmd_set_table(libdm_table_t libdm_table, libdm_cmd_t libdm_cmd)
    591 {
    592 
    593 	return prop_array_add(libdm_cmd->ldm_cmd,
    594 	    libdm_table->ldm_tbl);
    595 }
    596 
    597 
    598 libdm_target_t
    599 libdm_cmd_get_target(libdm_iter_t iter)
    600 {
    601 	libdm_target_t trgt;
    602 
    603 	trgt = malloc(sizeof(*trgt));
    604 	if (trgt == NULL)
    605 		return NULL;
    606 
    607 	trgt->ldm_trgt = prop_object_iterator_next(iter->ldm_obji);
    608 	if (trgt->ldm_trgt == NULL) {
    609 		free(trgt);
    610 		return NULL;
    611 	}
    612 
    613 	return trgt;
    614 }
    615 
    616 libdm_table_t
    617 libdm_cmd_get_table(libdm_iter_t iter)
    618 {
    619 	libdm_table_t tbl;
    620 
    621 	tbl = malloc(sizeof(*tbl));
    622 	if (tbl == NULL)
    623 		return NULL;
    624 
    625 	tbl->ldm_tbl = prop_object_iterator_next(iter->ldm_obji);
    626 	if (tbl->ldm_tbl == NULL) {
    627 		free(tbl);
    628 		return NULL;
    629 	}
    630 
    631 	return tbl;
    632 }
    633 
    634 libdm_dev_t
    635 libdm_cmd_get_dev(libdm_iter_t iter)
    636 {
    637 	libdm_dev_t dev;
    638 
    639 	dev = malloc(sizeof(*dev));
    640 	if (dev == NULL)
    641 		return NULL;
    642 
    643 	dev->ldm_dev = prop_object_iterator_next(iter->ldm_obji);
    644 	if (dev->ldm_dev == NULL) {
    645 		free(dev);
    646 		return NULL;
    647 	}
    648 
    649 	return dev;
    650 }
    651 
    652 /*
    653  * Deps manipulation routines
    654  */
    655 uint64_t
    656 libdm_cmd_get_deps(libdm_iter_t libdm_iter)
    657 {
    658 	prop_object_t obj;
    659 	uint64_t deps;
    660 
    661 	obj = prop_object_iterator_next(libdm_iter->ldm_obji);
    662 	deps = prop_number_unsigned_integer_value(obj);
    663 
    664 	if (obj != NULL)
    665 		prop_object_release(obj);
    666 
    667 	return deps;
    668 }
    669 
    670 /*
    671  * Table manipulation routines
    672  */
    673 libdm_table_t
    674 libdm_table_create(void)
    675 {
    676 	libdm_table_t table;
    677 
    678 	table = malloc(sizeof(*table));
    679 	if (table == NULL)
    680 		return NULL;
    681 
    682 	table->ldm_tbl = prop_dictionary_create();
    683 
    684 	return table;
    685 }
    686 
    687 void
    688 libdm_table_destroy(libdm_table_t libdm_table)
    689 {
    690 
    691 	prop_object_release(libdm_table->ldm_tbl);
    692 	free(libdm_table);
    693 }
    694 
    695 int
    696 libdm_table_set_start(uint64_t start, libdm_table_t libdm_table)
    697 {
    698 
    699 	if (libdm_table == NULL)
    700 		return ENOENT;
    701 
    702 	return prop_dictionary_set_uint64(libdm_table->ldm_tbl,
    703 	    DM_TABLE_START, start);
    704 }
    705 
    706 uint64_t
    707 libdm_table_get_start(libdm_table_t libdm_table)
    708 {
    709 	uint64_t start;
    710 
    711 	if (libdm_table == NULL)
    712 		return ENOENT;
    713 
    714 	(void)prop_dictionary_get_uint64(libdm_table->ldm_tbl, DM_TABLE_START,
    715 	    &start);
    716 
    717 	return start;
    718 }
    719 
    720 int
    721 libdm_table_set_length(uint64_t length, libdm_table_t libdm_table)
    722 {
    723 
    724 	if (libdm_table == NULL)
    725 		return ENOENT;
    726 
    727 	return prop_dictionary_set_uint64(libdm_table->ldm_tbl,
    728 	    DM_TABLE_LENGTH, length);
    729 }
    730 
    731 uint64_t
    732 libdm_table_get_length(libdm_table_t libdm_table)
    733 {
    734 	uint64_t length;
    735 
    736 	if (libdm_table == NULL)
    737 		return ENOENT;
    738 
    739 	prop_dictionary_get_uint64(libdm_table->ldm_tbl, DM_TABLE_LENGTH,
    740 	    &length);
    741 
    742 	return length;
    743 }
    744 
    745 int
    746 libdm_table_set_target(const char *name, libdm_table_t libdm_table)
    747 {
    748 
    749 	if (libdm_table == NULL)
    750 		return ENOENT;
    751 
    752 	return prop_dictionary_set_cstring(libdm_table->ldm_tbl, DM_TABLE_TYPE, name);
    753 }
    754 
    755 char *
    756 libdm_table_get_target(libdm_table_t libdm_table)
    757 {
    758 	char *target;
    759 
    760 	if (!prop_dictionary_get_cstring_nocopy(libdm_table->ldm_tbl, DM_TABLE_TYPE,
    761 	    (const char **)&target))
    762 		return NULL;
    763 
    764 	return target;
    765 }
    766 
    767 int
    768 libdm_table_set_params(const char *params, libdm_table_t  libdm_table)
    769 {
    770 
    771 	if (libdm_table == NULL)
    772 		return ENOENT;
    773 
    774 	return prop_dictionary_set_cstring(libdm_table->ldm_tbl,
    775 	    DM_TABLE_PARAMS, params);
    776 }
    777 
    778 /*
    779  * Get table params string from libdm_table_t
    780  * returned char * is dynamically allocated caller should free it.
    781  */
    782 char *
    783 libdm_table_get_params(libdm_table_t  libdm_table)
    784 {
    785 	char *params;
    786 
    787 	if (!prop_dictionary_get_cstring_nocopy(libdm_table->ldm_tbl, DM_TABLE_PARAMS,
    788 	    (const char **)&params))
    789 		return NULL;
    790 
    791 	return params;
    792 }
    793 
    794 int32_t
    795 libdm_table_get_status(libdm_table_t libdm_table)
    796 {
    797 	int32_t status;
    798 
    799 	(void)prop_dictionary_get_int32(libdm_table->ldm_tbl, DM_TABLE_STAT,
    800 	    &status);
    801 
    802 	return status;
    803 }
    804 
    805 /*
    806  * Target manipulation routines
    807  */
    808 void
    809 libdm_target_destroy(libdm_target_t libdm_target)
    810 {
    811 
    812 	prop_object_release(libdm_target->ldm_trgt);
    813 	free(libdm_target);
    814 }
    815 
    816 char *
    817 libdm_target_get_name(libdm_target_t libdm_target)
    818 {
    819 	char *name;
    820 
    821 	if (!prop_dictionary_get_cstring_nocopy(libdm_target->ldm_trgt,
    822 	    DM_TARGETS_NAME, (const char **)&name))
    823 		return NULL;
    824 
    825 	return name;
    826 }
    827 
    828 int32_t
    829 libdm_target_get_version(libdm_target_t libdm_target, uint32_t *ver, size_t size)
    830 {
    831 	prop_array_t prop_ver;
    832 	size_t i;
    833 
    834 	prop_ver = prop_dictionary_get(libdm_target->ldm_trgt,
    835 	    DM_TARGETS_VERSION);
    836 
    837 	i = prop_array_count(prop_ver);
    838 
    839 	if (i > size)
    840 		return -i;
    841 
    842 	for (i = 0; i < size; i++)
    843 		prop_array_get_uint32(prop_ver, i, &ver[i]);
    844 
    845 	return i;
    846 }
    847 
    848 
    849 /*
    850  * Dev manipulation routines
    851  */
    852 void
    853 libdm_dev_destroy(libdm_dev_t libdm_dev)
    854 {
    855 
    856 	prop_object_release(libdm_dev->ldm_dev);
    857 	free(libdm_dev);
    858 }
    859 
    860 char *
    861 libdm_dev_get_name(libdm_dev_t libdm_dev)
    862 {
    863 	char *name;
    864 
    865 	if (!prop_dictionary_get_cstring_nocopy(libdm_dev->ldm_dev,
    866 	    DM_DEV_NAME, (const char **)&name))
    867 		return NULL;
    868 
    869 	return name;
    870 }
    871 
    872 uint32_t
    873 libdm_dev_get_minor(libdm_dev_t libdm_dev)
    874 {
    875 	uint32_t dev;
    876 
    877 	(void)prop_dictionary_get_uint32(libdm_dev->ldm_dev, DM_DEV_DEV,
    878 	    &dev);
    879 
    880 	return dev;
    881 }
    882 
    883 int
    884 libdm_dev_set_newname(const char *newname, libdm_cmd_t libdm_cmd)
    885 {
    886 
    887 	if (newname == NULL)
    888 		return ENOENT;
    889 
    890 	return prop_array_set_cstring(libdm_cmd->ldm_cmd, 0, newname);
    891 }
    892