xref: /dflybsd-src/contrib/lvm2/dist/libdm/ioctl/libdm_dragonfly.c (revision d38cb10e387181997baac510409dbfb95af059f7)
12bc6f059SAlex Hornung /*      $NetBSD: libdm_netbsd.c,v 1.5 2009/12/05 11:42:24 haad Exp $        */
22bc6f059SAlex Hornung 
32bc6f059SAlex Hornung /*
42bc6f059SAlex Hornung  * Copyright (c) 1996, 1997, 1998, 1999, 2002 The NetBSD Foundation, Inc.
52bc6f059SAlex Hornung  * All rights reserved.
62bc6f059SAlex Hornung  *
72bc6f059SAlex Hornung  * This code is derived from software contributed to The NetBSD Foundation
82bc6f059SAlex Hornung  * by Adam Hamsik.
92bc6f059SAlex Hornung  *
102bc6f059SAlex Hornung  * Redistribution and use in source and binary forms, with or without
112bc6f059SAlex Hornung  * modification, are permitted provided that the following conditions
122bc6f059SAlex Hornung  * are met:
132bc6f059SAlex Hornung  * 1. Redistributions of source code must retain the above copyright
142bc6f059SAlex Hornung  *    notice, this list of conditions and the following disclaimer.
152bc6f059SAlex Hornung  * 2. Redistributions in binary form must reproduce the above copyright
162bc6f059SAlex Hornung  *    notice, this list of conditions and the following disclaimer in the
172bc6f059SAlex Hornung  *    documentation and/or other materials provided with the distribution.
182bc6f059SAlex Hornung  *
192bc6f059SAlex Hornung  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
202bc6f059SAlex Hornung  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
212bc6f059SAlex Hornung  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
222bc6f059SAlex Hornung  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
232bc6f059SAlex Hornung  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
242bc6f059SAlex Hornung  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
252bc6f059SAlex Hornung  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
262bc6f059SAlex Hornung  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
272bc6f059SAlex Hornung  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
282bc6f059SAlex Hornung  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
292bc6f059SAlex Hornung  * POSSIBILITY OF SUCH DAMAGE.
302bc6f059SAlex Hornung  */
312bc6f059SAlex Hornung 
322bc6f059SAlex Hornung 
332bc6f059SAlex Hornung #include <sys/ioctl.h>
342bc6f059SAlex Hornung #include <sys/types.h>
352bc6f059SAlex Hornung #include <sys/sysctl.h>
362bc6f059SAlex Hornung 
372bc6f059SAlex Hornung #include <err.h>
382bc6f059SAlex Hornung #include <errno.h>
392bc6f059SAlex Hornung 
402bc6f059SAlex Hornung #include <stdio.h>
412bc6f059SAlex Hornung #include <stdlib.h>
422bc6f059SAlex Hornung #include <unistd.h>
432bc6f059SAlex Hornung #include <sys/types.h>
442bc6f059SAlex Hornung #include <sys/stat.h>
452bc6f059SAlex Hornung 
462bc6f059SAlex Hornung #include <dev/disk/dm/netbsd-dm.h> /* XXX */
472bc6f059SAlex Hornung 
482bc6f059SAlex Hornung #include <dm-ioctl.h>
492bc6f059SAlex Hornung 
502bc6f059SAlex Hornung #include "lib.h"
512bc6f059SAlex Hornung #include "libdm-netbsd.h"
522bc6f059SAlex Hornung 
532bc6f059SAlex Hornung #define DMI_SIZE 16 * 1024
542bc6f059SAlex Hornung 
552bc6f059SAlex Hornung static int dm_list_versions(prop_dictionary_t, struct dm_ioctl *);
562bc6f059SAlex Hornung static int dm_list_devices(prop_dictionary_t, struct dm_ioctl *);
572bc6f059SAlex Hornung static int dm_dev_deps(prop_dictionary_t, struct dm_ioctl *);
582bc6f059SAlex Hornung static int dm_table_status(prop_dictionary_t, struct dm_ioctl *);
592bc6f059SAlex Hornung 
602bc6f059SAlex Hornung int
nbsd_get_dm_major(uint32_t * major,int type)612bc6f059SAlex Hornung nbsd_get_dm_major(uint32_t *major,  int type)
622bc6f059SAlex Hornung {
632bc6f059SAlex Hornung 	struct stat sb;
642bc6f059SAlex Hornung 	if (stat("/dev/mapper/control", &sb) < 0) {
65*d38cb10eSTomohiro Kusumi 		printf("stat failed\n");
662bc6f059SAlex Hornung 		return 0;
672bc6f059SAlex Hornung 	}
682bc6f059SAlex Hornung 	*major = major(sb.st_dev);
692bc6f059SAlex Hornung 
702bc6f059SAlex Hornung 	return 1;
712bc6f059SAlex Hornung }
722bc6f059SAlex Hornung 
732bc6f059SAlex Hornung int
nbsd_dmi_add_version(const int * version,prop_dictionary_t dm_dict)742bc6f059SAlex Hornung nbsd_dmi_add_version(const int *version, prop_dictionary_t dm_dict)
752bc6f059SAlex Hornung {
762bc6f059SAlex Hornung 	prop_array_t ver;
772bc6f059SAlex Hornung 	size_t i;
782bc6f059SAlex Hornung 
792bc6f059SAlex Hornung 	if ((ver = prop_array_create()) == NULL)
802bc6f059SAlex Hornung 		return -1;
812bc6f059SAlex Hornung 
822bc6f059SAlex Hornung        	for (i=0;i<3;i++)
832bc6f059SAlex Hornung 		prop_array_set_uint32(ver,i,version[i]);
842bc6f059SAlex Hornung 
852bc6f059SAlex Hornung 	if ((prop_dictionary_set(dm_dict,"version",ver)) == false)
862bc6f059SAlex Hornung 		return -1;
872bc6f059SAlex Hornung 
882bc6f059SAlex Hornung 	prop_object_release(ver);
892bc6f059SAlex Hornung 
902bc6f059SAlex Hornung 	return 0;
912bc6f059SAlex Hornung }
922bc6f059SAlex Hornung 
932bc6f059SAlex Hornung struct dm_ioctl*
nbsd_dm_dict_to_dmi(prop_dictionary_t dm_dict,const int cmd)942bc6f059SAlex Hornung nbsd_dm_dict_to_dmi(prop_dictionary_t dm_dict,const int cmd)
952bc6f059SAlex Hornung {
962bc6f059SAlex Hornung 	struct dm_ioctl *dmi;
972bc6f059SAlex Hornung 	prop_array_t ver;
982bc6f059SAlex Hornung 
992bc6f059SAlex Hornung 	size_t i;
1002bc6f059SAlex Hornung 	int r;
1012bc6f059SAlex Hornung 	char *name, *uuid;
1022bc6f059SAlex Hornung 	uint32_t major,minor;
1032bc6f059SAlex Hornung 
1042bc6f059SAlex Hornung 	name = NULL;
1052bc6f059SAlex Hornung 	uuid = NULL;
1062bc6f059SAlex Hornung 	minor = 0;
1072bc6f059SAlex Hornung 
1082bc6f059SAlex Hornung 	nbsd_get_dm_major(&major, DM_BLOCK_MAJOR);
1092bc6f059SAlex Hornung 
1102bc6f059SAlex Hornung 	if (!(dmi = dm_malloc(DMI_SIZE)))
1112bc6f059SAlex Hornung 		return NULL;
1122bc6f059SAlex Hornung 
1132bc6f059SAlex Hornung 	memset(dmi,0,DMI_SIZE);
1142bc6f059SAlex Hornung 
1152bc6f059SAlex Hornung 	prop_dictionary_get_int32(dm_dict, DM_IOCTL_OPEN, &dmi->open_count);
1162bc6f059SAlex Hornung 	prop_dictionary_get_uint32(dm_dict, DM_IOCTL_EVENT, &dmi->event_nr);
1172bc6f059SAlex Hornung 	prop_dictionary_get_uint32(dm_dict, DM_IOCTL_FLAGS, &dmi->flags);
1182bc6f059SAlex Hornung 	prop_dictionary_get_uint32(dm_dict, DM_IOCTL_TARGET_COUNT,
1192bc6f059SAlex Hornung 		&dmi->target_count);
1202bc6f059SAlex Hornung 
1212bc6f059SAlex Hornung 	if (prop_dictionary_get_uint32(dm_dict, DM_IOCTL_MINOR, &minor))
1222bc6f059SAlex Hornung 		dmi->dev = MKDEV(major, minor);
1232bc6f059SAlex Hornung 	else
1242bc6f059SAlex Hornung 		dmi->dev = 0;
1252bc6f059SAlex Hornung 
1262bc6f059SAlex Hornung 	/* Copy name and uuid to dm_ioctl. */
1272bc6f059SAlex Hornung 	if (prop_dictionary_get_cstring_nocopy(dm_dict, DM_IOCTL_NAME,
1282bc6f059SAlex Hornung 		(const char **)&name)){
1292bc6f059SAlex Hornung 		strlcpy(dmi->name, name, DM_NAME_LEN);
1302bc6f059SAlex Hornung 	} else
1312bc6f059SAlex Hornung 		dmi->name[0] = '\0';
1322bc6f059SAlex Hornung 
1332bc6f059SAlex Hornung 	if (prop_dictionary_get_cstring_nocopy(dm_dict, DM_IOCTL_UUID,
1342bc6f059SAlex Hornung 		(const char **)&uuid)){
1352bc6f059SAlex Hornung 		strlcpy(dmi->uuid, uuid, DM_UUID_LEN);
1362bc6f059SAlex Hornung 	}  else
1372bc6f059SAlex Hornung 		dmi->uuid[0] = '\0';
1382bc6f059SAlex Hornung 
1392bc6f059SAlex Hornung 	/* dmi parsing values, size of dmi block and offset to data. */
1402bc6f059SAlex Hornung 	dmi->data_size  = DMI_SIZE;
1412bc6f059SAlex Hornung 	dmi->data_start = sizeof(struct dm_ioctl);
1422bc6f059SAlex Hornung 
1432bc6f059SAlex Hornung 	/* Get kernel version from dm_dict. */
1442bc6f059SAlex Hornung 	ver = prop_dictionary_get(dm_dict,DM_IOCTL_VERSION);
1452bc6f059SAlex Hornung 
1462bc6f059SAlex Hornung 	for(i=0; i<3; i++)
1472bc6f059SAlex Hornung 		prop_array_get_uint32(ver,i,&dmi->version[i]);
1482bc6f059SAlex Hornung 
1492bc6f059SAlex Hornung 	switch (cmd){
1502bc6f059SAlex Hornung 
1512bc6f059SAlex Hornung 	case DM_LIST_VERSIONS:
1522bc6f059SAlex Hornung 		r = dm_list_versions(dm_dict,dmi);
1532bc6f059SAlex Hornung 		if (r >= 0)
1542bc6f059SAlex Hornung 			dmi->target_count = r;
1552bc6f059SAlex Hornung 		break;
1562bc6f059SAlex Hornung 
1572bc6f059SAlex Hornung 	case DM_LIST_DEVICES:
1582bc6f059SAlex Hornung 		r = dm_list_devices(dm_dict,dmi);
1592bc6f059SAlex Hornung 		if (r >= 0)
1602bc6f059SAlex Hornung 			dmi->target_count = r;
1612bc6f059SAlex Hornung 		break;
1622bc6f059SAlex Hornung 
1632bc6f059SAlex Hornung 	case DM_TABLE_STATUS:
1642bc6f059SAlex Hornung 		r = dm_table_status(dm_dict,dmi);
1652bc6f059SAlex Hornung 		if (r >= 0)
1662bc6f059SAlex Hornung 			dmi->target_count = r;
1672bc6f059SAlex Hornung 		break;
1682bc6f059SAlex Hornung 
1692bc6f059SAlex Hornung 	case DM_TABLE_DEPS:
1702bc6f059SAlex Hornung 		r = dm_dev_deps(dm_dict,dmi);
1712bc6f059SAlex Hornung 		if (r >= 0)
1722bc6f059SAlex Hornung 			dmi->target_count = r;
1732bc6f059SAlex Hornung 		break;
1742bc6f059SAlex Hornung 	}
1752bc6f059SAlex Hornung 
1762bc6f059SAlex Hornung 	return dmi;
1772bc6f059SAlex Hornung }
1782bc6f059SAlex Hornung 
1792bc6f059SAlex Hornung /*
1802bc6f059SAlex Hornung  * Parse dm_dict when targets command was called and fill dm_ioctl buffer with it.
1812bc6f059SAlex Hornung  *
1822bc6f059SAlex Hornung  * Return number of targets or if failed <0 error.
1832bc6f059SAlex Hornung  */
1842bc6f059SAlex Hornung 
1852bc6f059SAlex Hornung static int
dm_list_versions(prop_dictionary_t dm_dict,struct dm_ioctl * dmi)1862bc6f059SAlex Hornung dm_list_versions(prop_dictionary_t dm_dict, struct dm_ioctl *dmi)
1872bc6f059SAlex Hornung {
1882bc6f059SAlex Hornung 	struct dm_target_versions *dmtv,*odmtv;
1892bc6f059SAlex Hornung 
1902bc6f059SAlex Hornung 	prop_array_t targets,ver;
1912bc6f059SAlex Hornung 	prop_dictionary_t target_dict;
1922bc6f059SAlex Hornung 	prop_object_iterator_t iter;
1932bc6f059SAlex Hornung 
1942bc6f059SAlex Hornung 	char *name;
1952bc6f059SAlex Hornung 	size_t j,i,slen,rec_size;
1962bc6f059SAlex Hornung 
1972bc6f059SAlex Hornung 	odmtv = NULL;
1982bc6f059SAlex Hornung 	name = NULL;
1992bc6f059SAlex Hornung 	j = 0;
2002bc6f059SAlex Hornung 
2012bc6f059SAlex Hornung 	dmtv = (struct dm_target_versions *)((uint8_t *)dmi + dmi->data_start);
2022bc6f059SAlex Hornung 
2032bc6f059SAlex Hornung /*	printf("dmi: vers: %d.%d.%d data_size: %d data_start: %d name: %s t_count: %d\n",
2042bc6f059SAlex Hornung 	    dmi->version[0],dmi->version[1],dmi->version[2],dmi->data_size,dmi->data_start,
2052bc6f059SAlex Hornung 	    dmi->name,dmi->target_count);
2062bc6f059SAlex Hornung 
2072bc6f059SAlex Hornung 	printf("dmi: size: %d -- %p --- %p \n",sizeof(struct dm_ioctl),dmi,dmi+dmi->data_start);
2082bc6f059SAlex Hornung 	printf("dmtv: size: %p --- %p\n",dmtv,(struct dm_target_versions *)(dmi+312));*/
2092bc6f059SAlex Hornung 
2102bc6f059SAlex Hornung 	/* get prop_array of target_version dictionaries */
2112bc6f059SAlex Hornung 	if ((targets = prop_dictionary_get(dm_dict,DM_IOCTL_CMD_DATA))){
2122bc6f059SAlex Hornung 
2132bc6f059SAlex Hornung 		iter = prop_array_iterator(targets);
2142bc6f059SAlex Hornung 		if (!iter)
2152bc6f059SAlex Hornung 			err(EXIT_FAILURE,"dm_list_versions %s",__func__);
2162bc6f059SAlex Hornung 
2172bc6f059SAlex Hornung 		while((target_dict = prop_object_iterator_next(iter)) != NULL){
2182bc6f059SAlex Hornung 			j++;
2192bc6f059SAlex Hornung 
2202bc6f059SAlex Hornung 			prop_dictionary_get_cstring_nocopy(target_dict,
2212bc6f059SAlex Hornung 			    DM_TARGETS_NAME,(const char **)&name);
2222bc6f059SAlex Hornung 
2232bc6f059SAlex Hornung 			slen = strlen(name) + 1;
2242bc6f059SAlex Hornung 			rec_size = sizeof(struct dm_target_versions) + slen + 1;
2252bc6f059SAlex Hornung 
2262bc6f059SAlex Hornung 			if (rec_size > dmi->data_size)
2272bc6f059SAlex Hornung 				return -ENOMEM;
2282bc6f059SAlex Hornung 
2292bc6f059SAlex Hornung 			ver = prop_dictionary_get(target_dict,DM_TARGETS_VERSION);
2302bc6f059SAlex Hornung 
2312bc6f059SAlex Hornung 			for (i=0; i<3; i++)
2322bc6f059SAlex Hornung 				prop_array_get_uint32(ver,i,&dmtv->version[i]);
2332bc6f059SAlex Hornung 
2342bc6f059SAlex Hornung 			dmtv->next = rec_size;
2352bc6f059SAlex Hornung 
2362bc6f059SAlex Hornung 			strlcpy(dmtv->name,name,slen);
2372bc6f059SAlex Hornung 
2382bc6f059SAlex Hornung 			odmtv = dmtv;
2392bc6f059SAlex Hornung 
2402bc6f059SAlex Hornung 			dmtv =(struct dm_target_versions *)((uint8_t *)dmtv + rec_size);
2412bc6f059SAlex Hornung 		}
2422bc6f059SAlex Hornung 
2432bc6f059SAlex Hornung 		if (odmtv != NULL)
2442bc6f059SAlex Hornung 			odmtv->next = 0;
2452bc6f059SAlex Hornung 	}
2462bc6f059SAlex Hornung 
2472bc6f059SAlex Hornung 	prop_object_iterator_release(iter);
2482bc6f059SAlex Hornung 	return j;
2492bc6f059SAlex Hornung }
2502bc6f059SAlex Hornung 
2512bc6f059SAlex Hornung /*
2522bc6f059SAlex Hornung  * List all available dm devices in system.
2532bc6f059SAlex Hornung  */
2542bc6f059SAlex Hornung static int
dm_list_devices(prop_dictionary_t dm_dict,struct dm_ioctl * dmi)2552bc6f059SAlex Hornung dm_list_devices(prop_dictionary_t dm_dict, struct dm_ioctl *dmi)
2562bc6f059SAlex Hornung {
2572bc6f059SAlex Hornung 	struct dm_name_list *dml,*odml;
2582bc6f059SAlex Hornung 
2592bc6f059SAlex Hornung 	prop_array_t targets;
2602bc6f059SAlex Hornung 	prop_dictionary_t target_dict;
2612bc6f059SAlex Hornung 	prop_object_iterator_t iter;
2622bc6f059SAlex Hornung 
2632bc6f059SAlex Hornung 	uint32_t minor;
2642bc6f059SAlex Hornung 	uint32_t major;
2652bc6f059SAlex Hornung 
2662bc6f059SAlex Hornung 	char *name;
2672bc6f059SAlex Hornung 	size_t j,slen,rec_size;
2682bc6f059SAlex Hornung 
2692bc6f059SAlex Hornung 	odml = NULL;
2702bc6f059SAlex Hornung 	name = NULL;
2712bc6f059SAlex Hornung 	minor = 0;
2722bc6f059SAlex Hornung 	j = 0;
2732bc6f059SAlex Hornung 
2742bc6f059SAlex Hornung 	nbsd_get_dm_major(&major,DM_BLOCK_MAJOR);
2752bc6f059SAlex Hornung 
2762bc6f059SAlex Hornung 	dml = (struct dm_name_list *)((uint8_t *)dmi + dmi->data_start);
2772bc6f059SAlex Hornung 
2782bc6f059SAlex Hornung 	if ((targets = prop_dictionary_get(dm_dict,DM_IOCTL_CMD_DATA))){
2792bc6f059SAlex Hornung 
2802bc6f059SAlex Hornung 		iter = prop_array_iterator(targets);
2812bc6f059SAlex Hornung 		if (!iter)
2822bc6f059SAlex Hornung 			err(EXIT_FAILURE,"dm_list_devices %s",__func__);
2832bc6f059SAlex Hornung 
2842bc6f059SAlex Hornung 		while((target_dict = prop_object_iterator_next(iter)) != NULL){
2852bc6f059SAlex Hornung 
2862bc6f059SAlex Hornung 			prop_dictionary_get_cstring_nocopy(target_dict,
2872bc6f059SAlex Hornung 			    DM_DEV_NAME,(const char **)&name);
2882bc6f059SAlex Hornung 
2892bc6f059SAlex Hornung 			prop_dictionary_get_uint32(target_dict,DM_DEV_DEV,&minor);
2902bc6f059SAlex Hornung 
2912bc6f059SAlex Hornung 			dml->dev = MKDEV(major,minor);
2922bc6f059SAlex Hornung 
2932bc6f059SAlex Hornung 			slen = strlen(name) + 1;
2942bc6f059SAlex Hornung 			rec_size = sizeof(struct dm_name_list) + slen + 1;
2952bc6f059SAlex Hornung 
2962bc6f059SAlex Hornung 			if (rec_size > dmi->data_size)
2972bc6f059SAlex Hornung 				return -ENOMEM;
2982bc6f059SAlex Hornung 
2992bc6f059SAlex Hornung 			dml->next = rec_size;
3002bc6f059SAlex Hornung 
3012bc6f059SAlex Hornung 			strlcpy(dml->name,name,slen);
3022bc6f059SAlex Hornung 
3032bc6f059SAlex Hornung 			odml = dml;
3042bc6f059SAlex Hornung 
3052bc6f059SAlex Hornung 			dml =(struct dm_name_list *)((uint8_t *)dml + rec_size);
3062bc6f059SAlex Hornung 
3072bc6f059SAlex Hornung 			j++;
3082bc6f059SAlex Hornung 		}
3092bc6f059SAlex Hornung 
3102bc6f059SAlex Hornung 		if (odml != NULL)
3112bc6f059SAlex Hornung 			odml->next = 0;
3122bc6f059SAlex Hornung 	}
3132bc6f059SAlex Hornung 	prop_object_iterator_release(iter);
3142bc6f059SAlex Hornung 	return j;
3152bc6f059SAlex Hornung }
3162bc6f059SAlex Hornung 
3172bc6f059SAlex Hornung /*
3182bc6f059SAlex Hornung  * Print status of each table, target arguments, start sector,
3192bc6f059SAlex Hornung  * size and target name.
3202bc6f059SAlex Hornung  */
3212bc6f059SAlex Hornung static int
dm_table_status(prop_dictionary_t dm_dict,struct dm_ioctl * dmi)3222bc6f059SAlex Hornung dm_table_status(prop_dictionary_t dm_dict,struct dm_ioctl *dmi)
3232bc6f059SAlex Hornung {
3242bc6f059SAlex Hornung 	struct dm_target_spec *dmts, *odmts;
3252bc6f059SAlex Hornung 
3262bc6f059SAlex Hornung 	prop_array_t targets;
3272bc6f059SAlex Hornung 	prop_dictionary_t target_dict;
3282bc6f059SAlex Hornung 	prop_object_iterator_t iter;
3292bc6f059SAlex Hornung 
3302bc6f059SAlex Hornung 	char *type,*params,*params_start;
3312bc6f059SAlex Hornung 
3322bc6f059SAlex Hornung 	bool prm;
3332bc6f059SAlex Hornung 	size_t j,plen,rec_size,next;
3342bc6f059SAlex Hornung 
3352bc6f059SAlex Hornung 	j = 0;
3362bc6f059SAlex Hornung 	next = 0;
3372bc6f059SAlex Hornung 	params = NULL;
3382bc6f059SAlex Hornung 	odmts = NULL;
3392bc6f059SAlex Hornung 	rec_size = 0;
3402bc6f059SAlex Hornung 	plen = -1;
3412bc6f059SAlex Hornung 	prm = false;
3422bc6f059SAlex Hornung 
3432bc6f059SAlex Hornung 	dmts = (struct dm_target_spec *)((uint8_t *)dmi + dmi->data_start);
3442bc6f059SAlex Hornung 
3452bc6f059SAlex Hornung 	if ((targets = prop_dictionary_get(dm_dict,DM_IOCTL_CMD_DATA))){
3462bc6f059SAlex Hornung 
3472bc6f059SAlex Hornung 		iter = prop_array_iterator(targets);
3482bc6f059SAlex Hornung 		if (!iter)
3492bc6f059SAlex Hornung 			err(EXIT_FAILURE,"dm_table_status %s",__func__);
3502bc6f059SAlex Hornung 
3512bc6f059SAlex Hornung 		while((target_dict = prop_object_iterator_next(iter)) != NULL){
3522bc6f059SAlex Hornung 
3532bc6f059SAlex Hornung 			prop_dictionary_get_cstring_nocopy(target_dict,
3542bc6f059SAlex Hornung 			    DM_TABLE_TYPE,(const char **)&type);
3552bc6f059SAlex Hornung 
3562bc6f059SAlex Hornung 			prm = prop_dictionary_get_cstring_nocopy(target_dict,
3572bc6f059SAlex Hornung 			    DM_TABLE_PARAMS,(const char **)&params);
3582bc6f059SAlex Hornung 
3592bc6f059SAlex Hornung 			prop_dictionary_get_uint64(target_dict,DM_TABLE_START,&dmts->sector_start);
3602bc6f059SAlex Hornung 			prop_dictionary_get_uint64(target_dict,DM_TABLE_LENGTH,&dmts->length);
3612bc6f059SAlex Hornung 			prop_dictionary_get_int32(target_dict,DM_TABLE_STAT,&dmts->status);
3622bc6f059SAlex Hornung 
3632bc6f059SAlex Hornung 			if (prm)
3642bc6f059SAlex Hornung 				plen = strlen(params) + 1;
3652bc6f059SAlex Hornung 
3662bc6f059SAlex Hornung 			rec_size = sizeof(struct dm_target_spec) + plen;
3672bc6f059SAlex Hornung 
3682bc6f059SAlex Hornung 			/*
3692bc6f059SAlex Hornung 			 * In linux when copying table status from kernel next is
3702bc6f059SAlex Hornung 			 * number of bytes from the start of the first dm_target_spec
3712bc6f059SAlex Hornung 			 * structure. I don't know why but, it has to be done this way.
3722bc6f059SAlex Hornung 			 */
3732bc6f059SAlex Hornung 			next += rec_size;
3742bc6f059SAlex Hornung 
3752bc6f059SAlex Hornung 			if (rec_size > dmi->data_size)
3762bc6f059SAlex Hornung 				return -ENOMEM;
3772bc6f059SAlex Hornung 
3782bc6f059SAlex Hornung 			dmts->next = next;
3792bc6f059SAlex Hornung 
3802bc6f059SAlex Hornung 			strlcpy(dmts->target_type, type, DM_MAX_TYPE_NAME);
3812bc6f059SAlex Hornung 
3822bc6f059SAlex Hornung 			params_start = (char *)dmts + sizeof(struct dm_target_spec);
3832bc6f059SAlex Hornung 
3842bc6f059SAlex Hornung 			if (prm)
3852bc6f059SAlex Hornung 				strlcpy(params_start, params, plen);
3862bc6f059SAlex Hornung 			else
3872bc6f059SAlex Hornung 				params_start = "\0";
3882bc6f059SAlex Hornung 
3892bc6f059SAlex Hornung 
3902bc6f059SAlex Hornung 			odmts = dmts;
3912bc6f059SAlex Hornung 
3922bc6f059SAlex Hornung 			dmts = (struct dm_target_spec *)((uint8_t *)dmts + rec_size);
3932bc6f059SAlex Hornung 
3942bc6f059SAlex Hornung 			j++;
3952bc6f059SAlex Hornung 
3962bc6f059SAlex Hornung 		}
3972bc6f059SAlex Hornung 
3982bc6f059SAlex Hornung 		if (odmts != NULL)
3992bc6f059SAlex Hornung 			odmts->next = 0;
4002bc6f059SAlex Hornung 	}
4012bc6f059SAlex Hornung 	prop_object_iterator_release(iter);
4022bc6f059SAlex Hornung 
4032bc6f059SAlex Hornung 	return j;
4042bc6f059SAlex Hornung }
4052bc6f059SAlex Hornung 
4062bc6f059SAlex Hornung /*
4072bc6f059SAlex Hornung  * Print dm device dependiences, get minor/major number for
4082bc6f059SAlex Hornung  * devices. From kernel I will receive major:minor number of
4092bc6f059SAlex Hornung  * block device used with target. I have to translate it to
4102bc6f059SAlex Hornung  * raw device numbers and use them, because all other parts of lvm2
4112bc6f059SAlex Hornung  * uses raw devices internaly.
4122bc6f059SAlex Hornung  */
4132bc6f059SAlex Hornung static int
dm_dev_deps(prop_dictionary_t dm_dict,struct dm_ioctl * dmi)4142bc6f059SAlex Hornung dm_dev_deps(prop_dictionary_t dm_dict, struct dm_ioctl *dmi)
4152bc6f059SAlex Hornung {
4162bc6f059SAlex Hornung 	struct dm_target_deps *dmtd;
4172bc6f059SAlex Hornung 
4182bc6f059SAlex Hornung 	prop_array_t targets;
4192bc6f059SAlex Hornung 	prop_object_iterator_t iter;
4202bc6f059SAlex Hornung 
4212bc6f059SAlex Hornung 	uint32_t major;
4222bc6f059SAlex Hornung 
4232bc6f059SAlex Hornung 	size_t val_len, i, j;
4242bc6f059SAlex Hornung 
4252bc6f059SAlex Hornung 	uint64_t dev_tmp;
4262bc6f059SAlex Hornung 
4272bc6f059SAlex Hornung 	dev_tmp = 0;
4282bc6f059SAlex Hornung 	j = 0;
4292bc6f059SAlex Hornung 	i = 0;
4302bc6f059SAlex Hornung 
4312bc6f059SAlex Hornung 
4322bc6f059SAlex Hornung 	dmtd = (struct dm_target_deps *)((uint8_t *)dmi + dmi->data_start);
4332bc6f059SAlex Hornung 
4342bc6f059SAlex Hornung 	if ((targets = prop_dictionary_get(dm_dict, DM_IOCTL_CMD_DATA))){
4352bc6f059SAlex Hornung 
4362bc6f059SAlex Hornung 		iter = prop_array_iterator(targets);
4372bc6f059SAlex Hornung 		if (!iter)
4382bc6f059SAlex Hornung 			err(EXIT_FAILURE,"dm_target_deps %s", __func__);
4392bc6f059SAlex Hornung 
4402bc6f059SAlex Hornung 		while((prop_object_iterator_next(iter)) != NULL){
4412bc6f059SAlex Hornung 
4422bc6f059SAlex Hornung 			prop_array_get_uint64(targets, j, &dev_tmp);
4432bc6f059SAlex Hornung 
4442bc6f059SAlex Hornung 			dmtd->dev[j] = MKDEV(MAJOR(dev_tmp),MINOR(dev_tmp));
4452bc6f059SAlex Hornung 			/* XXX: worth revisiting */
4462bc6f059SAlex Hornung 			j++;
4472bc6f059SAlex Hornung 		}
4482bc6f059SAlex Hornung 	}
4492bc6f059SAlex Hornung 
4502bc6f059SAlex Hornung 	dmtd->count = j;
4512bc6f059SAlex Hornung 
4522bc6f059SAlex Hornung 	prop_object_iterator_release(iter);
4532bc6f059SAlex Hornung 
4542bc6f059SAlex Hornung 	return j;
4552bc6f059SAlex Hornung }
456