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
libdm_control_open(const char * path)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
libdm_control_close(int fd)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
libdm_iter_destroy(libdm_iter_t libdm_iter)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
libdm_task_run(libdm_task_t libdm_task)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 error = prop_dictionary_sendrecv_ioctl(libdm_task->ldm_task,
175 libdm_control_fd, NETBSD_DM_IOCTL, &dict);
176 if ( error != 0) {
177 libdm_control_close(libdm_control_fd);
178 return error;
179 }
180 #endif
181
182 libdm_control_close(libdm_control_fd);
183 prop_object_retain(dict);
184 prop_object_release(libdm_task->ldm_task);
185 libdm_task->ldm_task = dict;
186
187 return EXIT_SUCCESS;
188 }
189
190
191 /* Create libdm General task structure */
192 libdm_task_t
libdm_task_create(const char * command)193 libdm_task_create(const char *command)
194 {
195 libdm_task_t task;
196 size_t i,len,slen;
197 prop_array_t ver;
198
199 task = NULL;
200
201 task = malloc(sizeof(*task));
202 if (task == NULL)
203 return NULL;
204
205 if ((task->ldm_task = prop_dictionary_create()) == NULL) {
206 free(task);
207 return NULL;
208 }
209
210 if ((prop_dictionary_set_string(task->ldm_task, DM_IOCTL_COMMAND,
211 command)) == false) {
212 prop_object_release(task->ldm_task);
213 free(task);
214 return NULL;
215 }
216
217 len = strlen(command);
218
219 for (i = 0; cmd_ver[i].cmd != NULL; i++) {
220 slen = strlen(cmd_ver[i].cmd);
221
222 if (len != slen)
223 continue;
224
225 if ((strncmp(command, cmd_ver[i].cmd, slen)) == 0) {
226 ver = prop_array_create();
227 prop_array_add_uint32(ver, cmd_ver[i].version[0]);
228 prop_array_add_uint32(ver, cmd_ver[i].version[1]);
229 prop_array_add_uint32(ver, cmd_ver[i].version[2]);
230
231 prop_dictionary_set(task->ldm_task, DM_IOCTL_VERSION,
232 ver);
233
234 prop_object_release(ver);
235 break;
236 }
237 }
238
239 return task;
240 }
241
242 void
libdm_task_destroy(libdm_task_t libdm_task)243 libdm_task_destroy(libdm_task_t libdm_task)
244 {
245
246 if (libdm_task != NULL)
247 prop_object_release(libdm_task->ldm_task);
248 free(libdm_task);
249 }
250
251 /* Set device name */
252 int
libdm_task_set_name(const char * name,libdm_task_t libdm_task)253 libdm_task_set_name(const char *name, libdm_task_t libdm_task)
254 {
255
256 if ((prop_dictionary_set_string(libdm_task->ldm_task,
257 DM_IOCTL_NAME, name)) == false)
258 return ENOENT;
259
260 return 0;
261 }
262
263 /* Set device name */
264 char *
libdm_task_get_name(libdm_task_t libdm_task)265 libdm_task_get_name(libdm_task_t libdm_task)
266 {
267 char *name;
268
269 if (!prop_dictionary_get_string(libdm_task->ldm_task,
270 DM_IOCTL_NAME, (const char **)&name))
271 return NULL;
272
273 return name;
274 }
275
276 /* Set device uuid */
277 int
libdm_task_set_uuid(const char * uuid,libdm_task_t libdm_task)278 libdm_task_set_uuid(const char *uuid, libdm_task_t libdm_task)
279 {
280
281 if ((prop_dictionary_set_string(libdm_task->ldm_task,
282 DM_IOCTL_UUID, uuid)) == false)
283 return ENOENT;
284
285 return 0;
286 }
287
288 /* Set device name */
289 char *
libdm_task_get_uuid(libdm_task_t libdm_task)290 libdm_task_get_uuid(libdm_task_t libdm_task)
291 {
292 char *uuid;
293
294 if (!prop_dictionary_get_string(libdm_task->ldm_task,
295 DM_IOCTL_UUID, (const char **)&uuid))
296 return NULL;
297
298 return uuid;
299 }
300
301 /* Get command name */
302 char *
libdm_task_get_command(libdm_task_t libdm_task)303 libdm_task_get_command(libdm_task_t libdm_task)
304 {
305 char *command;
306
307 if (!prop_dictionary_get_string(libdm_task->ldm_task,
308 DM_IOCTL_COMMAND, (const char **)&command))
309 return NULL;
310
311 return command;
312 }
313
314 int32_t
libdm_task_get_cmd_version(libdm_task_t libdm_task,uint32_t * ver,size_t size)315 libdm_task_get_cmd_version(libdm_task_t libdm_task, uint32_t *ver, size_t size)
316 {
317 prop_array_t prop_ver;
318 size_t i;
319
320 prop_ver = prop_dictionary_get(libdm_task->ldm_task,
321 DM_IOCTL_VERSION);
322
323 i = prop_array_count(prop_ver);
324
325 if (i > size)
326 return -i;
327
328 for (i = 0; i < size; i++)
329 prop_array_get_uint32(prop_ver, i, &ver[i]);
330
331 return i;
332 }
333
334 /* Select device minor number. */
335 int
libdm_task_set_minor(uint32_t minor,libdm_task_t libdm_task)336 libdm_task_set_minor(uint32_t minor, libdm_task_t libdm_task)
337 {
338
339 if ((prop_dictionary_set_uint32(libdm_task->ldm_task,
340 DM_IOCTL_MINOR, minor)) == false)
341 return ENOENT;
342
343 return 0;
344 }
345
346 /* Select device minor number. */
347 uint32_t
libdm_task_get_minor(libdm_task_t libdm_task)348 libdm_task_get_minor(libdm_task_t libdm_task)
349 {
350 uint32_t minor;
351
352 minor = 0;
353
354 (void)prop_dictionary_get_uint32(libdm_task->ldm_task,
355 DM_IOCTL_MINOR, &minor);
356
357 return minor;
358 }
359
360 /* Set/Del DM_SUSPEND_FLAG for caller. */
361 void
libdm_task_set_suspend_flag(libdm_task_t libdm_task)362 libdm_task_set_suspend_flag(libdm_task_t libdm_task)
363 {
364 uint32_t flags;
365
366 flags = 0;
367
368 (void)prop_dictionary_get_uint32(libdm_task->ldm_task,
369 DM_IOCTL_FLAGS, &flags);
370
371 flags |= DM_SUSPEND_FLAG;
372
373 (void)prop_dictionary_set_uint32(libdm_task->ldm_task,
374 DM_IOCTL_FLAGS, flags);
375 }
376
377 void
libdm_task_del_suspend_flag(libdm_task_t libdm_task)378 libdm_task_del_suspend_flag(libdm_task_t libdm_task)
379 {
380 uint32_t flags;
381
382 (void)prop_dictionary_get_uint32(libdm_task->ldm_task,
383 DM_IOCTL_FLAGS, &flags);
384
385 flags &= ~DM_SUSPEND_FLAG;
386
387 (void)prop_dictionary_set_uint32(libdm_task->ldm_task,
388 DM_IOCTL_FLAGS, flags);
389 }
390
391 /* Set/Del DM_STATUS_FLAG for caller. */
392 void
libdm_task_set_status_flag(libdm_task_t libdm_task)393 libdm_task_set_status_flag(libdm_task_t libdm_task)
394 {
395 uint32_t flags;
396
397 flags = 0;
398
399 (void)prop_dictionary_get_uint32(libdm_task->ldm_task,
400 DM_IOCTL_FLAGS, &flags);
401
402 flags |= DM_STATUS_TABLE_FLAG;
403
404 (void)prop_dictionary_set_uint32(libdm_task->ldm_task,
405 DM_IOCTL_FLAGS, flags);
406 }
407
408 void
libdm_task_del_status_flag(libdm_task_t libdm_task)409 libdm_task_del_status_flag(libdm_task_t libdm_task)
410 {
411 uint32_t flags;
412
413 (void)prop_dictionary_get_uint32(libdm_task->ldm_task,
414 DM_IOCTL_FLAGS, &flags);
415
416 flags &= ~DM_STATUS_TABLE_FLAG;
417
418 (void)prop_dictionary_set_uint32(libdm_task->ldm_task,
419 DM_IOCTL_FLAGS, flags);
420 }
421
422 /* Set/Del DM_EXISTS_FLAG for caller. */
423 void
libdm_task_set_exists_flag(libdm_task_t libdm_task)424 libdm_task_set_exists_flag(libdm_task_t libdm_task)
425 {
426 uint32_t flags;
427
428 flags = 0;
429
430 (void)prop_dictionary_get_uint32(libdm_task->ldm_task,
431 DM_IOCTL_FLAGS, &flags);
432
433 flags |= DM_EXISTS_FLAG;
434
435 (void)prop_dictionary_set_uint32(libdm_task->ldm_task,
436 DM_IOCTL_FLAGS, flags);
437 }
438
439 void
libdm_task_del_exists_flag(libdm_task_t libdm_task)440 libdm_task_del_exists_flag(libdm_task_t libdm_task)
441 {
442 uint32_t flags;
443
444 (void)prop_dictionary_get_uint32(libdm_task->ldm_task,
445 DM_IOCTL_FLAGS, &flags);
446
447 flags &= ~DM_EXISTS_FLAG;
448
449 (void)prop_dictionary_set_uint32(libdm_task->ldm_task,
450 DM_IOCTL_FLAGS, flags);
451 }
452
453 /* Set flags used by LVM this is shortcut and should not be used
454 by anyone else. */
455 void
libdm_task_set_flags(libdm_task_t libdm_task,uint32_t flags)456 libdm_task_set_flags(libdm_task_t libdm_task, uint32_t flags)
457 {
458
459 (void)prop_dictionary_set_uint32(libdm_task->ldm_task,
460 DM_IOCTL_FLAGS, flags);
461 }
462
463 /* Get ioctl protocol status flags. */
464 uint32_t
libdm_task_get_flags(libdm_task_t libdm_task)465 libdm_task_get_flags(libdm_task_t libdm_task)
466 {
467 uint32_t flags;
468
469 (void)prop_dictionary_get_uint32(libdm_task->ldm_task,
470 DM_IOCTL_FLAGS, &flags);
471
472 return flags;
473 }
474
475 /* Set ioctl protocol status flags. */
476 uint32_t
libdm_task_get_target_num(libdm_task_t libdm_task)477 libdm_task_get_target_num(libdm_task_t libdm_task)
478 {
479 uint32_t count;
480
481 (void)prop_dictionary_get_uint32(libdm_task->ldm_task,
482 DM_IOCTL_TARGET_COUNT, &count);
483
484 return count;
485 }
486
487 int32_t
libdm_task_get_open_num(libdm_task_t libdm_task)488 libdm_task_get_open_num(libdm_task_t libdm_task)
489 {
490 int32_t count;
491
492 (void)prop_dictionary_get_int32(libdm_task->ldm_task,
493 DM_IOCTL_OPEN, &count);
494
495 return count;
496 }
497
498 uint32_t
libdm_task_get_event_num(libdm_task_t libdm_task)499 libdm_task_get_event_num(libdm_task_t libdm_task)
500 {
501 uint32_t event;
502
503 (void)prop_dictionary_get_uint32(libdm_task->ldm_task,
504 DM_IOCTL_EVENT, &event);
505
506 return event;
507 }
508
509 /* Set cmd_data dictionary entry to task struct. */
510 int
libdm_task_set_cmd(libdm_cmd_t libdm_cmd,libdm_task_t libdm_task)511 libdm_task_set_cmd(libdm_cmd_t libdm_cmd, libdm_task_t libdm_task)
512 {
513
514 if ((prop_dictionary_set(libdm_task->ldm_task,
515 DM_IOCTL_CMD_DATA, libdm_cmd->ldm_cmd)) == false)
516 return ENOENT;
517
518 return 0;
519 }
520
521 /* Get cmd_data dictionary entry from task struct */
522 libdm_cmd_t
libdm_task_get_cmd(libdm_task_t libdm_task)523 libdm_task_get_cmd(libdm_task_t libdm_task)
524 {
525 libdm_cmd_t cmd;
526
527 cmd = malloc(sizeof(*cmd));
528
529 cmd->ldm_cmd = prop_dictionary_get(libdm_task->ldm_task,
530 DM_IOCTL_CMD_DATA);
531
532 if (cmd->ldm_cmd == NULL) {
533 free(cmd);
534 return NULL;
535 }
536
537 /* Get a reference prop_dictionary_get will not get it */
538 prop_object_retain(cmd->ldm_cmd);
539
540 return cmd;
541 }
542
543 /* Command functions
544 *
545 * Functions for creation, destroing, set, get of command area of
546 * ioctl dictionary.
547 */
548 libdm_cmd_t
libdm_cmd_create(void)549 libdm_cmd_create(void)
550 {
551 libdm_cmd_t cmd;
552
553 cmd = malloc(sizeof(*cmd));
554 if (cmd == NULL)
555 return NULL;
556
557 cmd->ldm_cmd = prop_array_create();
558
559 return cmd;
560 }
561
562 void
libdm_cmd_destroy(libdm_cmd_t libdm_cmd)563 libdm_cmd_destroy(libdm_cmd_t libdm_cmd)
564 {
565
566 prop_object_release(libdm_cmd->ldm_cmd);
567 free(libdm_cmd);
568 }
569
570 /* Create iterator object for caller this can be used to
571 iterate through all members of cmd array. */
572 libdm_iter_t
libdm_cmd_iter_create(libdm_cmd_t libdm_cmd)573 libdm_cmd_iter_create(libdm_cmd_t libdm_cmd)
574 {
575
576 libdm_iter_t iter;
577
578 iter = malloc(sizeof(*iter));
579 if (iter == NULL)
580 return NULL;
581
582 iter->ldm_obji = prop_array_iterator(libdm_cmd->ldm_cmd);
583
584 return iter;
585 }
586
587 int
libdm_cmd_set_table(libdm_table_t libdm_table,libdm_cmd_t libdm_cmd)588 libdm_cmd_set_table(libdm_table_t libdm_table, libdm_cmd_t libdm_cmd)
589 {
590
591 return prop_array_add(libdm_cmd->ldm_cmd,
592 libdm_table->ldm_tbl);
593 }
594
595
596 libdm_target_t
libdm_cmd_get_target(libdm_iter_t iter)597 libdm_cmd_get_target(libdm_iter_t iter)
598 {
599 libdm_target_t trgt;
600
601 trgt = malloc(sizeof(*trgt));
602 if (trgt == NULL)
603 return NULL;
604
605 trgt->ldm_trgt = prop_object_iterator_next(iter->ldm_obji);
606 if (trgt->ldm_trgt == NULL) {
607 free(trgt);
608 return NULL;
609 }
610
611 return trgt;
612 }
613
614 libdm_table_t
libdm_cmd_get_table(libdm_iter_t iter)615 libdm_cmd_get_table(libdm_iter_t iter)
616 {
617 libdm_table_t tbl;
618
619 tbl = malloc(sizeof(*tbl));
620 if (tbl == NULL)
621 return NULL;
622
623 tbl->ldm_tbl = prop_object_iterator_next(iter->ldm_obji);
624 if (tbl->ldm_tbl == NULL) {
625 free(tbl);
626 return NULL;
627 }
628
629 return tbl;
630 }
631
632 libdm_dev_t
libdm_cmd_get_dev(libdm_iter_t iter)633 libdm_cmd_get_dev(libdm_iter_t iter)
634 {
635 libdm_dev_t dev;
636
637 dev = malloc(sizeof(*dev));
638 if (dev == NULL)
639 return NULL;
640
641 dev->ldm_dev = prop_object_iterator_next(iter->ldm_obji);
642 if (dev->ldm_dev == NULL) {
643 free(dev);
644 return NULL;
645 }
646
647 return dev;
648 }
649
650 /*
651 * Deps manipulation routines
652 */
653 uint64_t
libdm_cmd_get_deps(libdm_iter_t libdm_iter)654 libdm_cmd_get_deps(libdm_iter_t libdm_iter)
655 {
656 prop_object_t obj;
657 uint64_t deps;
658
659 obj = prop_object_iterator_next(libdm_iter->ldm_obji);
660 deps = prop_number_unsigned_value(obj);
661
662 if (obj != NULL)
663 prop_object_release(obj);
664
665 return deps;
666 }
667
668 /*
669 * Table manipulation routines
670 */
671 libdm_table_t
libdm_table_create(void)672 libdm_table_create(void)
673 {
674 libdm_table_t table;
675
676 table = malloc(sizeof(*table));
677 if (table == NULL)
678 return NULL;
679
680 table->ldm_tbl = prop_dictionary_create();
681
682 return table;
683 }
684
685 void
libdm_table_destroy(libdm_table_t libdm_table)686 libdm_table_destroy(libdm_table_t libdm_table)
687 {
688
689 prop_object_release(libdm_table->ldm_tbl);
690 free(libdm_table);
691 }
692
693 int
libdm_table_set_start(uint64_t start,libdm_table_t libdm_table)694 libdm_table_set_start(uint64_t start, libdm_table_t libdm_table)
695 {
696
697 if (libdm_table == NULL)
698 return ENOENT;
699
700 return prop_dictionary_set_uint64(libdm_table->ldm_tbl,
701 DM_TABLE_START, start);
702 }
703
704 uint64_t
libdm_table_get_start(libdm_table_t libdm_table)705 libdm_table_get_start(libdm_table_t libdm_table)
706 {
707 uint64_t start;
708
709 if (libdm_table == NULL)
710 return ENOENT;
711
712 (void)prop_dictionary_get_uint64(libdm_table->ldm_tbl, DM_TABLE_START,
713 &start);
714
715 return start;
716 }
717
718 int
libdm_table_set_length(uint64_t length,libdm_table_t libdm_table)719 libdm_table_set_length(uint64_t length, libdm_table_t libdm_table)
720 {
721
722 if (libdm_table == NULL)
723 return ENOENT;
724
725 return prop_dictionary_set_uint64(libdm_table->ldm_tbl,
726 DM_TABLE_LENGTH, length);
727 }
728
729 uint64_t
libdm_table_get_length(libdm_table_t libdm_table)730 libdm_table_get_length(libdm_table_t libdm_table)
731 {
732 uint64_t length;
733
734 if (libdm_table == NULL)
735 return ENOENT;
736
737 prop_dictionary_get_uint64(libdm_table->ldm_tbl, DM_TABLE_LENGTH,
738 &length);
739
740 return length;
741 }
742
743 int
libdm_table_set_target(const char * name,libdm_table_t libdm_table)744 libdm_table_set_target(const char *name, libdm_table_t libdm_table)
745 {
746
747 if (libdm_table == NULL)
748 return ENOENT;
749
750 return prop_dictionary_set_string(libdm_table->ldm_tbl, DM_TABLE_TYPE, name);
751 }
752
753 char *
libdm_table_get_target(libdm_table_t libdm_table)754 libdm_table_get_target(libdm_table_t libdm_table)
755 {
756 char *target;
757
758 if (!prop_dictionary_get_string(libdm_table->ldm_tbl, DM_TABLE_TYPE,
759 (const char **)&target))
760 return NULL;
761
762 return target;
763 }
764
765 int
libdm_table_set_params(const char * params,libdm_table_t libdm_table)766 libdm_table_set_params(const char *params, libdm_table_t libdm_table)
767 {
768
769 if (libdm_table == NULL)
770 return ENOENT;
771
772 return prop_dictionary_set_string(libdm_table->ldm_tbl,
773 DM_TABLE_PARAMS, params);
774 }
775
776 /*
777 * Get table params string from libdm_table_t
778 * returned char * is dynamically allocated caller should free it.
779 */
780 char *
libdm_table_get_params(libdm_table_t libdm_table)781 libdm_table_get_params(libdm_table_t libdm_table)
782 {
783 char *params;
784
785 if (!prop_dictionary_get_string(libdm_table->ldm_tbl, DM_TABLE_PARAMS,
786 (const char **)¶ms))
787 return NULL;
788
789 return params;
790 }
791
792 int32_t
libdm_table_get_status(libdm_table_t libdm_table)793 libdm_table_get_status(libdm_table_t libdm_table)
794 {
795 int32_t status;
796
797 (void)prop_dictionary_get_int32(libdm_table->ldm_tbl, DM_TABLE_STAT,
798 &status);
799
800 return status;
801 }
802
803 /*
804 * Target manipulation routines
805 */
806 void
libdm_target_destroy(libdm_target_t libdm_target)807 libdm_target_destroy(libdm_target_t libdm_target)
808 {
809
810 prop_object_release(libdm_target->ldm_trgt);
811 free(libdm_target);
812 }
813
814 char *
libdm_target_get_name(libdm_target_t libdm_target)815 libdm_target_get_name(libdm_target_t libdm_target)
816 {
817 char *name;
818
819 if (!prop_dictionary_get_string(libdm_target->ldm_trgt,
820 DM_TARGETS_NAME, (const char **)&name))
821 return NULL;
822
823 return name;
824 }
825
826 int32_t
libdm_target_get_version(libdm_target_t libdm_target,uint32_t * ver,size_t size)827 libdm_target_get_version(libdm_target_t libdm_target, uint32_t *ver, size_t size)
828 {
829 prop_array_t prop_ver;
830 size_t i;
831
832 prop_ver = prop_dictionary_get(libdm_target->ldm_trgt,
833 DM_TARGETS_VERSION);
834
835 i = prop_array_count(prop_ver);
836
837 if (i > size)
838 return -i;
839
840 for (i = 0; i < size; i++)
841 prop_array_get_uint32(prop_ver, i, &ver[i]);
842
843 return i;
844 }
845
846
847 /*
848 * Dev manipulation routines
849 */
850 void
libdm_dev_destroy(libdm_dev_t libdm_dev)851 libdm_dev_destroy(libdm_dev_t libdm_dev)
852 {
853
854 prop_object_release(libdm_dev->ldm_dev);
855 free(libdm_dev);
856 }
857
858 char *
libdm_dev_get_name(libdm_dev_t libdm_dev)859 libdm_dev_get_name(libdm_dev_t libdm_dev)
860 {
861 char *name;
862
863 if (!prop_dictionary_get_string(libdm_dev->ldm_dev,
864 DM_DEV_NAME, (const char **)&name))
865 return NULL;
866
867 return name;
868 }
869
870 uint32_t
libdm_dev_get_minor(libdm_dev_t libdm_dev)871 libdm_dev_get_minor(libdm_dev_t libdm_dev)
872 {
873 uint32_t dev;
874
875 (void)prop_dictionary_get_uint32(libdm_dev->ldm_dev, DM_DEV_DEV,
876 &dev);
877
878 return dev;
879 }
880
881 int
libdm_dev_set_newname(const char * newname,libdm_cmd_t libdm_cmd)882 libdm_dev_set_newname(const char *newname, libdm_cmd_t libdm_cmd)
883 {
884
885 if (newname == NULL)
886 return ENOENT;
887
888 return prop_array_set_string(libdm_cmd->ldm_cmd, 0, newname);
889 }
890