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