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