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