xref: /netbsd-src/lib/libdm/libdm_ioctl.c (revision 31510453944a10501ce606a0b8c7e5d36d433e6e)
183425a0fShaad /*
283425a0fShaad  * Copyright (c) 2010 The NetBSD Foundation, Inc.
383425a0fShaad  * All rights reserved.
483425a0fShaad  *
583425a0fShaad  * This code is derived from software contributed to The NetBSD Foundation
683425a0fShaad  * by Adam Hamsik.
783425a0fShaad  *
883425a0fShaad  * Redistribution and use in source and binary forms, with or without
983425a0fShaad  * modification, are permitted provided that the following conditions
1083425a0fShaad  * are met:
1183425a0fShaad  * 1. Redistributions of source code must retain the above copyright
1283425a0fShaad  *    notice, this list of conditions and the following disclaimer.
1383425a0fShaad  * 2. Redistributions in binary form must reproduce the above copyright
1483425a0fShaad  *    notice, this list of conditions and the following disclaimer in the
1583425a0fShaad  *    documentation and/or other materials provided with the distribution.
1683425a0fShaad  *
1783425a0fShaad  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
1883425a0fShaad  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
1983425a0fShaad  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
2083425a0fShaad  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
2183425a0fShaad  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
2283425a0fShaad  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
2383425a0fShaad  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
2483425a0fShaad  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
2583425a0fShaad  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
2683425a0fShaad  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
2783425a0fShaad  * POSSIBILITY OF SUCH DAMAGE.
2883425a0fShaad  */
2983425a0fShaad 
3083425a0fShaad #include <sys/types.h>
3183425a0fShaad #include <sys/param.h>
3283425a0fShaad #include <sys/ioctl.h>
3383425a0fShaad 
3483425a0fShaad #include <errno.h>
3583425a0fShaad #include <fcntl.h>
3683425a0fShaad #include <stdio.h>
3783425a0fShaad #include <stdlib.h>
3883425a0fShaad #include <string.h>
3983425a0fShaad #include <unistd.h>
4083425a0fShaad 
4183425a0fShaad #include <prop/proplib.h>
4283425a0fShaad 
4383425a0fShaad #include <dev/dm/netbsd-dm.h>
4483425a0fShaad 
4583425a0fShaad #include "dm.h"
4683425a0fShaad 
4783425a0fShaad /*
4883425a0fShaad  * Libdm library works like interface between device-mapper driver and
4983425a0fShaad  * NetBSD userspace. For start it uses same set of commands like linux
5083425a0fShaad  * libdevmapper, but in later stage if we introduce NetBSD device-mapper
5183425a0fShaad  * extensions we don't need to change libdevmapper.
5283425a0fShaad  *
5383425a0fShaad  * LIBDM basically creates one proplib dictionary with everything what is
5483425a0fShaad  * needed to work with device-mapper devices.
5583425a0fShaad  *
5683425a0fShaad  * Basic element of libdm is libdm_task which contains version and command
5783425a0fShaad  * string with another dictionary cmd.
5883425a0fShaad  */
5983425a0fShaad 
6083425a0fShaad struct libdm_cmd {
6183425a0fShaad 	prop_array_t ldm_cmd;
6283425a0fShaad };
6383425a0fShaad 
6483425a0fShaad struct libdm_iter {
6583425a0fShaad 	prop_object_iterator_t ldm_obji;
6683425a0fShaad };
6783425a0fShaad 
6883425a0fShaad struct libdm_task {
6983425a0fShaad 	prop_dictionary_t ldm_task;
7083425a0fShaad };
7183425a0fShaad 
7283425a0fShaad struct libdm_table {
7383425a0fShaad 	prop_dictionary_t ldm_tbl;
7483425a0fShaad };
7583425a0fShaad 
7683425a0fShaad struct libdm_target {
7783425a0fShaad 	prop_dictionary_t ldm_trgt;
7883425a0fShaad };
7983425a0fShaad 
8083425a0fShaad struct libdm_dev {
8183425a0fShaad 	prop_dictionary_t ldm_dev;
8283425a0fShaad };
8383425a0fShaad 
8483425a0fShaad struct cmd_version cmd_ver[] = {
8583425a0fShaad 	{"version", {4, 0, 0}},
8683425a0fShaad 	{"targets", {4, 0, 0}},
8783425a0fShaad 	{"create", {4, 0, 0}},
8883425a0fShaad 	{"info",   {4, 0, 0}},
8983425a0fShaad 	{"mknodes",{4, 0, 0}},
9083425a0fShaad 	{"names",  {4, 0, 0}},
9183425a0fShaad 	{"suspend",{4, 0, 0}},
9283425a0fShaad 	{"remove", {4, 0, 0}},
9383425a0fShaad 	{"rename", {4, 0, 0}},
9483425a0fShaad 	{"resume", {4, 0, 0}},
9583425a0fShaad 	{"clear",  {4, 0, 0}},
9683425a0fShaad 	{"deps",   {4, 0, 0}},
9783425a0fShaad 	{"reload", {4, 0, 0}},
9883425a0fShaad 	{"status", {4, 0, 0}},
9983425a0fShaad 	{"table",  {4, 0, 0}},
10083425a0fShaad 	/* NetBSD device-mapper command extension goes here */
10183425a0fShaad 	{NULL, {0, 0, 0}}
10283425a0fShaad };
10383425a0fShaad 
10483425a0fShaad /* /dev/mapper/control managing routines */
10583425a0fShaad static int libdm_control_open(const char *);
10683425a0fShaad static int libdm_control_close(int);
10783425a0fShaad 
10883425a0fShaad static int
libdm_control_open(const char * path)10983425a0fShaad libdm_control_open(const char *path)
11083425a0fShaad {
11183425a0fShaad 	int fd;
11283425a0fShaad #ifdef RUMP_ACTION
11383425a0fShaad 	if ((fd = rump_sys_open(path, O_RDWR)) < 0)
11483425a0fShaad 		return -1;
11583425a0fShaad #else
11683425a0fShaad 	if ((fd = open(path, O_RDWR)) < 0)
11783425a0fShaad 		return -1;
11883425a0fShaad #endif
11983425a0fShaad 	return fd;
12083425a0fShaad }
12183425a0fShaad 
12283425a0fShaad static int
libdm_control_close(int fd)12383425a0fShaad libdm_control_close(int fd)
12483425a0fShaad {
12583425a0fShaad 
12683425a0fShaad #ifdef RUMP_ACTION
12783425a0fShaad 	return rump_sys_close(fd);
12883425a0fShaad #else
12983425a0fShaad 	return close(fd);
13083425a0fShaad #endif
13183425a0fShaad }
13283425a0fShaad 
13383425a0fShaad /* Destroy iterator for arrays such as version strings, cmd_data. */
13483425a0fShaad void
libdm_iter_destroy(libdm_iter_t libdm_iter)13583425a0fShaad libdm_iter_destroy(libdm_iter_t libdm_iter)
13683425a0fShaad {
13783425a0fShaad 
13883425a0fShaad 	prop_object_iterator_release(libdm_iter->ldm_obji);
13983425a0fShaad 	free(libdm_iter);
14083425a0fShaad }
14183425a0fShaad 
14283425a0fShaad /*
14383425a0fShaad  * Issue ioctl call to kernel, releasing both dictionaries is
14483425a0fShaad  * left on callers.
14583425a0fShaad  */
14683425a0fShaad int
libdm_task_run(libdm_task_t libdm_task)14783425a0fShaad libdm_task_run(libdm_task_t libdm_task)
14883425a0fShaad {
14983425a0fShaad 	prop_dictionary_t dict;
15083425a0fShaad 	int libdm_control_fd = -1;
15183425a0fShaad 	int error;
15283425a0fShaad #ifdef RUMP_ACTION
15383425a0fShaad 	struct plistref prefp;
15483425a0fShaad #endif
15583425a0fShaad 	error = 0;
15683425a0fShaad 
15783425a0fShaad 	if (libdm_task == NULL)
15883425a0fShaad 		return ENOENT;
15983425a0fShaad 
16083425a0fShaad 	if ((libdm_control_fd = libdm_control_open(DM_DEVICE_PATH)) < 0)
16183425a0fShaad 		return errno;
16283425a0fShaad #ifdef RUMP_ACTION
16383425a0fShaad 	prop_dictionary_externalize_to_pref(libdm_task->ldm_task,
16483425a0fShaad 	    &prefp);
16583425a0fShaad 
16683425a0fShaad 	error = rump_sys_ioctl(libdm_control_fd, NETBSD_DM_IOCTL, &prefp);
16783425a0fShaad 	if (error < 0) {
16883425a0fShaad 		libdm_control_close(libdm_control_fd);
16983425a0fShaad 
17083425a0fShaad 		return error;
17183425a0fShaad 	}
17283425a0fShaad 	dict = prop_dictionary_internalize(prefp.pref_plist);
17383425a0fShaad #else
17483425a0fShaad 	error = prop_dictionary_sendrecv_ioctl(libdm_task->ldm_task,
17583425a0fShaad 	    libdm_control_fd, NETBSD_DM_IOCTL, &dict);
17683425a0fShaad 	if ( error != 0) {
17783425a0fShaad 		libdm_control_close(libdm_control_fd);
17883425a0fShaad 		return error;
17983425a0fShaad 	}
18083425a0fShaad #endif
18183425a0fShaad 
18283425a0fShaad 	libdm_control_close(libdm_control_fd);
18383425a0fShaad 	prop_object_retain(dict);
18483425a0fShaad 	prop_object_release(libdm_task->ldm_task);
18583425a0fShaad 	libdm_task->ldm_task = dict;
18683425a0fShaad 
18783425a0fShaad 	return EXIT_SUCCESS;
18883425a0fShaad }
18983425a0fShaad 
19083425a0fShaad 
19183425a0fShaad /* Create libdm General task structure */
19283425a0fShaad libdm_task_t
libdm_task_create(const char * command)19383425a0fShaad libdm_task_create(const char *command)
19483425a0fShaad {
19583425a0fShaad 	libdm_task_t task;
19683425a0fShaad 	size_t i,len,slen;
19783425a0fShaad 	prop_array_t ver;
19883425a0fShaad 
19983425a0fShaad 	task = NULL;
20083425a0fShaad 
20183425a0fShaad 	task = malloc(sizeof(*task));
20283425a0fShaad 	if (task == NULL)
20383425a0fShaad 		return NULL;
20483425a0fShaad 
20583425a0fShaad 	if ((task->ldm_task = prop_dictionary_create()) == NULL) {
20683425a0fShaad 		free(task);
20783425a0fShaad 		return NULL;
20883425a0fShaad 	}
20983425a0fShaad 
210abcb66ecSthorpej 	if ((prop_dictionary_set_string(task->ldm_task, DM_IOCTL_COMMAND,
21183425a0fShaad 		    command)) == false) {
21283425a0fShaad 		prop_object_release(task->ldm_task);
21383425a0fShaad 		free(task);
21483425a0fShaad 		return NULL;
21583425a0fShaad 	}
21683425a0fShaad 
21783425a0fShaad 	len = strlen(command);
21883425a0fShaad 
21983425a0fShaad 	for (i = 0; cmd_ver[i].cmd != NULL; i++) {
22083425a0fShaad 		slen = strlen(cmd_ver[i].cmd);
22183425a0fShaad 
22283425a0fShaad 		if (len != slen)
22383425a0fShaad 			continue;
22483425a0fShaad 
22583425a0fShaad 		if ((strncmp(command, cmd_ver[i].cmd, slen)) == 0) {
22683425a0fShaad 			ver = prop_array_create();
22783425a0fShaad 			prop_array_add_uint32(ver, cmd_ver[i].version[0]);
22883425a0fShaad 			prop_array_add_uint32(ver, cmd_ver[i].version[1]);
22983425a0fShaad 			prop_array_add_uint32(ver, cmd_ver[i].version[2]);
23083425a0fShaad 
23183425a0fShaad 			prop_dictionary_set(task->ldm_task, DM_IOCTL_VERSION,
23283425a0fShaad 			    ver);
23383425a0fShaad 
23483425a0fShaad 			prop_object_release(ver);
23583425a0fShaad 			break;
23683425a0fShaad 		}
23783425a0fShaad 	}
23883425a0fShaad 
23983425a0fShaad 	return task;
24083425a0fShaad }
24183425a0fShaad 
24283425a0fShaad void
libdm_task_destroy(libdm_task_t libdm_task)24383425a0fShaad libdm_task_destroy(libdm_task_t libdm_task)
24483425a0fShaad {
24583425a0fShaad 
24683425a0fShaad 	if (libdm_task != NULL)
24783425a0fShaad 		prop_object_release(libdm_task->ldm_task);
24883425a0fShaad 	free(libdm_task);
24983425a0fShaad }
25083425a0fShaad 
25183425a0fShaad /* Set device name */
25283425a0fShaad int
libdm_task_set_name(const char * name,libdm_task_t libdm_task)25383425a0fShaad libdm_task_set_name(const char *name, libdm_task_t libdm_task)
25483425a0fShaad {
25583425a0fShaad 
256abcb66ecSthorpej 	if ((prop_dictionary_set_string(libdm_task->ldm_task,
25783425a0fShaad 		    DM_IOCTL_NAME, name)) == false)
25883425a0fShaad 		return ENOENT;
25983425a0fShaad 
26083425a0fShaad 	return 0;
26183425a0fShaad }
26283425a0fShaad 
26383425a0fShaad /* Set device name */
26483425a0fShaad char *
libdm_task_get_name(libdm_task_t libdm_task)26583425a0fShaad libdm_task_get_name(libdm_task_t libdm_task)
26683425a0fShaad {
26783425a0fShaad 	char *name;
26883425a0fShaad 
269*31510453Schristos 	if (!prop_dictionary_get_string(libdm_task->ldm_task,
27083425a0fShaad 	    DM_IOCTL_NAME, (const char **)&name))
27183425a0fShaad 		return NULL;
27283425a0fShaad 
27383425a0fShaad 	return name;
27483425a0fShaad }
27583425a0fShaad 
27683425a0fShaad /* Set device uuid */
27783425a0fShaad int
libdm_task_set_uuid(const char * uuid,libdm_task_t libdm_task)27883425a0fShaad libdm_task_set_uuid(const char *uuid, libdm_task_t libdm_task)
27983425a0fShaad {
28083425a0fShaad 
281abcb66ecSthorpej 	if ((prop_dictionary_set_string(libdm_task->ldm_task,
2820c1ba949Shaad 	    DM_IOCTL_UUID, uuid)) == false)
28383425a0fShaad 		return ENOENT;
28483425a0fShaad 
28583425a0fShaad 	return 0;
28683425a0fShaad }
28783425a0fShaad 
28883425a0fShaad /* Set device name */
28983425a0fShaad char *
libdm_task_get_uuid(libdm_task_t libdm_task)29083425a0fShaad libdm_task_get_uuid(libdm_task_t libdm_task)
29183425a0fShaad {
29283425a0fShaad 	char *uuid;
29383425a0fShaad 
294*31510453Schristos 	if (!prop_dictionary_get_string(libdm_task->ldm_task,
29583425a0fShaad 	    DM_IOCTL_UUID, (const char **)&uuid))
29683425a0fShaad 		return NULL;
29783425a0fShaad 
29883425a0fShaad 	return uuid;
29983425a0fShaad }
30083425a0fShaad 
30183425a0fShaad /* Get command name */
30283425a0fShaad char *
libdm_task_get_command(libdm_task_t libdm_task)30383425a0fShaad libdm_task_get_command(libdm_task_t libdm_task)
30483425a0fShaad {
30583425a0fShaad 	char *command;
30683425a0fShaad 
307*31510453Schristos 	if (!prop_dictionary_get_string(libdm_task->ldm_task,
30883425a0fShaad 	    DM_IOCTL_COMMAND, (const char **)&command))
30983425a0fShaad 		return NULL;
31083425a0fShaad 
31183425a0fShaad 	return command;
31283425a0fShaad }
31383425a0fShaad 
31483425a0fShaad int32_t
libdm_task_get_cmd_version(libdm_task_t libdm_task,uint32_t * ver,size_t size)31583425a0fShaad libdm_task_get_cmd_version(libdm_task_t libdm_task, uint32_t *ver, size_t size)
31683425a0fShaad {
31783425a0fShaad 	prop_array_t prop_ver;
31883425a0fShaad 	size_t i;
31983425a0fShaad 
32083425a0fShaad 	prop_ver = prop_dictionary_get(libdm_task->ldm_task,
32183425a0fShaad 	    DM_IOCTL_VERSION);
32283425a0fShaad 
32383425a0fShaad 	i = prop_array_count(prop_ver);
32483425a0fShaad 
32583425a0fShaad 	if (i > size)
32683425a0fShaad 		return -i;
32783425a0fShaad 
32883425a0fShaad 	for (i = 0; i < size; i++)
32983425a0fShaad 		prop_array_get_uint32(prop_ver, i, &ver[i]);
33083425a0fShaad 
33183425a0fShaad 	return i;
33283425a0fShaad }
33383425a0fShaad 
33483425a0fShaad /* Select device minor number. */
33583425a0fShaad int
libdm_task_set_minor(uint32_t minor,libdm_task_t libdm_task)33683425a0fShaad libdm_task_set_minor(uint32_t minor, libdm_task_t libdm_task)
33783425a0fShaad {
33883425a0fShaad 
33983425a0fShaad 	if ((prop_dictionary_set_uint32(libdm_task->ldm_task,
34083425a0fShaad 	    DM_IOCTL_MINOR, minor)) == false)
34183425a0fShaad 		return ENOENT;
34283425a0fShaad 
34383425a0fShaad 	return 0;
34483425a0fShaad }
34583425a0fShaad 
34683425a0fShaad /* Select device minor number. */
34783425a0fShaad uint32_t
libdm_task_get_minor(libdm_task_t libdm_task)34883425a0fShaad libdm_task_get_minor(libdm_task_t libdm_task)
34983425a0fShaad {
35083425a0fShaad 	uint32_t minor;
35183425a0fShaad 
35283425a0fShaad 	minor = 0;
35383425a0fShaad 
35483425a0fShaad 	(void)prop_dictionary_get_uint32(libdm_task->ldm_task,
35583425a0fShaad 	    DM_IOCTL_MINOR, &minor);
35683425a0fShaad 
35783425a0fShaad 	return minor;
35883425a0fShaad }
35983425a0fShaad 
36083425a0fShaad /* Set/Del DM_SUSPEND_FLAG for caller. */
36183425a0fShaad void
libdm_task_set_suspend_flag(libdm_task_t libdm_task)36283425a0fShaad libdm_task_set_suspend_flag(libdm_task_t libdm_task)
36383425a0fShaad {
36483425a0fShaad 	uint32_t flags;
36583425a0fShaad 
36683425a0fShaad 	flags = 0;
36783425a0fShaad 
36883425a0fShaad 	(void)prop_dictionary_get_uint32(libdm_task->ldm_task,
36983425a0fShaad 	    DM_IOCTL_FLAGS, &flags);
37083425a0fShaad 
37183425a0fShaad 	flags |= DM_SUSPEND_FLAG;
37283425a0fShaad 
37383425a0fShaad 	(void)prop_dictionary_set_uint32(libdm_task->ldm_task,
37483425a0fShaad 	    DM_IOCTL_FLAGS, flags);
37583425a0fShaad }
37683425a0fShaad 
37783425a0fShaad void
libdm_task_del_suspend_flag(libdm_task_t libdm_task)37883425a0fShaad libdm_task_del_suspend_flag(libdm_task_t libdm_task)
37983425a0fShaad {
38083425a0fShaad 	uint32_t flags;
38183425a0fShaad 
38283425a0fShaad 	(void)prop_dictionary_get_uint32(libdm_task->ldm_task,
38383425a0fShaad 	    DM_IOCTL_FLAGS, &flags);
38483425a0fShaad 
38583425a0fShaad 	flags &= ~DM_SUSPEND_FLAG;
38683425a0fShaad 
38783425a0fShaad 	(void)prop_dictionary_set_uint32(libdm_task->ldm_task,
38883425a0fShaad 	    DM_IOCTL_FLAGS, flags);
38983425a0fShaad }
39083425a0fShaad 
39183425a0fShaad /* Set/Del DM_STATUS_FLAG for caller. */
39283425a0fShaad void
libdm_task_set_status_flag(libdm_task_t libdm_task)39383425a0fShaad libdm_task_set_status_flag(libdm_task_t libdm_task)
39483425a0fShaad {
39583425a0fShaad 	uint32_t flags;
39683425a0fShaad 
39783425a0fShaad 	flags = 0;
39883425a0fShaad 
39983425a0fShaad 	(void)prop_dictionary_get_uint32(libdm_task->ldm_task,
40083425a0fShaad 	    DM_IOCTL_FLAGS, &flags);
40183425a0fShaad 
40283425a0fShaad 	flags |= DM_STATUS_TABLE_FLAG;
40383425a0fShaad 
40483425a0fShaad 	(void)prop_dictionary_set_uint32(libdm_task->ldm_task,
40583425a0fShaad 	    DM_IOCTL_FLAGS, flags);
40683425a0fShaad }
40783425a0fShaad 
40883425a0fShaad void
libdm_task_del_status_flag(libdm_task_t libdm_task)40983425a0fShaad libdm_task_del_status_flag(libdm_task_t libdm_task)
41083425a0fShaad {
41183425a0fShaad 	uint32_t flags;
41283425a0fShaad 
41383425a0fShaad 	(void)prop_dictionary_get_uint32(libdm_task->ldm_task,
41483425a0fShaad 	    DM_IOCTL_FLAGS, &flags);
41583425a0fShaad 
41683425a0fShaad 	flags &= ~DM_STATUS_TABLE_FLAG;
41783425a0fShaad 
41883425a0fShaad 	(void)prop_dictionary_set_uint32(libdm_task->ldm_task,
41983425a0fShaad 	    DM_IOCTL_FLAGS, flags);
42083425a0fShaad }
42183425a0fShaad 
42283425a0fShaad /* Set/Del DM_EXISTS_FLAG for caller. */
42383425a0fShaad void
libdm_task_set_exists_flag(libdm_task_t libdm_task)42483425a0fShaad libdm_task_set_exists_flag(libdm_task_t libdm_task)
42583425a0fShaad {
42683425a0fShaad 	uint32_t flags;
42783425a0fShaad 
42883425a0fShaad 	flags = 0;
42983425a0fShaad 
43083425a0fShaad 	(void)prop_dictionary_get_uint32(libdm_task->ldm_task,
43183425a0fShaad 	    DM_IOCTL_FLAGS, &flags);
43283425a0fShaad 
43383425a0fShaad 	flags |= DM_EXISTS_FLAG;
43483425a0fShaad 
43583425a0fShaad 	(void)prop_dictionary_set_uint32(libdm_task->ldm_task,
43683425a0fShaad 	    DM_IOCTL_FLAGS, flags);
43783425a0fShaad }
43883425a0fShaad 
43983425a0fShaad void
libdm_task_del_exists_flag(libdm_task_t libdm_task)44083425a0fShaad libdm_task_del_exists_flag(libdm_task_t libdm_task)
44183425a0fShaad {
44283425a0fShaad 	uint32_t flags;
44383425a0fShaad 
44483425a0fShaad 	(void)prop_dictionary_get_uint32(libdm_task->ldm_task,
44583425a0fShaad 	    DM_IOCTL_FLAGS, &flags);
44683425a0fShaad 
44783425a0fShaad 	flags &= ~DM_EXISTS_FLAG;
44883425a0fShaad 
44983425a0fShaad 	(void)prop_dictionary_set_uint32(libdm_task->ldm_task,
45083425a0fShaad 	    DM_IOCTL_FLAGS, flags);
45183425a0fShaad }
45283425a0fShaad 
45383425a0fShaad /* Set flags used by LVM this is shortcut and should not be used
45483425a0fShaad    by anyone else. */
45583425a0fShaad void
libdm_task_set_flags(libdm_task_t libdm_task,uint32_t flags)45683425a0fShaad libdm_task_set_flags(libdm_task_t libdm_task, uint32_t flags)
45783425a0fShaad {
45883425a0fShaad 
45983425a0fShaad 	(void)prop_dictionary_set_uint32(libdm_task->ldm_task,
46083425a0fShaad 	    DM_IOCTL_FLAGS, flags);
46183425a0fShaad }
46283425a0fShaad 
46383425a0fShaad /* Get ioctl protocol status flags. */
46483425a0fShaad uint32_t
libdm_task_get_flags(libdm_task_t libdm_task)46583425a0fShaad libdm_task_get_flags(libdm_task_t libdm_task)
46683425a0fShaad {
46783425a0fShaad 	uint32_t flags;
46883425a0fShaad 
46983425a0fShaad 	(void)prop_dictionary_get_uint32(libdm_task->ldm_task,
47083425a0fShaad 	    DM_IOCTL_FLAGS, &flags);
47183425a0fShaad 
47283425a0fShaad 	return flags;
47383425a0fShaad }
47483425a0fShaad 
47583425a0fShaad /* Set ioctl protocol status flags. */
47683425a0fShaad uint32_t
libdm_task_get_target_num(libdm_task_t libdm_task)47783425a0fShaad libdm_task_get_target_num(libdm_task_t libdm_task)
47883425a0fShaad {
47983425a0fShaad 	uint32_t count;
48083425a0fShaad 
48183425a0fShaad 	(void)prop_dictionary_get_uint32(libdm_task->ldm_task,
48283425a0fShaad 	    DM_IOCTL_TARGET_COUNT, &count);
48383425a0fShaad 
48483425a0fShaad 	return count;
48583425a0fShaad }
48683425a0fShaad 
48783425a0fShaad int32_t
libdm_task_get_open_num(libdm_task_t libdm_task)48883425a0fShaad libdm_task_get_open_num(libdm_task_t libdm_task)
48983425a0fShaad {
49083425a0fShaad 	int32_t count;
49183425a0fShaad 
49283425a0fShaad 	(void)prop_dictionary_get_int32(libdm_task->ldm_task,
49383425a0fShaad 	    DM_IOCTL_OPEN, &count);
49483425a0fShaad 
49583425a0fShaad 	return count;
49683425a0fShaad }
49783425a0fShaad 
49883425a0fShaad uint32_t
libdm_task_get_event_num(libdm_task_t libdm_task)49983425a0fShaad libdm_task_get_event_num(libdm_task_t libdm_task)
50083425a0fShaad {
50183425a0fShaad 	uint32_t event;
50283425a0fShaad 
50383425a0fShaad 	(void)prop_dictionary_get_uint32(libdm_task->ldm_task,
50483425a0fShaad 	    DM_IOCTL_EVENT, &event);
50583425a0fShaad 
50683425a0fShaad 	return event;
50783425a0fShaad }
50883425a0fShaad 
50983425a0fShaad /* Set cmd_data dictionary entry to task struct. */
51083425a0fShaad int
libdm_task_set_cmd(libdm_cmd_t libdm_cmd,libdm_task_t libdm_task)51183425a0fShaad libdm_task_set_cmd(libdm_cmd_t libdm_cmd, libdm_task_t libdm_task)
51283425a0fShaad {
51383425a0fShaad 
51483425a0fShaad 	if ((prop_dictionary_set(libdm_task->ldm_task,
51583425a0fShaad 	    DM_IOCTL_CMD_DATA, libdm_cmd->ldm_cmd)) == false)
51683425a0fShaad 		return ENOENT;
51783425a0fShaad 
51883425a0fShaad 	return 0;
51983425a0fShaad }
52083425a0fShaad 
52183425a0fShaad /* Get cmd_data dictionary entry from task struct */
52283425a0fShaad libdm_cmd_t
libdm_task_get_cmd(libdm_task_t libdm_task)52383425a0fShaad libdm_task_get_cmd(libdm_task_t libdm_task)
52483425a0fShaad {
52583425a0fShaad 	libdm_cmd_t cmd;
52683425a0fShaad 
52783425a0fShaad 	cmd = malloc(sizeof(*cmd));
52883425a0fShaad 
52983425a0fShaad 	cmd->ldm_cmd = prop_dictionary_get(libdm_task->ldm_task,
53083425a0fShaad 	    DM_IOCTL_CMD_DATA);
53183425a0fShaad 
53283425a0fShaad 	if (cmd->ldm_cmd == NULL) {
53383425a0fShaad 		free(cmd);
53483425a0fShaad 		return NULL;
53583425a0fShaad 	}
53683425a0fShaad 
53783425a0fShaad 	/* Get a reference prop_dictionary_get will not get it */
53883425a0fShaad 	prop_object_retain(cmd->ldm_cmd);
53983425a0fShaad 
54083425a0fShaad 	return cmd;
54183425a0fShaad }
54283425a0fShaad 
54383425a0fShaad /* Command functions
54483425a0fShaad  *
54583425a0fShaad  * Functions for creation, destroing, set, get of command area of
54683425a0fShaad  * ioctl dictionary.
54783425a0fShaad  */
54883425a0fShaad libdm_cmd_t
libdm_cmd_create(void)54983425a0fShaad libdm_cmd_create(void)
55083425a0fShaad {
55183425a0fShaad 	libdm_cmd_t cmd;
55283425a0fShaad 
55383425a0fShaad 	cmd = malloc(sizeof(*cmd));
55483425a0fShaad 	if (cmd == NULL)
55583425a0fShaad 		return NULL;
55683425a0fShaad 
55783425a0fShaad 	cmd->ldm_cmd =  prop_array_create();
55883425a0fShaad 
55983425a0fShaad 	return cmd;
56083425a0fShaad }
56183425a0fShaad 
56283425a0fShaad void
libdm_cmd_destroy(libdm_cmd_t libdm_cmd)56383425a0fShaad libdm_cmd_destroy(libdm_cmd_t libdm_cmd)
56483425a0fShaad {
56583425a0fShaad 
56683425a0fShaad 	prop_object_release(libdm_cmd->ldm_cmd);
56783425a0fShaad 	free(libdm_cmd);
56883425a0fShaad }
56983425a0fShaad 
57083425a0fShaad /* Create iterator object for caller this can be used to
57183425a0fShaad    iterate through all members of cmd array. */
57283425a0fShaad libdm_iter_t
libdm_cmd_iter_create(libdm_cmd_t libdm_cmd)57383425a0fShaad libdm_cmd_iter_create(libdm_cmd_t libdm_cmd)
57483425a0fShaad {
57583425a0fShaad 
57683425a0fShaad 	libdm_iter_t iter;
57783425a0fShaad 
57883425a0fShaad 	iter = malloc(sizeof(*iter));
57983425a0fShaad 	if (iter == NULL)
58083425a0fShaad 		return NULL;
58183425a0fShaad 
58283425a0fShaad 	iter->ldm_obji = prop_array_iterator(libdm_cmd->ldm_cmd);
58383425a0fShaad 
58483425a0fShaad 	return iter;
58583425a0fShaad }
58683425a0fShaad 
58783425a0fShaad int
libdm_cmd_set_table(libdm_table_t libdm_table,libdm_cmd_t libdm_cmd)58883425a0fShaad libdm_cmd_set_table(libdm_table_t libdm_table, libdm_cmd_t libdm_cmd)
58983425a0fShaad {
59083425a0fShaad 
59183425a0fShaad 	return prop_array_add(libdm_cmd->ldm_cmd,
59283425a0fShaad 	    libdm_table->ldm_tbl);
59383425a0fShaad }
59483425a0fShaad 
59583425a0fShaad 
59683425a0fShaad libdm_target_t
libdm_cmd_get_target(libdm_iter_t iter)59783425a0fShaad libdm_cmd_get_target(libdm_iter_t iter)
59883425a0fShaad {
59983425a0fShaad 	libdm_target_t trgt;
60083425a0fShaad 
60183425a0fShaad 	trgt = malloc(sizeof(*trgt));
60283425a0fShaad 	if (trgt == NULL)
60383425a0fShaad 		return NULL;
60483425a0fShaad 
60583425a0fShaad 	trgt->ldm_trgt = prop_object_iterator_next(iter->ldm_obji);
60683425a0fShaad 	if (trgt->ldm_trgt == NULL) {
60783425a0fShaad 		free(trgt);
60883425a0fShaad 		return NULL;
60983425a0fShaad 	}
61083425a0fShaad 
61183425a0fShaad 	return trgt;
61283425a0fShaad }
61383425a0fShaad 
61483425a0fShaad libdm_table_t
libdm_cmd_get_table(libdm_iter_t iter)61583425a0fShaad libdm_cmd_get_table(libdm_iter_t iter)
61683425a0fShaad {
61783425a0fShaad 	libdm_table_t tbl;
61883425a0fShaad 
61983425a0fShaad 	tbl = malloc(sizeof(*tbl));
62083425a0fShaad 	if (tbl == NULL)
62183425a0fShaad 		return NULL;
62283425a0fShaad 
62383425a0fShaad 	tbl->ldm_tbl = prop_object_iterator_next(iter->ldm_obji);
62483425a0fShaad 	if (tbl->ldm_tbl == NULL) {
62583425a0fShaad 		free(tbl);
62683425a0fShaad 		return NULL;
62783425a0fShaad 	}
62883425a0fShaad 
62983425a0fShaad 	return tbl;
63083425a0fShaad }
63183425a0fShaad 
63283425a0fShaad libdm_dev_t
libdm_cmd_get_dev(libdm_iter_t iter)63383425a0fShaad libdm_cmd_get_dev(libdm_iter_t iter)
63483425a0fShaad {
63583425a0fShaad 	libdm_dev_t dev;
63683425a0fShaad 
63783425a0fShaad 	dev = malloc(sizeof(*dev));
63883425a0fShaad 	if (dev == NULL)
63983425a0fShaad 		return NULL;
64083425a0fShaad 
64183425a0fShaad 	dev->ldm_dev = prop_object_iterator_next(iter->ldm_obji);
64283425a0fShaad 	if (dev->ldm_dev == NULL) {
64383425a0fShaad 		free(dev);
64483425a0fShaad 		return NULL;
64583425a0fShaad 	}
64683425a0fShaad 
64783425a0fShaad 	return dev;
64883425a0fShaad }
64983425a0fShaad 
65083425a0fShaad /*
65183425a0fShaad  * Deps manipulation routines
65283425a0fShaad  */
65383425a0fShaad uint64_t
libdm_cmd_get_deps(libdm_iter_t libdm_iter)65483425a0fShaad libdm_cmd_get_deps(libdm_iter_t libdm_iter)
65583425a0fShaad {
65683425a0fShaad 	prop_object_t obj;
65783425a0fShaad 	uint64_t deps;
65883425a0fShaad 
65983425a0fShaad 	obj = prop_object_iterator_next(libdm_iter->ldm_obji);
660abcb66ecSthorpej 	deps = prop_number_unsigned_value(obj);
66183425a0fShaad 
66283425a0fShaad 	if (obj != NULL)
66383425a0fShaad 		prop_object_release(obj);
66483425a0fShaad 
66583425a0fShaad 	return deps;
66683425a0fShaad }
66783425a0fShaad 
66883425a0fShaad /*
66983425a0fShaad  * Table manipulation routines
67083425a0fShaad  */
67183425a0fShaad libdm_table_t
libdm_table_create(void)67283425a0fShaad libdm_table_create(void)
67383425a0fShaad {
67483425a0fShaad 	libdm_table_t table;
67583425a0fShaad 
67683425a0fShaad 	table = malloc(sizeof(*table));
67783425a0fShaad 	if (table == NULL)
67883425a0fShaad 		return NULL;
67983425a0fShaad 
68083425a0fShaad 	table->ldm_tbl = prop_dictionary_create();
68183425a0fShaad 
68283425a0fShaad 	return table;
68383425a0fShaad }
68483425a0fShaad 
68583425a0fShaad void
libdm_table_destroy(libdm_table_t libdm_table)68683425a0fShaad libdm_table_destroy(libdm_table_t libdm_table)
68783425a0fShaad {
68883425a0fShaad 
68983425a0fShaad 	prop_object_release(libdm_table->ldm_tbl);
69083425a0fShaad 	free(libdm_table);
69183425a0fShaad }
69283425a0fShaad 
69383425a0fShaad int
libdm_table_set_start(uint64_t start,libdm_table_t libdm_table)69483425a0fShaad libdm_table_set_start(uint64_t start, libdm_table_t libdm_table)
69583425a0fShaad {
69683425a0fShaad 
69783425a0fShaad 	if (libdm_table == NULL)
69883425a0fShaad 		return ENOENT;
69983425a0fShaad 
70083425a0fShaad 	return prop_dictionary_set_uint64(libdm_table->ldm_tbl,
70183425a0fShaad 	    DM_TABLE_START, start);
70283425a0fShaad }
70383425a0fShaad 
70483425a0fShaad uint64_t
libdm_table_get_start(libdm_table_t libdm_table)70583425a0fShaad libdm_table_get_start(libdm_table_t libdm_table)
70683425a0fShaad {
70783425a0fShaad 	uint64_t start;
70883425a0fShaad 
70983425a0fShaad 	if (libdm_table == NULL)
71083425a0fShaad 		return ENOENT;
71183425a0fShaad 
71283425a0fShaad 	(void)prop_dictionary_get_uint64(libdm_table->ldm_tbl, DM_TABLE_START,
71383425a0fShaad 	    &start);
71483425a0fShaad 
71583425a0fShaad 	return start;
71683425a0fShaad }
71783425a0fShaad 
71883425a0fShaad int
libdm_table_set_length(uint64_t length,libdm_table_t libdm_table)71983425a0fShaad libdm_table_set_length(uint64_t length, libdm_table_t libdm_table)
72083425a0fShaad {
72183425a0fShaad 
72283425a0fShaad 	if (libdm_table == NULL)
72383425a0fShaad 		return ENOENT;
72483425a0fShaad 
72583425a0fShaad 	return prop_dictionary_set_uint64(libdm_table->ldm_tbl,
72683425a0fShaad 	    DM_TABLE_LENGTH, length);
72783425a0fShaad }
72883425a0fShaad 
72983425a0fShaad uint64_t
libdm_table_get_length(libdm_table_t libdm_table)73083425a0fShaad libdm_table_get_length(libdm_table_t libdm_table)
73183425a0fShaad {
73283425a0fShaad 	uint64_t length;
73383425a0fShaad 
73483425a0fShaad 	if (libdm_table == NULL)
73583425a0fShaad 		return ENOENT;
73683425a0fShaad 
73783425a0fShaad 	prop_dictionary_get_uint64(libdm_table->ldm_tbl, DM_TABLE_LENGTH,
73883425a0fShaad 	    &length);
73983425a0fShaad 
74083425a0fShaad 	return length;
74183425a0fShaad }
74283425a0fShaad 
74383425a0fShaad int
libdm_table_set_target(const char * name,libdm_table_t libdm_table)74483425a0fShaad libdm_table_set_target(const char *name, libdm_table_t libdm_table)
74583425a0fShaad {
74683425a0fShaad 
74783425a0fShaad 	if (libdm_table == NULL)
74883425a0fShaad 		return ENOENT;
74983425a0fShaad 
750abcb66ecSthorpej 	return prop_dictionary_set_string(libdm_table->ldm_tbl, DM_TABLE_TYPE, name);
75183425a0fShaad }
75283425a0fShaad 
75383425a0fShaad char *
libdm_table_get_target(libdm_table_t libdm_table)75483425a0fShaad libdm_table_get_target(libdm_table_t libdm_table)
75583425a0fShaad {
75683425a0fShaad 	char *target;
75783425a0fShaad 
758*31510453Schristos 	if (!prop_dictionary_get_string(libdm_table->ldm_tbl, DM_TABLE_TYPE,
75983425a0fShaad 	    (const char **)&target))
76083425a0fShaad 		return NULL;
76183425a0fShaad 
76283425a0fShaad 	return target;
76383425a0fShaad }
76483425a0fShaad 
76583425a0fShaad int
libdm_table_set_params(const char * params,libdm_table_t libdm_table)76683425a0fShaad libdm_table_set_params(const char *params, libdm_table_t  libdm_table)
76783425a0fShaad {
76883425a0fShaad 
76983425a0fShaad 	if (libdm_table == NULL)
77083425a0fShaad 		return ENOENT;
77183425a0fShaad 
772abcb66ecSthorpej 	return prop_dictionary_set_string(libdm_table->ldm_tbl,
77383425a0fShaad 	    DM_TABLE_PARAMS, params);
77483425a0fShaad }
77583425a0fShaad 
77683425a0fShaad /*
77783425a0fShaad  * Get table params string from libdm_table_t
77883425a0fShaad  * returned char * is dynamically allocated caller should free it.
77983425a0fShaad  */
78083425a0fShaad char *
libdm_table_get_params(libdm_table_t libdm_table)78183425a0fShaad libdm_table_get_params(libdm_table_t  libdm_table)
78283425a0fShaad {
78383425a0fShaad 	char *params;
78483425a0fShaad 
785*31510453Schristos 	if (!prop_dictionary_get_string(libdm_table->ldm_tbl, DM_TABLE_PARAMS,
78683425a0fShaad 	    (const char **)&params))
78783425a0fShaad 		return NULL;
78883425a0fShaad 
78983425a0fShaad 	return params;
79083425a0fShaad }
79183425a0fShaad 
79283425a0fShaad int32_t
libdm_table_get_status(libdm_table_t libdm_table)79383425a0fShaad libdm_table_get_status(libdm_table_t libdm_table)
79483425a0fShaad {
79583425a0fShaad 	int32_t status;
79683425a0fShaad 
79783425a0fShaad 	(void)prop_dictionary_get_int32(libdm_table->ldm_tbl, DM_TABLE_STAT,
79883425a0fShaad 	    &status);
79983425a0fShaad 
80083425a0fShaad 	return status;
80183425a0fShaad }
80283425a0fShaad 
80383425a0fShaad /*
80483425a0fShaad  * Target manipulation routines
80583425a0fShaad  */
80683425a0fShaad void
libdm_target_destroy(libdm_target_t libdm_target)80783425a0fShaad libdm_target_destroy(libdm_target_t libdm_target)
80883425a0fShaad {
80983425a0fShaad 
81083425a0fShaad 	prop_object_release(libdm_target->ldm_trgt);
81183425a0fShaad 	free(libdm_target);
81283425a0fShaad }
81383425a0fShaad 
81483425a0fShaad char *
libdm_target_get_name(libdm_target_t libdm_target)81583425a0fShaad libdm_target_get_name(libdm_target_t libdm_target)
81683425a0fShaad {
81783425a0fShaad 	char *name;
81883425a0fShaad 
819*31510453Schristos 	if (!prop_dictionary_get_string(libdm_target->ldm_trgt,
82083425a0fShaad 	    DM_TARGETS_NAME, (const char **)&name))
82183425a0fShaad 		return NULL;
82283425a0fShaad 
82383425a0fShaad 	return name;
82483425a0fShaad }
82583425a0fShaad 
82683425a0fShaad int32_t
libdm_target_get_version(libdm_target_t libdm_target,uint32_t * ver,size_t size)82783425a0fShaad libdm_target_get_version(libdm_target_t libdm_target, uint32_t *ver, size_t size)
82883425a0fShaad {
82983425a0fShaad 	prop_array_t prop_ver;
83083425a0fShaad 	size_t i;
83183425a0fShaad 
83283425a0fShaad 	prop_ver = prop_dictionary_get(libdm_target->ldm_trgt,
83383425a0fShaad 	    DM_TARGETS_VERSION);
83483425a0fShaad 
83583425a0fShaad 	i = prop_array_count(prop_ver);
83683425a0fShaad 
83783425a0fShaad 	if (i > size)
83883425a0fShaad 		return -i;
83983425a0fShaad 
84083425a0fShaad 	for (i = 0; i < size; i++)
84183425a0fShaad 		prop_array_get_uint32(prop_ver, i, &ver[i]);
84283425a0fShaad 
84383425a0fShaad 	return i;
84483425a0fShaad }
84583425a0fShaad 
84683425a0fShaad 
84783425a0fShaad /*
84883425a0fShaad  * Dev manipulation routines
84983425a0fShaad  */
85083425a0fShaad void
libdm_dev_destroy(libdm_dev_t libdm_dev)85183425a0fShaad libdm_dev_destroy(libdm_dev_t libdm_dev)
85283425a0fShaad {
85383425a0fShaad 
85483425a0fShaad 	prop_object_release(libdm_dev->ldm_dev);
85583425a0fShaad 	free(libdm_dev);
85683425a0fShaad }
85783425a0fShaad 
85883425a0fShaad char *
libdm_dev_get_name(libdm_dev_t libdm_dev)85983425a0fShaad libdm_dev_get_name(libdm_dev_t libdm_dev)
86083425a0fShaad {
86183425a0fShaad 	char *name;
86283425a0fShaad 
863*31510453Schristos 	if (!prop_dictionary_get_string(libdm_dev->ldm_dev,
86483425a0fShaad 	    DM_DEV_NAME, (const char **)&name))
86583425a0fShaad 		return NULL;
86683425a0fShaad 
86783425a0fShaad 	return name;
86883425a0fShaad }
86983425a0fShaad 
87083425a0fShaad uint32_t
libdm_dev_get_minor(libdm_dev_t libdm_dev)87183425a0fShaad libdm_dev_get_minor(libdm_dev_t libdm_dev)
87283425a0fShaad {
87383425a0fShaad 	uint32_t dev;
87483425a0fShaad 
87583425a0fShaad 	(void)prop_dictionary_get_uint32(libdm_dev->ldm_dev, DM_DEV_DEV,
87683425a0fShaad 	    &dev);
87783425a0fShaad 
87883425a0fShaad 	return dev;
87983425a0fShaad }
88083425a0fShaad 
88183425a0fShaad int
libdm_dev_set_newname(const char * newname,libdm_cmd_t libdm_cmd)88283425a0fShaad libdm_dev_set_newname(const char *newname, libdm_cmd_t libdm_cmd)
88383425a0fShaad {
88483425a0fShaad 
88583425a0fShaad 	if (newname == NULL)
88683425a0fShaad 		return ENOENT;
88783425a0fShaad 
888abcb66ecSthorpej 	return prop_array_set_string(libdm_cmd->ldm_cmd, 0, newname);
88983425a0fShaad }
890