1 /* 2 * This file and its contents are supplied under the terms of the 3 * Common Development and Distribution License ("CDDL"), version 1.0. 4 * You may only use this file in accordance with the terms of version 5 * 1.0 of the CDDL. 6 * 7 * A full copy of the text of the CDDL should have accompanied this 8 * source. A copy of the CDDL is also available via the Internet at 9 * http://www.illumos.org/license/CDDL. 10 */ 11 /* 12 * Copyright 2021 Tintri by DDN, Inc. All rights reserved. 13 */ 14 15 #include <sys/mdb_modapi.h> 16 #include <sys/zone.h> 17 #include <nfs/nfs4_kprot.h> 18 #include <nfs/nfs4_idmap_impl.h> 19 20 #include "idmap.h" 21 #include "common.h" 22 23 /* 24 * nfs4_idmap dcmd implementation 25 */ 26 27 int 28 nfs4_idmap_dcmd(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv) 29 { 30 nfsidmap_t idmap; 31 char *s; 32 33 if (argc > 0) 34 return (DCMD_USAGE); 35 36 if ((flags & DCMD_ADDRSPEC) == 0) { 37 mdb_printf("requires address of nfsidmap_t\n"); 38 return (DCMD_USAGE); 39 } 40 41 if (mdb_vread(&idmap, sizeof (idmap), addr) == -1) { 42 mdb_warn("unable to read nfsidmap_t"); 43 return (DCMD_ERR); 44 } 45 46 if (DCMD_HDRSPEC(flags)) 47 mdb_printf("%<b>%<u>%-20s %10s %-20s%</u>%</b>\n", "TimeStamp", 48 "Number", "String"); 49 50 s = mdb_alloc(idmap.id_str.utf8string_len + 1, UM_NOSLEEP | UM_GC); 51 if (s == NULL || mdb_readstr(s, idmap.id_str.utf8string_len + 1, 52 (uintptr_t)idmap.id_str.utf8string_val) == -1) 53 s = "??"; 54 55 mdb_printf("%-20Y %10i %s\n", idmap.id_time, idmap.id_no, s); 56 57 return (DCMD_OK); 58 } 59 60 /* 61 * nfs4_idmap_info dcmd implementation 62 */ 63 64 int 65 nfs4_idmap_info_dcmd(uintptr_t addr, uint_t flags, int argc, 66 const mdb_arg_t *argv) 67 { 68 uint_t u2s, g2s, s2u, s2g; 69 int i; 70 71 if ((flags & DCMD_ADDRSPEC) == 0) 72 addr = 0; 73 74 u2s = g2s = s2u = s2g = argc == 0; 75 76 for (i = 0; i < argc; i++) { 77 const char *s; 78 79 if (argv[i].a_type != MDB_TYPE_STRING) 80 return (DCMD_USAGE); 81 82 s = argv[i].a_un.a_str; 83 84 if (strcmp(s, "u2s") == 0) 85 u2s = TRUE; 86 else if (strcmp(s, "g2s") == 0) 87 g2s = TRUE; 88 else if (strcmp(s, "s2u") == 0) 89 s2u = TRUE; 90 else if (strcmp(s, "s2g") == 0) 91 s2g = TRUE; 92 else 93 return (DCMD_USAGE); 94 } 95 96 if (u2s) { 97 mdb_printf("%<b>NFSv4 uid-to-string idmap cache:%</b>\n"); 98 mdb_pwalk_dcmd("nfs4_u2s", "nfs4_idmap", 0, NULL, addr); 99 } 100 101 if (g2s) { 102 mdb_printf("%<b>NFSv4 gid-to-string idmap cache:%</b>\n"); 103 mdb_pwalk_dcmd("nfs4_g2s", "nfs4_idmap", 0, NULL, addr); 104 } 105 106 if (s2u) { 107 mdb_printf("%<b>NFSv4 string-to-uid idmap cache:%</b>\n"); 108 mdb_pwalk_dcmd("nfs4_s2u", "nfs4_idmap", 0, NULL, addr); 109 } 110 111 if (s2g) { 112 mdb_printf("%<b>NFSv4 string-to-gid idmap cache:%</b>\n"); 113 mdb_pwalk_dcmd("nfs4_s2g", "nfs4_idmap", 0, NULL, addr); 114 } 115 116 return (DCMD_OK); 117 } 118 119 void 120 nfs4_idmap_info_help(void) 121 { 122 mdb_printf( 123 "u2s display entries from NFSv4 uid-to-string idmap cache\n" 124 "g2s display entries from NFSv4 gid-to-string idmap cache\n" 125 "s2u display entries from NFSv4 string-to-uid idmap cache\n" 126 "s2g display entries from NFSv4 string-to-gid idmap cache\n" 127 "\nWithout arguments display entries from all caches.\n"); 128 } 129 130 /* 131 * nfs4_u2s/nfs4_s2u/nfs4_g2s/nfs4_s2g walker implementation 132 */ 133 134 int 135 nfs4_idmap_walk_init(mdb_walk_state_t *wsp) 136 { 137 uintptr_t table; 138 hash_table_walk_arg_t *arg; 139 int status; 140 141 /* Use global zone by default */ 142 if (wsp->walk_addr == 0) { 143 /* wsp->walk_addr = global_zone */ 144 if (mdb_readvar(&wsp->walk_addr, "global_zone") == -1) { 145 mdb_warn("failed to locate global_zone"); 146 return (WALK_ERR); 147 } 148 } 149 150 if (zoned_get_zsd(wsp->walk_addr, "nfsidmap_zone_key", 151 &wsp->walk_addr) != DCMD_OK) { 152 mdb_warn("failed to get zoned idmap"); 153 return (WALK_ERR); 154 } 155 156 if (mdb_vread(&table, sizeof (table), wsp->walk_addr 157 + (uintptr_t)wsp->walk_arg + OFFSETOF(idmap_cache_info_t, table)) 158 == -1) { 159 mdb_warn("unable to read table pointer"); 160 return (WALK_ERR); 161 } 162 163 arg = mdb_alloc(sizeof (hash_table_walk_arg_t), UM_SLEEP); 164 arg->array_addr = table; 165 arg->array_len = NFSID_CACHE_ANCHORS; 166 arg->head_size = sizeof (nfsidhq_t); 167 arg->first_name = "hq_lru_forw"; 168 arg->first_offset = OFFSETOF(nfsidhq_t, hq_lru_forw); 169 arg->member_type_name = "nfsidmap_t"; 170 arg->member_size = sizeof (nfsidmap_t); 171 arg->next_offset = OFFSETOF(nfsidmap_t, id_forw); 172 173 wsp->walk_arg = arg; 174 175 status = hash_table_walk_init(wsp); 176 if (status != WALK_NEXT) 177 mdb_free(wsp->walk_arg, sizeof (hash_table_walk_arg_t)); 178 return (status); 179 } 180 181 void 182 nfs4_idmap_walk_fini(mdb_walk_state_t *wsp) 183 { 184 hash_table_walk_fini(wsp); 185 mdb_free(wsp->walk_arg, sizeof (hash_table_walk_arg_t)); 186 } 187