1 /* 2 * CDDL HEADER START 3 * 4 * The contents of this file are subject to the terms of the 5 * Common Development and Distribution License, Version 1.0 only 6 * (the "License"). You may not use this file except in compliance 7 * with the License. 8 * 9 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 10 * or http://www.opensolaris.org/os/licensing. 11 * See the License for the specific language governing permissions 12 * and limitations under the License. 13 * 14 * When distributing Covered Code, include this CDDL HEADER in each 15 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 16 * If applicable, add the following below this CDDL HEADER, with the 17 * fields enclosed by brackets "[]" replaced with your own identifying 18 * information: Portions Copyright [yyyy] [name of copyright owner] 19 * 20 * CDDL HEADER END 21 */ 22 /* 23 * Copyright 2004 Sun Microsystems, Inc. All rights reserved. 24 * Use is subject to license terms. 25 */ 26 27 #pragma ident "%Z%%M% %I% %E% SMI" 28 29 #include "mdinclude.h" 30 #include <sys/lvm/md_names.h> 31 32 /* 33 * work out the offset size 34 */ 35 #define MY_DID_SHR_NAMSIZ(n) \ 36 (((sizeof (struct did_shr_name) - 1) + \ 37 n + (sizeof (uint_t) - 1)) & ~(sizeof (uint_t) - 1)) 38 #define MY_SHR_NAMSIZ(n) \ 39 (((sizeof (struct nm_shared_name) - 1) + \ 40 n + (sizeof (uint_t) - 1)) & ~(sizeof (uint_t) - 1)) 41 #define MY_DID_NAMSIZ(n) \ 42 (((sizeof (struct did_min_name) - 1) + \ 43 n + (sizeof (uint_t) - 1)) & ~(sizeof (uint_t) - 1)) 44 #define MY_NAMSIZ(n) \ 45 (((sizeof (struct nm_name) - 1) + \ 46 n + (sizeof (uint_t) - 1)) & ~(sizeof (uint_t) - 1)) 47 48 static uintptr_t 49 print_did_shared_name(uintptr_t addr, int i) 50 { 51 struct did_shr_name shn; 52 uintptr_t sn_name_addr; 53 void *sn_name; 54 uintptr_t next_addr = addr; 55 56 if (mdb_vread(&shn, sizeof (struct did_shr_name), addr) != 57 sizeof (struct did_shr_name)) { 58 mdb_warn("failed to read did_shr_name at %p\n", addr); 59 return (NULL); 60 } 61 if (shn.did_size == 0) 62 return (NULL); 63 mdb_printf("device_id[%d] at %p\n", i, addr); 64 mdb_inc_indent(2); 65 mdb_printf("did_key: %d\n", shn.did_key); 66 mdb_printf("did_count: %u\n", shn.did_count); 67 mdb_printf("did_data: 0x%x \n", shn.did_data); 68 mdb_printf("did_size: %u\n", shn.did_size); 69 sn_name_addr = addr + ((uintptr_t)&shn.did_devid - (uintptr_t)&shn); 70 if (shn.did_size > 0) { 71 sn_name = mdb_alloc(shn.did_size + 1, UM_SLEEP | UM_GC); 72 if (mdb_readstr((char *)sn_name, shn.did_size + 1, 73 sn_name_addr) <= 0) { 74 mdb_warn("failed to read sn_name at %p\n", 75 sn_name_addr); 76 return (NULL); 77 } 78 mdb_printf("did_devid: %s at %p\n", (char *)sn_name, 79 sn_name_addr); 80 next_addr = addr + MY_DID_SHR_NAMSIZ(shn.did_size); 81 } 82 mdb_dec_indent(2); 83 return (next_addr); 84 } 85 86 static uintptr_t 87 print_nm_shared_name(uintptr_t addr, int i) 88 { 89 struct nm_shared_name shn; 90 uintptr_t sn_name_addr; 91 void *sn_name; 92 uintptr_t next_addr = addr; 93 94 if (mdb_vread(&shn, sizeof (struct nm_shared_name), addr) != 95 sizeof (struct nm_shared_name)) { 96 mdb_warn("failed to read nm_shared_name at %p\n", addr); 97 return (NULL); 98 } 99 if (shn.sn_namlen == 0) 100 return (NULL); 101 mdb_printf("sr_name[%d] at %p\n", i, addr); 102 mdb_inc_indent(2); 103 mdb_printf("sn_key: %d \n", shn.sn_key); 104 mdb_printf("sn_count: %u\n", shn.sn_count); 105 mdb_printf("sn_data: 0x%x \n", shn.sn_data); 106 mdb_printf("sn_namlen: %u\n", shn.sn_namlen); 107 sn_name_addr = addr + ((uintptr_t)&shn.sn_name - (uintptr_t)&shn); 108 if (shn.sn_namlen > 0) { 109 sn_name = mdb_alloc(shn.sn_namlen + 1, UM_SLEEP | UM_GC); 110 if (mdb_readstr((char *)sn_name, shn.sn_namlen + 1, 111 sn_name_addr) <= 0) { 112 mdb_warn("failed to read sn_name at %p\n", 113 sn_name_addr); 114 } 115 mdb_printf("sn_name: %s at %p\n", (char *)sn_name, 116 sn_name_addr); 117 next_addr = addr + MY_SHR_NAMSIZ(shn.sn_namlen); 118 } 119 mdb_dec_indent(2); 120 return (next_addr); 121 } 122 123 static uintptr_t 124 print_devid_name(uintptr_t addr, int i) 125 { 126 struct did_min_name didmn; 127 uintptr_t did_name_addr; 128 void *min_name; 129 uintptr_t next_addr = addr; 130 131 if (mdb_vread(&didmn, sizeof (struct did_min_name), addr) != 132 sizeof (struct did_min_name)) { 133 mdb_warn("failed to read did_min_name at %p\n", addr); 134 return (NULL); 135 } 136 if (didmn.min_namlen == 0) 137 return (NULL); 138 mdb_printf("minor_name[%d] at %p\n", i, addr); 139 mdb_inc_indent(2); 140 mdb_printf("min_key: %d \n", didmn.min_key); 141 mdb_printf("min_count: %u\n", didmn.min_count); 142 mdb_printf("min_devid_key: %d \n", didmn.min_devid_key); 143 mdb_printf("min_namlen: %u\n", didmn.min_namlen); 144 did_name_addr = addr + ((uintptr_t)&didmn.min_name - (uintptr_t)&didmn); 145 if (didmn.min_namlen > 0) { 146 min_name = mdb_alloc(didmn.min_namlen + 1, UM_SLEEP | UM_GC); 147 if (mdb_readstr((char *)min_name, didmn.min_namlen + 1, 148 did_name_addr) <= 0) { 149 mdb_warn("failed to read min_name at %p\n", 150 did_name_addr); 151 } 152 mdb_printf("min_name: %s at %p\n", (char *)min_name, 153 did_name_addr); 154 next_addr = addr + MY_DID_NAMSIZ(didmn.min_namlen); 155 } 156 mdb_dec_indent(2); 157 return (next_addr); 158 } 159 160 static uintptr_t 161 print_nm_name(uintptr_t addr, int i) 162 { 163 struct nm_name nm; 164 uintptr_t nm_name_addr; 165 void *n_name; 166 uintptr_t next_addr = addr; 167 168 if (mdb_vread(&nm, sizeof (struct nm_name), addr) != 169 sizeof (struct nm_name)) { 170 mdb_warn("failed to read nm_name at %p\n", addr); 171 return (NULL); 172 } 173 if (nm.n_namlen == 0) 174 return (NULL); 175 mdb_printf("r_name[%d] at %p\n", i, addr); 176 mdb_inc_indent(2); 177 mdb_printf("n_key: %d \n", nm.n_key); 178 mdb_printf("n_count: %u\n", nm.n_count); 179 mdb_printf("n_minor: %x\n", nm.n_minor); 180 mdb_printf("n_drv_key: %d \n", nm.n_drv_key); 181 mdb_printf("n_dir_key: %d \n", nm.n_dir_key); 182 mdb_printf("n_namlen: %u\n", nm.n_namlen); 183 nm_name_addr = addr + ((uintptr_t)&nm.n_name - (uintptr_t)&nm); 184 if (nm.n_namlen > 0) { 185 n_name = mdb_alloc(nm.n_namlen + 1, UM_SLEEP | UM_GC); 186 if (mdb_readstr((char *)n_name, nm.n_namlen + 1, 187 nm_name_addr) <= 0) { 188 mdb_warn("failed to read n_name at %p\n", nm_name_addr); 189 } 190 mdb_printf("n_name: %s at %p\n", (char *)n_name, 191 nm_name_addr); 192 next_addr = addr + MY_NAMSIZ(nm.n_namlen); 193 } 194 195 mdb_dec_indent(2); 196 return (next_addr); 197 } 198 199 static uint_t 200 process_nmn_record_hdr(uintptr_t addr) 201 { 202 struct nm_rec_hdr rhdr; 203 204 /* 205 * we read this anyway as the first part of nm_rec, devid_min_rec, 206 * nm_shr_rec, and devid_shr_rec record is a nm_rec_hdr 207 */ 208 if (mdb_vread(&rhdr, sizeof (struct nm_rec_hdr), addr) != 209 sizeof (struct nm_rec_hdr)) { 210 mdb_warn("failed to read nm_rec_hdr at %p\n", addr); 211 return (0); 212 } 213 214 mdb_printf("nmn_record: %p\n", addr); 215 mdb_inc_indent(2); 216 mdb_printf("r_revision: %4u\n", rhdr.r_revision); 217 mdb_printf("r_alloc_size: %4u\n", rhdr.r_alloc_size); 218 mdb_printf("r_used_size: %4u\n", rhdr.r_used_size); 219 mdb_printf("r_next_recid: %4x\n", rhdr.r_next_recid); 220 mdb_printf("xr_next_rec: %4u\n", rhdr.xr_next_rec); 221 mdb_printf("r_next_key: %4d\n", rhdr.r_next_key); 222 mdb_dec_indent(2); 223 return (rhdr.r_used_size); 224 } 225 226 static void 227 process_nmn_record(uintptr_t addr, int shared, int devid) 228 { 229 struct nm_shr_rec srhdr; 230 struct devid_shr_rec didsrhdr; 231 struct nm_rec nm_record; 232 struct devid_min_rec devid_record; 233 uintptr_t shn_addr; 234 int i; 235 uintptr_t next_addr, start_addr; 236 uint_t used_size; 237 238 used_size = process_nmn_record_hdr(addr); 239 240 if (devid) { 241 if (shared) { 242 if (mdb_vread(&didsrhdr, sizeof (struct devid_shr_rec), 243 addr) != sizeof (struct devid_shr_rec)) { 244 mdb_warn("failed to read devid_shr_rec at %p\n", 245 addr); 246 return; 247 } 248 } else { 249 if (mdb_vread(&devid_record, 250 sizeof (struct devid_min_rec), addr) 251 != sizeof (struct devid_min_rec)) { 252 mdb_warn("failed to read devid_min_rec at %p\n", 253 addr); 254 return; 255 } 256 } 257 } else { 258 if (shared) { 259 if (mdb_vread(&srhdr, sizeof (struct nm_shr_rec), addr) 260 != sizeof (struct nm_shr_rec)) { 261 mdb_warn("failed to read nm_shr_rec at %p\n", 262 addr); 263 return; 264 } 265 } else { 266 if (mdb_vread(&nm_record, sizeof (struct nm_rec), addr) 267 != sizeof (struct nm_rec)) { 268 mdb_warn("failed to read nm_rec at %p\n", addr); 269 return; 270 } 271 } 272 } 273 mdb_inc_indent(2); 274 if (devid) { 275 if (shared) { 276 /* 277 * Do the rest of the device_id records. 278 */ 279 next_addr = addr + ((uintptr_t)&didsrhdr.device_id[0] - 280 (uintptr_t)&didsrhdr); 281 start_addr = next_addr; 282 for (i = 0; ; i++) { 283 shn_addr = next_addr; 284 next_addr = print_did_shared_name(shn_addr, i); 285 if (next_addr == NULL) { 286 mdb_dec_indent(2); 287 return; 288 } 289 /* 290 * Causes us to print one extra record. 291 */ 292 if ((next_addr - start_addr > used_size) || 293 (next_addr == shn_addr)) { 294 break; 295 } 296 } 297 } else { 298 /* 299 * Now do the rest of the record. 300 */ 301 next_addr = addr + 302 ((uintptr_t)&devid_record.minor_name[0] - 303 (uintptr_t)&devid_record); 304 start_addr = next_addr; 305 for (i = 0; ; i++) { 306 shn_addr = next_addr; 307 next_addr = print_devid_name(shn_addr, i); 308 if (next_addr == NULL) { 309 mdb_dec_indent(2); 310 return; 311 } 312 if ((next_addr - start_addr > used_size) || 313 (next_addr == shn_addr)) { 314 break; 315 } 316 } 317 } 318 } else { 319 if (shared) { 320 /* 321 * Now do the rest of the sr_name records. 322 */ 323 next_addr = addr + ((uintptr_t)&srhdr.sr_name[0] - 324 (uintptr_t)&srhdr); 325 start_addr = next_addr; 326 for (i = 0; ; i++) { 327 shn_addr = next_addr; 328 next_addr = print_nm_shared_name(shn_addr, i); 329 if (next_addr == NULL) { 330 mdb_dec_indent(2); 331 return; 332 } 333 /* 334 * Causes us to print one extra record 335 */ 336 if ((next_addr - start_addr > used_size) || 337 (next_addr == shn_addr)) { 338 break; 339 } 340 } 341 } else { 342 /* 343 * Now do the rest of the record 344 */ 345 next_addr = addr + ((uintptr_t)&nm_record.r_name[0] - 346 (uintptr_t)&nm_record); 347 start_addr = next_addr; 348 for (i = 0; ; i++) { 349 shn_addr = next_addr; 350 next_addr = print_nm_name(shn_addr, i); 351 if (next_addr == NULL) { 352 mdb_dec_indent(2); 353 return; 354 } 355 if ((next_addr - start_addr > used_size) || 356 (next_addr == shn_addr)) { 357 break; 358 } 359 } 360 } 361 } 362 mdb_dec_indent(2); 363 } 364 365 static void 366 process_nm_next_hdr(uintptr_t addr, int shared, int devid) 367 { 368 uintptr_t next = addr; 369 struct nm_next_hdr nhdr; 370 371 mdb_inc_indent(2); 372 mdb_printf("%p\n", next); 373 if (mdb_vread(&nhdr, sizeof (struct nm_next_hdr), next) != 374 sizeof (struct nm_next_hdr)) { 375 mdb_warn("failed to read nm_next_hdr at %p", next); 376 return; 377 } 378 (void) process_nmn_record_hdr((uintptr_t)nhdr.nmn_record); 379 next = (uintptr_t)nhdr.nmn_nextp; 380 while (next != (uintptr_t)0) { 381 382 mdb_printf("\n"); 383 mdb_printf("nmn_nextp %p\n", nhdr.nmn_nextp); 384 if (mdb_vread(&nhdr, sizeof (struct nm_next_hdr), next) != 385 sizeof (struct nm_next_hdr)) { 386 mdb_warn("failed to read nm_next_hdr at %p\n", next); 387 break; 388 } 389 process_nmn_record((uintptr_t)nhdr.nmn_record, shared, devid); 390 next = (uintptr_t)nhdr.nmn_nextp; 391 } 392 mdb_printf("\n"); 393 mdb_dec_indent(2); 394 } 395 /* 396 * Start the processing of a nominated set 397 */ 398 static void 399 process_set(int setno) 400 { 401 uintptr_t addr = (uintptr_t)mdset[setno].s_nm; 402 uintptr_t did_addr = (uintptr_t)mdset[setno].s_did_nm; 403 uintptr_t shared_addr, names_addr; 404 uintptr_t did_names_addr, did_shared_addr; 405 struct nm_header_hdr hdr, did_hdr; 406 407 mdb_printf("------ Name Space for setno %d ------\n", setno); 408 409 if (mdb_vread(&hdr, sizeof (struct nm_header_hdr), addr) != 410 sizeof (struct nm_header_hdr)) { 411 mdb_warn("failed to read nm_header_hdr at %p\n", addr); 412 return; 413 } 414 mdb_printf("hh_header: %p \n", hdr.hh_header); 415 if (did_addr != NULL) { /* device id's exist */ 416 if (mdb_vread(&did_hdr, sizeof (struct nm_header_hdr), 417 did_addr) != sizeof (struct nm_header_hdr)) { 418 mdb_warn("failed to read nm_header_hdr at %p\n", 419 did_addr); 420 return; 421 } 422 mdb_printf("did hh_header: %p \n", did_hdr.hh_header); 423 did_names_addr = 424 (uintptr_t)&(((struct nm_header_hdr *)did_addr)->hh_names); 425 did_shared_addr = 426 (uintptr_t)&(((struct nm_header_hdr *)did_addr)->hh_shared); 427 } 428 429 names_addr = (uintptr_t)&(((struct nm_header_hdr *)addr)->hh_names); 430 shared_addr = (uintptr_t)&(((struct nm_header_hdr *)addr)->hh_shared); 431 mdb_printf("hh_names: %p \n", names_addr); 432 mdb_printf("hh_shared: %p\n", shared_addr); 433 434 if (did_addr != NULL) { 435 mdb_printf("did hh_names: %p \n", did_names_addr); 436 mdb_printf("did hh_shared: %p\n", did_shared_addr); 437 } 438 439 mdb_printf("hh_names:"); 440 process_nm_next_hdr(names_addr, 0, 0); 441 mdb_printf("\nhh_shared:"); 442 process_nm_next_hdr(shared_addr, 1, 0); 443 444 if (did_addr != NULL) { 445 mdb_printf("did hh_names:"); 446 process_nm_next_hdr(did_names_addr, 0, 1); 447 mdb_printf("\ndid hh_shared:"); 448 process_nm_next_hdr(did_shared_addr, 1, 1); 449 } 450 } 451 /* 452 * Dump the name space for all sets or specified set (-s option) 453 * usage: ::dumpnamespace [-s setname] 454 */ 455 /* ARGSUSED */ 456 int 457 dumpnamespace(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv) 458 { 459 char *s_opt = NULL; 460 int j; 461 int setno; 462 463 if (mdb_getopts(argc, argv, 's', MDB_OPT_STR, &s_opt, 464 NULL) != argc) { 465 /* left over arguments ?? */ 466 return (DCMD_USAGE); 467 } 468 469 snarf_sets(); 470 471 if (argc == 0) { 472 for (j = 0; j < md_nsets; j++) { 473 if (mdset[j].s_status & MD_SET_NM_LOADED) { 474 process_set(j); 475 } 476 } 477 } else { 478 setno = findset(s_opt); 479 if (setno == -1) { 480 mdb_warn("no such set: %s\n", s_opt); 481 return (DCMD_ERR); 482 } 483 if (mdset[setno].s_status & MD_SET_NM_LOADED) { 484 process_set(setno); 485 } 486 } 487 return (DCMD_OK); 488 } 489