xref: /illumos-gate/usr/src/cmd/mdb/common/modules/nfs/idmap.c (revision 2a295025ab352ac2f6469a947d5b5e2f9379f943)
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