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 2005 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 <mdb/mdb_param.h> 30 #include <mdb/mdb_modapi.h> 31 #include <mdb/mdb_ks.h> 32 33 #include "zone.h" 34 35 #include <stddef.h> 36 #include <sys/zone.h> 37 38 #define ZONE_NAMELEN 20 39 #ifdef _LP64 40 #define ZONE_PATHLEN 32 41 #else 42 #define ZONE_PATHLEN 40 43 #endif 44 45 int 46 zoneprt(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv) 47 { 48 zone_t zn; 49 char name[ZONE_NAMELEN]; 50 char path[ZONE_PATHLEN]; 51 int len; 52 53 if (argc != 0) 54 return (DCMD_USAGE); 55 56 if (!(flags & DCMD_ADDRSPEC)) { 57 if (mdb_walk_dcmd("zone", "zone", argc, argv) == -1) { 58 mdb_warn("can't walk zones"); 59 return (DCMD_ERR); 60 } 61 return (DCMD_OK); 62 } 63 if (DCMD_HDRSPEC(flags)) { 64 mdb_printf("%<u>%?s %6s %-20s %-s%</u>\n", 65 "ADDR", "ID", "NAME", "PATH"); 66 } 67 if (mdb_vread(&zn, sizeof (zone_t), addr) == -1) { 68 mdb_warn("can't read zone_t structure at %p", addr); 69 return (DCMD_ERR); 70 } 71 len = mdb_readstr(name, ZONE_NAMELEN, (uintptr_t)zn.zone_name); 72 if (len > 0) { 73 if (len == ZONE_NAMELEN) 74 (void) strcpy(&name[len - 4], "..."); 75 } else { 76 (void) strcpy(name, "??"); 77 } 78 len = mdb_readstr(path, ZONE_PATHLEN, (uintptr_t)zn.zone_rootpath); 79 if (len > 0) { 80 if (len == ZONE_PATHLEN) 81 (void) strcpy(&path[len - 4], "..."); 82 } else { 83 (void) strcpy(path, "??"); 84 } 85 mdb_printf("%0?p %6d %-20s %s\n", addr, zn.zone_id, name, path); 86 return (DCMD_OK); 87 } 88 89 int 90 zone_walk_init(mdb_walk_state_t *wsp) 91 { 92 GElf_Sym sym; 93 94 if (wsp->walk_addr == NULL) { 95 if (mdb_lookup_by_name("zone_active", &sym) == -1) { 96 mdb_warn("failed to find 'zone_active'"); 97 return (WALK_ERR); 98 } 99 wsp->walk_addr = (uintptr_t)sym.st_value; 100 } 101 if (mdb_layered_walk("list", wsp) == -1) { 102 mdb_warn("couldn't walk 'list'"); 103 return (WALK_ERR); 104 } 105 return (WALK_NEXT); 106 } 107 108 int 109 zone_walk_step(mdb_walk_state_t *wsp) 110 { 111 return (wsp->walk_callback(wsp->walk_addr, wsp->walk_layer, 112 wsp->walk_cbdata)); 113 } 114 115 int 116 zsd_walk_init(mdb_walk_state_t *wsp) 117 { 118 if (wsp->walk_addr == NULL) { 119 mdb_warn("global walk not supported\n"); 120 return (WALK_ERR); 121 } 122 wsp->walk_addr += offsetof(struct zone, zone_zsd); 123 if (mdb_layered_walk("list", wsp) == -1) { 124 mdb_warn("couldn't walk 'list'"); 125 return (WALK_ERR); 126 } 127 return (WALK_NEXT); 128 } 129 130 int 131 zsd_walk_step(mdb_walk_state_t *wsp) 132 { 133 return (wsp->walk_callback(wsp->walk_addr, wsp->walk_layer, 134 wsp->walk_cbdata)); 135 } 136 137 struct zsd_cb_data { 138 zone_key_t key; 139 int found; 140 }; 141 142 /* ARGSUSED */ 143 static int 144 zsd_match(uintptr_t addr, const void *data, void *private) 145 { 146 struct zsd_entry ze; 147 struct zsd_cb_data *cbdata = private; 148 149 if (mdb_vread(&ze, sizeof (struct zsd_entry), addr) == -1) { 150 mdb_warn("couldn't read zsd_entry at %p", addr); 151 return (WALK_ERR); 152 } 153 if (ze.zsd_key != cbdata->key) 154 return (WALK_NEXT); 155 cbdata->found = 1; 156 mdb_printf("%p\n", ze.zsd_data); 157 return (WALK_DONE); 158 } 159 160 int 161 zsd(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv) 162 { 163 zone_t zone; 164 const mdb_arg_t *argp = &argv[0]; 165 zone_key_t key; 166 struct zsd_cb_data cbd; 167 168 if ((flags & DCMD_ADDRSPEC) == 0) { 169 mdb_warn("address of zone not specified\n"); 170 return (DCMD_ERR); 171 } 172 if (argc != 1) 173 return (DCMD_USAGE); 174 if (argp->a_type == MDB_TYPE_IMMEDIATE) 175 key = argp->a_un.a_val; 176 else 177 key = mdb_strtoull(argp->a_un.a_str); 178 if (mdb_vread(&zone, sizeof (struct zone), addr) == -1) { 179 mdb_warn("couldn't read zone_t at %p", addr); 180 return (DCMD_ERR); 181 } 182 cbd.key = key; 183 cbd.found = 0; 184 if (mdb_pwalk("zsd", zsd_match, &cbd, addr) != 0) { 185 mdb_warn("failed to walk zsd\n"); 186 return (DCMD_ERR); 187 } 188 if (cbd.found == 0) { 189 mdb_warn("no corresponding ZSD value found for key %d\n", 190 key); 191 return (DCMD_ERR); 192 } 193 return (DCMD_OK); 194 } 195