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 **)¶ms);
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