xref: /dflybsd-src/contrib/lvm2/dist/libdm/ioctl/libdm_dragonfly.c (revision 2bc6f0594baddf61b251df97adc58d99252e001d)
1*2bc6f059SAlex Hornung /*      $NetBSD: libdm_netbsd.c,v 1.5 2009/12/05 11:42:24 haad Exp $        */
2*2bc6f059SAlex Hornung 
3*2bc6f059SAlex Hornung /*
4*2bc6f059SAlex Hornung  * Copyright (c) 1996, 1997, 1998, 1999, 2002 The NetBSD Foundation, Inc.
5*2bc6f059SAlex Hornung  * All rights reserved.
6*2bc6f059SAlex Hornung  *
7*2bc6f059SAlex Hornung  * This code is derived from software contributed to The NetBSD Foundation
8*2bc6f059SAlex Hornung  * by Adam Hamsik.
9*2bc6f059SAlex Hornung  *
10*2bc6f059SAlex Hornung  * Redistribution and use in source and binary forms, with or without
11*2bc6f059SAlex Hornung  * modification, are permitted provided that the following conditions
12*2bc6f059SAlex Hornung  * are met:
13*2bc6f059SAlex Hornung  * 1. Redistributions of source code must retain the above copyright
14*2bc6f059SAlex Hornung  *    notice, this list of conditions and the following disclaimer.
15*2bc6f059SAlex Hornung  * 2. Redistributions in binary form must reproduce the above copyright
16*2bc6f059SAlex Hornung  *    notice, this list of conditions and the following disclaimer in the
17*2bc6f059SAlex Hornung  *    documentation and/or other materials provided with the distribution.
18*2bc6f059SAlex Hornung  *
19*2bc6f059SAlex Hornung  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
20*2bc6f059SAlex Hornung  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
21*2bc6f059SAlex Hornung  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
22*2bc6f059SAlex Hornung  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
23*2bc6f059SAlex Hornung  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
24*2bc6f059SAlex Hornung  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25*2bc6f059SAlex Hornung  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26*2bc6f059SAlex Hornung  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
27*2bc6f059SAlex Hornung  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28*2bc6f059SAlex Hornung  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29*2bc6f059SAlex Hornung  * POSSIBILITY OF SUCH DAMAGE.
30*2bc6f059SAlex Hornung  */
31*2bc6f059SAlex Hornung 
32*2bc6f059SAlex Hornung 
33*2bc6f059SAlex Hornung #include <sys/ioctl.h>
34*2bc6f059SAlex Hornung #include <sys/types.h>
35*2bc6f059SAlex Hornung #include <sys/sysctl.h>
36*2bc6f059SAlex Hornung 
37*2bc6f059SAlex Hornung #include <err.h>
38*2bc6f059SAlex Hornung #include <errno.h>
39*2bc6f059SAlex Hornung 
40*2bc6f059SAlex Hornung #include <stdio.h>
41*2bc6f059SAlex Hornung #include <stdlib.h>
42*2bc6f059SAlex Hornung #include <unistd.h>
43*2bc6f059SAlex Hornung #include <sys/types.h>
44*2bc6f059SAlex Hornung #include <sys/stat.h>
45*2bc6f059SAlex Hornung 
46*2bc6f059SAlex Hornung #include <dev/disk/dm/netbsd-dm.h> /* XXX */
47*2bc6f059SAlex Hornung 
48*2bc6f059SAlex Hornung #include <dm-ioctl.h>
49*2bc6f059SAlex Hornung 
50*2bc6f059SAlex Hornung #include "lib.h"
51*2bc6f059SAlex Hornung #include "libdm-netbsd.h"
52*2bc6f059SAlex Hornung 
53*2bc6f059SAlex Hornung #define DMI_SIZE 16 * 1024
54*2bc6f059SAlex Hornung 
55*2bc6f059SAlex Hornung static int dm_list_versions(prop_dictionary_t, struct dm_ioctl *);
56*2bc6f059SAlex Hornung static int dm_list_devices(prop_dictionary_t, struct dm_ioctl *);
57*2bc6f059SAlex Hornung static int dm_dev_deps(prop_dictionary_t, struct dm_ioctl *);
58*2bc6f059SAlex Hornung static int dm_table_status(prop_dictionary_t, struct dm_ioctl *);
59*2bc6f059SAlex Hornung 
60*2bc6f059SAlex Hornung int
61*2bc6f059SAlex Hornung nbsd_get_dm_major(uint32_t *major,  int type)
62*2bc6f059SAlex Hornung {
63*2bc6f059SAlex Hornung 	struct stat sb;
64*2bc6f059SAlex Hornung 	if (stat("/dev/mapper/control", &sb) < 0) {
65*2bc6f059SAlex Hornung 		printf("stat failed");
66*2bc6f059SAlex Hornung 		return 0;
67*2bc6f059SAlex Hornung 	}
68*2bc6f059SAlex Hornung 	*major = major(sb.st_dev);
69*2bc6f059SAlex Hornung 
70*2bc6f059SAlex Hornung 	return 1;
71*2bc6f059SAlex Hornung }
72*2bc6f059SAlex Hornung 
73*2bc6f059SAlex Hornung int
74*2bc6f059SAlex Hornung nbsd_dmi_add_version(const int *version, prop_dictionary_t dm_dict)
75*2bc6f059SAlex Hornung {
76*2bc6f059SAlex Hornung 	prop_array_t ver;
77*2bc6f059SAlex Hornung 	size_t i;
78*2bc6f059SAlex Hornung 
79*2bc6f059SAlex Hornung 	if ((ver = prop_array_create()) == NULL)
80*2bc6f059SAlex Hornung 		return -1;
81*2bc6f059SAlex Hornung 
82*2bc6f059SAlex Hornung        	for (i=0;i<3;i++)
83*2bc6f059SAlex Hornung 		prop_array_set_uint32(ver,i,version[i]);
84*2bc6f059SAlex Hornung 
85*2bc6f059SAlex Hornung 	if ((prop_dictionary_set(dm_dict,"version",ver)) == false)
86*2bc6f059SAlex Hornung 		return -1;
87*2bc6f059SAlex Hornung 
88*2bc6f059SAlex Hornung 	prop_object_release(ver);
89*2bc6f059SAlex Hornung 
90*2bc6f059SAlex Hornung 	return 0;
91*2bc6f059SAlex Hornung }
92*2bc6f059SAlex Hornung 
93*2bc6f059SAlex Hornung struct dm_ioctl*
94*2bc6f059SAlex Hornung nbsd_dm_dict_to_dmi(prop_dictionary_t dm_dict,const int cmd)
95*2bc6f059SAlex Hornung {
96*2bc6f059SAlex Hornung 	struct dm_ioctl *dmi;
97*2bc6f059SAlex Hornung 	prop_array_t ver;
98*2bc6f059SAlex Hornung 
99*2bc6f059SAlex Hornung 	size_t i;
100*2bc6f059SAlex Hornung 	int r;
101*2bc6f059SAlex Hornung 	char *name, *uuid;
102*2bc6f059SAlex Hornung 	uint32_t major,minor;
103*2bc6f059SAlex Hornung 
104*2bc6f059SAlex Hornung 	name = NULL;
105*2bc6f059SAlex Hornung 	uuid = NULL;
106*2bc6f059SAlex Hornung 	minor = 0;
107*2bc6f059SAlex Hornung 
108*2bc6f059SAlex Hornung 	nbsd_get_dm_major(&major, DM_BLOCK_MAJOR);
109*2bc6f059SAlex Hornung 
110*2bc6f059SAlex Hornung 	if (!(dmi = dm_malloc(DMI_SIZE)))
111*2bc6f059SAlex Hornung 		return NULL;
112*2bc6f059SAlex Hornung 
113*2bc6f059SAlex Hornung 	memset(dmi,0,DMI_SIZE);
114*2bc6f059SAlex Hornung 
115*2bc6f059SAlex Hornung 	prop_dictionary_get_int32(dm_dict, DM_IOCTL_OPEN, &dmi->open_count);
116*2bc6f059SAlex Hornung 	prop_dictionary_get_uint32(dm_dict, DM_IOCTL_EVENT, &dmi->event_nr);
117*2bc6f059SAlex Hornung 	prop_dictionary_get_uint32(dm_dict, DM_IOCTL_FLAGS, &dmi->flags);
118*2bc6f059SAlex Hornung 	prop_dictionary_get_uint32(dm_dict, DM_IOCTL_TARGET_COUNT,
119*2bc6f059SAlex Hornung 		&dmi->target_count);
120*2bc6f059SAlex Hornung 
121*2bc6f059SAlex Hornung 	if (prop_dictionary_get_uint32(dm_dict, DM_IOCTL_MINOR, &minor))
122*2bc6f059SAlex Hornung 		dmi->dev = MKDEV(major, minor);
123*2bc6f059SAlex Hornung 	else
124*2bc6f059SAlex Hornung 		dmi->dev = 0;
125*2bc6f059SAlex Hornung 
126*2bc6f059SAlex Hornung 	/* Copy name and uuid to dm_ioctl. */
127*2bc6f059SAlex Hornung 	if (prop_dictionary_get_cstring_nocopy(dm_dict, DM_IOCTL_NAME,
128*2bc6f059SAlex Hornung 		(const char **)&name)){
129*2bc6f059SAlex Hornung 		strlcpy(dmi->name, name, DM_NAME_LEN);
130*2bc6f059SAlex Hornung 	} else
131*2bc6f059SAlex Hornung 		dmi->name[0] = '\0';
132*2bc6f059SAlex Hornung 
133*2bc6f059SAlex Hornung 	if (prop_dictionary_get_cstring_nocopy(dm_dict, DM_IOCTL_UUID,
134*2bc6f059SAlex Hornung 		(const char **)&uuid)){
135*2bc6f059SAlex Hornung 		strlcpy(dmi->uuid, uuid, DM_UUID_LEN);
136*2bc6f059SAlex Hornung 	}  else
137*2bc6f059SAlex Hornung 		dmi->uuid[0] = '\0';
138*2bc6f059SAlex Hornung 
139*2bc6f059SAlex Hornung 	/* dmi parsing values, size of dmi block and offset to data. */
140*2bc6f059SAlex Hornung 	dmi->data_size  = DMI_SIZE;
141*2bc6f059SAlex Hornung 	dmi->data_start = sizeof(struct dm_ioctl);
142*2bc6f059SAlex Hornung 
143*2bc6f059SAlex Hornung 	/* Get kernel version from dm_dict. */
144*2bc6f059SAlex Hornung 	ver = prop_dictionary_get(dm_dict,DM_IOCTL_VERSION);
145*2bc6f059SAlex Hornung 
146*2bc6f059SAlex Hornung 	for(i=0; i<3; i++)
147*2bc6f059SAlex Hornung 		prop_array_get_uint32(ver,i,&dmi->version[i]);
148*2bc6f059SAlex Hornung 
149*2bc6f059SAlex Hornung 	switch (cmd){
150*2bc6f059SAlex Hornung 
151*2bc6f059SAlex Hornung 	case DM_LIST_VERSIONS:
152*2bc6f059SAlex Hornung 		r = dm_list_versions(dm_dict,dmi);
153*2bc6f059SAlex Hornung 		if (r >= 0)
154*2bc6f059SAlex Hornung 			dmi->target_count = r;
155*2bc6f059SAlex Hornung 		break;
156*2bc6f059SAlex Hornung 
157*2bc6f059SAlex Hornung 	case DM_LIST_DEVICES:
158*2bc6f059SAlex Hornung 		r = dm_list_devices(dm_dict,dmi);
159*2bc6f059SAlex Hornung 		if (r >= 0)
160*2bc6f059SAlex Hornung 			dmi->target_count = r;
161*2bc6f059SAlex Hornung 		break;
162*2bc6f059SAlex Hornung 
163*2bc6f059SAlex Hornung 	case DM_TABLE_STATUS:
164*2bc6f059SAlex Hornung 		r = dm_table_status(dm_dict,dmi);
165*2bc6f059SAlex Hornung 		if (r >= 0)
166*2bc6f059SAlex Hornung 			dmi->target_count = r;
167*2bc6f059SAlex Hornung 		break;
168*2bc6f059SAlex Hornung 
169*2bc6f059SAlex Hornung 	case DM_TABLE_DEPS:
170*2bc6f059SAlex Hornung 		r = dm_dev_deps(dm_dict,dmi);
171*2bc6f059SAlex Hornung 		if (r >= 0)
172*2bc6f059SAlex Hornung 			dmi->target_count = r;
173*2bc6f059SAlex Hornung 		break;
174*2bc6f059SAlex Hornung 	}
175*2bc6f059SAlex Hornung 
176*2bc6f059SAlex Hornung 	return dmi;
177*2bc6f059SAlex Hornung }
178*2bc6f059SAlex Hornung 
179*2bc6f059SAlex Hornung /*
180*2bc6f059SAlex Hornung  * Parse dm_dict when targets command was called and fill dm_ioctl buffer with it.
181*2bc6f059SAlex Hornung  *
182*2bc6f059SAlex Hornung  * Return number of targets or if failed <0 error.
183*2bc6f059SAlex Hornung  */
184*2bc6f059SAlex Hornung 
185*2bc6f059SAlex Hornung static int
186*2bc6f059SAlex Hornung dm_list_versions(prop_dictionary_t dm_dict, struct dm_ioctl *dmi)
187*2bc6f059SAlex Hornung {
188*2bc6f059SAlex Hornung 	struct dm_target_versions *dmtv,*odmtv;
189*2bc6f059SAlex Hornung 
190*2bc6f059SAlex Hornung 	prop_array_t targets,ver;
191*2bc6f059SAlex Hornung 	prop_dictionary_t target_dict;
192*2bc6f059SAlex Hornung 	prop_object_iterator_t iter;
193*2bc6f059SAlex Hornung 
194*2bc6f059SAlex Hornung 	char *name;
195*2bc6f059SAlex Hornung 	size_t j,i,slen,rec_size;
196*2bc6f059SAlex Hornung 
197*2bc6f059SAlex Hornung 	odmtv = NULL;
198*2bc6f059SAlex Hornung 	name = NULL;
199*2bc6f059SAlex Hornung 	j = 0;
200*2bc6f059SAlex Hornung 
201*2bc6f059SAlex Hornung 	dmtv = (struct dm_target_versions *)((uint8_t *)dmi + dmi->data_start);
202*2bc6f059SAlex Hornung 
203*2bc6f059SAlex Hornung /*	printf("dmi: vers: %d.%d.%d data_size: %d data_start: %d name: %s t_count: %d\n",
204*2bc6f059SAlex Hornung 	    dmi->version[0],dmi->version[1],dmi->version[2],dmi->data_size,dmi->data_start,
205*2bc6f059SAlex Hornung 	    dmi->name,dmi->target_count);
206*2bc6f059SAlex Hornung 
207*2bc6f059SAlex Hornung 	printf("dmi: size: %d -- %p --- %p \n",sizeof(struct dm_ioctl),dmi,dmi+dmi->data_start);
208*2bc6f059SAlex Hornung 	printf("dmtv: size: %p --- %p\n",dmtv,(struct dm_target_versions *)(dmi+312));*/
209*2bc6f059SAlex Hornung 
210*2bc6f059SAlex Hornung 	/* get prop_array of target_version dictionaries */
211*2bc6f059SAlex Hornung 	if ((targets = prop_dictionary_get(dm_dict,DM_IOCTL_CMD_DATA))){
212*2bc6f059SAlex Hornung 
213*2bc6f059SAlex Hornung 		iter = prop_array_iterator(targets);
214*2bc6f059SAlex Hornung 		if (!iter)
215*2bc6f059SAlex Hornung 			err(EXIT_FAILURE,"dm_list_versions %s",__func__);
216*2bc6f059SAlex Hornung 
217*2bc6f059SAlex Hornung 		while((target_dict = prop_object_iterator_next(iter)) != NULL){
218*2bc6f059SAlex Hornung 			j++;
219*2bc6f059SAlex Hornung 
220*2bc6f059SAlex Hornung 			prop_dictionary_get_cstring_nocopy(target_dict,
221*2bc6f059SAlex Hornung 			    DM_TARGETS_NAME,(const char **)&name);
222*2bc6f059SAlex Hornung 
223*2bc6f059SAlex Hornung 			slen = strlen(name) + 1;
224*2bc6f059SAlex Hornung 			rec_size = sizeof(struct dm_target_versions) + slen + 1;
225*2bc6f059SAlex Hornung 
226*2bc6f059SAlex Hornung 			if (rec_size > dmi->data_size)
227*2bc6f059SAlex Hornung 				return -ENOMEM;
228*2bc6f059SAlex Hornung 
229*2bc6f059SAlex Hornung 			ver = prop_dictionary_get(target_dict,DM_TARGETS_VERSION);
230*2bc6f059SAlex Hornung 
231*2bc6f059SAlex Hornung 			for (i=0; i<3; i++)
232*2bc6f059SAlex Hornung 				prop_array_get_uint32(ver,i,&dmtv->version[i]);
233*2bc6f059SAlex Hornung 
234*2bc6f059SAlex Hornung 			dmtv->next = rec_size;
235*2bc6f059SAlex Hornung 
236*2bc6f059SAlex Hornung 			strlcpy(dmtv->name,name,slen);
237*2bc6f059SAlex Hornung 
238*2bc6f059SAlex Hornung 			odmtv = dmtv;
239*2bc6f059SAlex Hornung 
240*2bc6f059SAlex Hornung 			dmtv =(struct dm_target_versions *)((uint8_t *)dmtv + rec_size);
241*2bc6f059SAlex Hornung 		}
242*2bc6f059SAlex Hornung 
243*2bc6f059SAlex Hornung 		if (odmtv != NULL)
244*2bc6f059SAlex Hornung 			odmtv->next = 0;
245*2bc6f059SAlex Hornung 	}
246*2bc6f059SAlex Hornung 
247*2bc6f059SAlex Hornung 	prop_object_iterator_release(iter);
248*2bc6f059SAlex Hornung 	return j;
249*2bc6f059SAlex Hornung }
250*2bc6f059SAlex Hornung 
251*2bc6f059SAlex Hornung /*
252*2bc6f059SAlex Hornung  * List all available dm devices in system.
253*2bc6f059SAlex Hornung  */
254*2bc6f059SAlex Hornung static int
255*2bc6f059SAlex Hornung dm_list_devices(prop_dictionary_t dm_dict, struct dm_ioctl *dmi)
256*2bc6f059SAlex Hornung {
257*2bc6f059SAlex Hornung 	struct dm_name_list *dml,*odml;
258*2bc6f059SAlex Hornung 
259*2bc6f059SAlex Hornung 	prop_array_t targets;
260*2bc6f059SAlex Hornung 	prop_dictionary_t target_dict;
261*2bc6f059SAlex Hornung 	prop_object_iterator_t iter;
262*2bc6f059SAlex Hornung 
263*2bc6f059SAlex Hornung 	uint32_t minor;
264*2bc6f059SAlex Hornung 	uint32_t major;
265*2bc6f059SAlex Hornung 
266*2bc6f059SAlex Hornung 	char *name;
267*2bc6f059SAlex Hornung 	size_t j,slen,rec_size;
268*2bc6f059SAlex Hornung 
269*2bc6f059SAlex Hornung 	odml = NULL;
270*2bc6f059SAlex Hornung 	name = NULL;
271*2bc6f059SAlex Hornung 	minor = 0;
272*2bc6f059SAlex Hornung 	j = 0;
273*2bc6f059SAlex Hornung 
274*2bc6f059SAlex Hornung 	nbsd_get_dm_major(&major,DM_BLOCK_MAJOR);
275*2bc6f059SAlex Hornung 
276*2bc6f059SAlex Hornung 	dml = (struct dm_name_list *)((uint8_t *)dmi + dmi->data_start);
277*2bc6f059SAlex Hornung 
278*2bc6f059SAlex Hornung 	if ((targets = prop_dictionary_get(dm_dict,DM_IOCTL_CMD_DATA))){
279*2bc6f059SAlex Hornung 
280*2bc6f059SAlex Hornung 		iter = prop_array_iterator(targets);
281*2bc6f059SAlex Hornung 		if (!iter)
282*2bc6f059SAlex Hornung 			err(EXIT_FAILURE,"dm_list_devices %s",__func__);
283*2bc6f059SAlex Hornung 
284*2bc6f059SAlex Hornung 		while((target_dict = prop_object_iterator_next(iter)) != NULL){
285*2bc6f059SAlex Hornung 
286*2bc6f059SAlex Hornung 			prop_dictionary_get_cstring_nocopy(target_dict,
287*2bc6f059SAlex Hornung 			    DM_DEV_NAME,(const char **)&name);
288*2bc6f059SAlex Hornung 
289*2bc6f059SAlex Hornung 			prop_dictionary_get_uint32(target_dict,DM_DEV_DEV,&minor);
290*2bc6f059SAlex Hornung 
291*2bc6f059SAlex Hornung 			dml->dev = MKDEV(major,minor);
292*2bc6f059SAlex Hornung 
293*2bc6f059SAlex Hornung 			slen = strlen(name) + 1;
294*2bc6f059SAlex Hornung 			rec_size = sizeof(struct dm_name_list) + slen + 1;
295*2bc6f059SAlex Hornung 
296*2bc6f059SAlex Hornung 			if (rec_size > dmi->data_size)
297*2bc6f059SAlex Hornung 				return -ENOMEM;
298*2bc6f059SAlex Hornung 
299*2bc6f059SAlex Hornung 			dml->next = rec_size;
300*2bc6f059SAlex Hornung 
301*2bc6f059SAlex Hornung 			strlcpy(dml->name,name,slen);
302*2bc6f059SAlex Hornung 
303*2bc6f059SAlex Hornung 			odml = dml;
304*2bc6f059SAlex Hornung 
305*2bc6f059SAlex Hornung 			dml =(struct dm_name_list *)((uint8_t *)dml + rec_size);
306*2bc6f059SAlex Hornung 
307*2bc6f059SAlex Hornung 			j++;
308*2bc6f059SAlex Hornung 		}
309*2bc6f059SAlex Hornung 
310*2bc6f059SAlex Hornung 		if (odml != NULL)
311*2bc6f059SAlex Hornung 			odml->next = 0;
312*2bc6f059SAlex Hornung 	}
313*2bc6f059SAlex Hornung 	prop_object_iterator_release(iter);
314*2bc6f059SAlex Hornung 	return j;
315*2bc6f059SAlex Hornung }
316*2bc6f059SAlex Hornung 
317*2bc6f059SAlex Hornung /*
318*2bc6f059SAlex Hornung  * Print status of each table, target arguments, start sector,
319*2bc6f059SAlex Hornung  * size and target name.
320*2bc6f059SAlex Hornung  */
321*2bc6f059SAlex Hornung static int
322*2bc6f059SAlex Hornung dm_table_status(prop_dictionary_t dm_dict,struct dm_ioctl *dmi)
323*2bc6f059SAlex Hornung {
324*2bc6f059SAlex Hornung 	struct dm_target_spec *dmts, *odmts;
325*2bc6f059SAlex Hornung 
326*2bc6f059SAlex Hornung 	prop_array_t targets;
327*2bc6f059SAlex Hornung 	prop_dictionary_t target_dict;
328*2bc6f059SAlex Hornung 	prop_object_iterator_t iter;
329*2bc6f059SAlex Hornung 
330*2bc6f059SAlex Hornung 	char *type,*params,*params_start;
331*2bc6f059SAlex Hornung 
332*2bc6f059SAlex Hornung 	bool prm;
333*2bc6f059SAlex Hornung 	size_t j,plen,rec_size,next;
334*2bc6f059SAlex Hornung 
335*2bc6f059SAlex Hornung 	j = 0;
336*2bc6f059SAlex Hornung 	next = 0;
337*2bc6f059SAlex Hornung 	params = NULL;
338*2bc6f059SAlex Hornung 	odmts = NULL;
339*2bc6f059SAlex Hornung 	rec_size = 0;
340*2bc6f059SAlex Hornung 	plen = -1;
341*2bc6f059SAlex Hornung 	prm = false;
342*2bc6f059SAlex Hornung 
343*2bc6f059SAlex Hornung 	dmts = (struct dm_target_spec *)((uint8_t *)dmi + dmi->data_start);
344*2bc6f059SAlex Hornung 
345*2bc6f059SAlex Hornung 	if ((targets = prop_dictionary_get(dm_dict,DM_IOCTL_CMD_DATA))){
346*2bc6f059SAlex Hornung 
347*2bc6f059SAlex Hornung 		iter = prop_array_iterator(targets);
348*2bc6f059SAlex Hornung 		if (!iter)
349*2bc6f059SAlex Hornung 			err(EXIT_FAILURE,"dm_table_status %s",__func__);
350*2bc6f059SAlex Hornung 
351*2bc6f059SAlex Hornung 		while((target_dict = prop_object_iterator_next(iter)) != NULL){
352*2bc6f059SAlex Hornung 
353*2bc6f059SAlex Hornung 			prop_dictionary_get_cstring_nocopy(target_dict,
354*2bc6f059SAlex Hornung 			    DM_TABLE_TYPE,(const char **)&type);
355*2bc6f059SAlex Hornung 
356*2bc6f059SAlex Hornung 			prm = prop_dictionary_get_cstring_nocopy(target_dict,
357*2bc6f059SAlex Hornung 			    DM_TABLE_PARAMS,(const char **)&params);
358*2bc6f059SAlex Hornung 
359*2bc6f059SAlex Hornung 			prop_dictionary_get_uint64(target_dict,DM_TABLE_START,&dmts->sector_start);
360*2bc6f059SAlex Hornung 			prop_dictionary_get_uint64(target_dict,DM_TABLE_LENGTH,&dmts->length);
361*2bc6f059SAlex Hornung 			prop_dictionary_get_int32(target_dict,DM_TABLE_STAT,&dmts->status);
362*2bc6f059SAlex Hornung 
363*2bc6f059SAlex Hornung 			if (prm)
364*2bc6f059SAlex Hornung 				plen = strlen(params) + 1;
365*2bc6f059SAlex Hornung 
366*2bc6f059SAlex Hornung 			rec_size = sizeof(struct dm_target_spec) + plen;
367*2bc6f059SAlex Hornung 
368*2bc6f059SAlex Hornung 			/*
369*2bc6f059SAlex Hornung 			 * In linux when copying table status from kernel next is
370*2bc6f059SAlex Hornung 			 * number of bytes from the start of the first dm_target_spec
371*2bc6f059SAlex Hornung 			 * structure. I don't know why but, it has to be done this way.
372*2bc6f059SAlex Hornung 			 */
373*2bc6f059SAlex Hornung 			next += rec_size;
374*2bc6f059SAlex Hornung 
375*2bc6f059SAlex Hornung 			if (rec_size > dmi->data_size)
376*2bc6f059SAlex Hornung 				return -ENOMEM;
377*2bc6f059SAlex Hornung 
378*2bc6f059SAlex Hornung 			dmts->next = next;
379*2bc6f059SAlex Hornung 
380*2bc6f059SAlex Hornung 			strlcpy(dmts->target_type, type, DM_MAX_TYPE_NAME);
381*2bc6f059SAlex Hornung 
382*2bc6f059SAlex Hornung 			params_start = (char *)dmts + sizeof(struct dm_target_spec);
383*2bc6f059SAlex Hornung 
384*2bc6f059SAlex Hornung 			if (prm)
385*2bc6f059SAlex Hornung 				strlcpy(params_start, params, plen);
386*2bc6f059SAlex Hornung 			else
387*2bc6f059SAlex Hornung 				params_start = "\0";
388*2bc6f059SAlex Hornung 
389*2bc6f059SAlex Hornung 
390*2bc6f059SAlex Hornung 			odmts = dmts;
391*2bc6f059SAlex Hornung 
392*2bc6f059SAlex Hornung 			dmts = (struct dm_target_spec *)((uint8_t *)dmts + rec_size);
393*2bc6f059SAlex Hornung 
394*2bc6f059SAlex Hornung 			j++;
395*2bc6f059SAlex Hornung 
396*2bc6f059SAlex Hornung 		}
397*2bc6f059SAlex Hornung 
398*2bc6f059SAlex Hornung 		if (odmts != NULL)
399*2bc6f059SAlex Hornung 			odmts->next = 0;
400*2bc6f059SAlex Hornung 	}
401*2bc6f059SAlex Hornung 	prop_object_iterator_release(iter);
402*2bc6f059SAlex Hornung 
403*2bc6f059SAlex Hornung 	return j;
404*2bc6f059SAlex Hornung }
405*2bc6f059SAlex Hornung 
406*2bc6f059SAlex Hornung /*
407*2bc6f059SAlex Hornung  * Print dm device dependiences, get minor/major number for
408*2bc6f059SAlex Hornung  * devices. From kernel I will receive major:minor number of
409*2bc6f059SAlex Hornung  * block device used with target. I have to translate it to
410*2bc6f059SAlex Hornung  * raw device numbers and use them, because all other parts of lvm2
411*2bc6f059SAlex Hornung  * uses raw devices internaly.
412*2bc6f059SAlex Hornung  */
413*2bc6f059SAlex Hornung static int
414*2bc6f059SAlex Hornung dm_dev_deps(prop_dictionary_t dm_dict, struct dm_ioctl *dmi)
415*2bc6f059SAlex Hornung {
416*2bc6f059SAlex Hornung 	struct dm_target_deps *dmtd;
417*2bc6f059SAlex Hornung 
418*2bc6f059SAlex Hornung 	prop_array_t targets;
419*2bc6f059SAlex Hornung 	prop_object_iterator_t iter;
420*2bc6f059SAlex Hornung 
421*2bc6f059SAlex Hornung 	uint32_t major;
422*2bc6f059SAlex Hornung 
423*2bc6f059SAlex Hornung 	size_t val_len, i, j;
424*2bc6f059SAlex Hornung 
425*2bc6f059SAlex Hornung 	uint64_t dev_tmp;
426*2bc6f059SAlex Hornung 
427*2bc6f059SAlex Hornung 	dev_tmp = 0;
428*2bc6f059SAlex Hornung 	j = 0;
429*2bc6f059SAlex Hornung 	i = 0;
430*2bc6f059SAlex Hornung 
431*2bc6f059SAlex Hornung 
432*2bc6f059SAlex Hornung 	dmtd = (struct dm_target_deps *)((uint8_t *)dmi + dmi->data_start);
433*2bc6f059SAlex Hornung 
434*2bc6f059SAlex Hornung 	if ((targets = prop_dictionary_get(dm_dict, DM_IOCTL_CMD_DATA))){
435*2bc6f059SAlex Hornung 
436*2bc6f059SAlex Hornung 		iter = prop_array_iterator(targets);
437*2bc6f059SAlex Hornung 		if (!iter)
438*2bc6f059SAlex Hornung 			err(EXIT_FAILURE,"dm_target_deps %s", __func__);
439*2bc6f059SAlex Hornung 
440*2bc6f059SAlex Hornung 		while((prop_object_iterator_next(iter)) != NULL){
441*2bc6f059SAlex Hornung 
442*2bc6f059SAlex Hornung 			prop_array_get_uint64(targets, j, &dev_tmp);
443*2bc6f059SAlex Hornung 
444*2bc6f059SAlex Hornung 			dmtd->dev[j] = MKDEV(MAJOR(dev_tmp),MINOR(dev_tmp));
445*2bc6f059SAlex Hornung 			/* XXX: worth revisiting */
446*2bc6f059SAlex Hornung 			j++;
447*2bc6f059SAlex Hornung 		}
448*2bc6f059SAlex Hornung 	}
449*2bc6f059SAlex Hornung 
450*2bc6f059SAlex Hornung 	dmtd->count = j;
451*2bc6f059SAlex Hornung 
452*2bc6f059SAlex Hornung 	prop_object_iterator_release(iter);
453*2bc6f059SAlex Hornung 
454*2bc6f059SAlex Hornung 	return j;
455*2bc6f059SAlex Hornung }
456