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 (the "License"). 6 * You may not use this file except in compliance with the License. 7 * 8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9 * or http://www.opensolaris.org/os/licensing. 10 * See the License for the specific language governing permissions 11 * and limitations under the License. 12 * 13 * When distributing Covered Code, include this CDDL HEADER in each 14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15 * If applicable, add the following below this CDDL HEADER, with the 16 * fields enclosed by brackets "[]" replaced with your own identifying 17 * information: Portions Copyright [yyyy] [name of copyright owner] 18 * 19 * CDDL HEADER END 20 */ 21 /* 22 * Copyright 2008 Sun Microsystems, Inc. All rights reserved. 23 * Use is subject to license terms. 24 */ 25 26 #include <ctype.h> 27 #include <string.h> 28 #include <strings.h> 29 #include <stdlib.h> 30 #include <sys/types.h> 31 #include <sys/errno.h> 32 #include <sys/tiuser.h> 33 #include <setjmp.h> 34 #include <netdb.h> 35 #include <sys/socket.h> 36 #include <errno.h> 37 38 #include <rpc/types.h> 39 #include <rpc/xdr.h> 40 #include <rpc/auth.h> 41 #include <rpc/clnt.h> 42 #include <rpc/rpc_msg.h> 43 #include "snoop.h" 44 45 #include <sys/stat.h> 46 #include <sys/param.h> 47 #include <rpcsvc/nfs_prot.h> 48 49 /* use the same nfs4_prot.h as the xdr code */ 50 /* #include "rpcsvc/nfs4_prot.h" */ 51 #include "nfs4_prot.h" 52 53 /* 54 * Things common to nfs4 and ctl. 55 */ 56 #include "nfs4_cmn.h" 57 58 /* 59 * XXX With NFS v2 and v3, we only need to xdr the pieces that we care 60 * about. Anything else we can ignore and just skip to the next packet. 61 * So all the stuff that deals directly with XDR lives in snoop_display.c 62 * With v4, we need to XDR entire structures so that we can skip over 63 * uninteresting bits in a compound array, so we call XDR directly from 64 * here. We need to rethink how we're going to structure XDR access. Do 65 * we continue to hide it all in snoop_display.c, or do we expose it to all 66 * the protocol modules? 67 */ 68 extern XDR xdrm; 69 70 #ifndef MIN 71 #define MIN(a, b) ((a) < (b) ? (a) : (b)) 72 #endif 73 74 /* 75 * Maximum number of characters to display in compound4 summary line. 76 */ 77 #define SUM_COMPND_MAX 100 78 79 /* 80 * Maximum number of recognized attributes. 81 */ 82 #define MAX_ATTRIBUTES 77 83 84 /* 85 * This data structure provides a more convenient way to access an 86 * attribute bitmask. map[N] = value of bit N in a bitmap4. 87 * It's defined as a struct so as to step around all the weird rules in C 88 * about arrays, pointers, passing them as arguments, etc. 89 */ 90 91 typedef struct { 92 char map[MAX_ATTRIBUTES]; 93 } unpkd_attrmap_t; 94 95 static void sumarg_cb_getattr(char *buf, size_t buflen, void *obj); 96 static void dtlarg_cb_getattr(void *obj); 97 static void sumarg_cb_recall(char *buf, size_t buflen, void *obj); 98 static void dtlarg_cb_recall(void *obj); 99 100 static void sumarg_access(char *buf, size_t buflen, void *obj); 101 static void dtlarg_access(void *obj); 102 static void sumarg_close(char *buf, size_t buflen, void *obj); 103 static void dtlarg_close(void *obj); 104 static void sumarg_commit(char *buf, size_t buflen, void *obj); 105 static void dtlarg_commit(void *obj); 106 static void sumarg_compnt(char *buf, size_t buflen, void *obj); 107 static void dtlarg_compnt(void *obj); 108 static void sumarg_create(char *buf, size_t buflen, void *obj); 109 static void dtlarg_create(void *obj); 110 static void sumarg_delprge(char *buf, size_t buflen, void *obj); 111 static void dtlarg_delprge(void *obj); 112 static void sumarg_delret(char *buf, size_t buflen, void *obj); 113 static void dtlarg_delret(void *obj); 114 static void sumarg_getattr(char *buf, size_t buflen, void *obj); 115 static void dtlarg_getattr(void *obj); 116 static void sumarg_link(char *buf, size_t buflen, void *obj); 117 static void dtlarg_link(void *obj); 118 static void sum_open_to_lock_owner(char *buf, int buflen, 119 open_to_lock_owner4 *own); 120 static void sum_exist_lock_owner(char *buf, int buflen, 121 exist_lock_owner4 *own); 122 static void sum_locker(char *buf, size_t buflen, locker4 *lk); 123 static void sumarg_lock(char *buf, size_t buflen, void *obj); 124 static void detail_headerpadsize(count4); 125 static void detail_open_to_lock_owner(open_to_lock_owner4 *own); 126 static void detail_exist_lock_owner(exist_lock_owner4 *own); 127 static void detail_locker(locker4 *lk); 128 static void dtlarg_lock(void *obj); 129 static void sumarg_lockt(char *buf, size_t buflen, void *obj); 130 static void dtlarg_lockt(void *obj); 131 static void sumarg_locku(char *buf, size_t buflen, void *obj); 132 static void dtlarg_locku(void *obj); 133 static void sumarg_lookup(char *buf, size_t buflen, void *obj); 134 static void dtlarg_lookup(void *obj); 135 static char *detail_lortype_name(layoutrecall_type4); 136 static char *sum_lortype_name(layoutrecall_type4); 137 static void sumarg_open(char *buf, size_t buflen, void *obj); 138 static void dtlarg_open(void *obj); 139 static void sumarg_openattr(char *buf, size_t buflen, void *obj); 140 static void dtlarg_openattr(void *obj); 141 static void sumarg_open_confirm(char *buf, size_t buflen, void *obj); 142 static void dtlarg_open_confirm(void *obj); 143 static void sumarg_open_downgrd(char *buf, size_t buflen, void *obj); 144 static void dtlarg_open_downgrd(void *obj); 145 static void sumarg_putfh(char *buf, size_t buflen, void *obj); 146 static void dtlarg_putfh(void *obj); 147 static void sumarg_read(char *buf, size_t buflen, void *obj); 148 static void dtlarg_read(void *obj); 149 static void sumarg_readdir(char *buf, size_t buflen, void *obj); 150 static void dtlarg_readdir(void *obj); 151 static void sumarg_release_lkown(char *buf, size_t buflen, void *obj); 152 static void dtlarg_release_lkown(void *obj); 153 static void sumarg_rename(char *buf, size_t buflen, void *obj); 154 static void dtlarg_rename(void *obj); 155 static void sumarg_renew(char *buf, size_t buflen, void *obj); 156 static void dtlarg_renew(void *buf); 157 static void sumarg_secinfo(char *buf, size_t buflen, void *obj); 158 static void dtlarg_secinfo(void *obj); 159 static void sumarg_setattr(char *buf, size_t buflen, void *obj); 160 static void dtlarg_setattr(void *obj); 161 static void sumarg_setclid(char *buf, size_t buflen, void *obj); 162 static void dtlarg_setclid(void *obj); 163 static void sumarg_setclid_cfm(char *buf, size_t buflen, void *obj); 164 static void dtlarg_setclid_cfm(void *obj); 165 static void dtlarg_verify(void *obj); 166 static void sumarg_write(char *buf, size_t buflen, void *obj); 167 static void dtlarg_write(void *obj); 168 169 static void sumres_cb_getattr(char *buf, size_t buflen, void *obj); 170 static void dtlres_cb_getattr(void *obj); 171 172 static void sumres_access(char *buf, size_t buflen, void *obj); 173 static void dtlres_access(void *obj); 174 static void sumres_close(char *buf, size_t buflen, void *obj); 175 static void dtlres_close(void *obj); 176 static void sumres_commit(char *buf, size_t buflen, void *obj); 177 static void dtlres_commit(void *obj); 178 static void dtlres_create(void *obj); 179 static void sumres_getattr(char *buf, size_t buflen, void *obj); 180 static void dtlres_getattr(void *obj); 181 static void sumres_getfh(char *buf, size_t buflen, void *obj); 182 static void dtlres_getfh(void *obj); 183 static void dtlres_link(void *obj); 184 static void sumres_lock(char *buf, size_t buflen, void *obj); 185 static void dtlres_lock(void *obj); 186 static void sumres_lockt(char *buf, size_t buflen, void *obj); 187 static void dtlres_lockt(void *obj); 188 static void sumres_locku(char *buf, size_t buflen, void *obj); 189 static void dtlres_locku(void *obj); 190 static void sumres_open(char *buf, size_t buflen, void *obj); 191 static void dtlres_open(void *obj); 192 static void sumres_open_confirm(char *buf, size_t buflen, void *obj); 193 static void dtlres_open_confirm(void *obj); 194 static void sumres_open_downgrd(char *buf, size_t buflen, void *obj); 195 static void dtlres_open_downgrd(void *obj); 196 static void sumres_read(char *buf, size_t buflen, void *obj); 197 static void dtlres_read(void *obj); 198 static void sumres_readdir(char *buf, size_t buflen, void *obj); 199 static void dtlres_readdir(void *obj); 200 static void sumres_readlnk(char *buf, size_t buflen, void *obj); 201 static void dtlres_readlnk(void *obj); 202 static void dtlres_remove(void *obj); 203 static void dtlres_rename(void *obj); 204 static void sumres_secinfo(char *buf, size_t buflen, void *obj); 205 static void dtlres_secinfo(void *obj); 206 static void sumres_setattr(char *buf, size_t buflen, void *obj); 207 static void dtlres_setattr(void *obj); 208 static void sumres_setclid(char *buf, size_t buflen, void *obj); 209 static void dtlres_setclid(void *obj); 210 static void sumres_write(char *buf, size_t buflen, void *obj); 211 static void dtlres_write(void *obj); 212 static void sum_nfsstat4(char *buf, size_t buflen, void *obj); 213 static void dtl_nfsstat4(void *obj); 214 static void nfs4_xdr_skip(int nbytes); 215 static char *sum_lock_type_name(enum nfs_lock_type4 type); 216 217 /* nfs4.1 operations */ 218 static void sumarg_cb_layoutrecall(char *buf, size_t buflen, void *obj); 219 static void dtlarg_cb_layoutrecall(void *obj); 220 static void sumres_cb_layoutrecall(char *buf, size_t buflen, void *obj); 221 static void dtlres_cb_layoutrecall(void *obj); 222 static void sumarg_cb_notify(char *buf, size_t buflen, void *obj); 223 static void dtlarg_cb_notify(void *obj); 224 static void sumres_cb_notify(char *buf, size_t buflen, void *obj); 225 static void dtlres_cb_notify(void *obj); 226 static void sumarg_cb_push_deleg(char *buf, size_t buflen, void *obj); 227 static void dtlarg_cb_push_deleg(void *obj); 228 static void sumres_cb_push_deleg(char *buf, size_t buflen, void *obj); 229 static void dtlres_cb_push_deleg(void *obj); 230 static void sumarg_cb_recall_any(char *buf, size_t buflen, void *obj); 231 static void dtlarg_cb_recall_any(void *obj); 232 static void sumres_cb_recall_any(char *buf, size_t buflen, void *obj); 233 static void dtlres_cb_recall_any(void *obj); 234 static void sumarg_cb_recallable_obj_avail(char *buf, size_t buflen, void *obj); 235 static void dtlarg_cb_recallable_obj_avail(void *obj); 236 static void sumres_cb_recallable_obj_avail(char *buf, size_t buflen, void *obj); 237 static void dtlres_cb_recallable_obj_avail(void *obj); 238 static void sumarg_cb_recall_slot(char *buf, size_t buflen, void *obj); 239 static void dtlarg_cb_recall_slot(void *obj); 240 static void sumres_cb_recall_slot(char *buf, size_t buflen, void *obj); 241 static void dtlres_cb_recall_slot(void *obj); 242 static void sumarg_cb_sequence(char *buf, size_t buflen, void *obj); 243 static void dtlarg_cb_sequence(void *obj); 244 static void sumres_cb_sequence(char *buf, size_t buflen, void *obj); 245 static void dtlres_cb_sequence(void *obj); 246 static void sumarg_cb_wants_cancelled(char *buf, size_t buflen, void *obj); 247 static void dtlarg_cb_wants_cancelled(void *obj); 248 static void sumres_cb_wants_cancelled(char *buf, size_t buflen, void *obj); 249 static void dtlres_cb_wants_cancelled(void *obj); 250 static void sumarg_cb_notify_lock(char *buf, size_t buflen, void *obj); 251 static void dtlarg_cb_notify_lock(void *obj); 252 static void sumres_cb_notify_lock(char *buf, size_t buflen, void *obj); 253 static void dtlres_cb_notify_lock(void *obj); 254 static void sumarg_cb_notify_deviceid(char *buf, size_t buflen, void *obj); 255 static void dtlarg_cb_notify_deviceid(void *obj); 256 257 /* nfs4.1 operations */ 258 static void sumarg_backchannel_ctl(char *buf, size_t buflen, void *obj); 259 static void dtlarg_backchannel_ctl(void *obj); 260 static void sumarg_bind_conn_to_session(char *buf, size_t buflen, void *obj); 261 static void dtlarg_bind_conn_to_session(void *obj); 262 static void sumres_bind_conn_to_session(char *buf, size_t buflen, void *obj); 263 static void dtlres_bind_conn_to_session(void *obj); 264 static void sumarg_exchange_id(char *buf, size_t buflen, void *obj); 265 static void dtlarg_exchange_id(void *obj); 266 static void sumres_exchange_id(char *buf, size_t buflen, void *obj); 267 static void dtlres_exchange_id(void *obj); 268 static void sumarg_create_session(char *buf, size_t buflen, void *obj); 269 static void sumres_create_session(char *buf, size_t buflen, void *obj); 270 static void dtlarg_create_session(void *obj); 271 static void dtlres_create_session(void *obj); 272 static void sumarg_destroy_session(char *buf, size_t buflen, void *obj); 273 static void dtlarg_destroy_session(void *obj); 274 static void sumarg_free_stateid(char *buf, size_t buflen, void *obj); 275 static void dtlarg_free_stateid(void *obj); 276 static void sumarg_get_dir_delegation(char *buf, size_t buflen, void *obj); 277 static void dtlarg_get_dir_delegation(void *obj); 278 static void sumres_get_dir_delegation(char *buf, size_t buflen, void *obj); 279 static void dtlres_get_dir_delegation(void *obj); 280 static void sumarg_getdeviceinfo(char *buf, size_t buflen, void *obj); 281 static void dtlarg_getdeviceinfo(void *obj); 282 static void sumres_getdeviceinfo(char *buf, size_t buflen, void *obj); 283 static void dtlres_getdeviceinfo(void *obj); 284 static void sumarg_getdevicelist(char *buf, size_t buflen, void *obj); 285 static void dtlarg_getdevicelist(void *obj); 286 static void sumres_getdevicelist(char *buf, size_t buflen, void *obj); 287 static void dtlres_getdevicelist(void *obj); 288 static void sumarg_layoutcommit(char *buf, size_t buflen, void *obj); 289 static void dtlarg_layoutcommit(void *obj); 290 static void sumres_layoutcommit(char *buf, size_t buflen, void *obj); 291 static void dtlres_layoutcommit(void *obj); 292 static void sumarg_layoutget(char *buf, size_t buflen, void *obj); 293 static void dtlarg_layoutget(void *obj); 294 static void sumres_layoutget(char *buf, size_t buflen, void *obj); 295 static void dtlres_layoutget(void *obj); 296 static void sumarg_layoutreturn(char *buf, size_t buflen, void *obj); 297 static void dtlarg_layoutreturn(void *obj); 298 static void sumarg_secinfo_no_name(char *buf, size_t buflen, void *obj); 299 static void dtlarg_secinfo_no_name(void *obj); 300 static void sumarg_sequence(char *buf, size_t buflen, void *obj); 301 static void dtlarg_sequence(void *obj); 302 static void sumres_sequence(char *buf, size_t buflen, void *obj); 303 static void dtlres_sequence(void *obj); 304 static void sumarg_set_ssv(char *buf, size_t buflen, void *obj); 305 static void dtlarg_set_ssv(void *obj); 306 static void sumres_set_ssv(char *buf, size_t buflen, void *obj); 307 static void dtlres_set_ssv(void *obj); 308 static void sumarg_test_stateid(char *buf, size_t buflen, void *obj); 309 static void dtlarg_test_stateid(void *obj); 310 static void sumres_test_stateid(char *buf, size_t buflen, void *obj); 311 static void dtlres_test_stateid(void *obj); 312 static void sumarg_want_delegation(char *buf, size_t buflen, void *obj); 313 static void dtlarg_want_delegation(void *obj); 314 static void sumres_want_delegation(char *buf, size_t buflen, void *obj); 315 static void dtlres_want_delegation(void *obj); 316 static void sumarg_destroy_clientid(char *buf, size_t buflen, void *obj); 317 static void dtlarg_destroy_clientid(void *obj); 318 static void sumres_destroy_clientid(char *buf, size_t buflen, void *obj); 319 static void dtlres_destroy_clientid(void *obj); 320 static void sumarg_reclaim_complete(char *buf, size_t buflen, void *obj); 321 static void dtlarg_reclaim_complete(void *obj); 322 static void sumres_reclaim_complete(char *buf, size_t buflen, void *obj); 323 static void dtlres_reclaim_complete(void *obj); 324 325 static void detail_threshold_hint_bitmap(uint32_t); 326 327 int nfs4_pkt_start; 328 int nfs4_pkt_len; 329 int nfs4_skip_bytes; 330 int nfs4_fragged_rpc; 331 char *nfs4err_fragrpc = "<Fragmented RPC>"; 332 char *nfs4err_xdrfrag = "<XDR Error or Fragmented RPC>"; 333 334 /* 335 * need a way to enable this if current testcases are parsing snoop 336 * error text. -- maybe an env var would do as temp workaround until 337 * testcases changed to grep for new error text. 338 */ 339 int nfs4_use_old_error_text = 0; 340 341 /* 342 * Information about each operation that can appear in a compound call. 343 * The function pointers are to formatting functions for summary arguments 344 * and results, and detail arguments & results. 345 */ 346 347 typedef struct { 348 char *name; 349 void (*sumarg)(char *, size_t, void *); 350 void (*sumres)(char *, size_t, void *); 351 void (*dtlarg)(void *); 352 void (*dtlres)(void *); 353 } op_info_t; 354 355 static op_info_t cb_opcode_info[] = { 356 {"OP_ZERO", NULL, NULL, NULL, NULL}, /* 0 */ 357 {"OP_ONE", NULL, NULL, NULL, NULL}, 358 {"OP_TWO", NULL, NULL, NULL, NULL}, /* minor vers */ 359 {"CB_GETATTR", 360 sumarg_cb_getattr, sumres_cb_getattr, 361 dtlarg_cb_getattr, dtlres_cb_getattr}, 362 {"CB_RECALL", 363 sumarg_cb_recall, sum_nfsstat4, 364 dtlarg_cb_recall, dtl_nfsstat4}, 365 {"CB_LAYOUTRECALL", /* 5 */ 366 sumarg_cb_layoutrecall, sumres_cb_layoutrecall, 367 dtlarg_cb_layoutrecall, dtlres_cb_layoutrecall}, 368 {"CB_NOTIFY", 369 sumarg_cb_notify, sumres_cb_notify, 370 dtlarg_cb_notify, dtlres_cb_notify}, 371 {"CB_PUSH_DELEG", 372 sumarg_cb_push_deleg, sumres_cb_push_deleg, 373 dtlarg_cb_push_deleg, dtlres_cb_push_deleg}, 374 {"CB_RECALL_ANY", 375 sumarg_cb_recall_any, sumres_cb_recall_any, 376 dtlarg_cb_recall_any, dtlres_cb_recall_any}, 377 {"CB_RECALLABLE_OBJ_AVAIL", 378 sumarg_cb_recallable_obj_avail, 379 sumres_cb_recallable_obj_avail, 380 dtlarg_cb_recallable_obj_avail, 381 dtlres_cb_recallable_obj_avail}, 382 {"CB_RECALL_SLOT", /* 10 */ 383 sumarg_cb_recall_slot, sumres_cb_recall_slot, 384 dtlarg_cb_recall_slot, dtlres_cb_recall_slot}, 385 {"CB_SEQUENCE", 386 sumarg_cb_sequence, sumres_cb_sequence, 387 dtlarg_cb_sequence, dtlres_cb_sequence}, 388 {"CB_WANTS_CANCELLED", 389 sumarg_cb_wants_cancelled, 390 sumres_cb_wants_cancelled, 391 dtlarg_cb_wants_cancelled, 392 dtlres_cb_wants_cancelled}, 393 {"CB_NOTIFY_LOCK", 394 sumarg_cb_notify_lock, sumres_cb_notify_lock, 395 dtlarg_cb_notify_lock, dtlres_cb_notify_lock}, 396 {"CB_NOTIFY_DEVICEID", 397 sumarg_cb_notify_deviceid, sum_nfsstat4, 398 dtlarg_cb_notify_deviceid, dtl_nfsstat4}, 399 }; 400 static uint_t cb_num_opcodes = sizeof (cb_opcode_info) / sizeof (op_info_t *); 401 402 static op_info_t opcode_info[] = { 403 {"OP_ZERO", NULL, NULL, NULL, NULL}, /* 0 */ 404 {"OP_ONE", NULL, NULL, NULL, NULL}, 405 {"OP_TWO", NULL, NULL, NULL, NULL}, /* minor vers */ 406 {"ACCESS", 407 sumarg_access, sumres_access, dtlarg_access, dtlres_access}, 408 {"CLOSE", 409 sumarg_close, sumres_close, dtlarg_close, dtlres_close}, 410 {"COMMIT", 411 sumarg_commit, sumres_commit, dtlarg_commit, dtlres_commit}, 412 {"CREATE", /* 5 */ 413 sumarg_create, sum_nfsstat4, dtlarg_create, dtlres_create}, 414 {"DELEGPURGE", 415 sumarg_delprge, sum_nfsstat4, dtlarg_delprge, dtl_nfsstat4}, 416 {"DELEGRETURN", 417 sumarg_delret, sum_nfsstat4, dtlarg_delret, dtl_nfsstat4}, 418 {"GETATTR", 419 sumarg_getattr, sumres_getattr, dtlarg_getattr, dtlres_getattr}, 420 {"GETFH", 421 NULL, sumres_getfh, NULL, dtlres_getfh}, 422 {"LINK", /* 10 */ 423 sumarg_link, sum_nfsstat4, dtlarg_link, dtlres_link}, 424 {"LOCK", 425 sumarg_lock, sumres_lock, dtlarg_lock, dtlres_lock}, 426 {"LOCKT", 427 sumarg_lockt, sumres_lockt, dtlarg_lockt, dtlres_lockt}, 428 {"LOCKU", 429 sumarg_locku, sumres_locku, dtlarg_locku, dtlres_locku}, 430 {"LOOKUP", 431 sumarg_lookup, sum_nfsstat4, dtlarg_lookup, dtl_nfsstat4}, 432 {"LOOKUPP", /* 15 */ 433 NULL, sum_nfsstat4, NULL, dtl_nfsstat4}, 434 {"NVERIFY", 435 NULL, sum_nfsstat4, dtlarg_verify, dtl_nfsstat4}, 436 {"OPEN", 437 sumarg_open, sumres_open, dtlarg_open, dtlres_open}, 438 {"OPENATTR", 439 sumarg_openattr, sum_nfsstat4, dtlarg_openattr, dtl_nfsstat4}, 440 {"OPEN_CONFIRM", 441 sumarg_open_confirm, 442 sumres_open_confirm, 443 dtlarg_open_confirm, 444 dtlres_open_confirm}, 445 {"OPEN_DOWNGRADE", 446 sumarg_open_downgrd, 447 sumres_open_downgrd, 448 dtlarg_open_downgrd, 449 dtlres_open_downgrd}, 450 {"PUTFH", 451 sumarg_putfh, sum_nfsstat4, dtlarg_putfh, dtl_nfsstat4}, 452 {"PUTPUBFH", /* 20 */ 453 NULL, sum_nfsstat4, NULL, dtl_nfsstat4}, 454 {"PUTROOTFH", 455 NULL, sum_nfsstat4, NULL, dtl_nfsstat4}, 456 {"READ", 457 sumarg_read, sumres_read, dtlarg_read, dtlres_read}, 458 {"READDIR", 459 sumarg_readdir, sumres_readdir, dtlarg_readdir, dtlres_readdir}, 460 {"READLINK", 461 NULL, sumres_readlnk, NULL, dtlres_readlnk}, 462 {"REMOVE", /* 25 */ 463 sumarg_compnt, sum_nfsstat4, dtlarg_compnt, dtlres_remove}, 464 {"RENAME", 465 sumarg_rename, sum_nfsstat4, dtlarg_rename, dtlres_rename}, 466 {"RENEW", 467 sumarg_renew, sum_nfsstat4, dtlarg_renew, dtl_nfsstat4}, 468 {"RESTOREFH", 469 NULL, sum_nfsstat4, NULL, dtl_nfsstat4}, 470 {"SAVEFH", 471 NULL, sum_nfsstat4, NULL, dtl_nfsstat4}, 472 {"SECINFO", /* 30 */ 473 sumarg_secinfo, sumres_secinfo, dtlarg_secinfo, dtlres_secinfo}, 474 {"SETATTR", 475 sumarg_setattr, sumres_setattr, dtlarg_setattr, dtlres_setattr}, 476 {"SETCLIENTID", 477 sumarg_setclid, sumres_setclid, dtlarg_setclid, dtlres_setclid}, 478 {"SETCLIENTID_CONFIRM", 479 sumarg_setclid_cfm, 480 sum_nfsstat4, 481 dtlarg_setclid_cfm, 482 dtl_nfsstat4}, 483 {"VERIFY", 484 NULL, sum_nfsstat4, dtlarg_verify, dtl_nfsstat4}, 485 {"WRITE", 486 sumarg_write, sumres_write, dtlarg_write, dtlres_write}, 487 {"RELEASE_LOCKOWNER", 488 sumarg_release_lkown, sum_nfsstat4, 489 dtlarg_release_lkown, dtl_nfsstat4}, 490 /* nfs4.1 operations */ 491 {"BACKCHANNEL_CTL", /* 40 */ 492 sumarg_backchannel_ctl, sum_nfsstat4, 493 dtlarg_backchannel_ctl, dtl_nfsstat4}, 494 {"BIND_CONN_TO_SESSION", 495 sumarg_bind_conn_to_session, sumres_bind_conn_to_session, 496 dtlarg_bind_conn_to_session, dtlres_bind_conn_to_session}, 497 {"EXCHANGE_ID", 498 sumarg_exchange_id, sumres_exchange_id, 499 dtlarg_exchange_id, dtlres_exchange_id}, 500 {"CREATE_SESSION", 501 sumarg_create_session, sumres_create_session, 502 dtlarg_create_session, dtlres_create_session}, 503 {"DESTROY_SESSION", 504 sumarg_destroy_session, sum_nfsstat4, 505 dtlarg_destroy_session, dtl_nfsstat4}, 506 {"FREE_STATEID", /* 45 */ 507 sumarg_free_stateid, sum_nfsstat4, 508 dtlarg_free_stateid, dtl_nfsstat4}, 509 {"GET_DIR_DELEGATION", 510 sumarg_get_dir_delegation, sumres_get_dir_delegation, 511 dtlarg_get_dir_delegation, dtlres_get_dir_delegation}, 512 {"GETDEVICEINFO", 513 sumarg_getdeviceinfo, sumres_getdeviceinfo, 514 dtlarg_getdeviceinfo, dtlres_getdeviceinfo}, 515 {"GETDEVICELIST", 516 sumarg_getdevicelist, sumres_getdevicelist, 517 dtlarg_getdevicelist, dtlres_getdevicelist}, 518 {"LAYOUTCOMMIT", 519 sumarg_layoutcommit, sumres_layoutcommit, 520 dtlarg_layoutcommit, dtlres_layoutcommit}, 521 {"LAYOUTGET", /* 50 */ 522 sumarg_layoutget, sumres_layoutget, 523 dtlarg_layoutget, dtlres_layoutget}, 524 {"LAYOUTRETURN", 525 sumarg_layoutreturn, sum_nfsstat4, 526 dtlarg_layoutreturn, dtl_nfsstat4}, 527 {"SECINFO_NO_NAME", 528 sumarg_secinfo_no_name, sumres_secinfo, 529 dtlarg_secinfo_no_name, dtlres_secinfo}, 530 {"SEQUENCE", 531 sumarg_sequence, sumres_sequence, 532 dtlarg_sequence, dtlres_sequence}, 533 {"SET_SSV", 534 sumarg_set_ssv, sumres_set_ssv, 535 dtlarg_set_ssv, dtlres_set_ssv}, 536 {"TEST_STATEID", /* 55 */ 537 sumarg_test_stateid, sumres_test_stateid, 538 dtlarg_test_stateid, dtlres_test_stateid}, 539 {"WANT_DELEGATION", 540 sumarg_want_delegation, sumres_want_delegation, 541 dtlarg_want_delegation, dtlres_want_delegation}, 542 {"DESTROY_CLIENTID", 543 sumarg_destroy_clientid, sumres_destroy_clientid, 544 dtlarg_destroy_clientid, dtlres_destroy_clientid}, 545 {"RECLAIM_COMPLETE", 546 sumarg_reclaim_complete, sumres_reclaim_complete, 547 dtlarg_reclaim_complete, dtlres_reclaim_complete}, 548 }; 549 static uint_t num_opcodes = sizeof (opcode_info) / sizeof (op_info_t *); 550 551 552 typedef struct { 553 char *short_name; /* for summary output */ 554 char *long_name; /* for detail output */ 555 } type_names_t; 556 557 558 /* 559 * Layout Recall types 560 */ 561 static type_names_t lortype_names[] = { 562 {"Type 0", "Type 0"}, 563 {"FILE", "Layout for File handle"}, 564 {"FSID", "All layouts for objects in FSID"}, 565 {"ALL", "All layouts"}, 566 }; 567 static uint_t num_lortypes = sizeof (lortype_names) / sizeof (type_names_t); 568 569 570 /* 571 * Layout types 572 */ 573 static type_names_t lotype_names[] = { 574 {"Type 0", "Type 0"}, 575 {"FILE", "LAYOUT4_NFSV4_1_FILES"}, 576 {"OBJ", "LAYOUT4_OSD2_OBJECTS"}, 577 {"VOL", "LAYOUT4_BLOCK_VOLUME"}, 578 }; 579 static uint_t num_lotypes = sizeof (lotype_names) / sizeof (type_names_t); 580 581 /* 582 * Layout iomodes 583 */ 584 585 static type_names_t iomode_names[] = { 586 {"?", "UNKNOWN"}, 587 {"READ", "LAYOUTIOMODE4_READ"}, 588 {"RW", "LAYOUTIOMODE4_RW"}, 589 {"ANY", "LAYOUTIOMODE4_ANY"}, 590 }; 591 static uint_t num_iomodes = sizeof (iomode_names) / sizeof (type_names_t); 592 593 /* 594 * Layoutreturn types 595 */ 596 597 static type_names_t lrtype_names[] = { 598 {"?", "UNKNOWN"}, 599 {"FILE", "LAYOUTRETURN4_FILE"}, 600 {"FSID", "LAYOUTRETURN4_FSID"}, 601 {"ALL", "LAYOUTRETURN4_ALL"}, 602 }; 603 static uint_t num_lrtypes = sizeof (lrtype_names) / sizeof (type_names_t); 604 605 /* stripe type */ 606 static type_names_t stripe_names[] = { 607 {"?", "UNKNOWN"}, 608 {"SPARSE", "STRIPE4_SPARSE"}, 609 {"DENSE", "STRIPE4_DENSE"}, 610 }; 611 static uint_t num_stripes = sizeof (stripe_names) / sizeof (type_names_t); 612 613 /* how the client wants to protect its client */ 614 static type_names_t ps_names[] = { 615 {"NONE", "SP4_NONE"}, 616 {"MACH_CRED", "SP4_MACH_CRED"}, 617 {"SSV", "SP4_SSV"}, 618 }; 619 static uint_t num_ps = sizeof (ps_names) / sizeof (type_names_t); 620 621 /* 622 * File types. 623 */ 624 625 typedef type_names_t ftype_names_t; 626 627 static ftype_names_t ftype_names[] = { 628 {"Type 0", "Type 0"}, 629 {"REG", "Regular File"}, 630 {"DIR", "Directory"}, 631 {"BLK", "Block Device"}, 632 {"CHR", "Character Device"}, 633 {"LNK", "Symbolic Link"}, /* 5 */ 634 {"SOCK", "Socket"}, 635 {"FIFO", "FIFO"}, 636 {"ATTRDIR", "Attribute Directory"}, 637 {"NAMEDATTR", "Named Attribute"}, 638 }; 639 static uint_t num_ftypes = sizeof (ftype_names) / sizeof (ftype_names_t); 640 641 typedef type_names_t flag_t; 642 643 static flag_t open_rflags[] = { 644 {"?", "UNKNOWN"}, /* 0 */ 645 {"CF", "CONFIRM"}, /* 1 */ 646 {"PL", "POSIX LOCK"}, /* 2 */ 647 {"?", "UNKNOWN"}, 648 }; 649 static uint_t num_open_rflags = 650 sizeof (open_rflags) / sizeof (ftype_names_t) - 1; 651 652 static char *get_flags(uint_t, ftype_names_t *, uint_t, int, char *); 653 654 #define sum_open_rflags(flag) \ 655 get_flags((flag), open_rflags, num_open_rflags, 1, " RF=") 656 657 #define detail_open_rflags(flag) \ 658 get_flags((flag), open_rflags, num_open_rflags, 0, NULL) 659 660 static void prt_supported_attrs(XDR *); 661 static void prt_type(XDR *); 662 static void prt_fh_expire_type(XDR *); 663 static void prt_change(XDR *); 664 static void prt_size(XDR *); 665 static void prt_link_support(XDR *); 666 static void prt_symlink_support(XDR *); 667 static void prt_named_attr(XDR *); 668 static void prt_fsid(XDR *); 669 static void prt_unique_handles(XDR *); 670 static void prt_lease_time(XDR *); 671 static void prt_rdattr_error(XDR *); 672 static void prt_acl(XDR *); 673 static void prt_aclsupport(XDR *); 674 static void prt_archive(XDR *); 675 static void prt_cansettime(XDR *); 676 static void prt_case_insensitive(XDR *); 677 static void prt_case_preserving(XDR *); 678 static void prt_chown_restricted(XDR *); 679 static void prt_filehandle(XDR *); 680 static void prt_fileid(XDR *); 681 static void prt_mounted_on_fileid(XDR *); 682 static void prt_files_avail(XDR *); 683 static void prt_files_free(XDR *); 684 static void prt_files_total(XDR *); 685 static void prt_fs_locations(XDR *); 686 static void prt_hidden(XDR *); 687 static void prt_homogeneous(XDR *); 688 static void prt_maxfilesize(XDR *); 689 static void prt_maxlink(XDR *); 690 static void prt_maxname(XDR *); 691 static void prt_maxread(XDR *); 692 static void prt_maxwrite(XDR *); 693 static void prt_mimetype(XDR *); 694 static void prt_mode(XDR *); 695 static void prt_no_trunc(XDR *); 696 static void prt_numlinks(XDR *); 697 static void prt_owner(XDR *); 698 static void prt_owner_group(XDR *); 699 static void prt_quota_avail_hard(XDR *); 700 static void prt_quota_avail_soft(XDR *); 701 static void prt_quota_used(XDR *); 702 static void prt_rawdev(XDR *); 703 static void prt_space_avail(XDR *); 704 static void prt_space_free(XDR *); 705 static void prt_space_total(XDR *); 706 static void prt_space_used(XDR *); 707 static void prt_system(XDR *); 708 static void prt_time_access(XDR *); 709 static void prt_time_access_set(XDR *); 710 static void prt_time_backup(XDR *); 711 static void prt_time_create(XDR *); 712 static void prt_time_delta(XDR *); 713 static void prt_time_metadata(XDR *); 714 static void prt_time_modify(XDR *); 715 static void prt_time_modify_set(XDR *); 716 /* nfs4.1 attributes */ 717 static void prt_dir_notif_delay(XDR *); 718 static void prt_dirent_notif_delay(XDR *); 719 static void prt_dacl(XDR *); 720 static void prt_sacl(XDR *); 721 static void prt_change_policy(XDR *); 722 static void prt_fs_status(XDR *); 723 static void prt_fs_layout_type(XDR *); 724 static void prt_layout_hint(XDR *); 725 static void prt_layout_type(XDR *); 726 static void prt_layout_blksize(XDR *); 727 static void prt_layout_alignment(XDR *); 728 static void prt_fs_locations_info(XDR *); 729 static void prt_mdsthreshold(XDR *); 730 static void prt_retention_get(XDR *); 731 static void prt_retention_set(XDR *); 732 static void prt_retentevt_get(XDR *); 733 static void prt_retentevt_set(XDR *); 734 static void prt_retention_hold(XDR *); 735 static void prt_mode_set_masked(XDR *); 736 static void prt_suppattr_exclcreat(XDR *); 737 static void prt_fs_charset_cap(XDR *); 738 739 740 /* 741 * Information for attributes. 742 * name name of the attribute. 743 * prt_details function to XDR decode the attribute and print it. 744 * 745 * XXX If this table ever gets extensively changed (including 746 * reorganization to track changes to the spec), it would probably be a 747 * good idea to change to a scheme where the table is mechanically 748 * generated. Look at $SRC/uts/common/rpcsvc for how this is done in the 749 * kernel. 750 */ 751 752 typedef struct { 753 char *name; 754 void (*prt_details)(XDR *); 755 } attr_info_t; 756 757 758 #define TH4_READ_SIZE_MASK (1 << TH4_READ_SIZE) 759 #define TH4_WRITE_SIZE_MASK (1 << TH4_WRITE_SIZE) 760 #define TH4_READ_IOSIZE_MASK (1 << TH4_READ_IOSIZE) 761 #define TH4_WRITE_IOSIZE_MASK (1 << TH4_WRITE_IOSIZE) 762 763 static attr_info_t attr_info[MAX_ATTRIBUTES] = { 764 {"SUPPORTED_ATTRS", prt_supported_attrs}, 765 {"TYPE", prt_type}, 766 {"FH_EXPIRE_TYPE", prt_fh_expire_type}, 767 {"CHANGE", prt_change}, 768 {"SIZE", prt_size}, 769 {"LINK_SUPPORT", prt_link_support}, /* 5 */ 770 {"SYMLINK_SUPPORT", prt_symlink_support}, 771 {"NAMED_ATTR", prt_named_attr}, 772 {"FSID", prt_fsid}, 773 {"UNIQUE_HANDLES", prt_unique_handles}, 774 {"LEASE_TIME", prt_lease_time}, /* 10 */ 775 {"RDATTR_ERROR", prt_rdattr_error}, 776 {"ACL", prt_acl}, 777 {"ACLSUPPORT", prt_aclsupport}, 778 {"ARCHIVE", prt_archive}, 779 {"CANSETTIME", prt_cansettime}, /* 15 */ 780 {"CASE_INSENSITIVE", prt_case_insensitive}, 781 {"CASE_PRESERVING", prt_case_preserving}, 782 {"CHOWN_RESTRICTED", prt_chown_restricted}, 783 {"FILEHANDLE", prt_filehandle}, 784 {"FILEID", prt_fileid}, /* 20 */ 785 {"FILES_AVAIL", prt_files_avail}, 786 {"FILES_FREE", prt_files_free}, 787 {"FILES_TOTAL", prt_files_total}, 788 {"FS_LOCATIONS", prt_fs_locations}, 789 {"HIDDEN", prt_hidden}, /* 25 */ 790 {"HOMOGENEOUS", prt_homogeneous}, 791 {"MAXFILESIZE", prt_maxfilesize}, 792 {"MAXLINK", prt_maxlink}, 793 {"MAXNAME", prt_maxname}, 794 {"MAXREAD", prt_maxread}, /* 30 */ 795 {"MAXWRITE", prt_maxwrite}, 796 {"MIMETYPE", prt_mimetype}, 797 {"MODE", prt_mode}, 798 {"NO_TRUNC", prt_no_trunc}, 799 {"NUMLINKS", prt_numlinks}, /* 35 */ 800 {"OWNER", prt_owner}, 801 {"OWNER_GROUP", prt_owner_group}, 802 {"QUOTA_AVAIL_HARD", prt_quota_avail_hard}, 803 {"QUOTA_AVAIL_SOFT", prt_quota_avail_soft}, 804 {"QUOTA_USED", prt_quota_used}, /* 40 */ 805 {"RAWDEV", prt_rawdev}, 806 {"SPACE_AVAIL", prt_space_avail}, 807 {"SPACE_FREE", prt_space_free}, 808 {"SPACE_TOTAL", prt_space_total}, 809 {"SPACE_USED", prt_space_used}, /* 45 */ 810 {"SYSTEM", prt_system}, 811 {"TIME_ACCESS", prt_time_access}, 812 {"TIME_ACCESS_SET", prt_time_access_set}, 813 {"TIME_BACKUP", prt_time_backup}, 814 {"TIME_CREATE", prt_time_create}, /* 50 */ 815 {"TIME_DELTA", prt_time_delta}, 816 {"TIME_METADATA", prt_time_metadata}, 817 {"TIME_MODIFY", prt_time_modify}, 818 {"TIME_MODIFY_SET", prt_time_modify_set}, 819 {"MOUNTED_ON_FILEID", prt_mounted_on_fileid}, /* 55 */ 820 /* Attributes supported in nfs4.1 */ 821 {"DIR_NOTIF_DELAY", prt_dir_notif_delay}, 822 {"DIRENT_NOTIF_DELAY", prt_dirent_notif_delay}, 823 {"DACL", prt_dacl}, 824 {"SACL", prt_sacl}, 825 {"CHANGE_POLICY", prt_change_policy}, /* 60 */ 826 {"FS_STATUS", prt_fs_status}, 827 {"FS_LAYOUT_TYPE", prt_fs_layout_type}, 828 {"LAYOUT_HINT", prt_layout_hint}, 829 {"LAYOUT_TYPE", prt_layout_type}, 830 {"LAYOUT_BLKSIZE", prt_layout_blksize}, /* 65 */ 831 {"LAYOUT_ALIGNMENT", prt_layout_alignment}, 832 {"FS_LOCATIONS_INFO", prt_fs_locations_info}, 833 {"MDSTHRESHOLD", prt_mdsthreshold}, 834 {"RETENTION_GET", prt_retention_get}, 835 {"RETENTION_SET", prt_retention_set}, /* 70 */ 836 {"RETENTEVT_GET", prt_retentevt_get}, 837 {"RETENTEVT_SET", prt_retentevt_set}, 838 {"RETENTION_HOLD", prt_retention_hold}, 839 {"MODE_SET_MASKED", prt_mode_set_masked}, 840 {"SUPPATTR_EXCLCREAT", prt_suppattr_exclcreat}, /* 75 */ 841 {"FS_CHARSET_CAP", prt_fs_charset_cap}, 842 }; 843 844 extern char *get_sum_line(); 845 846 extern jmp_buf xdr_err; 847 848 static void sum_comp4res(char *, char *(*)(void)); 849 static char *sum_compound4args(void); 850 static char *sum_compound4res(void); 851 static char *sum_operand(nfs_argop4 *opp); 852 static char *sum_result(nfs_resop4 *resp); 853 854 static char *sum_cb_compound4args(void); 855 static char *sum_cb_compound4res(void); 856 static char *sum_cb_operand(nfs_cb_argop4 *opp); 857 static char *sum_cb_result(nfs_cb_resop4 *resp); 858 859 static void detail_acetype4(acetype4); 860 static void detail_uint32_bitmap(uint32_t, char *[], int); 861 static void detail_aceflag4(aceflag4); 862 static void detail_acemask4(acemask4); 863 static void detail_nfs_argop4(void); 864 static void detail_nfs_resop4(void); 865 static void detail_cb_argop4(void); 866 static void detail_cb_resop4(void); 867 868 static char *attr_name(uint_t); 869 static char *claim_name(enum open_claim_type4 claim_type); 870 static char *delegation_type_name(enum open_delegation_type4 type); 871 static char *flavor_name(uint_t flavor); 872 static char *gss_svc_name(rpc_gss_svc_t svc); 873 static char *limitby_name(enum limit_by4 limitby); 874 static char *lock_type_name(enum nfs_lock_type4); 875 static char *opcode_name(uint_t); 876 static char *cb_opcode_name(uint_t opnum); 877 static char *status_name(int); 878 static char *status_name_compat(int); 879 static char *status_name_pcol(int); 880 static char *sum_type_name(nfs_ftype4); 881 static void sum_access4(char *buf, size_t buflen, uint32_t bits); 882 static void detail_access4(char *, uint32_t); 883 static void sum_claim(char *buf, size_t buflen, open_claim4 *claim); 884 static void detail_claim(open_claim4 *claim); 885 static void sum_delegation(char *buf, size_t buflen, open_delegation4 *delp); 886 static void detail_delegation(open_delegation4 *delp); 887 static void detail_lock_owner(lock_owner4 *owner); 888 static void detail_open_owner(open_owner4 *owner); 889 static void sum_openflag(char *bufp, int buflen, openflag4 *flagp); 890 static char *get_deleg_typestr(open_delegation_type4 dt); 891 static void detail_openflag(openflag4 *flagp); 892 static void sum_name(char *buf, size_t buflen, open_claim4 *claim); 893 static void detail_rpcsec_gss(rpcsec_gss_info *); 894 static char *sum_space_limit(nfs_space_limit4 *limitp); 895 static void detail_space_limit(nfs_space_limit4 *limitp); 896 static char *detail_type_name(nfs_ftype4); 897 static char *createhow4_name(createhow4 *crtp); 898 899 900 static void showxdr_utf8string(char *); 901 static void sum_pathname4(char *, size_t, pathname4 *); 902 static void detail_pathname4(pathname4 *pathp); 903 static void sum_compname4(char *buf, size_t buflen, component4 *comp); 904 static void detail_compname4(component4 *comp); 905 906 static void detail_fattr4(fattr4 *attrp); 907 static void detail_attr_bitmap(char *, bitmap4 *, unpkd_attrmap_t *); 908 static void sum_attr_bitmap(char *buf, size_t buflen, bitmap4 *mapp); 909 static void detail_fattr4_change(char *msg, fattr4_change chg); 910 911 #define DONT_CHANGE 0 912 #define SET_TO_SERVER_TIME 1 913 #define SET_TO_CLIENT_TIME 2 914 915 static stateid4 spec_stateid_0 = 916 {0, {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}}; 917 static stateid4 spec_stateid_1 = 918 {0xFFFFFFFF, {-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}}; 919 920 static char *procnames_short[] = { 921 "NULL4", /* 0 */ 922 "COMPOUND4" /* 1 */ 923 }; 924 925 static char *procnames_long[] = { 926 "Null procedure", /* 0 */ 927 "Compound", /* 1 */ 928 }; 929 930 static char *cb_procnames_short[] = { 931 "CB_NULL", /* 0 */ 932 "CB_COMPOUND" /* 1 */ 933 }; 934 935 static char *cb_procnames_long[] = { 936 "Null CallBack procedure", /* 0 */ 937 "CallBack compound", /* 1 */ 938 }; 939 940 static char *acetype4_names[] = { 941 "ACE4_ACCESS_ALLOWED_ACE_TYPE", 942 "ACE4_ACCESS_DENIED_ACE_TYPE", 943 "ACE4_SYSTEM_AUDIT_ACE_TYPE", 944 "ACE4_SYSTEM_ALARM_ACE_TYPE" 945 }; 946 #define ACETYPE4_NAMES_MAX (sizeof (acetype4_names) / sizeof (char *)) 947 948 static char *aceflag4_names[] = { 949 "ACE4_FILE_INHERIT_ACE", 950 "ACE4_DIRECTORY_INHERIT_ACE", 951 "ACE4_NO_PROPAGATE_INHERIT_ACE", 952 "ACE4_INHERIT_ONLY_ACE", 953 "ACE4_SUCCESSFUL_ACCESS_ACE_FLAG", 954 "ACE4_FAILED_ACCESS_ACE_FLAG", 955 "ACE4_IDENTIFIER_GROUP" 956 }; 957 #define ACEFLAG4_NAMES_MAX (sizeof (aceflag4_names) / sizeof (char *)) 958 959 static char *acemask4_names[] = { 960 "ACE4_READ_DATA/ACE4_LIST_DIRECTORY", 961 "ACE4_WRITE_DATA/ACE4_ADD_FILE", 962 "ACE4_APPEND_DATA/ACE4_ADD_SUBDIRECTORY", 963 "ACE4_READ_NAMED_ATTRS", 964 "ACE4_WRITE_NAMED_ATTRS", 965 "ACE4_EXECUTE", 966 "ACE4_DELETE_CHILD", 967 "ACE4_READ_ATTRIBUTES", 968 "ACE4_WRITE_ATTRIBUTES", 969 "UNDEFINED", /* 0x00000200 */ 970 "UNDEFINED", /* 0x00000400 */ 971 "UNDEFINED", /* 0x00000800 */ 972 "UNDEFINED", /* 0x00001000 */ 973 "UNDEFINED", /* 0x00002000 */ 974 "UNDEFINED", /* 0x00004000 */ 975 "UNDEFINED", /* 0x00008000 */ 976 "ACE4_DELETE", 977 "ACE4_READ_ACL", 978 "ACE4_WRITE_ACL", 979 "ACE4_WRITE_OWNER", 980 "ACE4_SYNCHRONIZE" 981 }; 982 #define ACEMASK4_NAMES_MAX (sizeof (acemask4_names) / sizeof (char *)) 983 984 static char *seq_status[] = { 985 "SEQ4_STATUS_CB_PATH_DOWN", 986 "SEQ4_STATUS_CB_GSS_CONTEXTS_EXPIRING", 987 "SEQ4_STATUS_CB_GSS_CONTEXTS_EXPIRED", 988 "SEQ4_STATUS_EXPIRED_ALL_STATE_REVOKED", 989 "SEQ4_STATUS_EXPIRED_SOME_STATE_REVOKED", 990 "SEQ4_STATUS_ADMIN_STATE_REVOKED", 991 "SEQ4_STATUS_RECALLABLE_STATE_REVOKED", 992 "SEQ4_STATUS_LEASE_MOVED", 993 "SEQ4_STATUS_RESTART_RECLAIM_NEEDED" 994 }; 995 #define SEQ_STATUS_MAX (sizeof (seq_status) / sizeof (char *)) 996 997 static flag_t session_flags[] = { 998 {"RS", "PERSIST"}, /* 1: Reliable semantics */ 999 {"BC", "BACKCHAN"}, /* 2: conn used for back channel, too */ 1000 {"DP", "RDMA"}, /* 3: conn is non-streamed; Begin RDMA */ 1001 {"?", "UNKNOWN"} /* 4: Unknown Flag */ 1002 }; 1003 static uint_t num_session_flags = sizeof (session_flags) / sizeof (flag_t) - 1; 1004 1005 #define sum_sn_flags(flag) \ 1006 get_flags((flag), session_flags, num_session_flags, 1, " SF=") 1007 #define detail_sn_flags(flag) \ 1008 get_flags((flag), session_flags, num_session_flags, 0, NULL) 1009 1010 #define MAXPROC 1 1011 1012 /*ARGSUSED*/ 1013 void 1014 interpret_nfs4_cb(int flags, int type, int xid, int vers, int proc, 1015 char *data, int len) 1016 { 1017 char *line = NULL; 1018 1019 if (proc < 0 || proc > MAXPROC) 1020 return; 1021 1022 if (flags & F_SUM) { 1023 line = get_sum_line(); 1024 1025 if (type == CALL) { 1026 (void) sprintf(line, "NFS C %s", 1027 proc == CB_COMPOUND ? "CB4" : 1028 cb_procnames_short[proc]); 1029 line += strlen(line); 1030 1031 if (proc == CB_COMPOUND) { 1032 static utf8string tag; 1033 1034 if (!xdr_utf8string(&xdrm, &tag)) 1035 longjmp(xdr_err, 1); 1036 sprintf(line, " (%.20s) %s", 1037 utf8localize(&tag), 1038 sum_cb_compound4args()); 1039 xdr_free(xdr_utf8string, (char *)&tag); 1040 } 1041 check_retransmit(line, xid); 1042 } else { 1043 (void) sprintf(line, "NFS R %s ", 1044 proc == CB_COMPOUND ? "CB4" : 1045 cb_procnames_short[proc]); 1046 line += strlen(line); 1047 if (proc == CB_COMPOUND) 1048 sum_comp4res(line, sum_cb_compound4res); 1049 } 1050 } 1051 1052 if (flags & F_DTAIL) { 1053 show_header("NFS: ", "Sun NFS4 CallBack", len); 1054 show_space(); 1055 (void) sprintf(get_line(0, 0), "Proc = %d (%s)", 1056 proc, cb_procnames_long[proc]); 1057 if (proc == CB_COMPOUND) { 1058 if (type == CALL) { 1059 showxdr_utf8string("Tag = %s"); 1060 detail_cb_argop4(); 1061 } else { 1062 nfsstat4 status; 1063 1064 status = getxdr_long(); 1065 showxdr_utf8string("Tag = %s"); 1066 sprintf(get_line(0, 0), "Status = %d (%s)", 1067 status, status_name(status)); 1068 detail_cb_resop4(); 1069 } 1070 } 1071 show_trailer(); 1072 } 1073 1074 utf8free(); /* cf. utf8localize() */ 1075 } 1076 1077 1078 /*ARGSUSED*/ 1079 void 1080 interpret_nfs4(int flags, int type, int xid, int vers, int proc, 1081 char *data, int len) 1082 { 1083 char *line = NULL; 1084 1085 if (proc < 0 || proc > MAXPROC) 1086 return; 1087 1088 nfs4_fragged_rpc = 0; 1089 nfs4_pkt_len = len; 1090 nfs4_pkt_start = xdr_getpos(&xdrm); 1091 1092 if (flags & F_SUM) { 1093 line = get_sum_line(); 1094 1095 if (type == CALL) { 1096 (void) sprintf(line, "NFS C %s", 1097 proc == NFSPROC4_COMPOUND ? "4" : 1098 procnames_short[proc]); 1099 line += strlen(line); 1100 1101 if (proc == NFSPROC4_COMPOUND) { 1102 static utf8string tag; 1103 1104 if (!xdr_utf8string(&xdrm, &tag)) 1105 longjmp(xdr_err, 1); 1106 sprintf(line, " (%.20s) %s", 1107 utf8localize(&tag), 1108 sum_compound4args()); 1109 xdr_free(xdr_utf8string, (char *)&tag); 1110 } 1111 check_retransmit(line, xid); 1112 } else { 1113 (void) sprintf(line, "NFS R %s ", 1114 proc == NFSPROC4_COMPOUND ? "4" : 1115 procnames_short[proc]); 1116 line += strlen(line); 1117 1118 if (proc == NFSPROC4_COMPOUND) 1119 sum_comp4res(line, sum_compound4res); 1120 } 1121 } 1122 1123 if (flags & F_DTAIL) { 1124 show_header("NFS: ", "Sun NFS", len); 1125 show_space(); 1126 (void) sprintf(get_line(0, 0), "Proc = %d (%s)", 1127 proc, procnames_long[proc]); 1128 if (proc == NFSPROC4_COMPOUND) { 1129 if (type == CALL) { 1130 showxdr_utf8string("Tag = %s"); 1131 detail_nfs_argop4(); 1132 } else { 1133 nfsstat4 status; 1134 1135 status = getxdr_long(); 1136 showxdr_utf8string("Tag = %s"); 1137 sprintf(get_line(0, 0), "Status = %d (%s)", 1138 status, status_name(status)); 1139 detail_nfs_resop4(); 1140 } 1141 } 1142 show_trailer(); 1143 } 1144 1145 utf8free(); /* cf. utf8localize() */ 1146 } 1147 1148 1149 1150 /* 1151 * Return the names and arguments of the oplist elements, up to 1152 * SUM_COMPND_MAX characters. If the elements don't fit, include a "..." 1153 * at the end of the string. 1154 */ 1155 1156 static char * 1157 sum_compound4args(void) 1158 { 1159 static char buf[SUM_COMPND_MAX + 2]; /* 1 for null, 1 for overflow */ 1160 int numops; 1161 const size_t buflen = sizeof (buf); 1162 char *bp; 1163 nfs_argop4 one_op; 1164 uint32_t minor_version; 1165 1166 buf[0] = '\0'; 1167 1168 if (setjmp(xdr_err)) { 1169 bp = buf + strlen(buf); 1170 snprintf(bp, buflen - (bp - buf), 1171 nfs4_fragged_rpc ? nfs4err_fragrpc : nfs4err_xdrfrag); 1172 return (buf); 1173 } 1174 1175 /* 1176 * might be nice to print minor version, but doesn't 1177 * seem like very useful info for summary mode 1178 */ 1179 if (!xdr_uint32_t(&xdrm, &minor_version)) 1180 longjmp(xdr_err, 1); 1181 1182 numops = getxdr_long(); 1183 bp = buf; 1184 while (numops-- > 0) { 1185 char *operand; 1186 1187 bzero(&one_op, sizeof (one_op)); 1188 1189 if (!xdr_nfs_argop4(&xdrm, &one_op)) { 1190 xdr_free(xdr_nfs_argop4, (char *)&one_op); 1191 longjmp(xdr_err, 1); 1192 } 1193 snprintf(bp, buflen - (bp - buf), "%s ", 1194 opcode_name(one_op.argop)); 1195 bp += strlen(bp); 1196 1197 operand = sum_operand(&one_op); 1198 if (strlen(operand) > 0) { 1199 snprintf(bp, buflen - (bp - buf), "%s ", operand); 1200 bp += strlen(bp); 1201 } 1202 1203 /* nfs4_skip_bytes set by xdr_nfs4_argop4 */ 1204 if (nfs4_skip_bytes != 0) 1205 nfs4_xdr_skip(nfs4_skip_bytes); 1206 1207 xdr_free(xdr_nfs_argop4, (char *)&one_op); 1208 1209 /* add "..." if past the "end" of the buffer */ 1210 if (bp - buf > SUM_COMPND_MAX) { 1211 strcpy(buf + SUM_COMPND_MAX - strlen("..."), 1212 "..."); 1213 break; 1214 } 1215 } 1216 1217 return (buf); 1218 } 1219 1220 static void 1221 nfs4_xdr_skip(int nbytes) 1222 { 1223 int resid, off, len, cur_pos, new_pos; 1224 1225 len = RNDUP(nbytes); 1226 cur_pos = xdr_getpos(&xdrm); 1227 1228 /* 1229 * Time to skip over the rd/wr data. If the 1230 * rd/wr data is completely contained in the first 1231 * frag, we must skip over it to process the rest of 1232 * the packet. 1233 * 1234 * nfs4_pkt_start: XDR position of start of NFS4 compound 1235 * nfs4_pkt_len: number of bytes in pkt relative to 1236 * nfs4_pkt_start 1237 * 1238 * cur_pos: current XDR position 1239 * off: current XDR position relative to nfs4_pkt_start 1240 * resid: number of unprocessed bytes in current pkt 1241 * (relative to cur_pos/off) 1242 * 1243 * If nbytes <= resid, then we must skip over the rd/wr 1244 * bytes so we can read the next op/compound in this 1245 * packet. Otherwise, set the fragged flag so we can 1246 * display the fragged_rpc message. 1247 */ 1248 off = cur_pos - nfs4_pkt_start; 1249 resid = nfs4_pkt_len - off; 1250 1251 /* 1252 * set nfs4_fragged_rpc if the requested number of "skip" 1253 * bytes is larger than the bytes remaining in the XDR 1254 * stream/current packet. The global is reset to 0 at 1255 * start of interpret_nfs4. 1256 */ 1257 new_pos = cur_pos + ((nfs4_fragged_rpc = len > resid) ? resid : len); 1258 1259 /* there's nothing to do for error case (if it fails pkt is doomed) */ 1260 xdr_setpos(&xdrm, new_pos); 1261 } 1262 1263 1264 /* 1265 * Return the names and arguments of the oplist elements, up to 1266 * SUM_COMPND_MAX characters. If the elements don't fit, include a "..." 1267 * at the end of the string. 1268 */ 1269 static char * 1270 sum_cb_compound4args(void) 1271 { 1272 static char buf[SUM_COMPND_MAX + 2]; /* 1 for null, 1 for overflow */ 1273 int numops; 1274 const size_t buflen = sizeof (buf); 1275 char *bp; 1276 nfs_cb_argop4 one_op; 1277 uint32_t minor_version, callback_ident; 1278 1279 buf[0] = '\0'; 1280 if (setjmp(xdr_err)) { 1281 bp = buf + strlen(buf); 1282 snprintf(bp, buflen - (bp - buf), "<XDR Error or Fragmented" 1283 " RPC>"); 1284 return (buf); 1285 } 1286 1287 /* 1288 * might be nice to print minor version, but doesn't 1289 * seem like very useful info for summary mode 1290 */ 1291 if (!xdr_uint32_t(&xdrm, &minor_version)) 1292 longjmp(xdr_err, 1); 1293 1294 /* print callback_ident */ 1295 if (!xdr_uint32_t(&xdrm, &callback_ident)) 1296 longjmp(xdr_err, 1); 1297 snprintf(buf, buflen, "CBID=%u ", callback_ident); 1298 1299 bp = buf + strlen(buf); 1300 numops = getxdr_long(); 1301 1302 while (numops-- > 0) { 1303 char *operand; 1304 1305 bzero(&one_op, sizeof (one_op)); 1306 if (!xdr_nfs_cb_argop4(&xdrm, &one_op)) { 1307 xdr_free(xdr_nfs_cb_argop4, (char *)&one_op); 1308 longjmp(xdr_err, 1); 1309 } 1310 1311 snprintf(bp, buflen - (bp - buf), "%s ", 1312 cb_opcode_name(one_op.argop)); 1313 bp += strlen(bp); 1314 operand = sum_cb_operand(&one_op); 1315 if (strlen(operand) > 0) { 1316 snprintf(bp, buflen - (bp - buf), "%s ", operand); 1317 bp += strlen(bp); 1318 } 1319 1320 xdr_free(xdr_nfs_cb_argop4, (char *)&one_op); 1321 1322 /* add "..." if past the "end" of the buffer */ 1323 if (bp - buf > SUM_COMPND_MAX) { 1324 strcpy(buf + SUM_COMPND_MAX - strlen("..."), 1325 "..."); 1326 break; 1327 } 1328 } 1329 1330 return (buf); 1331 } 1332 1333 /* 1334 * Return the summarized argument list for the given nfs_argop4. 1335 */ 1336 1337 static char * 1338 sum_operand(nfs_argop4 *opp) 1339 { 1340 static char buf[1024]; 1341 void (*fmtproc)(char *, size_t, void *); 1342 1343 buf[0] = '\0'; 1344 if (opp->argop < num_opcodes) { 1345 fmtproc = opcode_info[opp->argop].sumarg; 1346 if (fmtproc != NULL) 1347 fmtproc(buf, sizeof (buf), &opp->nfs_argop4_u); 1348 } 1349 1350 return (buf); 1351 } 1352 1353 /* 1354 * Return the summarized argument list for the given nfs_argop4. 1355 */ 1356 1357 static char * 1358 sum_cb_operand(nfs_cb_argop4 *opp) 1359 { 1360 static char buf[1024]; 1361 void (*fmtproc)(char *, size_t, void *); 1362 1363 buf[0] = '\0'; 1364 if (opp->argop < cb_num_opcodes) { 1365 fmtproc = cb_opcode_info[opp->argop].sumarg; 1366 if (fmtproc != NULL) 1367 fmtproc(buf, sizeof (buf), &opp->nfs_cb_argop4_u); 1368 } 1369 1370 return (buf); 1371 } 1372 1373 /* 1374 * Print details about the nfs_argop4 that is next in the XDR stream. 1375 */ 1376 1377 static void 1378 detail_nfs_argop4(void) 1379 { 1380 int numops; 1381 nfs_argop4 one_op; 1382 void (*fmtproc)(void *); 1383 uint32_t minor_version; 1384 1385 if (!xdr_uint32_t(&xdrm, &minor_version)) 1386 longjmp(xdr_err, 1); 1387 1388 (void) sprintf(get_line(0, 0), "Minor version = %u", 1389 minor_version); 1390 1391 numops = getxdr_long(); 1392 (void) sprintf(get_line(0, 0), "Number of operations = %d", 1393 numops); 1394 1395 while (numops-- > 0) { 1396 bzero(&one_op, sizeof (one_op)); 1397 1398 if (!xdr_nfs_argop4(&xdrm, &one_op)) { 1399 xdr_free(xdr_nfs_argop4, (char *)&one_op); 1400 longjmp(xdr_err, 1); 1401 } 1402 1403 get_line(0, 0); /* blank line to separate ops */ 1404 sprintf(get_line(0, 0), "Op = %d (%s)", 1405 one_op.argop, opcode_name(one_op.argop)); 1406 if (one_op.argop < num_opcodes) { 1407 fmtproc = opcode_info[one_op.argop].dtlarg; 1408 if (fmtproc != NULL) 1409 fmtproc(&one_op.nfs_argop4_u); 1410 } 1411 1412 /* nfs4_skip_bytes set by xdr_nfs_argop4() */ 1413 if (nfs4_skip_bytes) 1414 nfs4_xdr_skip(nfs4_skip_bytes); 1415 1416 xdr_free(xdr_nfs_argop4, (char *)&one_op); 1417 } 1418 } 1419 1420 1421 /* 1422 * Print details about the nfs_argop4 that is next in the XDR stream. 1423 */ 1424 static void 1425 detail_cb_argop4(void) 1426 { 1427 int numops; 1428 nfs_cb_argop4 one_op; 1429 void (*fmtproc)(void *); 1430 uint32_t minor_version, callback_ident; 1431 1432 if (!xdr_uint32_t(&xdrm, &minor_version)) 1433 longjmp(xdr_err, 1); 1434 (void) sprintf(get_line(0, 0), "Minor version = %u", 1435 minor_version); 1436 1437 if (!xdr_uint32_t(&xdrm, &callback_ident)) 1438 longjmp(xdr_err, 1); 1439 (void) sprintf(get_line(0, 0), "Callback Ident = %u", 1440 callback_ident); 1441 1442 numops = getxdr_long(); 1443 (void) sprintf(get_line(0, 0), "Number of operations = %d", 1444 numops); 1445 1446 while (numops-- > 0) { 1447 bzero(&one_op, sizeof (one_op)); 1448 if (!xdr_nfs_cb_argop4(&xdrm, &one_op)) { 1449 xdr_free(xdr_nfs_cb_argop4, (char *)&one_op); 1450 longjmp(xdr_err, 1); 1451 } 1452 1453 get_line(0, 0); /* blank line to separate ops */ 1454 sprintf(get_line(0, 0), "Op = %d (%s)", 1455 one_op.argop, cb_opcode_name(one_op.argop)); 1456 if (one_op.argop < cb_num_opcodes) { 1457 fmtproc = cb_opcode_info[one_op.argop].dtlarg; 1458 if (fmtproc != NULL) 1459 fmtproc(&one_op.nfs_cb_argop4_u); 1460 } 1461 1462 xdr_free(xdr_nfs_cb_argop4, (char *)&one_op); 1463 } 1464 } 1465 1466 /* 1467 * component_name: return a printable string for the given component4. I'm 1468 * leaving this as a separate function (as opposed to having the callers 1469 * call utf8localize() directly) in case the definition of component4 1470 * changes. 1471 */ 1472 1473 static char * 1474 component_name(component4 *cp) 1475 { 1476 return (utf8localize(cp)); 1477 } 1478 1479 /* 1480 * linktext_name. cf. component_name(). 1481 */ 1482 1483 static char * 1484 linktext_name(linktext4 *lp) 1485 { 1486 return (utf8localize(lp)); 1487 } 1488 1489 /* 1490 * stable_how4_name: return a string for "how". 1491 */ 1492 1493 static char * 1494 stable_how4_name(stable_how4 how) 1495 { 1496 char *result; 1497 1498 switch (how) { 1499 case UNSTABLE4: 1500 result = "ASYNC"; 1501 break; 1502 case DATA_SYNC4: 1503 result = "DSYNC"; 1504 break; 1505 case FILE_SYNC4: 1506 result = "FSYNC"; 1507 break; 1508 default: 1509 result = "?"; 1510 break; 1511 } 1512 1513 return (result); 1514 } 1515 1516 /* 1517 * sum_open_share_access: return a string corresponding to the 1518 * given OPEN share access bitmask. 1519 */ 1520 1521 static char * 1522 sum_open_share_access(int32_t mask) 1523 { 1524 char *result; 1525 1526 switch (mask) { 1527 case 0: 1528 result = "N"; 1529 break; 1530 case OPEN4_SHARE_ACCESS_READ: 1531 result = "R"; 1532 break; 1533 case OPEN4_SHARE_ACCESS_WRITE: 1534 result = "W"; 1535 break; 1536 case OPEN4_SHARE_ACCESS_BOTH: 1537 result = "RW"; 1538 break; 1539 default: 1540 result = "?"; 1541 break; 1542 } 1543 1544 return (result); 1545 } 1546 1547 /* 1548 * sum_open_share_deny: return a string corresponding to the 1549 * given OPEN share deny bitmask. 1550 */ 1551 1552 static char * 1553 sum_open_share_deny(int32_t mask) 1554 { 1555 char *result; 1556 1557 switch (mask) { 1558 case OPEN4_SHARE_DENY_NONE: 1559 result = "N"; 1560 break; 1561 case OPEN4_SHARE_DENY_READ: 1562 result = "R"; 1563 break; 1564 case OPEN4_SHARE_DENY_WRITE: 1565 result = "W"; 1566 break; 1567 case OPEN4_SHARE_DENY_BOTH: 1568 result = "RW"; 1569 break; 1570 default: 1571 result = "?"; 1572 break; 1573 } 1574 1575 return (result); 1576 } 1577 1578 static int 1579 special_stateid(stateid4 *stateid) 1580 { 1581 1582 if (! memcmp(stateid, &spec_stateid_0, sizeof (*stateid))) 1583 return (0); 1584 1585 if (! memcmp(stateid, &spec_stateid_1, sizeof (*stateid))) 1586 return (1); 1587 1588 return (-1); 1589 } 1590 1591 char * 1592 cmn_sum_stateid(stateid4 *stateid, char *prefix) 1593 { 1594 static char buf[32]; 1595 int spec; 1596 1597 if ((spec = special_stateid(stateid)) < 0) 1598 snprintf(buf, sizeof (buf), "%s%04X:%u", prefix, 1599 stateid_hash(stateid), stateid->seqid); 1600 else 1601 snprintf(buf, sizeof (buf), "%s%s", prefix, 1602 spec == 0 ? "SPC0" : (spec == 1 ? "SPC1" : "SPC?")); 1603 return (buf); 1604 } 1605 1606 void 1607 cmn_detail_stateid(stateid4 *stateid, char *prefix) 1608 { 1609 int spec; 1610 char seqstr[32] = {0}; 1611 1612 spec = special_stateid(stateid); 1613 1614 if (spec < 0) 1615 sprintf(get_line(0, 0), "%sState ID hash = %04X", 1616 prefix, stateid_hash(stateid)); 1617 else 1618 sprintf(get_line(0, 0), "%sState ID hash = %s", prefix, 1619 spec == 0 ? "SPECIAL_0" : 1620 (spec == 1 ? "SPECIAL_1" : "SPECIAL_?")); 1621 1622 sprintf(get_line(0, 0), " len = %u val = %s", 1623 sizeof (stateid->other), 1624 tohex(stateid->other, sizeof (stateid->other))); 1625 1626 /* 1627 * If spec 0/1 stateid, print seqid in hex; otherwise, 1628 * use decimal. This makes it more clear how spec stateids 1629 * are constructed [obvious that either all bits are 0, or all 1630 * bits are 1]. 1631 */ 1632 if (spec == -1) 1633 sprintf(seqstr, "%d", stateid->seqid); 1634 else 1635 sprintf(seqstr, "%08X", stateid->seqid); 1636 1637 sprintf(get_line(0, 0), " %sState ID Sequence ID = %s", 1638 prefix, seqstr); 1639 } 1640 1641 static char * 1642 sum_lock_denied(LOCK4denied *denied) 1643 { 1644 static char buf[64]; 1645 1646 sprintf(buf, "%s %llu %llu LO=%04X", 1647 sum_lock_type_name(denied->locktype), 1648 denied->offset, denied->length, 1649 owner_hash(&denied->owner.owner)); 1650 1651 return (buf); 1652 } 1653 1654 static void 1655 detail_lock_denied(LOCK4denied *denied) 1656 { 1657 sprintf(get_line(0, 0), "Type = %s", lock_type_name(denied->locktype)); 1658 detail_lock_owner(&denied->owner); 1659 sprintf(get_line(0, 0), "Offset = %llu", denied->offset); 1660 sprintf(get_line(0, 0), "Length = %llu", denied->length); 1661 } 1662 1663 /* 1664 * sum_createhow4: return the string name of "how". 1665 */ 1666 1667 static char * 1668 createhow4_name(createhow4 *crtp) 1669 { 1670 char *result; 1671 1672 switch (crtp->mode) { 1673 case UNCHECKED4: 1674 result = "UNCHECKED"; 1675 break; 1676 case GUARDED4: 1677 result = "GUARDED"; 1678 break; 1679 case EXCLUSIVE4: 1680 result = "EXCLUSIVE"; 1681 break; 1682 default: 1683 result = "?"; 1684 break; 1685 } 1686 1687 return (result); 1688 } 1689 1690 /* 1691 * detail_createhow4: print detail information about "how". 1692 */ 1693 1694 static void 1695 detail_createhow4(createhow4 *crtp) 1696 { 1697 sprintf(get_line(0, 0), "Method = %s", 1698 createhow4_name(crtp)); 1699 1700 switch (crtp->mode) { 1701 case UNCHECKED4: 1702 case GUARDED4: 1703 detail_fattr4(&crtp->createhow4_u.createattrs); 1704 break; 1705 case EXCLUSIVE4: 1706 sprintf(get_line(0, 0), " Verifier = %s", 1707 tohex(crtp->createhow4_u.createverf, 1708 NFS4_VERIFIER_SIZE)); 1709 break; 1710 } 1711 } 1712 1713 static void 1714 detail_createtype4(createtype4 *crtp) 1715 { 1716 sprintf(get_line(0, 0), "Type = %s", 1717 detail_type_name(crtp->type)); 1718 switch (crtp->type) { 1719 case NF4LNK: 1720 sprintf(get_line(0, 0), "Linkdata = %s", 1721 utf8localize(&crtp->createtype4_u.linkdata)); 1722 break; 1723 case NF4BLK: 1724 case NF4CHR: 1725 sprintf(get_line(0, 0), "Specdata1 = %04x Specdata2 = %04x", 1726 crtp->createtype4_u.devdata.specdata1, 1727 crtp->createtype4_u.devdata.specdata2); 1728 break; 1729 default: 1730 break; 1731 } 1732 } 1733 1734 static void 1735 sumarg_access(char *buf, size_t buflen, void *obj) 1736 { 1737 ACCESS4args *args = (ACCESS4args *)obj; 1738 1739 sum_access4(buf, buflen, args->access); 1740 } 1741 1742 static void 1743 dtlarg_access(void *obj) 1744 { 1745 ACCESS4args *args = (ACCESS4args *)obj; 1746 1747 detail_access4("Access bits", args->access); 1748 } 1749 1750 static void 1751 sumarg_close(char *buf, size_t buflen, void *obj) 1752 { 1753 CLOSE4args *args = (CLOSE4args *)obj; 1754 1755 snprintf(buf, buflen, "SQ=%u %s", 1756 args->seqid, sum_open_stateid(&args->open_stateid)); 1757 } 1758 1759 static void 1760 dtlarg_close(void *obj) 1761 { 1762 CLOSE4args *args = (CLOSE4args *)obj; 1763 1764 detail_open_stateid(&args->open_stateid); 1765 sprintf(get_line(0, 0), "Sequence ID = %u", args->seqid); 1766 } 1767 1768 static void 1769 sumarg_commit(char *buf, size_t buflen, void *obj) 1770 { 1771 COMMIT4args *args = (COMMIT4args *)obj; 1772 1773 snprintf(buf, buflen, "at %llu for %u ", args->offset, 1774 args->count); 1775 } 1776 1777 static void 1778 dtlarg_commit(void *obj) 1779 { 1780 COMMIT4args *args = (COMMIT4args *)obj; 1781 1782 sprintf(get_line(0, 0), "Offset = %llu", args->offset); 1783 sprintf(get_line(0, 0), "Count = %u", args->count); 1784 } 1785 1786 static void 1787 sumarg_compnt(char *buf, size_t buflen, void *obj) 1788 { 1789 component4 *comp = (component4 *)obj; 1790 1791 snprintf(buf, buflen, "%s", component_name(comp)); 1792 } 1793 1794 static void 1795 dtlarg_compnt(void *obj) 1796 { 1797 component4 *comp = (component4 *)obj; 1798 1799 sprintf(get_line(0, 0), "Name = %s", component_name(comp)); 1800 } 1801 1802 static void 1803 sumarg_create(char *buf, size_t buflen, void *obj) 1804 { 1805 CREATE4args *args = (CREATE4args *)obj; 1806 1807 snprintf(buf, buflen, "%s %s ", component_name(&args->objname), 1808 sum_type_name(args->objtype.type)); 1809 } 1810 1811 static void 1812 dtlarg_create(void *obj) 1813 { 1814 CREATE4args *args = (CREATE4args *)obj; 1815 1816 sprintf(get_line(0, 0), "Name = %s", component_name(&args->objname)); 1817 detail_createtype4(&args->objtype); 1818 detail_fattr4(&args->createattrs); 1819 } 1820 1821 static void 1822 sumarg_delprge(char *buf, size_t buflen, void *obj) 1823 { 1824 DELEGPURGE4args *args = (DELEGPURGE4args *)obj; 1825 1826 snprintf(buf, buflen, "%s", sum_clientid(args->clientid)); 1827 } 1828 1829 static void 1830 dtlarg_delprge(void *obj) 1831 { 1832 DELEGPURGE4args *args = (DELEGPURGE4args *)obj; 1833 1834 detail_clientid(args->clientid); 1835 } 1836 1837 static void 1838 sumarg_delret(char *buf, size_t buflen, void *obj) 1839 { 1840 DELEGRETURN4args *args = (DELEGRETURN4args *)obj; 1841 1842 snprintf(buf, buflen, "%s", sum_deleg_stateid(&args->deleg_stateid)); 1843 } 1844 1845 static void 1846 dtlarg_delret(void *obj) 1847 { 1848 DELEGRETURN4args *args = (DELEGRETURN4args *)obj; 1849 1850 detail_deleg_stateid(&args->deleg_stateid); 1851 } 1852 1853 static void 1854 sumarg_getattr(char *buf, size_t buflen, void *obj) 1855 { 1856 GETATTR4args *args = (GETATTR4args *)obj; 1857 1858 sum_attr_bitmap(buf, buflen, &args->attr_request); 1859 } 1860 1861 static void 1862 dtlarg_getattr(void *obj) 1863 { 1864 GETATTR4args *args = (GETATTR4args *)obj; 1865 1866 detail_attr_bitmap("", &args->attr_request, NULL); 1867 } 1868 1869 static void 1870 sumarg_cb_getattr(char *buf, size_t buflen, void *obj) 1871 { 1872 CB_GETATTR4args *args = (CB_GETATTR4args *)obj; 1873 char *bp = buf; 1874 1875 snprintf(bp, buflen, "%s ", sum_fh4(&args->fh)); 1876 bp += strlen(bp); 1877 sum_attr_bitmap(bp, buflen - (bp - buf), &args->attr_request); 1878 } 1879 1880 static void 1881 dtlarg_cb_getattr(void *obj) 1882 { 1883 CB_GETATTR4args *args = (CB_GETATTR4args *)obj; 1884 1885 detail_fh4(&args->fh, ""); 1886 detail_attr_bitmap("", &args->attr_request, NULL); 1887 } 1888 1889 static void 1890 sumarg_cb_recall(char *buf, size_t buflen, void *obj) 1891 { 1892 CB_RECALL4args *args = (CB_RECALL4args *)obj; 1893 char *bp = buf; 1894 1895 snprintf(bp, buflen, "%s %s TR=%s", sum_fh4(&args->fh), 1896 sum_stateid(&args->stateid), args->truncate ? "T" : "F"); 1897 } 1898 1899 static void 1900 dtlarg_cb_recall(void *obj) 1901 { 1902 CB_RECALL4args *args = (CB_RECALL4args *)obj; 1903 1904 detail_fh4(&args->fh, ""); 1905 detail_stateid(&args->stateid); 1906 sprintf(get_line(0, 0), "Truncate = %s", 1907 args->truncate ? "True" : "False"); 1908 } 1909 1910 1911 /* 1912 * name openhow seqid claim access deny owner 1913 */ 1914 static void 1915 sumarg_open(char *buf, size_t buflen, void *obj) 1916 { 1917 OPEN4args *args = (OPEN4args *)obj; 1918 char *bp = buf; 1919 int blen = buflen, len; 1920 1921 sum_name(bp, buflen, &args->claim); 1922 bp += (len = strlen(bp)); 1923 blen -= len; 1924 1925 sum_openflag(bp, blen, &args->openhow); 1926 bp += (len = strlen(bp)); 1927 blen -= len; 1928 1929 snprintf(bp, blen, " SQ=%u", args->seqid); 1930 bp += (len = strlen(bp)); 1931 blen -= len; 1932 1933 sum_claim(bp, blen, &args->claim); 1934 bp += (len = strlen(bp)); 1935 blen -= len; 1936 1937 snprintf(bp, blen, " AC=%s DN=%s OO=%04X", 1938 sum_open_share_access(args->share_access), 1939 sum_open_share_deny(args->share_deny), 1940 owner_hash(&args->owner.owner)); 1941 } 1942 1943 static void 1944 dtlarg_open(void *obj) 1945 { 1946 OPEN4args *args = (OPEN4args *)obj; 1947 1948 detail_claim(&args->claim); 1949 detail_openflag(&args->openhow); 1950 detail_open_owner(&args->owner); 1951 sprintf(get_line(0, 0), "Sequence ID = %u", args->seqid); 1952 sprintf(get_line(0, 0), "Access = 0x%x (%s)", 1953 args->share_access, sum_open_share_access(args->share_access)); 1954 sprintf(get_line(0, 0), "Deny = 0x%x (%s)", 1955 args->share_deny, sum_open_share_access(args->share_deny)); 1956 } 1957 1958 static void 1959 sumarg_openattr(char *buf, size_t buflen, void *obj) 1960 { 1961 OPENATTR4args *args = (OPENATTR4args *)obj; 1962 1963 snprintf(buf, buflen, "CD=%s", 1964 args->createdir ? "T" : "F"); 1965 } 1966 1967 static void 1968 dtlarg_openattr(void *obj) 1969 { 1970 OPENATTR4args *args = (OPENATTR4args *)obj; 1971 1972 sprintf(get_line(0, 0), "CreateDir = %s", 1973 args->createdir ? "True" : "False"); 1974 } 1975 1976 static void 1977 sumarg_open_confirm(char *buf, size_t buflen, void *obj) 1978 { 1979 char *bp = buf; 1980 OPEN_CONFIRM4args *args = (OPEN_CONFIRM4args *)obj; 1981 1982 snprintf(bp, buflen, "SQ=%u %s", args->seqid, 1983 sum_open_stateid(&args->open_stateid)); 1984 } 1985 1986 static void 1987 dtlarg_open_confirm(void *obj) 1988 { 1989 OPEN_CONFIRM4args *args = (OPEN_CONFIRM4args *)obj; 1990 1991 sprintf(get_line(0, 0), "Sequence ID = %u", args->seqid); 1992 detail_open_stateid(&args->open_stateid); 1993 } 1994 1995 static void 1996 sumarg_open_downgrd(char *buf, size_t buflen, void *obj) 1997 { 1998 OPEN_DOWNGRADE4args *args = (OPEN_DOWNGRADE4args *)obj; 1999 2000 snprintf(buf, buflen, "SQ=%u %s AC=%s DN=%s", 2001 args->seqid, sum_open_stateid(&args->open_stateid), 2002 sum_open_share_access(args->share_access), 2003 sum_open_share_deny(args->share_deny)); 2004 } 2005 2006 static void 2007 dtlarg_open_downgrd(void *obj) 2008 { 2009 OPEN_DOWNGRADE4args *args = (OPEN_DOWNGRADE4args *)obj; 2010 2011 sprintf(get_line(0, 0), "Open Sequence ID = %u", args->seqid); 2012 detail_open_stateid(&args->open_stateid); 2013 sprintf(get_line(0, 0), "Access = 0x%x (%s)", 2014 args->share_access, sum_open_share_access(args->share_access)); 2015 sprintf(get_line(0, 0), "Deny = 0x%x (%s)", 2016 args->share_deny, sum_open_share_access(args->share_deny)); 2017 } 2018 2019 static void 2020 sumarg_putfh(char *buf, size_t buflen, void *obj) 2021 { 2022 PUTFH4args *args = (PUTFH4args *)obj; 2023 2024 snprintf(buf, buflen, "%s", sum_fh4(&args->object)); 2025 } 2026 2027 static void 2028 dtlarg_putfh(void *obj) 2029 { 2030 PUTFH4args *args = (PUTFH4args *)obj; 2031 2032 detail_fh4(&args->object, ""); 2033 } 2034 2035 static void 2036 sumarg_link(char *buf, size_t buflen, void *obj) 2037 { 2038 LINK4args *args = (LINK4args *)obj; 2039 2040 snprintf(buf, buflen, "%s", component_name(&args->newname)); 2041 } 2042 2043 static void 2044 dtlarg_link(void *obj) 2045 { 2046 LINK4args *args = (LINK4args *)obj; 2047 2048 sprintf(get_line(0, 0), "New name = %s", 2049 component_name(&args->newname)); 2050 } 2051 2052 static void 2053 sum_open_to_lock_owner(char *buf, int buflen, open_to_lock_owner4 *own) 2054 { 2055 snprintf(buf, buflen, " OSQ=%u %s LSQ=%u LO=%04X", own->open_seqid, 2056 sum_open_stateid(&own->open_stateid), own->lock_seqid, 2057 owner_hash(&own->lock_owner.owner)); 2058 } 2059 2060 static void 2061 sum_exist_lock_owner(char *buf, int buflen, exist_lock_owner4 *own) 2062 { 2063 snprintf(buf, buflen, " LSQ=%u %s", own->lock_seqid, 2064 sum_lock_stateid(&own->lock_stateid)); 2065 } 2066 2067 static void 2068 sum_locker(char *buf, size_t len, locker4 *lk) 2069 { 2070 if (lk->new_lock_owner == TRUE) 2071 sum_open_to_lock_owner(buf, len, &lk->locker4_u.open_owner); 2072 else 2073 sum_exist_lock_owner(buf, len, &lk->locker4_u.lock_owner); 2074 } 2075 2076 static char * 2077 sum_lock_type_name(enum nfs_lock_type4 type) 2078 { 2079 char *result; 2080 2081 switch (type) { 2082 case READ_LT: 2083 result = "RD"; 2084 break; 2085 case WRITE_LT: 2086 result = "WR"; 2087 break; 2088 case READW_LT: 2089 result = "RDW"; 2090 break; 2091 case WRITEW_LT: 2092 result = "WRW"; 2093 break; 2094 default: 2095 result = "?"; 2096 break; 2097 } 2098 2099 return (result); 2100 } 2101 2102 static void 2103 sumarg_lock(char *buf, size_t buflen, void *obj) 2104 { 2105 LOCK4args *args = (LOCK4args *)obj; 2106 char *bp = buf; 2107 2108 snprintf(buf, buflen, "%s%s%llu:%llu", 2109 sum_lock_type_name(args->locktype), 2110 args->reclaim ? " reclaim " : " ", 2111 args->offset, args->length); 2112 2113 bp += strlen(buf); 2114 sum_locker(bp, buflen - (bp - buf), &args->locker); 2115 } 2116 2117 static void 2118 detail_open_to_lock_owner(open_to_lock_owner4 *own) 2119 { 2120 sprintf(get_line(0, 0), "Open Sequence ID = %u", own->open_seqid); 2121 detail_open_stateid(&own->open_stateid); 2122 sprintf(get_line(0, 0), "Lock Sequence ID = %u", own->lock_seqid); 2123 detail_lock_owner(&own->lock_owner); 2124 } 2125 2126 static void 2127 detail_exist_lock_owner(exist_lock_owner4 *own) 2128 { 2129 detail_lock_stateid(&own->lock_stateid); 2130 sprintf(get_line(0, 0), "Lock Sequence ID = %u", own->lock_seqid); 2131 } 2132 2133 static void 2134 detail_locker(locker4 *lk) 2135 { 2136 if (lk->new_lock_owner == TRUE) 2137 detail_open_to_lock_owner(&lk->locker4_u.open_owner); 2138 else 2139 detail_exist_lock_owner(&lk->locker4_u.lock_owner); 2140 } 2141 2142 static void 2143 dtlarg_lock(void *obj) 2144 { 2145 LOCK4args *args = (LOCK4args *)obj; 2146 2147 sprintf(get_line(0, 0), "Type = %s", lock_type_name(args->locktype)); 2148 sprintf(get_line(0, 0), "Reclaim = %s", 2149 args->reclaim ? "TRUE" : "FALSE"); 2150 sprintf(get_line(0, 0), "Offset = %llu", args->offset); 2151 sprintf(get_line(0, 0), "Length = %llu", args->length); 2152 detail_locker(&args->locker); 2153 } 2154 2155 static void 2156 sumarg_lockt(char *buf, size_t buflen, void *obj) 2157 { 2158 LOCKT4args *args = (LOCKT4args *)obj; 2159 2160 snprintf(buf, buflen, "R=%llu:%llu", 2161 args->offset, args->length); 2162 } 2163 2164 static void 2165 dtlarg_lockt(void *obj) 2166 { 2167 LOCKT4args *args = (LOCKT4args *)obj; 2168 2169 sprintf(get_line(0, 0), "Type = %s", lock_type_name(args->locktype)); 2170 detail_lock_owner(&args->owner); 2171 sprintf(get_line(0, 0), "Offset = %llu", args->offset); 2172 sprintf(get_line(0, 0), "Length = %llu", args->length); 2173 } 2174 2175 static void 2176 sumarg_locku(char *buf, size_t buflen, void *obj) 2177 { 2178 LOCKU4args *args = (LOCKU4args *)obj; 2179 2180 snprintf(buf, buflen, "R=%llu:%llu LSQ=%u %s", 2181 args->offset, args->length, args->seqid, 2182 sum_lock_stateid(&args->lock_stateid)); 2183 } 2184 2185 2186 static void 2187 dtlarg_locku(void *obj) 2188 { 2189 LOCKU4args *args = (LOCKU4args *)obj; 2190 2191 sprintf(get_line(0, 0), "Type = %s", lock_type_name(args->locktype)); 2192 sprintf(get_line(0, 0), "Sequence ID = %u", args->seqid); 2193 detail_lock_stateid(&args->lock_stateid); 2194 sprintf(get_line(0, 0), "Offset = %llu", args->offset); 2195 sprintf(get_line(0, 0), "Length = %llu", args->length); 2196 } 2197 2198 static void 2199 sumarg_lookup(char *buf, size_t buflen, void *obj) 2200 { 2201 LOOKUP4args *args = (LOOKUP4args *)obj; 2202 2203 sum_compname4(buf, buflen, &args->objname); 2204 } 2205 2206 static void 2207 dtlarg_lookup(void *obj) 2208 { 2209 LOOKUP4args *args = (LOOKUP4args *)obj; 2210 2211 detail_compname4(&args->objname); 2212 } 2213 2214 static void 2215 sumarg_read(char *buf, size_t buflen, void *obj) 2216 { 2217 READ4args *args = (READ4args *)obj; 2218 2219 snprintf(buf, buflen, "%s at %llu for %u", 2220 sum_stateid(&args->stateid), args->offset, args->count); 2221 } 2222 2223 static void 2224 dtlarg_read(void *obj) 2225 { 2226 READ4args *args = (READ4args *)obj; 2227 2228 sprintf(get_line(0, 0), "Offset = %llu", args->offset); 2229 sprintf(get_line(0, 0), "Count = %u", args->count); 2230 detail_stateid(&args->stateid); 2231 } 2232 2233 static void 2234 sumarg_readdir(char *buf, size_t buflen, void *obj) 2235 { 2236 READDIR4args *args = (READDIR4args *)obj; 2237 2238 snprintf(buf, buflen, "Cookie=%llu (%s) for %u/%u", 2239 args->cookie, tohex(args->cookieverf, NFS4_VERIFIER_SIZE), 2240 args->dircount, args->maxcount); 2241 } 2242 2243 static void 2244 dtlarg_readdir(void *obj) 2245 { 2246 READDIR4args *args = (READDIR4args *)obj; 2247 2248 sprintf(get_line(0, 0), "Cookie = %llu", args->cookie); 2249 sprintf(get_line(0, 0), "Verifier = %s", 2250 tohex(args->cookieverf, NFS4_VERIFIER_SIZE)); 2251 sprintf(get_line(0, 0), "Dircount = %u", args->dircount); 2252 sprintf(get_line(0, 0), "Maxcount = %u", args->maxcount); 2253 detail_attr_bitmap("", &args->attr_request, NULL); 2254 } 2255 2256 static void 2257 dtlarg_release_lkown(void *obj) 2258 { 2259 RELEASE_LOCKOWNER4args *args = (RELEASE_LOCKOWNER4args *)obj; 2260 2261 detail_lock_owner(&args->lock_owner); 2262 } 2263 2264 static void 2265 sumarg_release_lkown(char *buf, size_t buflen, void *obj) 2266 2267 { 2268 RELEASE_LOCKOWNER4args *args = (RELEASE_LOCKOWNER4args *)obj; 2269 2270 snprintf(buf, buflen, "LO=%04X", owner_hash(&args->lock_owner.owner)); 2271 } 2272 2273 static void 2274 sumarg_rename(char *buf, size_t buflen, void *obj) 2275 { 2276 RENAME4args *args = (RENAME4args *)obj; 2277 2278 snprintf(buf, buflen, "%s to %s", 2279 component_name(&args->oldname), 2280 component_name(&args->newname)); 2281 } 2282 2283 static void 2284 dtlarg_rename(void *obj) 2285 { 2286 RENAME4args *args = (RENAME4args *)obj; 2287 2288 sprintf(get_line(0, 0), "Old name = %s", 2289 component_name(&args->oldname)); 2290 sprintf(get_line(0, 0), "New name = %s", 2291 component_name(&args->newname)); 2292 } 2293 2294 static void 2295 sumarg_renew(char *buf, size_t buflen, void *obj) 2296 { 2297 RENEW4args *args = (RENEW4args *)obj; 2298 2299 snprintf(buf, buflen, "%s", sum_clientid(args->clientid)); 2300 } 2301 static void 2302 dtlarg_renew(void *obj) 2303 { 2304 RENEW4args *args = (RENEW4args *)obj; 2305 2306 detail_clientid(args->clientid); 2307 } 2308 2309 static void 2310 sumarg_secinfo(char *buf, size_t buflen, void *obj) 2311 { 2312 SECINFO4args *args = (SECINFO4args *)obj; 2313 2314 snprintf(buf, buflen, "%s", 2315 component_name(&args->name)); 2316 } 2317 2318 static void 2319 dtlarg_secinfo(void *obj) 2320 { 2321 SECINFO4args *args = (SECINFO4args *)obj; 2322 2323 sprintf(get_line(0, 0), "Name = %s", 2324 component_name(&args->name)); 2325 } 2326 2327 static void 2328 sumarg_setattr(char *buf, size_t buflen, void *obj) 2329 { 2330 SETATTR4args *args = (SETATTR4args *)obj; 2331 2332 snprintf(buf, buflen, "%s", sum_stateid(&args->stateid)); 2333 } 2334 2335 static void 2336 dtlarg_setattr(void *obj) 2337 { 2338 SETATTR4args *args = (SETATTR4args *)obj; 2339 2340 detail_stateid(&args->stateid); 2341 detail_fattr4(&args->obj_attributes); 2342 } 2343 2344 static void 2345 sumarg_setclid(char *buf, size_t buflen, void *obj) 2346 { 2347 SETCLIENTID4args *args = (SETCLIENTID4args *)obj; 2348 2349 snprintf(buf, buflen, "Prog=%u ID=%s Addr=%s CBID=%u", 2350 args->callback.cb_program, 2351 args->callback.cb_location.na_r_netid, 2352 args->callback.cb_location.na_r_addr, args->callback_ident); 2353 } 2354 2355 static void 2356 dtlarg_setclid(void *obj) 2357 { 2358 SETCLIENTID4args *args = (SETCLIENTID4args *)obj; 2359 2360 sprintf(get_line(0, 0), "Verifier=%s", 2361 tohex(args->client.verifier, NFS4_VERIFIER_SIZE)); 2362 sprintf(get_line(0, 0), "ID = (%d) %s", 2363 args->client.id.id_len, 2364 tohex(args->client.id.id_val, args->client.id.id_len)); 2365 2366 sprintf(get_line(0, 0), "Callback Program = %u", 2367 args->callback.cb_program); 2368 sprintf(get_line(0, 0), "Callback Net ID = %s", 2369 args->callback.cb_location.na_r_netid); 2370 sprintf(get_line(0, 0), "Callback Addr = %s", 2371 args->callback.cb_location.na_r_addr); 2372 sprintf(get_line(0, 0), "Callback Ident = %u", args->callback_ident); 2373 } 2374 2375 static void 2376 sumarg_setclid_cfm(char *buf, size_t buflen, void *obj) 2377 { 2378 SETCLIENTID_CONFIRM4args *args = (SETCLIENTID_CONFIRM4args *)obj; 2379 2380 snprintf(buf, buflen, "%s CFV=%s", sum_clientid(args->clientid), 2381 tohex(args->setclientid_confirm, NFS4_VERIFIER_SIZE)); 2382 } 2383 2384 static void 2385 dtlarg_setclid_cfm(void *obj) 2386 { 2387 SETCLIENTID_CONFIRM4args *args = (SETCLIENTID_CONFIRM4args *)obj; 2388 2389 detail_clientid(args->clientid); 2390 sprintf(get_line(0, 0), "Set Client ID Confirm Verifier = %s", 2391 tohex(args->setclientid_confirm, NFS4_VERIFIER_SIZE)); 2392 } 2393 2394 2395 static void 2396 dtlarg_verify(void *obj) 2397 { 2398 NVERIFY4args *args = (NVERIFY4args *)obj; 2399 2400 detail_fattr4(&args->obj_attributes); 2401 } 2402 2403 static void 2404 sumarg_write(char *buf, size_t buflen, void *obj) 2405 { 2406 WRITE4args *args = (WRITE4args *)obj; 2407 2408 snprintf(buf, buflen, "%s at %llu for %u", 2409 sum_stateid(&args->stateid), args->offset, args->data.data_len); 2410 } 2411 2412 static void 2413 dtlarg_write(void *obj) 2414 { 2415 WRITE4args *args = (WRITE4args *)obj; 2416 2417 sprintf(get_line(0, 0), "Offset = %llu", args->offset); 2418 sprintf(get_line(0, 0), "Count = %u", args->data.data_len); 2419 sprintf(get_line(0, 0), "Stable = %s", stable_how4_name(args->stable)); 2420 detail_stateid(&args->stateid); 2421 } 2422 2423 char * 2424 sum_fh4(nfs_fh4 *fh) 2425 { 2426 static char buf[20]; 2427 2428 sprintf(buf, "FH=%04X", fh4_hash(fh)); 2429 2430 return (buf); 2431 } 2432 2433 void 2434 detail_fh4(nfs_fh4 *fh, char *label) 2435 { 2436 int i; 2437 uchar_t *cp; 2438 char *bufp; 2439 2440 sprintf(get_line(0, 0), "%sFile handle = [%04X]", label, fh4_hash(fh)); 2441 bufp = get_line(0, 0); 2442 sprintf(bufp, "(%d) ", fh->nfs_fh4_len); 2443 bufp += strlen(bufp); 2444 /* XXX use tohex()? */ 2445 for (i = 0, cp = (uchar_t *)fh->nfs_fh4_val; 2446 i < fh->nfs_fh4_len; 2447 i++, cp++) { 2448 if (i != 0 && i % 32 == 0) 2449 bufp = get_line(0, 0); 2450 sprintf(bufp, "%02x", *cp); 2451 bufp += strlen(bufp); 2452 } 2453 } 2454 2455 static void 2456 detail_fattr4(fattr4 *attrp) 2457 { 2458 unpkd_attrmap_t provided; 2459 uint_t attrnum; 2460 XDR attrxdr; 2461 jmp_buf old_errbuf; 2462 2463 xdrmem_create(&attrxdr, attrp->attr_vals.attrlist4_val, 2464 attrp->attr_vals.attrlist4_len, XDR_DECODE); 2465 2466 bcopy(xdr_err, old_errbuf, sizeof (old_errbuf)); 2467 if (setjmp(xdr_err)) { 2468 sprintf(get_line(0, 0), "<attr_vals too short>"); 2469 goto done; 2470 } 2471 2472 detail_attr_bitmap("", &attrp->attrmask, &provided); 2473 for (attrnum = 0; attrnum < MAX_ATTRIBUTES; attrnum++) { 2474 if (provided.map[attrnum]) { 2475 attr_info[attrnum].prt_details(&attrxdr); 2476 } 2477 } 2478 2479 done: 2480 bcopy(old_errbuf, xdr_err, sizeof (old_errbuf)); 2481 } 2482 2483 static void 2484 detail_threshold_item4(threshold_item4 *thi) 2485 { 2486 XDR txdr; 2487 jmp_buf old_errbuf; 2488 uint32_t b, val; 2489 2490 sprintf(get_line(0, 0), " %s", 2491 detail_lotype_name(thi->thi_layout_type)); 2492 2493 if (thi->thi_hintset.bitmap4_len == 0) 2494 return; 2495 2496 b = ((uint32_t *)(thi->thi_hintset.bitmap4_val))[0]; 2497 sprintf(get_line(0, 0), " Threshold hint bitmap = 0x%08x", b); 2498 2499 xdrmem_create(&txdr, thi->thi_hintlist.thi_hintlist_val, 2500 thi->thi_hintlist.thi_hintlist_len, XDR_DECODE); 2501 2502 bcopy(xdr_err, old_errbuf, sizeof (old_errbuf)); 2503 if (setjmp(xdr_err)) { 2504 sprintf(get_line(0, 0), "<attr_vals too short>"); 2505 goto done; 2506 } 2507 2508 if (b & TH4_READ_SIZE_MASK) { 2509 if (!xdr_uint32_t(&txdr, &val)) 2510 longjmp(xdr_err, 1); 2511 sprintf(get_line(0, 0), " Read size = %u", val); 2512 } 2513 if (b & TH4_READ_IOSIZE_MASK) { 2514 if (!xdr_uint32_t(&txdr, &val)) 2515 longjmp(xdr_err, 1); 2516 sprintf(get_line(0, 0), " Read IO size = %u", val); 2517 } 2518 if (b & TH4_WRITE_SIZE_MASK) { 2519 if (!xdr_uint32_t(&txdr, &val)) 2520 longjmp(xdr_err, 1); 2521 sprintf(get_line(0, 0), " Write size = %u", val); 2522 } 2523 if (b & TH4_WRITE_IOSIZE_MASK) { 2524 if (!xdr_uint32_t(&txdr, &val)) 2525 longjmp(xdr_err, 1); 2526 sprintf(get_line(0, 0), " Write IO size = %u", val); 2527 } 2528 done: 2529 bcopy(old_errbuf, xdr_err, sizeof (old_errbuf)); 2530 } 2531 2532 static void 2533 sum_attr_bitmap(char *buf, size_t buflen, bitmap4 *mapp) 2534 { 2535 uint_t num_words; 2536 char *bp; 2537 size_t curlen, remaining; 2538 2539 buf[0] = '\0'; 2540 for (num_words = 0; num_words < mapp->bitmap4_len; num_words++) { 2541 curlen = strlen(buf); 2542 if (curlen + sizeof ("<Too Long>") >= buflen) { 2543 strcpy(buf + buflen - sizeof ("<Too Long>"), 2544 "<Too Long>"); 2545 return; 2546 } 2547 bp = buf + curlen; 2548 remaining = buflen - curlen; 2549 snprintf(bp, remaining, 2550 num_words == 0 ? "%x" : " %x", 2551 mapp->bitmap4_val[num_words]); 2552 } 2553 } 2554 2555 /* 2556 * Print detail information for the given attribute bitmap, and fill in the 2557 * unpacked version of the map if "unpacked" is non-null. Returns the 2558 * number of bytes in the bitmap. "prefix" is an initial string that is 2559 * printed at the front of each line. 2560 */ 2561 2562 static void 2563 detail_attr_bitmap(char *prefix, bitmap4 *bitp, unpkd_attrmap_t *unpacked) 2564 { 2565 uint_t num_words; 2566 uint32_t *wp; 2567 uint_t byte_num; 2568 2569 if (unpacked != NULL) 2570 memset(unpacked, 0, sizeof (unpkd_attrmap_t)); 2571 2572 /* 2573 * Break the bitmap into octets, then print in hex and 2574 * symbolically. 2575 */ 2576 2577 for (num_words = 0, wp = bitp->bitmap4_val; 2578 num_words < bitp->bitmap4_len; 2579 num_words++, wp++) { 2580 for (byte_num = 0; byte_num < 4; byte_num++) { 2581 uchar_t val = (*wp) >> (byte_num * 8); 2582 char *buf = get_line(0, 0); 2583 uint_t attrnum; 2584 int bit; 2585 2586 sprintf(buf, "%s 0x%02x ", prefix, val); 2587 attrnum = num_words * 32 + byte_num * 8; 2588 for (bit = 7; bit >= 0; bit--) { 2589 if (val & (1 << bit)) { 2590 strcat(buf, " "); 2591 strcat(buf, 2592 attr_name(attrnum + bit)); 2593 if (unpacked != NULL) 2594 unpacked->map[attrnum + bit] = 2595 1; 2596 } 2597 } 2598 } 2599 } 2600 } 2601 2602 /* 2603 * Format the summary line results from a COMPOUND4 call. 2604 */ 2605 2606 static void 2607 sum_comp4res(char *line, char *(*sumres_fn)(void)) 2608 { 2609 nfsstat4 status; 2610 static utf8string tag; 2611 2612 status = getxdr_long(); 2613 if (!xdr_utf8string(&xdrm, &tag)) 2614 longjmp(xdr_err, 1); 2615 2616 sprintf(line, "(%.20s) %s %s", utf8localize(&tag), 2617 status_name(status), sumres_fn()); 2618 2619 xdr_free(xdr_utf8string, (char *)&tag); 2620 } 2621 2622 2623 /* 2624 * Return a set of summary strings for the result data that's next in the 2625 * XDR stream, up to SUM_COMPND_MAX characters. If the strings don't fit, 2626 * include a "..." at the end of the string. 2627 */ 2628 2629 static char * 2630 sum_compound4res(void) 2631 { 2632 static char buf[SUM_COMPND_MAX + 2]; /* 1 for null, 1 for overflow */ 2633 int numres; 2634 const size_t buflen = sizeof (buf); 2635 char *bp; 2636 nfs_resop4 one_res; 2637 2638 buf[0] = '\0'; 2639 if (setjmp(xdr_err)) { 2640 bp = buf + strlen(buf); 2641 snprintf(bp, buflen - (bp - buf), 2642 nfs4_fragged_rpc ? nfs4err_fragrpc : nfs4err_xdrfrag); 2643 return (buf); 2644 } 2645 2646 numres = getxdr_long(); 2647 bp = buf; 2648 while (numres-- > 0) { 2649 char *result; 2650 2651 bzero(&one_res, sizeof (one_res)); 2652 2653 if (!xdr_nfs_resop4(&xdrm, &one_res)) { 2654 xdr_free(xdr_nfs_resop4, (char *)&one_res); 2655 longjmp(xdr_err, 1); 2656 } 2657 2658 snprintf(bp, buflen - (bp - buf), "%s ", 2659 opcode_name(one_res.resop)); 2660 bp += strlen(bp); 2661 2662 result = sum_result(&one_res); 2663 if (strlen(result) > 0) { 2664 snprintf(bp, buflen - (bp - buf), "%s ", result); 2665 bp += strlen(bp); 2666 } 2667 2668 /* nfs4_skip_bytes set by xdr_nfs4_argop4() */ 2669 if (nfs4_skip_bytes != 0) 2670 nfs4_xdr_skip(nfs4_skip_bytes); 2671 2672 xdr_free(xdr_nfs_resop4, (char *)&one_res); 2673 /* add "..." if past the "end" of the buffer */ 2674 if (bp - buf > SUM_COMPND_MAX) { 2675 strcpy(buf + SUM_COMPND_MAX - strlen("..."), 2676 "..."); 2677 break; 2678 } 2679 } 2680 2681 return (buf); 2682 } 2683 2684 2685 /* 2686 * Return a set of summary strings for the result data that's next in the 2687 * XDR stream, up to SUM_COMPND_MAX characters. If the strings don't fit, 2688 * include a "..." at the end of the string. 2689 */ 2690 2691 static char * 2692 sum_cb_compound4res(void) 2693 { 2694 static char buf[SUM_COMPND_MAX + 2]; /* 1 for null, 1 for overflow */ 2695 int numres; 2696 const size_t buflen = sizeof (buf); 2697 char *bp; 2698 nfs_cb_resop4 one_res; 2699 2700 buf[0] = '\0'; 2701 if (setjmp(xdr_err)) { 2702 bp = buf + strlen(buf); 2703 snprintf(bp, buflen - (bp - buf), "<XDR Error or Fragmented" 2704 " RPC>"); 2705 return (buf); 2706 } 2707 2708 numres = getxdr_long(); 2709 bp = buf; 2710 while (numres-- > 0) { 2711 bzero(&one_res, sizeof (one_res)); 2712 if (!xdr_nfs_cb_resop4(&xdrm, &one_res)) { 2713 xdr_free(xdr_nfs_cb_resop4, (char *)&one_res); 2714 longjmp(xdr_err, 1); 2715 } 2716 snprintf(bp, buflen - (bp - buf), "%s %s ", 2717 cb_opcode_name(one_res.resop), 2718 sum_cb_result(&one_res)); 2719 bp += strlen(bp); 2720 2721 xdr_free(xdr_nfs_cb_resop4, (char *)&one_res); 2722 2723 /* add "..." if past the "end" of the buffer */ 2724 if (bp - buf > SUM_COMPND_MAX) { 2725 strcpy(buf + SUM_COMPND_MAX - strlen("..."), 2726 "..."); 2727 break; 2728 } 2729 } 2730 2731 return (buf); 2732 } 2733 2734 2735 /* 2736 * Return the summarized results for the given resultdata. 2737 */ 2738 2739 static char * 2740 sum_result(nfs_resop4 *resp) 2741 { 2742 static char buf[1024]; 2743 void (*fmtproc)(char *, size_t, void *); 2744 2745 buf[0] = '\0'; 2746 if (resp->resop < num_opcodes) 2747 fmtproc = opcode_info[resp->resop].sumres; 2748 else if (resp->resop == OP_ILLEGAL) 2749 fmtproc = sum_nfsstat4; 2750 else 2751 fmtproc = NULL; 2752 2753 if (fmtproc != NULL) 2754 fmtproc(buf, sizeof (buf), &resp->nfs_resop4_u); 2755 2756 return (buf); 2757 } 2758 2759 /* 2760 * Return the summarized results for the given resultdata. 2761 */ 2762 2763 static char * 2764 sum_cb_result(nfs_cb_resop4 *resp) 2765 { 2766 static char buf[1024]; 2767 void (*fmtproc)(char *, size_t, void *); 2768 2769 buf[0] = '\0'; 2770 if (resp->resop < cb_num_opcodes) 2771 fmtproc = cb_opcode_info[resp->resop].sumres; 2772 else if (resp->resop == OP_CB_ILLEGAL) 2773 fmtproc = sum_nfsstat4; 2774 else 2775 fmtproc = NULL; 2776 2777 if (fmtproc != NULL) 2778 fmtproc(buf, sizeof (buf), &resp->nfs_cb_resop4_u); 2779 2780 return (buf); 2781 } 2782 2783 2784 static void 2785 dtl_change_info(char *msg, change_info4 *infop) 2786 { 2787 sprintf(get_line(0, 0), "%s:", msg); 2788 sprintf(get_line(0, 0), " Atomic = %s", 2789 infop->atomic ? "TRUE" : "FALSE"); 2790 detail_fattr4_change(" Before", infop->before); 2791 detail_fattr4_change(" After", infop->after); 2792 } 2793 2794 static void 2795 detail_fattr4_change(char *msg, fattr4_change chg) 2796 { 2797 sprintf(get_line(0, 0), "%s: 0x%llx", msg, chg); 2798 /* XXX print as time_t, too? */ 2799 } 2800 2801 static void 2802 sum_nfsstat4(char *buf, size_t buflen, void *obj) 2803 { 2804 nfsstat4 status = *(nfsstat4 *)obj; 2805 2806 strncpy(buf, status_name(status), buflen); 2807 } 2808 2809 static void 2810 dtl_nfsstat4(void *obj) 2811 { 2812 nfsstat4 status = *(nfsstat4 *)obj; 2813 2814 sprintf(get_line(0, 0), "Status = %d (%s)", status, 2815 status_name(status)); 2816 } 2817 2818 static void 2819 sumres_access(char *buf, size_t buflen, void *obj) 2820 { 2821 ACCESS4res *res = (ACCESS4res *)obj; 2822 char *bp = buf; 2823 int len, blen = buflen; 2824 2825 strcpy(bp, status_name(res->status)); 2826 if (res->status == NFS4_OK) { 2827 bp += (len = strlen(bp)); 2828 blen -= len; 2829 2830 snprintf(bp, blen, " Supp="); 2831 bp += (len = strlen(bp)); 2832 blen -= len; 2833 2834 sum_access4(bp, blen, res->ACCESS4res_u.resok4.supported); 2835 bp += (len = strlen(bp)); 2836 blen -= len; 2837 2838 snprintf(bp, blen, " Allow="); 2839 bp += (len = strlen(bp)); 2840 blen -= len; 2841 2842 sum_access4(bp, blen, res->ACCESS4res_u.resok4.access); 2843 } 2844 } 2845 2846 static void 2847 dtlres_access(void *obj) 2848 { 2849 ACCESS4res *res = (ACCESS4res *)obj; 2850 2851 dtl_nfsstat4(obj); 2852 if (res->status == NFS4_OK) { 2853 detail_access4("Supported Attributes", 2854 res->ACCESS4res_u.resok4.supported); 2855 detail_access4("Allowed Attributes", 2856 res->ACCESS4res_u.resok4.access); 2857 } 2858 } 2859 2860 static void 2861 sumres_close(char *buf, size_t buflen, void *obj) 2862 { 2863 CLOSE4res *res = (CLOSE4res *)obj; 2864 2865 if (res->status == NFS4_OK) 2866 snprintf(buf, buflen, "%s", 2867 sum_open_stateid(&res->CLOSE4res_u.open_stateid)); 2868 } 2869 2870 static void 2871 dtlres_close(void *obj) 2872 { 2873 CLOSE4res *res = (CLOSE4res *)obj; 2874 2875 dtl_nfsstat4(obj); 2876 if (res->status == NFS4_OK) { 2877 detail_open_stateid(&res->CLOSE4res_u.open_stateid); 2878 } 2879 } 2880 2881 static void 2882 sumres_commit(char *buf, size_t buflen, void *obj) 2883 { 2884 COMMIT4res *res = (COMMIT4res *)obj; 2885 2886 if (res->status == NFS4_OK) 2887 snprintf(buf, buflen, "Verf=%s", 2888 tohex(res->COMMIT4res_u.resok4.writeverf, 2889 NFS4_VERIFIER_SIZE)); 2890 } 2891 2892 static void 2893 dtlres_commit(void *obj) 2894 { 2895 COMMIT4res *res = (COMMIT4res *)obj; 2896 2897 dtl_nfsstat4(obj); 2898 if (res->status == NFS4_OK) { 2899 sprintf(get_line(0, 0), "Verifier = %s", 2900 tohex(res->COMMIT4res_u.resok4.writeverf, 2901 NFS4_VERIFIER_SIZE)); 2902 } 2903 } 2904 2905 static void 2906 dtlres_create(void *obj) 2907 { 2908 CREATE4res *res = (CREATE4res *)obj; 2909 2910 dtl_nfsstat4(obj); 2911 if (res->status == NFS4_OK) { 2912 dtl_change_info("Change Information", 2913 &res->CREATE4res_u.resok4.cinfo); 2914 detail_attr_bitmap("", &res->CREATE4res_u.resok4.attrset, 2915 NULL); 2916 } 2917 } 2918 2919 static void 2920 sumres_getattr(char *buf, size_t buflen, void *obj) 2921 { 2922 GETATTR4res *res = (GETATTR4res *)obj; 2923 2924 strncpy(buf, status_name(res->status), buflen); 2925 } 2926 2927 static void 2928 dtlres_getattr(void *obj) 2929 { 2930 GETATTR4res *res = (GETATTR4res *)obj; 2931 2932 dtl_nfsstat4(obj); 2933 if (res->status == NFS4_OK) { 2934 detail_fattr4(&res->GETATTR4res_u.resok4.obj_attributes); 2935 } 2936 } 2937 2938 static void 2939 sumres_cb_getattr(char *buf, size_t buflen, void *obj) 2940 { 2941 CB_GETATTR4res *res = (CB_GETATTR4res *)obj; 2942 2943 strncpy(buf, status_name(res->status), buflen); 2944 } 2945 2946 static void 2947 dtlres_cb_getattr(void *obj) 2948 { 2949 CB_GETATTR4res *res = (CB_GETATTR4res *)obj; 2950 2951 dtl_nfsstat4(obj); 2952 if (res->status == NFS4_OK) { 2953 detail_fattr4(&res->CB_GETATTR4res_u.resok4.obj_attributes); 2954 } 2955 } 2956 2957 2958 static void 2959 sumres_getfh(char *buf, size_t buflen, void *obj) 2960 { 2961 char *bp; 2962 GETFH4res *res = (GETFH4res *)obj; 2963 2964 strncpy(buf, status_name(res->status), buflen); 2965 if (res->status == NFS4_OK) { 2966 bp = buf + strlen(buf); 2967 snprintf(bp, buflen - (bp - buf), " %s", 2968 sum_fh4(&res->GETFH4res_u.resok4.object)); 2969 } 2970 } 2971 2972 static void 2973 dtlres_getfh(void *obj) 2974 { 2975 GETFH4res *res = (GETFH4res *)obj; 2976 2977 dtl_nfsstat4(obj); 2978 if (res->status == NFS4_OK) { 2979 detail_fh4(&res->GETFH4res_u.resok4.object, ""); 2980 } 2981 } 2982 2983 static void 2984 dtlres_link(void *obj) 2985 { 2986 LINK4res *res = (LINK4res *)obj; 2987 2988 dtl_nfsstat4(obj); 2989 if (res->status == NFS4_OK) { 2990 dtl_change_info("Change Information", 2991 &res->LINK4res_u.resok4.cinfo); 2992 } 2993 } 2994 2995 static void 2996 sumres_lock(char *buf, size_t buflen, void *obj) 2997 { 2998 char *bp; 2999 LOCK4res *res = (LOCK4res *)obj; 3000 3001 strncpy(buf, status_name(res->status), buflen); 3002 if (res->status == NFS4_OK) { 3003 bp = buf + strlen(buf); 3004 snprintf(bp, buflen - (bp - buf), " %s", 3005 sum_lock_stateid(&res->LOCK4res_u.resok4.lock_stateid)); 3006 } 3007 if (res->status == NFS4ERR_DENIED) { 3008 bp = buf + strlen(buf); 3009 snprintf(bp, buflen - (bp - buf), " %s", 3010 sum_lock_denied(&res->LOCK4res_u.denied)); 3011 } 3012 } 3013 3014 static void 3015 dtlres_lock(void *obj) 3016 { 3017 LOCK4res *res = (LOCK4res *)obj; 3018 3019 dtl_nfsstat4(obj); 3020 if (res->status == NFS4_OK) { 3021 detail_lock_stateid(&res->LOCK4res_u.resok4.lock_stateid); 3022 } 3023 if (res->status == NFS4ERR_DENIED) { 3024 detail_lock_denied(&res->LOCK4res_u.denied); 3025 } 3026 } 3027 3028 static void 3029 sumres_lockt(char *buf, size_t buflen, void *obj) 3030 { 3031 char *bp; 3032 LOCKT4res *res = (LOCKT4res *)obj; 3033 3034 strcpy(buf, status_name(res->status)); 3035 if (res->status == NFS4ERR_DENIED) { 3036 bp = buf + strlen(buf); 3037 snprintf(bp, buflen - (bp - buf), " %s", 3038 sum_lock_denied(&res->LOCKT4res_u.denied)); 3039 } 3040 } 3041 3042 static void 3043 dtlres_lockt(void *obj) 3044 { 3045 LOCKT4res *res = (LOCKT4res *)obj; 3046 3047 dtl_nfsstat4(obj); 3048 if (res->status == NFS4ERR_DENIED) { 3049 detail_lock_denied(&res->LOCKT4res_u.denied); 3050 } 3051 } 3052 3053 static void 3054 sumres_locku(char *buf, size_t buflen, void *obj) 3055 { 3056 char *bp; 3057 LOCKU4res *res = (LOCKU4res *)obj; 3058 3059 strncpy(buf, status_name(res->status), buflen); 3060 bp = buf + strlen(buf); 3061 if (res->status == NFS4_OK) 3062 snprintf(bp, buflen - (bp - buf), " %s", 3063 sum_lock_stateid(&res->LOCKU4res_u.lock_stateid)); 3064 } 3065 3066 static void 3067 dtlres_locku(void *obj) 3068 { 3069 LOCKU4res *res = (LOCKU4res *)obj; 3070 3071 dtl_nfsstat4(obj); 3072 if (res->status == NFS4_OK) 3073 detail_lock_stateid(&res->LOCKU4res_u.lock_stateid); 3074 } 3075 3076 static void 3077 sumres_open(char *buf, size_t buflen, void *obj) 3078 { 3079 char *bp = buf; 3080 OPEN4res *res = (OPEN4res *)obj; 3081 uint_t rflags; 3082 int len, blen = buflen; 3083 3084 strncpy(bp, status_name(res->status), blen); 3085 3086 if (res->status == NFS4_OK) { 3087 bp += (len = strlen(bp)); 3088 blen -= len; 3089 3090 snprintf(bp, blen, " %s", 3091 sum_stateid(&res->OPEN4res_u.resok4.stateid)); 3092 bp += (len = strlen(bp)); 3093 blen -= len; 3094 3095 if ((rflags = res->OPEN4res_u.resok4.rflags) != 0) { 3096 snprintf(bp, blen, "%s", sum_open_rflags(rflags)); 3097 bp += (len = strlen(bp)); 3098 blen -= len; 3099 } 3100 3101 sum_delegation(bp, blen, &res->OPEN4res_u.resok4.delegation); 3102 } 3103 } 3104 3105 static void 3106 dtlres_open(void *obj) 3107 { 3108 OPEN4res *res = (OPEN4res *)obj; 3109 3110 dtl_nfsstat4(obj); 3111 if (res->status == NFS4_OK) { 3112 detail_stateid(&res->OPEN4res_u.resok4.stateid); 3113 dtl_change_info("Change Information", 3114 &res->OPEN4res_u.resok4.cinfo); 3115 sprintf(get_line(0, 0), "Flags = 0x%x (%s)", 3116 res->OPEN4res_u.resok4.rflags, 3117 detail_open_rflags(res->OPEN4res_u.resok4.rflags)); 3118 detail_attr_bitmap("", &res->OPEN4res_u.resok4.attrset, 3119 NULL); 3120 detail_delegation(&res->OPEN4res_u.resok4.delegation); 3121 } 3122 } 3123 3124 static void 3125 sumres_open_confirm(char *buf, size_t buflen, void *obj) 3126 { 3127 char *bp; 3128 OPEN_CONFIRM4res *res = (OPEN_CONFIRM4res *)obj; 3129 3130 strncpy(buf, status_name(res->status), buflen); 3131 if (res->status == NFS4_OK) { 3132 bp = buf + strlen(buf); 3133 snprintf(bp, buflen - (bp - buf), " %s", 3134 sum_open_stateid(&res->OPEN_CONFIRM4res_u.resok4. 3135 open_stateid)); 3136 } 3137 } 3138 3139 static void 3140 dtlres_open_confirm(void *obj) 3141 { 3142 OPEN_CONFIRM4res *res = (OPEN_CONFIRM4res *)obj; 3143 3144 dtl_nfsstat4(obj); 3145 if (res->status == NFS4_OK) { 3146 detail_open_stateid(&res->OPEN_CONFIRM4res_u.resok4. 3147 open_stateid); 3148 } 3149 } 3150 3151 static void 3152 sumres_open_downgrd(char *buf, size_t buflen, void *obj) 3153 { 3154 char *bp; 3155 OPEN_DOWNGRADE4res *res = (OPEN_DOWNGRADE4res *)obj; 3156 3157 strncpy(buf, status_name(res->status), buflen); 3158 if (res->status == NFS4_OK) { 3159 bp = buf + strlen(buf); 3160 snprintf(bp, buflen - (bp - buf), " %s", 3161 sum_open_stateid(&res->OPEN_DOWNGRADE4res_u.resok4. 3162 open_stateid)); 3163 } 3164 } 3165 3166 static void 3167 dtlres_open_downgrd(void *obj) 3168 { 3169 OPEN_DOWNGRADE4res *res = (OPEN_DOWNGRADE4res *)obj; 3170 3171 dtl_nfsstat4(obj); 3172 if (res->status == NFS4_OK) { 3173 detail_open_stateid(&res->OPEN_DOWNGRADE4res_u.resok4. 3174 open_stateid); 3175 } 3176 } 3177 3178 static void 3179 sumres_read(char *buf, size_t buflen, void *obj) 3180 { 3181 char *bp; 3182 READ4res *res = (READ4res *)obj; 3183 3184 strncpy(buf, status_name(res->status), buflen); 3185 if (res->status == NFS4_OK) { 3186 bp = buf + strlen(buf); 3187 snprintf(bp, buflen - (bp - buf), " (%u bytes) %s", 3188 res->READ4res_u.resok4.data.data_len, 3189 res->READ4res_u.resok4.eof ? "EOF" : ""); 3190 } 3191 } 3192 3193 static void 3194 dtlres_read(void *obj) 3195 { 3196 READ4res *res = (READ4res *)obj; 3197 3198 dtl_nfsstat4(obj); 3199 if (res->status == NFS4_OK) { 3200 sprintf(get_line(0, 0), "Count = %u bytes read", 3201 res->READ4res_u.resok4.data.data_len); 3202 sprintf(get_line(0, 0), "End of file = %s", 3203 res->READ4res_u.resok4.eof ? "TRUE" : "FALSE"); 3204 } 3205 } 3206 3207 static void 3208 sumres_readdir(char *buf, size_t buflen, void *obj) 3209 { 3210 char *bp; 3211 READDIR4res *res = (READDIR4res *)obj; 3212 int num_entries = 0; 3213 entry4 *ep; 3214 3215 strncpy(buf, status_name(res->status), buflen); 3216 if (res->status == NFS4_OK) { 3217 for (ep = res->READDIR4res_u.resok4.reply.entries; 3218 ep != NULL; 3219 ep = ep->nextentry) 3220 num_entries++; 3221 bp = buf + strlen(buf); 3222 snprintf(bp, buflen - (bp - buf), " %d entries (%s)", 3223 num_entries, 3224 res->READDIR4res_u.resok4.reply.eof 3225 ? "No more" : "More"); 3226 } 3227 } 3228 3229 static void 3230 dtlres_readdir(void *obj) 3231 { 3232 READDIR4res *res = (READDIR4res *)obj; 3233 int num_entries = 0; 3234 entry4 *ep; 3235 3236 dtl_nfsstat4(obj); 3237 if (res->status == NFS4_OK) { 3238 for (ep = res->READDIR4res_u.resok4.reply.entries; 3239 ep != NULL; 3240 ep = ep->nextentry) { 3241 num_entries++; 3242 sprintf(get_line(0, 0), 3243 "------------------ entry #%d", 3244 num_entries); 3245 sprintf(get_line(0, 0), "Cookie = %llu", 3246 ep->cookie); 3247 sprintf(get_line(0, 0), "Name = %s", 3248 component_name(&ep->name)); 3249 detail_fattr4(&ep->attrs); 3250 } 3251 if (num_entries == 0) 3252 sprintf(get_line(0, 0), "(No entries)"); 3253 sprintf(get_line(0, 0), "EOF = %s", 3254 res->READDIR4res_u.resok4.reply.eof ? "TRUE" : "FALSE"); 3255 sprintf(get_line(0, 0), "Verifer = %s", 3256 tohex(res->READDIR4res_u.resok4.cookieverf, 3257 NFS4_VERIFIER_SIZE)); 3258 } 3259 } 3260 3261 static void 3262 sumres_readlnk(char *buf, size_t buflen, void *obj) 3263 { 3264 char *bp; 3265 READLINK4res *res = (READLINK4res *)obj; 3266 3267 strncpy(buf, status_name(res->status), buflen); 3268 if (res->status == NFS4_OK) { 3269 bp = buf + strlen(buf); 3270 snprintf(bp, buflen - (bp - buf), " %s", 3271 linktext_name(&res->READLINK4res_u.resok4.link)); 3272 } 3273 } 3274 3275 static void 3276 dtlres_readlnk(void *obj) 3277 { 3278 READLINK4res *res = (READLINK4res *)obj; 3279 3280 dtl_nfsstat4(obj); 3281 if (res->status == NFS4_OK) { 3282 sprintf(get_line(0, 0), "Link = %s", 3283 linktext_name(&res->READLINK4res_u.resok4.link)); 3284 } 3285 } 3286 3287 static void 3288 dtlres_remove(void *obj) 3289 { 3290 REMOVE4res *res = (REMOVE4res *)obj; 3291 3292 dtl_nfsstat4(obj); 3293 if (res->status == NFS4_OK) { 3294 dtl_change_info("Change Information", 3295 &res->REMOVE4res_u.resok4.cinfo); 3296 } 3297 } 3298 3299 static void 3300 dtlres_rename(void *obj) 3301 { 3302 RENAME4res *res = (RENAME4res *)obj; 3303 3304 dtl_nfsstat4(obj); 3305 if (res->status == NFS4_OK) { 3306 dtl_change_info("Source Change Information", 3307 &res->RENAME4res_u.resok4.source_cinfo); 3308 dtl_change_info("Target Change Information", 3309 &res->RENAME4res_u.resok4.target_cinfo); 3310 } 3311 } 3312 3313 static void 3314 sumres_secinfo(char *buf, size_t buflen, void *obj) 3315 { 3316 char *bp; 3317 SECINFO4res *res = (SECINFO4res *)obj; 3318 3319 strncpy(buf, status_name(res->status), buflen); 3320 bp = buf + strlen(buf); 3321 if (res->status == NFS4_OK) { 3322 uint_t numinfo = res->SECINFO4res_u.resok4.SECINFO4resok_len; 3323 secinfo4 *infop; 3324 3325 for (infop = res->SECINFO4res_u.resok4.SECINFO4resok_val; 3326 numinfo != 0; 3327 infop++, numinfo--) { 3328 snprintf(bp, buflen - (bp - buf), " %s", 3329 flavor_name(infop->flavor)); 3330 bp += strlen(bp); 3331 } 3332 } 3333 } 3334 3335 static void 3336 dtlres_secinfo(void *obj) 3337 { 3338 SECINFO4res *res = (SECINFO4res *)obj; 3339 3340 dtl_nfsstat4(obj); 3341 if (res->status == NFS4_OK) { 3342 uint_t numinfo = 3343 res->SECINFO4res_u.resok4.SECINFO4resok_len; 3344 secinfo4 *infop; 3345 3346 for (infop = res->SECINFO4res_u.resok4.SECINFO4resok_val; 3347 numinfo != 0; 3348 infop++, numinfo--) { 3349 detail_secinfo4(infop); 3350 } 3351 } 3352 } 3353 3354 static void 3355 sumres_setattr(char *buf, size_t buflen, void *obj) 3356 { 3357 SETATTR4res *res = (SETATTR4res *)obj; 3358 3359 strncpy(buf, status_name(res->status), buflen); 3360 sum_attr_bitmap(buf, buflen, &res->attrsset); 3361 } 3362 3363 static void 3364 dtlres_setattr(void *obj) 3365 { 3366 SETATTR4res *res = (SETATTR4res *)obj; 3367 3368 dtl_nfsstat4(obj); 3369 detail_attr_bitmap("", &res->attrsset, NULL); 3370 } 3371 3372 static void 3373 sumres_setclid(char *buf, size_t buflen, void *obj) 3374 { 3375 char *bp; 3376 SETCLIENTID4res *res = (SETCLIENTID4res *)obj; 3377 3378 strncpy(buf, status_name(res->status), buflen); 3379 switch (res->status) { 3380 case NFS_OK: 3381 bp = buf + strlen(buf); 3382 snprintf(bp, buflen - (bp - buf), " %s CFV=%s", 3383 sum_clientid(res->SETCLIENTID4res_u.resok4.clientid), 3384 tohex(res->SETCLIENTID4res_u.resok4.setclientid_confirm, 3385 NFS4_VERIFIER_SIZE)); 3386 break; 3387 case NFS4ERR_CLID_INUSE: 3388 bp = buf + strlen(buf); 3389 snprintf(bp, buflen - (bp - buf), " ID=%s Addr=%s", 3390 res->SETCLIENTID4res_u.client_using.na_r_netid, 3391 res->SETCLIENTID4res_u.client_using.na_r_addr); 3392 break; 3393 } 3394 } 3395 3396 static void 3397 dtlres_setclid(void *obj) 3398 { 3399 SETCLIENTID4res *res = (SETCLIENTID4res *)obj; 3400 3401 dtl_nfsstat4(obj); 3402 switch (res->status) { 3403 case NFS_OK: 3404 detail_clientid(res->SETCLIENTID4res_u.resok4.clientid); 3405 sprintf(get_line(0, 0), "Set Client ID Confirm Verifier = %s", 3406 tohex(res->SETCLIENTID4res_u.resok4.setclientid_confirm, 3407 NFS4_VERIFIER_SIZE)); 3408 break; 3409 case NFS4ERR_CLID_INUSE: 3410 sprintf(get_line(0, 0), "Used by Net ID = %s", 3411 res->SETCLIENTID4res_u.client_using.na_r_netid); 3412 sprintf(get_line(0, 0), "Used by Addr = %s", 3413 res->SETCLIENTID4res_u.client_using.na_r_addr); 3414 break; 3415 } 3416 } 3417 3418 static void 3419 sumres_write(char *buf, size_t buflen, void *obj) 3420 { 3421 char *bp; 3422 WRITE4res *res = (WRITE4res *)obj; 3423 3424 strncpy(buf, status_name(res->status), buflen); 3425 if (res->status == NFS4_OK) { 3426 bp = buf + strlen(buf); 3427 snprintf(bp, buflen - (bp - buf), " %u (%s)", 3428 res->WRITE4res_u.resok4.count, 3429 stable_how4_name(res->WRITE4res_u.resok4.committed)); 3430 } 3431 } 3432 3433 static void 3434 dtlres_write(void *obj) 3435 { 3436 WRITE4res *res = (WRITE4res *)obj; 3437 3438 dtl_nfsstat4(obj); 3439 if (res->status == NFS4_OK) { 3440 sprintf(get_line(0, 0), "Count = %u bytes written", 3441 res->WRITE4res_u.resok4.count); 3442 sprintf(get_line(0, 0), "Stable = %s", 3443 stable_how4_name(res->WRITE4res_u.resok4.committed)); 3444 sprintf(get_line(0, 0), "Verifier = %s", 3445 tohex(res->WRITE4res_u.resok4.writeverf, 3446 NFS4_VERIFIER_SIZE)); 3447 } 3448 } 3449 3450 /* 3451 * Print details about the nfs_resop4 that is next in the XDR stream. 3452 */ 3453 3454 static void 3455 detail_nfs_resop4(void) 3456 { 3457 int numres; 3458 nfs_resop4 one_res; 3459 void (*fmtproc)(void *); 3460 3461 numres = getxdr_long(); 3462 (void) sprintf(get_line(0, 0), "Number of results = %d", 3463 numres); 3464 3465 while (numres-- > 0) { 3466 bzero(&one_res, sizeof (one_res)); 3467 3468 if (!xdr_nfs_resop4(&xdrm, &one_res)) { 3469 xdr_free(xdr_nfs_resop4, (char *)&one_res); 3470 longjmp(xdr_err, 1); 3471 } 3472 3473 get_line(0, 0); /* blank line to separate ops */ 3474 sprintf(get_line(0, 0), "Op = %d (%s)", 3475 one_res.resop, opcode_name(one_res.resop)); 3476 if (one_res.resop < num_opcodes) 3477 fmtproc = opcode_info[one_res.resop].dtlres; 3478 else if (one_res.resop == OP_ILLEGAL) 3479 fmtproc = dtl_nfsstat4; 3480 else 3481 fmtproc = NULL; 3482 3483 if (fmtproc != NULL) 3484 fmtproc(&one_res.nfs_resop4_u); 3485 3486 /* nfs4_skip_bytes set by xdr_nfs_resop4()() */ 3487 if (nfs4_skip_bytes) 3488 nfs4_xdr_skip(nfs4_skip_bytes); 3489 3490 xdr_free(xdr_nfs_resop4, (char *)&one_res); 3491 } 3492 } 3493 3494 3495 /* 3496 * Print details about the nfs_cb_resop4 that is next in the XDR stream. 3497 */ 3498 3499 static void 3500 detail_cb_resop4(void) 3501 { 3502 int numres; 3503 nfs_cb_resop4 one_res; 3504 void (*fmtproc)(void *); 3505 3506 numres = getxdr_long(); 3507 (void) sprintf(get_line(0, 0), "Number of results = %d", 3508 numres); 3509 3510 while (numres-- > 0) { 3511 bzero(&one_res, sizeof (one_res)); 3512 if (!xdr_nfs_cb_resop4(&xdrm, &one_res)) 3513 longjmp(xdr_err, 1); 3514 3515 get_line(0, 0); /* blank line to separate ops */ 3516 sprintf(get_line(0, 0), "Op = %d (%s)", 3517 one_res.resop, cb_opcode_name(one_res.resop)); 3518 if (one_res.resop < cb_num_opcodes) 3519 fmtproc = cb_opcode_info[one_res.resop].dtlres; 3520 else if (one_res.resop == OP_CB_ILLEGAL) 3521 fmtproc = dtl_nfsstat4; 3522 else 3523 fmtproc = NULL; 3524 3525 if (fmtproc != NULL) 3526 fmtproc(&one_res.nfs_cb_resop4_u); 3527 3528 xdr_free(xdr_nfs_cb_resop4, (char *)&one_res); 3529 } 3530 } 3531 3532 3533 /* 3534 * Return the name of a lock type. 3535 */ 3536 static char * 3537 lock_type_name(enum nfs_lock_type4 type) 3538 { 3539 char *result; 3540 3541 switch (type) { 3542 case READ_LT: 3543 result = "READ"; 3544 break; 3545 case WRITE_LT: 3546 result = "WRITE"; 3547 break; 3548 case READW_LT: 3549 result = "READW"; 3550 break; 3551 case WRITEW_LT: 3552 result = "WRITEW"; 3553 break; 3554 default: 3555 result = "?"; 3556 break; 3557 } 3558 3559 return (result); 3560 } 3561 3562 /* 3563 * Return the name of an opcode. 3564 */ 3565 3566 static char * 3567 opcode_name(uint_t opnum) 3568 { 3569 static char buf[20]; 3570 3571 if (opnum < num_opcodes) 3572 return (opcode_info[opnum].name); 3573 3574 if (opnum == OP_ILLEGAL) 3575 return ("ILLEGAL"); 3576 3577 sprintf(buf, "op %d", opnum); 3578 return (buf); 3579 } 3580 3581 /* 3582 * Return the name of an opcode. 3583 */ 3584 static char * 3585 cb_opcode_name(uint_t opnum) 3586 { 3587 static char buf[20]; 3588 3589 if (opnum < cb_num_opcodes) 3590 return (cb_opcode_info[opnum].name); 3591 3592 if (opnum == OP_CB_ILLEGAL) 3593 return ("CB_ILLEGAL"); 3594 3595 sprintf(buf, "op %d", opnum); 3596 return (buf); 3597 } 3598 3599 3600 /* 3601 * Fill in a summary string for the given access bitmask. 3602 */ 3603 3604 static void 3605 sum_access4(char *buf, size_t buflen, uint32_t bits) 3606 { 3607 buf[0] = '\0'; 3608 3609 if (bits & ACCESS4_READ) 3610 (void) strncat(buf, "rd,", buflen); 3611 if (bits & ACCESS4_LOOKUP) 3612 (void) strncat(buf, "lk,", buflen); 3613 if (bits & ACCESS4_MODIFY) 3614 (void) strncat(buf, "mo,", buflen); 3615 if (bits & ACCESS4_EXTEND) 3616 (void) strncat(buf, "ext,", buflen); 3617 if (bits & ACCESS4_DELETE) 3618 (void) strncat(buf, "dl,", buflen); 3619 if (bits & ACCESS4_EXECUTE) 3620 (void) strncat(buf, "exc,", buflen); 3621 if (buf[0] != '\0') 3622 buf[strlen(buf) - 1] = '\0'; 3623 } 3624 3625 /* 3626 * Print detail information about the given access bitmask. 3627 */ 3628 3629 static void 3630 detail_access4(char *descrip, uint32_t bits) 3631 { 3632 sprintf(get_line(0, 0), "%s = 0x%08x", descrip, bits); 3633 3634 (void) sprintf(get_line(0, 0), " %s", 3635 getflag(bits, ACCESS4_READ, "Read", "(no read)")); 3636 (void) sprintf(get_line(0, 0), " %s", 3637 getflag(bits, ACCESS4_LOOKUP, "Lookup", "(no lookup)")); 3638 (void) sprintf(get_line(0, 0), " %s", 3639 getflag(bits, ACCESS4_MODIFY, "Modify", "(no modify)")); 3640 (void) sprintf(get_line(0, 0), " %s", 3641 getflag(bits, ACCESS4_EXTEND, "Extend", "(no extend)")); 3642 (void) sprintf(get_line(0, 0), " %s", 3643 getflag(bits, ACCESS4_DELETE, "Delete", "(no delete)")); 3644 (void) sprintf(get_line(0, 0), " %s", 3645 getflag(bits, ACCESS4_EXECUTE, "Execute", "(no execute)")); 3646 } 3647 3648 3649 /* 3650 * Fill in a summary string for the given open_claim4. 3651 */ 3652 static void 3653 sum_name(char *buf, size_t buflen, open_claim4 *claim) 3654 { 3655 char *bp = buf; 3656 3657 switch (claim->claim) { 3658 case CLAIM_NULL: 3659 snprintf(bp, buflen, "%s ", 3660 component_name(&claim->open_claim4_u.file)); 3661 break; 3662 case CLAIM_PREVIOUS: 3663 break; 3664 case CLAIM_DELEGATE_CUR: 3665 snprintf(bp, buflen, "%s ", 3666 component_name(&claim->open_claim4_u. 3667 delegate_cur_info.file)); 3668 break; 3669 case CLAIM_DELEGATE_PREV: 3670 snprintf(bp, buflen, "%s ", 3671 component_name(&claim->open_claim4_u. 3672 file_delegate_prev)); 3673 break; 3674 case CLAIM_FH: 3675 break; 3676 case CLAIM_DELEG_CUR_FH: 3677 break; 3678 case CLAIM_DELEG_PREV_FH: 3679 break; 3680 } 3681 } 3682 3683 /* 3684 * Fill in a summary string for the given open_claim4. 3685 */ 3686 static void 3687 sum_claim(char *buf, size_t buflen, open_claim4 *claim) 3688 { 3689 char *bp = buf; 3690 3691 switch (claim->claim) { 3692 case CLAIM_NULL: 3693 snprintf(bp, buflen, " CT=N"); 3694 break; 3695 case CLAIM_PREVIOUS: 3696 snprintf(bp, buflen, " CT=P DT=%s", 3697 get_deleg_typestr(claim->open_claim4_u.delegate_type)); 3698 break; 3699 case CLAIM_DELEGATE_CUR: 3700 snprintf(bp, buflen, " CT=DC %s", 3701 sum_deleg_stateid(&claim->open_claim4_u. 3702 delegate_cur_info.delegate_stateid)); 3703 break; 3704 case CLAIM_DELEGATE_PREV: 3705 snprintf(bp, buflen, " CT=DP"); 3706 break; 3707 case CLAIM_FH: 3708 snprintf(bp, buflen, " CT=FH"); 3709 break; 3710 case CLAIM_DELEG_CUR_FH: 3711 snprintf(bp, buflen, " CT=CUR_FH"); 3712 break; 3713 case CLAIM_DELEG_PREV_FH: 3714 snprintf(bp, buflen, " CT=PREV_FH"); 3715 break; 3716 default: 3717 snprintf(bp, buflen, " CT=? (%d)", claim->claim); 3718 break; 3719 } 3720 } 3721 3722 static char * 3723 get_deleg_typestr(open_delegation_type4 dt) 3724 { 3725 char *str = ""; 3726 3727 switch (dt) { 3728 case OPEN_DELEGATE_NONE: 3729 str = "N"; 3730 break; 3731 case OPEN_DELEGATE_READ: 3732 str = "R"; 3733 break; 3734 case OPEN_DELEGATE_WRITE: 3735 str = "W"; 3736 break; 3737 default: 3738 str = "?"; 3739 } 3740 3741 return (str); 3742 } 3743 3744 /* 3745 * Print detail information for the given open_claim4. 3746 */ 3747 3748 static void 3749 detail_claim(open_claim4 *claim) 3750 { 3751 sprintf(get_line(0, 0), "Claim Type = %d (%s)", 3752 claim->claim, claim_name(claim->claim)); 3753 3754 switch (claim->claim) { 3755 case CLAIM_NULL: 3756 detail_compname4(&claim->open_claim4_u.file); 3757 break; 3758 case CLAIM_PREVIOUS: 3759 sprintf(get_line(0, 0), "Delegate Type = %s (val = %d)", 3760 get_deleg_typestr(claim->open_claim4_u.delegate_type), 3761 claim->open_claim4_u.delegate_type); 3762 break; 3763 case CLAIM_DELEGATE_CUR: 3764 detail_compname4(&claim->open_claim4_u.delegate_cur_info.file); 3765 detail_deleg_stateid(&claim->open_claim4_u.delegate_cur_info. 3766 delegate_stateid); 3767 break; 3768 case CLAIM_DELEGATE_PREV: 3769 detail_compname4(&claim->open_claim4_u.file_delegate_prev); 3770 break; 3771 } 3772 } 3773 3774 /* 3775 * Return a summary string for the given clientid4. 3776 */ 3777 char * 3778 sum_clientid(clientid4 client) 3779 { 3780 static char buf[50]; 3781 3782 snprintf(buf, sizeof (buf), "CL=%llx", client); 3783 3784 return (buf); 3785 } 3786 3787 /* 3788 * Print a detail string for the given clientid4. 3789 */ 3790 void 3791 detail_clientid(clientid4 client) 3792 { 3793 sprintf(get_line(0, 0), "Client ID = %llx", client); 3794 } 3795 3796 /* 3797 * Write a summary string for the given delegation into buf. 3798 */ 3799 3800 static void 3801 sum_delegation(char *buf, size_t buflen, open_delegation4 *delp) 3802 { 3803 switch (delp->delegation_type) { 3804 case OPEN_DELEGATE_NONE: 3805 snprintf(buf, buflen, " DT=N"); 3806 break; 3807 case OPEN_DELEGATE_READ: 3808 snprintf(buf, buflen, " DT=R %s", 3809 sum_deleg_stateid(&delp->open_delegation4_u.write. 3810 stateid)); 3811 break; 3812 case OPEN_DELEGATE_WRITE: 3813 snprintf(buf, buflen, " DT=W %s %s", 3814 sum_deleg_stateid(&delp->open_delegation4_u.write. 3815 stateid), 3816 sum_space_limit(&delp->open_delegation4_u.write. 3817 space_limit)); 3818 break; 3819 default: 3820 snprintf(buf, buflen, " DT=?"); 3821 break; 3822 } 3823 } 3824 3825 static void 3826 detail_delegation(open_delegation4 *delp) 3827 { 3828 sprintf(get_line(0, 0), "Delegation Type = %d (%s)", 3829 delp->delegation_type, 3830 delegation_type_name(delp->delegation_type)); 3831 3832 switch (delp->delegation_type) { 3833 case OPEN_DELEGATE_NONE: 3834 /* no-op */ 3835 break; 3836 case OPEN_DELEGATE_READ: 3837 detail_deleg_stateid(&delp->open_delegation4_u.read.stateid); 3838 sprintf(get_line(0, 0), "Recall = %s", 3839 delp->open_delegation4_u.read.recall ? 3840 "TRUE" : "FALSE"); 3841 sprintf(get_line(0, 0), "[nfsacl4]"); 3842 break; 3843 case OPEN_DELEGATE_WRITE: 3844 detail_deleg_stateid(&delp->open_delegation4_u.write.stateid); 3845 sprintf(get_line(0, 0), "Recall = %s", 3846 delp->open_delegation4_u.write.recall ? 3847 "TRUE" : "FALSE"); 3848 detail_space_limit(&delp->open_delegation4_u.write. 3849 space_limit); 3850 sprintf(get_line(0, 0), "[nfsacl4]"); 3851 break; 3852 } 3853 } 3854 3855 3856 static void 3857 detail_open_owner(open_owner4 *owner) 3858 { 3859 sprintf(get_line(0, 0), "Open Owner hash = [%04X] ", 3860 owner_hash(&owner->owner)); 3861 sprintf(get_line(0, 0), " len = %u val = %s ", 3862 owner->owner.owner_len, 3863 tohex(owner->owner.owner_val, owner->owner.owner_len)); 3864 detail_clientid(owner->clientid); 3865 } 3866 3867 static void 3868 detail_lock_owner(lock_owner4 *owner) 3869 { 3870 sprintf(get_line(0, 0), "Lock Owner hash = [%04X] ", 3871 owner_hash(&owner->owner)); 3872 sprintf(get_line(0, 0), " len = %u val = %s ", 3873 owner->owner.owner_len, 3874 tohex(owner->owner.owner_val, owner->owner.owner_len)); 3875 detail_clientid(owner->clientid); 3876 } 3877 3878 static void 3879 sum_openflag(char *bufp, int buflen, openflag4 *flagp) 3880 { 3881 if (flagp->opentype == OPEN4_CREATE) { 3882 switch (flagp->openflag4_u.how.mode) { 3883 case UNCHECKED4: 3884 snprintf(bufp, buflen, "OT=CR(U)"); 3885 break; 3886 case GUARDED4: 3887 snprintf(bufp, buflen, "OT=CR(G)"); 3888 break; 3889 case EXCLUSIVE4: 3890 snprintf(bufp, buflen, "OT=CR(E)"); 3891 break; 3892 default: 3893 snprintf(bufp, buflen, "OT=CR(?:%d)", 3894 flagp->openflag4_u.how.mode); 3895 break; 3896 } 3897 } else 3898 snprintf(bufp, buflen, "OT=NC"); 3899 } 3900 3901 static void 3902 detail_openflag(openflag4 *flagp) 3903 { 3904 sprintf(get_line(0, 0), "Open Type = %s", 3905 flagp->opentype == OPEN4_CREATE ? "CREATE" : "NOCREATE"); 3906 if (flagp->opentype == OPEN4_CREATE) 3907 detail_createhow4(&flagp->openflag4_u.how); 3908 } 3909 3910 /* 3911 * Fill in buf with the given path. 3912 */ 3913 static void 3914 sum_pathname4(char *buf, size_t buflen, pathname4 *pathp) 3915 { 3916 char *bp = buf; 3917 uint_t component; 3918 3919 for (component = 0; component < pathp->pathname4_len; 3920 component++) { 3921 snprintf(bp, buflen - (bp - buf), 3922 component == 0 ? "%s" : "/%s", 3923 component_name(&pathp->pathname4_val[component])); 3924 bp += strlen(bp); 3925 } 3926 } 3927 3928 static void 3929 sum_compname4(char *buf, size_t buflen, component4 *comp) 3930 { 3931 snprintf(buf, buflen, "%s", component_name(comp)); 3932 } 3933 3934 static void 3935 detail_compname4(component4 *comp) 3936 { 3937 sprintf(get_line(0, 0), "%s", component_name(comp)); 3938 } 3939 3940 static void 3941 detail_pathname4(pathname4 *pathp) 3942 { 3943 char *bp = get_line(0, 0); 3944 uint_t component; 3945 3946 sprintf(bp, "File name = "); 3947 bp += strlen(bp); 3948 3949 for (component = 0; component < pathp->pathname4_len; component++) { 3950 sprintf(bp, component == 0 ? "%s" : "/%s", 3951 component_name(&pathp->pathname4_val[component])); 3952 bp += strlen(bp); 3953 } 3954 } 3955 3956 /* 3957 * Print detail information about the rpcsec_gss_info that is XDR-encoded 3958 * at mem. 3959 */ 3960 3961 void 3962 detail_rpcsec_gss(rpcsec_gss_info *info) 3963 { 3964 sprintf(get_line(0, 0), "OID = %s", 3965 tohex(info->oid.sec_oid4_val, info->oid.sec_oid4_len)); 3966 sprintf(get_line(0, 0), "QOP = %u", info->qop); 3967 sprintf(get_line(0, 0), "Service = %d (%s)", 3968 info->service, gss_svc_name(info->service)); 3969 } 3970 3971 /* 3972 * Print detail information about the given secinfo4. 3973 */ 3974 3975 void 3976 detail_secinfo4(secinfo4 *infop) 3977 { 3978 sprintf(get_line(0, 0), "Flavor = %d (%s)", 3979 infop->flavor, flavor_name(infop->flavor)); 3980 switch (infop->flavor) { 3981 case RPCSEC_GSS: 3982 detail_rpcsec_gss(&infop->secinfo4_u.flavor_info); 3983 break; 3984 } 3985 } 3986 3987 3988 /* 3989 * Return a summary string corresponding to the given nfs_space_limit4. 3990 */ 3991 3992 static char * 3993 sum_space_limit(nfs_space_limit4 *limitp) 3994 { 3995 static char buf[64]; 3996 int buflen = sizeof (buf); 3997 3998 buf[0] = '\0'; 3999 switch (limitp->limitby) { 4000 case NFS_LIMIT_SIZE: 4001 snprintf(buf, buflen, "LB=SZ(%llu)", 4002 limitp->nfs_space_limit4_u.filesize); 4003 break; 4004 case NFS_LIMIT_BLOCKS: 4005 snprintf(buf, buflen, "LB=BL(%u*%u)", 4006 limitp->nfs_space_limit4_u.mod_blocks.num_blocks, 4007 limitp->nfs_space_limit4_u.mod_blocks.bytes_per_block); 4008 break; 4009 default: 4010 snprintf(buf, buflen, "LB=?(%d)", limitp->limitby); 4011 break; 4012 } 4013 4014 return (buf); 4015 } 4016 4017 /* 4018 * Print detail information about the given nfs_space_limit4. 4019 */ 4020 4021 static void 4022 detail_space_limit(nfs_space_limit4 *limitp) 4023 { 4024 sprintf(get_line(0, 0), "LimitBy = %d (%s)", 4025 limitp->limitby, 4026 limitby_name(limitp->limitby)); 4027 4028 switch (limitp->limitby) { 4029 case NFS_LIMIT_SIZE: 4030 sprintf(get_line(0, 0), "Bytes = %llu", 4031 limitp->nfs_space_limit4_u.filesize); 4032 break; 4033 case NFS_LIMIT_BLOCKS: 4034 sprintf(get_line(0, 0), "Blocks = %u", 4035 limitp->nfs_space_limit4_u.mod_blocks.num_blocks); 4036 sprintf(get_line(0, 0), "Bytes Per Block = %u", 4037 limitp->nfs_space_limit4_u.mod_blocks.bytes_per_block); 4038 break; 4039 } 4040 } 4041 4042 4043 /* 4044 * Return the short name of a file type. 4045 */ 4046 4047 static char * 4048 sum_type_name(nfs_ftype4 type) 4049 { 4050 static char buf[20]; 4051 4052 if (type < num_ftypes) 4053 return (ftype_names[type].short_name); 4054 else { 4055 sprintf(buf, "type %d", type); 4056 return (buf); 4057 } 4058 } 4059 4060 4061 /* 4062 * Return string with long/short flag names 4063 */ 4064 4065 static char * 4066 get_flags(uint_t flag, ftype_names_t *names, uint_t num_flags, int shortname, 4067 char *prefix) 4068 { 4069 static char buf[200]; 4070 char *bp = buf, *str; 4071 int i, len, blen = sizeof (buf); 4072 ftype_names_t *fn = NULL; 4073 4074 *bp = '\0'; 4075 4076 if (prefix) { 4077 snprintf(bp, blen, "%s", prefix); 4078 bp += (len = sizeof (bp)); 4079 blen -= len; 4080 } 4081 4082 for (i = 0; i < 32; i++) 4083 if (flag & (1 << i)) { 4084 fn = names + (i < num_flags ? i : num_flags); 4085 str = (shortname ? fn->short_name : fn->long_name); 4086 4087 snprintf(bp, blen, "%s,", str); 4088 bp += (len = strlen(bp)); 4089 blen -= len; 4090 } 4091 4092 if (fn) 4093 *(bp - 1) = '\0'; 4094 else 4095 *buf = '\0'; 4096 4097 return (buf); 4098 } 4099 4100 4101 /* 4102 * Return the long name of a file type. 4103 */ 4104 4105 static char * 4106 detail_type_name(nfs_ftype4 type) 4107 { 4108 static char buf[20]; 4109 4110 if (type < num_ftypes) 4111 return (ftype_names[type].long_name); 4112 else { 4113 sprintf(buf, "type %d", type); 4114 return (buf); 4115 } 4116 } 4117 4118 /* 4119 * Return the name of an attribute. 4120 */ 4121 4122 static char * 4123 attr_name(uint_t attrnum) 4124 { 4125 static char buf[20]; 4126 4127 if (attrnum < MAX_ATTRIBUTES) 4128 return (attr_info[attrnum].name); 4129 else { 4130 sprintf(buf, "attr #%d", attrnum); 4131 return (buf); 4132 } 4133 } 4134 4135 /* 4136 * Return the name of the given open_claim_type4. 4137 */ 4138 4139 static char * 4140 claim_name(enum open_claim_type4 claim_type) 4141 { 4142 char *result; 4143 4144 switch (claim_type) { 4145 case CLAIM_NULL: 4146 result = "NULL"; 4147 break; 4148 case CLAIM_PREVIOUS: 4149 result = "PREVIOUS"; 4150 break; 4151 case CLAIM_DELEGATE_CUR: 4152 result = "DELEGATE CURRENT"; 4153 break; 4154 case CLAIM_DELEGATE_PREV: 4155 result = "DELEGATE PREVIOUS"; 4156 break; 4157 case CLAIM_FH: 4158 result = "FILEHANDLE"; 4159 break; 4160 default: 4161 result = "?"; 4162 break; 4163 } 4164 4165 return (result); 4166 } 4167 4168 /* 4169 * Return a string naming the given delegation. 4170 */ 4171 4172 static char * 4173 delegation_type_name(enum open_delegation_type4 type) 4174 { 4175 char *result; 4176 4177 switch (type) { 4178 case OPEN_DELEGATE_NONE: 4179 result = "NONE"; 4180 break; 4181 case OPEN_DELEGATE_READ: 4182 result = "READ"; 4183 break; 4184 case OPEN_DELEGATE_WRITE: 4185 result = "WRITE"; 4186 break; 4187 default: 4188 result = "?"; 4189 break; 4190 } 4191 4192 return (result); 4193 } 4194 4195 /* 4196 * Return the name of the given authentication flavor. 4197 */ 4198 4199 static char * 4200 flavor_name(uint_t flavor) 4201 { 4202 char *result; 4203 static char buf[50]; 4204 4205 switch (flavor) { 4206 case AUTH_SYS: 4207 result = "AUTH_SYS"; 4208 break; 4209 case AUTH_NONE: 4210 result = "AUTH_NONE"; 4211 break; 4212 case AUTH_DH: 4213 result = "AUTH_DH"; 4214 break; 4215 case RPCSEC_GSS: 4216 result = "RPCSEC_GSS"; 4217 break; 4218 default: 4219 sprintf(buf, "[flavor %d]", flavor); 4220 result = buf; 4221 break; 4222 } 4223 4224 return (result); 4225 } 4226 4227 /* 4228 * Return the name of the given rpc_gss_svc_t. 4229 */ 4230 4231 static char * 4232 gss_svc_name(rpc_gss_svc_t svc) 4233 { 4234 char *result; 4235 static char buf[50]; 4236 4237 switch (svc) { 4238 case RPC_GSS_SVC_NONE: 4239 result = "NONE"; 4240 break; 4241 case RPC_GSS_SVC_INTEGRITY: 4242 result = "INTEGRITY"; 4243 break; 4244 case RPC_GSS_SVC_PRIVACY: 4245 result = "PRIVACY"; 4246 break; 4247 default: 4248 sprintf(buf, "Service %d", svc); 4249 result = buf; 4250 break; 4251 } 4252 4253 return (result); 4254 } 4255 4256 /* 4257 * Return a string name for the given limit_by4. 4258 */ 4259 4260 static char * 4261 limitby_name(enum limit_by4 limitby) 4262 { 4263 char *result; 4264 4265 switch (limitby) { 4266 case NFS_LIMIT_SIZE: 4267 result = "SIZE"; 4268 break; 4269 case NFS_LIMIT_BLOCKS: 4270 result = "BLOCKS"; 4271 break; 4272 default: 4273 result = "?"; 4274 break; 4275 } 4276 4277 return (result); 4278 } 4279 4280 static char * 4281 status_name(int status) 4282 { 4283 char *p; 4284 4285 switch (status) { 4286 case NFS4_OK: /* 0 */ 4287 p = "NFS4_OK"; break; 4288 case NFS4ERR_PERM: /* 1 */ 4289 p = "NFS4ERR_PERM"; break; 4290 case NFS4ERR_NOENT: /* 2 */ 4291 p = "NFS4ERR_NOENT"; break; 4292 case NFS4ERR_IO: /* 5 */ 4293 p = "NFS4ERR_IO"; break; 4294 case NFS4ERR_NXIO: /* 6 */ 4295 p = "NFS4ERR_NXIO"; break; 4296 case NFS4ERR_ACCESS: /* 13 */ 4297 p = "NFS4ERR_ACCESS"; break; 4298 case NFS4ERR_EXIST: /* 17 */ 4299 p = "NFS4ERR_EXIST"; break; 4300 case NFS4ERR_XDEV: /* 18 */ 4301 p = "NFS4ERR_XDEV"; break; 4302 case NFS4ERR_NOTDIR: /* 20 */ 4303 p = "NFS4ERR_NOTDIR"; break; 4304 case NFS4ERR_ISDIR: /* 21 */ 4305 p = "NFS4ERR_ISDIR"; break; 4306 case NFS4ERR_INVAL: /* 22 */ 4307 p = "NFS4ERR_INVAL"; break; 4308 case NFS4ERR_FBIG: /* 27 */ 4309 p = "NFS4ERR_FBIG"; break; 4310 case NFS4ERR_NOSPC: /* 28 */ 4311 p = "NFS4ERR_NOSPC"; break; 4312 case NFS4ERR_ROFS: /* 30 */ 4313 p = "NFS4ERR_ROFS"; break; 4314 case NFS4ERR_MLINK: /* 31 */ 4315 p = "NFS4ERR_MLINK"; break; 4316 case NFS4ERR_NAMETOOLONG: /* 63 */ 4317 p = "NFS4ERR_NAMETOOLONG"; break; 4318 case NFS4ERR_NOTEMPTY: /* 66 */ 4319 p = "NFS4ERR_NOTEMPTY"; break; 4320 case NFS4ERR_DQUOT: /* 69 */ 4321 p = "NFS4ERR_DQUOT"; break; 4322 case NFS4ERR_STALE: /* 70 */ 4323 p = "NFS4ERR_STALE"; break; 4324 case NFS4ERR_BADHANDLE: /* 10001 */ 4325 p = "NFS4ERR_BADHANDLE"; break; 4326 case NFS4ERR_BAD_COOKIE: /* 10003 */ 4327 p = "NFS4ERR_BAD_COOKIE"; break; 4328 case NFS4ERR_NOTSUPP: /* 10004 */ 4329 p = "NFS4ERR_NOTSUPP"; break; 4330 case NFS4ERR_TOOSMALL: /* 10005 */ 4331 p = "NFS4ERR_TOOSMALL"; break; 4332 case NFS4ERR_SERVERFAULT: /* 10006 */ 4333 p = "NFS4ERR_SERVERFAULT"; break; 4334 case NFS4ERR_BADTYPE: /* 10007 */ 4335 p = "NFS4ERR_BADTYPE"; break; 4336 case NFS4ERR_DELAY: /* 10008 */ 4337 p = "NFS4ERR_DELAY"; break; 4338 case NFS4ERR_SAME: /* 10009 */ 4339 p = "NFS4ERR_SAME"; break; 4340 case NFS4ERR_DENIED: /* 10010 */ 4341 p = "NFS4ERR_DENIED"; break; 4342 case NFS4ERR_EXPIRED: /* 10011 */ 4343 p = "NFS4ERR_EXPIRED"; break; 4344 case NFS4ERR_LOCKED: /* 10012 */ 4345 p = "NFS4ERR_LOCKED"; break; 4346 case NFS4ERR_GRACE: /* 10013 */ 4347 p = "NFS4ERR_GRACE"; break; 4348 case NFS4ERR_FHEXPIRED: /* 10014 */ 4349 p = "NFS4ERR_FHEXPIRED"; break; 4350 case NFS4ERR_SHARE_DENIED: /* 10015 */ 4351 p = "NFS4ERR_SHARE_DENIED"; break; 4352 case NFS4ERR_WRONGSEC: /* 10016 */ 4353 p = "NFS4ERR_WRONGSEC"; break; 4354 case NFS4ERR_CLID_INUSE: /* 10017 */ 4355 p = "NFS4ERR_CLID_INUSE"; break; 4356 case NFS4ERR_RESOURCE: /* 10018 */ 4357 p = "NFS4ERR_RESOURCE"; break; 4358 case NFS4ERR_MOVED: /* 10019 */ 4359 p = "NFS4ERR_MOVED"; break; 4360 case NFS4ERR_NOFILEHANDLE: /* 10020 */ 4361 p = "NFS4ERR_NOFILEHANDLE"; break; 4362 case NFS4ERR_MINOR_VERS_MISMATCH: /* 10021 */ 4363 p = "NFS4ERR_MINOR_VERS_MISMATCH"; break; 4364 case NFS4ERR_STALE_CLIENTID: /* 10022 */ 4365 p = "NFS4ERR_STALE_CLIENTID"; break; 4366 case NFS4ERR_STALE_STATEID: /* 10023 */ 4367 p = "NFS4ERR_STALE_STATEID"; break; 4368 case NFS4ERR_OLD_STATEID: /* 10024 */ 4369 p = "NFS4ERR_OLD_STATEID"; break; 4370 case NFS4ERR_BAD_STATEID: /* 10025 */ 4371 p = "NFS4ERR_BAD_STATEID"; break; 4372 case NFS4ERR_BAD_SEQID: /* 10026 */ 4373 p = "NFS4ERR_BAD_SEQID"; break; 4374 case NFS4ERR_NOT_SAME: /* 10027 */ 4375 p = "NFS4ERR_NOT_SAME"; break; 4376 case NFS4ERR_LOCK_RANGE: /* 10028 */ 4377 p = "NFS4ERR_LOCK_RANGE"; break; 4378 case NFS4ERR_SYMLINK: /* 10029 */ 4379 p = "NFS4ERR_SYMLINK"; break; 4380 case NFS4ERR_RESTOREFH: /* 10030 */ 4381 p = "NFS4ERR_RESTOREFH"; break; 4382 case NFS4ERR_LEASE_MOVED: /* 10031 */ 4383 p = "NFS4ERR_LEASE_MOVED"; break; 4384 case NFS4ERR_ATTRNOTSUPP: /* 10032 */ 4385 p = "NFS4ERR_ATTRNOTSUPP"; break; 4386 case NFS4ERR_NO_GRACE: /* 10033 */ 4387 p = "NFS4ERR_NO_GRACE"; break; 4388 case NFS4ERR_RECLAIM_BAD: /* 10034 */ 4389 p = "NFS4ERR_RECLAIM_BAD"; break; 4390 case NFS4ERR_RECLAIM_CONFLICT: /* 10035 */ 4391 p = "NFS4ERR_RECLAIM_CONFLICT"; break; 4392 case NFS4ERR_BADXDR: /* 10036 */ 4393 p = "NFS4ERR_BADXDR"; break; 4394 case NFS4ERR_LOCKS_HELD: /* 10037 */ 4395 p = "NFS4ERR_LOCKS_HELD"; break; 4396 case NFS4ERR_OPENMODE: /* 10038 */ 4397 p = "NFS4ERR_OPENMODE"; break; 4398 case NFS4ERR_BADOWNER: /* 10039 */ 4399 p = "NFS4ERR_BADOWNER"; break; 4400 case NFS4ERR_BADCHAR: /* 10040 */ 4401 p = "NFS4ERR_BADCHAR"; break; 4402 case NFS4ERR_BADNAME: /* 10041 */ 4403 p = "NFS4ERR_BADNAME"; break; 4404 case NFS4ERR_BAD_RANGE: /* 10042 */ 4405 p = "NFS4ERR_BAD_RANGE"; break; 4406 case NFS4ERR_LOCK_NOTSUPP: /* 10043 */ 4407 p = "NFS4ERR_LOCK_NOTSUPP"; break; 4408 case NFS4ERR_OP_ILLEGAL: /* 10044 */ 4409 p = "NFS4ERR_OP_ILLEGAL"; break; 4410 case NFS4ERR_DEADLOCK: /* 10045 */ 4411 p = "NFS4ERR_DEADLOCK"; break; 4412 case NFS4ERR_FILE_OPEN: /* 10046 */ 4413 p = "NFS4ERR_FILE_OPEN"; break; 4414 case NFS4ERR_ADMIN_REVOKED: /* 10047 */ 4415 p = "NFS4ERR_ADMIN_REVOKED"; break; 4416 case NFS4ERR_CB_PATH_DOWN: /* 10048 */ 4417 p = "NFS4ERR_CB_PATH_DOWN"; break; 4418 /* nfs4.1 error code */ 4419 case NFS4ERR_BADIOMODE: /* 10049 */ 4420 p = "NFS4ERR_BADIOMODE"; break; 4421 case NFS4ERR_BADLAYOUT: /* 10050 */ 4422 p = "NFS4ERR_BADLAYOUT"; break; 4423 case NFS4ERR_BAD_SESSION_DIGEST: /* 10051 */ 4424 p = "NFS4ERR_BAD_SESSION_DIGEST"; break; 4425 case NFS4ERR_BADSESSION: /* 10052 */ 4426 p = "NFS4ERR_BADSESSION"; break; 4427 case NFS4ERR_BADSLOT: /* 10053 */ 4428 p = "NFS4ERR_BADSLOT"; break; 4429 case NFS4ERR_COMPLETE_ALREADY: /* 10054 */ 4430 p = "NFS4ERR_COMPLETE_ALREADY"; break; 4431 case NFS4ERR_CONN_NOT_BOUND_TO_SESSION: /* 10055 */ 4432 p = "NFS4ERR_CONN_NOT_BOUND_TO_SESSION"; break; 4433 case NFS4ERR_DELEG_ALREADY_WANTED: /* 10056 */ 4434 p = "NFS4ERR_DELEG_ALREADY_WANTED"; break; 4435 case NFS4ERR_BACK_CHAN_BUSY: /* 10057 */ 4436 p = "NFS4ERR_BACK_CHAN_BUSY"; break; 4437 case NFS4ERR_LAYOUTTRYLATER: /* 10058 */ 4438 p = "NFS4ERR_LAYOUTTRYLATER"; break; 4439 case NFS4ERR_LAYOUTUNAVAILABLE: /* 10059 */ 4440 p = "NFS4ERR_LAYOUTUNAVAILABLE"; break; 4441 case NFS4ERR_NOMATCHING_LAYOUT: /* 10060 */ 4442 p = "NFS4ERR_NOMATCHING_LAYOUT"; break; 4443 case NFS4ERR_RECALLCONFLICT: /* 10061 */ 4444 p = "NFS4ERR_RECALLCONFLICT"; break; 4445 case NFS4ERR_UNKNOWN_LAYOUTTYPE: /* 10062 */ 4446 p = "NFS4ERR_UNKNOWN_LAYOUTTYPE"; break; 4447 case NFS4ERR_SEQ_MISORDERED: /* 10063 */ 4448 p = "NFS4ERR_SEQ_MISORDERED"; break; 4449 case NFS4ERR_SEQUENCE_POS: /* 10064 */ 4450 p = "NFS4ERR_SEQUENCE_POS"; break; 4451 case NFS4ERR_REQ_TOO_BIG: /* 10065 */ 4452 p = "NFS4ERR_REQ_TOO_BIG"; break; 4453 case NFS4ERR_REP_TOO_BIG: /* 10066 */ 4454 p = "NFS4ERR_REP_TOO_BIG"; break; 4455 case NFS4ERR_REP_TOO_BIG_TO_CACHE: /* 10067 */ 4456 p = "NFS4ERR_REP_TOO_BIG_TO_CACHE"; break; 4457 case NFS4ERR_RETRY_UNCACHED_REP: /* 10068 */ 4458 p = "NFS4ERR_RETRY_UNCACHED_REP"; break; 4459 case NFS4ERR_UNSAFE_COMPOUND: /* 10069 */ 4460 p = "NFS4ERR_UNSAFE_COMPOUND"; break; 4461 case NFS4ERR_TOO_MANY_OPS: /* 10070 */ 4462 p = "NFS4ERR_TOO_MANY_OPS"; break; 4463 case NFS4ERR_OP_NOT_IN_SESSION: /* 10071 */ 4464 p = "NFS4ERR_OP_NOT_IN_SESSION"; break; 4465 case NFS4ERR_HASH_ALG_UNSUPP: /* 10072 */ 4466 p = "NFS4ERR_HASH_ALG_UNSUPP"; break; 4467 /* Error 10073 is unused. */ 4468 case NFS4ERR_CLIENTID_BUSY: /* 10074 */ 4469 p = "NFS4ERR_CLIENTID_BUSY"; break; 4470 case NFS4ERR_PNFS_IO_HOLE: /* 10075 */ 4471 p = "NFS4ERR_PNFS_IO_HOLE"; break; 4472 case NFS4ERR_SEQ_FALSE_RETRY: /* 10076 */ 4473 p = "NFS4ERR_SEQ_FALSE_RETRY"; break; 4474 case NFS4ERR_BAD_HIGH_SLOT: /* 10077 */ 4475 p = "NFS4ERR_BAD_HIGH_SLOT"; break; 4476 case NFS4ERR_DEADSESSION: /* 10078 */ 4477 p = "NFS4ERR_DEADSESSION"; break; 4478 case NFS4ERR_ENCR_ALG_UNSUPP: /* 10079 */ 4479 p = "NFS4ERR_ENCR_ALG_UNSUPP"; break; 4480 case NFS4ERR_PNFS_NO_LAYOUT: /* 10080 */ 4481 p = "NFS4ERR_PNFS_NO_LAYOUT"; break; 4482 case NFS4ERR_NOT_ONLY_OP: /* 10081 */ 4483 p = "NFS4ERR_NOT_ONLY_OP"; break; 4484 case NFS4ERR_WRONG_CRED: /* 10082 */ 4485 p = "NFS4ERR_WRONG_CRED"; break; 4486 case NFS4ERR_WRONG_TYPE: /* 10083 */ 4487 p = "NFS4ERR_WRONG_TYPE"; break; 4488 case NFS4ERR_DIRDELEG_UNAVAIL: /* 10084 */ 4489 p = "NFS4ERR_DIRDELEG_UNAVAIL"; break; 4490 case NFS4ERR_REJECT_DELEG: /* 10085 */ 4491 p = "NFS4ERR_REJECT_DELEG"; break; 4492 case NFS4ERR_RETURNCONFLICT: /* 10086 */ 4493 p = "NFS4ERR_RETURNCONFLICT"; break; 4494 default: 4495 p = "(unknown error)"; break; 4496 } 4497 4498 return (p); 4499 } 4500 4501 char * 4502 nfsstat4_to_name(int status) 4503 { 4504 return (status_name(status)); 4505 } 4506 4507 static char * 4508 sum_sequenceid(sequenceid4 seq) 4509 { 4510 static char buf[64]; 4511 4512 snprintf(buf, sizeof (buf), "SQ=%u", seq); 4513 return (buf); 4514 } 4515 4516 static void 4517 sum_sec_parm(char *buf, size_t buflen, callback_sec_parms4 parms) 4518 { 4519 snprintf(buf, buflen, " %s", flavor_name(parms.cb_secflavor)); 4520 } 4521 4522 static void 4523 sumarg_create_session(char *buf, size_t buflen, void *obj) 4524 { 4525 CREATE_SESSION4args *args = (CREATE_SESSION4args *)obj; 4526 char *bp = buf; 4527 uint_t i; 4528 4529 snprintf(bp, buflen, "%s ", sum_clientid(args->csa_clientid)); 4530 bp += strlen(bp); 4531 snprintf(bp, buflen - (bp - buf), "%s ", 4532 sum_sequenceid(args->csa_sequence)); 4533 bp += strlen(bp); 4534 snprintf(bp, buflen - (bp - buf), "%s ", sum_sn_flags(args->csa_flags)); 4535 bp += strlen(bp); 4536 snprintf(bp, buflen - (bp - buf), "CB=%u", 4537 args->csa_cb_program); 4538 4539 for (i = 0; i < args->csa_sec_parms.csa_sec_parms_len; i++) { 4540 bp += strlen(bp); 4541 sum_sec_parm(bp, buflen - (bp - buf), 4542 args->csa_sec_parms.csa_sec_parms_val[i]); 4543 } 4544 } 4545 4546 static char * 4547 sum_sessionid(sessionid4 sid) 4548 { 4549 static char buf[64]; 4550 4551 snprintf(buf, sizeof (buf), "SID=%04X", sessionid_hash(sid)); 4552 return (buf); 4553 } 4554 4555 static void 4556 sumres_create_session(char *buf, size_t buflen, void *obj) 4557 { 4558 CREATE_SESSION4res *res = (CREATE_SESSION4res *)obj; 4559 CREATE_SESSION4resok *resok; 4560 char *bp = buf; 4561 4562 strcpy(bp, status_name(res->csr_status)); 4563 if (res->csr_status == NFS4_OK) { 4564 resok = &res->CREATE_SESSION4res_u.csr_resok4; 4565 bp += strlen(bp); 4566 snprintf(bp, buflen - (bp - buf), " %s", 4567 sum_sessionid(resok->csr_sessionid)); 4568 bp += strlen(bp); 4569 snprintf(bp, buflen - (bp - buf), " %s", 4570 sum_sequenceid(resok->csr_sequence)); 4571 bp += strlen(bp); 4572 snprintf(bp, buflen - (bp -buf), " %s", 4573 sum_sn_flags(resok->csr_flags)); 4574 } 4575 } 4576 4577 static void 4578 detail_sequenceid(sequenceid4 seq) 4579 { 4580 sprintf(get_line(0, 0), "Sequence ID = %u", seq); 4581 } 4582 4583 static void 4584 detail_channel_attr(channel_attrs4 attr) 4585 { 4586 int i; 4587 4588 detail_headerpadsize(attr.ca_headerpadsize); 4589 sprintf(get_line(0, 0), "\tMaximum request size = %u", 4590 attr.ca_maxrequestsize); 4591 sprintf(get_line(0, 0), "\tMaximum response size = %u", 4592 attr.ca_maxresponsesize); 4593 sprintf(get_line(0, 0), "\tMaximum response cache size = %u", 4594 attr.ca_maxresponsesize_cached); 4595 sprintf(get_line(0, 0), "\tMaximum number of operations = %u", 4596 attr.ca_maxoperations); 4597 sprintf(get_line(0, 0), "\tMaximum number of requests = %u", 4598 attr.ca_maxrequests); 4599 4600 for (i = 0; i < attr.ca_rdma_ird.ca_rdma_ird_len; i++) 4601 sprintf(get_line(0, 0), "\tRDMA channel attribute [i] = %u", 4602 attr.ca_rdma_ird.ca_rdma_ird_val[i]); 4603 } 4604 4605 static void 4606 detail_sessionid(sessionid4 sid) 4607 { 4608 sprintf(get_line(0, 0), "Session ID hash = [%04X] ", 4609 sessionid_hash(sid)); 4610 sprintf(get_line(0, 0), " (16) %s", 4611 tohex(sid, 16)); 4612 } 4613 4614 static void 4615 detail_headerpadsize(count4 size) 4616 { 4617 sprintf(get_line(0, 0), "Header padding = %u", size); 4618 } 4619 4620 static void 4621 detail_use_in_rdma_mode(bool_t val) 4622 { 4623 sprintf(get_line(0, 0), "Use the connection in RDMA mode = %s", 4624 val ? "TRUE" : "FALSE"); 4625 } 4626 4627 static void 4628 detail_authsys_parms(authsys_parms aup) 4629 { 4630 uint_t i; 4631 4632 char *bp = get_line(0, 0); 4633 sprintf(bp, "time=%u machine=%s uid=%u gid=%u", 4634 aup.aup_time, aup.aup_machname, aup.aup_uid, aup.aup_gid); 4635 4636 for (i = 0; i < aup.aup_len; i++) { 4637 bp += strlen(bp); 4638 sprintf(bp, " gids[i]=%u", aup.aup_gids[i]); 4639 } 4640 } 4641 4642 static void 4643 detail_gss_handles4(gss_cb_handles4 hdl) 4644 { 4645 uint_t i; 4646 4647 char *bp = get_line(0, 0); 4648 sprintf(bp, "Service = %d (%s); ", 4649 hdl.gcbp_service, gss_svc_name(hdl.gcbp_service)); 4650 4651 bp += strlen(bp); 4652 sprintf(bp, "The handle from server=%s;", 4653 tohex(hdl.gcbp_handle_from_server.gsshandle4_t_val, 4654 hdl.gcbp_handle_from_server.gsshandle4_t_len)); 4655 4656 bp += strlen(bp); 4657 sprintf(bp, "The handle for client=%s", 4658 tohex(hdl.gcbp_handle_from_client.gsshandle4_t_val, 4659 hdl.gcbp_handle_from_client.gsshandle4_t_len)); 4660 } 4661 4662 static void 4663 detail_sec_parm(callback_sec_parms4 sec) 4664 { 4665 sprintf(get_line(0, 0), "Flavor = %d (%s)", 4666 sec.cb_secflavor, flavor_name(sec.cb_secflavor)); 4667 4668 switch (sec.cb_secflavor) { 4669 case AUTH_NONE: 4670 break; 4671 case AUTH_SYS: 4672 detail_authsys_parms(sec.callback_sec_parms4_u.cbsp_sys_cred); 4673 break; 4674 case RPCSEC_GSS: 4675 detail_gss_handles4(sec.callback_sec_parms4_u.cbsp_gss_handles); 4676 break; 4677 defaul: 4678 break; 4679 } 4680 } 4681 4682 static void 4683 dtlarg_create_session(void *obj) 4684 { 4685 CREATE_SESSION4args *args = (CREATE_SESSION4args *)obj; 4686 callback_sec_parms4 parms; 4687 uint_t i; 4688 4689 detail_clientid(args->csa_clientid); 4690 detail_sequenceid(args->csa_sequence); 4691 sprintf(get_line(0, 0), "Flags = 0x%x (%s)", 4692 args->csa_flags, detail_sn_flags(args->csa_flags)); 4693 sprintf(get_line(0, 0), "Attributes of the fore channel: "); 4694 detail_channel_attr(args->csa_fore_chan_attrs); 4695 sprintf(get_line(0, 0), "Attributes of the back channel: "); 4696 detail_channel_attr(args->csa_back_chan_attrs); 4697 sprintf(get_line(0, 0), "Callback program ID = %u", 4698 args->csa_cb_program); 4699 for (i = 0; i < args->csa_sec_parms.csa_sec_parms_len; i++) 4700 parms = args->csa_sec_parms.csa_sec_parms_val[i]; 4701 detail_sec_parm(parms); 4702 } 4703 4704 static void 4705 dtlres_create_session(void *obj) 4706 { 4707 CREATE_SESSION4res *res = (CREATE_SESSION4res *)obj; 4708 CREATE_SESSION4resok *resok; 4709 4710 dtl_nfsstat4(obj); 4711 if (res->csr_status == NFS4_OK) { 4712 resok = &res->CREATE_SESSION4res_u.csr_resok4; 4713 detail_sessionid(resok->csr_sessionid); 4714 detail_sequenceid(resok->csr_sequence); 4715 sprintf(get_line(0, 0), "Flags = 0x%x (%s)", 4716 resok->csr_flags, detail_sn_flags(resok->csr_flags)); 4717 sprintf(get_line(0, 0), "Attributes of the fore channel:"); 4718 detail_channel_attr(resok->csr_fore_chan_attrs); 4719 sprintf(get_line(0, 0), "Attributes of the back channel:"); 4720 detail_channel_attr(resok->csr_back_chan_attrs); 4721 } 4722 } 4723 4724 static char * 4725 sum_verifier(verifier4 verifier) 4726 { 4727 static char buf[32]; 4728 4729 snprintf(buf, sizeof (buf), "Verf=%s", 4730 tohex(verifier, NFS4_VERIFIER_SIZE)); 4731 4732 return (buf); 4733 } 4734 4735 static void 4736 detail_verifier(verifier4 verifier) 4737 { 4738 sprintf(get_line(0, 0), "Verifier=%s", 4739 tohex(verifier, NFS4_VERIFIER_SIZE)); 4740 } 4741 4742 static char * 4743 print_ei_flag(uint32_t flag) 4744 { 4745 static char buf[64]; 4746 char *bp = buf; 4747 size_t buflen = sizeof (buf); 4748 4749 if (flag & EXCHGID4_FLAG_SUPP_MOVED_REFER) { 4750 snprintf(bp, buflen, "MOVED_REFER "); 4751 bp += strlen(buf); 4752 } 4753 4754 if (flag & EXCHGID4_FLAG_SUPP_MOVED_MIGR) { 4755 snprintf(bp, buflen - (bp - buf), "MOVED_MIGR "); 4756 bp += strlen(bp); 4757 } 4758 4759 if (flag & EXCHGID4_FLAG_BIND_PRINC_STATEID) { 4760 snprintf(bp, buflen - (bp - buf), "PRINC_STATEID "); 4761 bp += strlen(bp); 4762 } 4763 4764 if (flag & EXCHGID4_FLAG_USE_NON_PNFS) { 4765 snprintf(bp, buflen - (bp - buf), "NON_PNFS "); 4766 bp += strlen(bp); 4767 } 4768 4769 if (flag & EXCHGID4_FLAG_USE_PNFS_MDS) { 4770 snprintf(bp, buflen - (bp - buf), "PNFS_MDS "); 4771 bp += strlen(bp); 4772 } 4773 4774 if (flag & EXCHGID4_FLAG_USE_PNFS_DS) { 4775 snprintf(bp, buflen - (bp - buf), "PNFS_DS "); 4776 bp += strlen(bp); 4777 } 4778 4779 if (flag & EXCHGID4_FLAG_UPD_CONFIRMED_REC_A) { 4780 snprintf(bp, buflen - (bp - buf), "CONFIRMED_REC_A "); 4781 bp += strlen(bp); 4782 } 4783 4784 if (flag & EXCHGID4_FLAG_CONFIRMED_R) { 4785 snprintf(bp, buflen - (bp - buf), "CONFIRMED_R "); 4786 bp += strlen(bp); 4787 } 4788 4789 return (buf); 4790 } 4791 static char * 4792 sum_ps_name(state_protect_how4 type) 4793 { 4794 static char buf[32]; 4795 4796 if (type < num_ps) 4797 return (ps_names[type].short_name); 4798 else { 4799 sprintf(buf, "ps_how=%d", type); 4800 return (buf); 4801 } 4802 } 4803 4804 static char * 4805 detail_ps_name(state_protect_how4 type) 4806 { 4807 static char buf[64]; 4808 4809 if (type < num_ps) 4810 return (ps_names[type].long_name); 4811 else { 4812 sprintf(buf, "Unkown protect state type = %d", type); 4813 return (buf); 4814 } 4815 } 4816 4817 static void 4818 sum_ei_state_protect4_a(char *buf, size_t buflen, state_protect4_a *spa) 4819 { 4820 char *bp = buf; 4821 4822 snprintf(bp, buflen - (bp - buf), " %s", 4823 sum_ps_name(spa->spa_how)); 4824 } 4825 4826 static void 4827 detail_ei_state_protect4_a(state_protect4_a *spa) 4828 { 4829 sprintf(get_line(0, 0), "State protest = %s", 4830 detail_ps_name(spa->spa_how)); 4831 } 4832 4833 static void 4834 sum_ei_state_protect4_r(char *buf, size_t buflen, state_protect4_r *spr) 4835 { 4836 char *bp = buf; 4837 4838 snprintf(bp, buflen - (bp - buf), " %s", 4839 sum_ps_name(spr->spr_how)); 4840 } 4841 4842 static void 4843 detail_ei_state_protect4_r(state_protect4_r *spr) 4844 { 4845 sprintf(get_line(0, 0), "State protect = %s", 4846 detail_ps_name(spr->spr_how)); 4847 } 4848 4849 static void 4850 sum_nfs_impl_id4(char *buf, size_t buflen, nfs_impl_id4 *impl) 4851 { 4852 char *bp = buf; 4853 4854 snprintf(bp, buflen - (bp - buf), "%*s.", 4855 impl->nii_name.utf8string_len, 4856 impl->nii_name.utf8string_val); 4857 bp += strlen(bp); 4858 snprintf(bp, buflen - (bp - buf), "%*s ", 4859 impl->nii_domain.utf8string_len, 4860 impl->nii_domain.utf8string_val); 4861 bp += strlen(bp); 4862 snprintf(bp, buflen - (bp - buf), "%s ", 4863 format_time(impl->nii_date.seconds, impl->nii_date.nseconds)); 4864 bp += strlen(bp); 4865 } 4866 4867 static void 4868 detail_nfs_impl_id4(nfs_impl_id4 *impl) 4869 { 4870 sprintf(get_line(0, 0), "Domain = %*s", 4871 impl->nii_domain.utf8string_len, 4872 impl->nii_domain.utf8string_val); 4873 sprintf(get_line(0, 0), "Name = %*s", 4874 impl->nii_name.utf8string_len, 4875 impl->nii_name.utf8string_val); 4876 sprintf(get_line(0, 0), "Time = %s", 4877 format_time(impl->nii_date.seconds, impl->nii_date.nseconds)); 4878 } 4879 4880 static void 4881 sumarg_exchange_id(char *buf, size_t buflen, void *obj) 4882 { 4883 EXCHANGE_ID4args *args = (EXCHANGE_ID4args *)obj; 4884 nfs_impl_id4 *impl; 4885 char *bp = buf; 4886 int i, n; 4887 4888 snprintf(bp, buflen, "%s", 4889 sum_verifier(args->eia_clientowner.co_verifier)); 4890 bp += strlen(bp); 4891 snprintf(bp, buflen - (bp - buf), " COID=%04X", 4892 cowner_hash(&args->eia_clientowner.co_ownerid)); 4893 bp += strlen(bp); 4894 snprintf(bp, buflen - (bp - buf), " %s", 4895 print_ei_flag(args->eia_flags)); 4896 bp += strlen(bp); 4897 sum_ei_state_protect4_a(bp, buflen - (bp - buf), 4898 &args->eia_state_protect); 4899 bp += strlen(bp); 4900 4901 n = args->eia_client_impl_id.eia_client_impl_id_len; 4902 impl = args->eia_client_impl_id.eia_client_impl_id_val; 4903 for (i = 0; i < n; i++) { 4904 sum_nfs_impl_id4(bp, buflen - (bp - buf), impl + i); 4905 bp += strlen(bp); 4906 } 4907 } 4908 4909 static void 4910 dtlarg_exchange_id(void *obj) 4911 { 4912 nfs_impl_id4 *impl; 4913 int n, i; 4914 4915 EXCHANGE_ID4args *args = (EXCHANGE_ID4args *)obj; 4916 4917 detail_verifier(args->eia_clientowner.co_verifier); 4918 sprintf(get_line(0, 0), "Client Owner ID hash = [%04X] ", 4919 cowner_hash(&args->eia_clientowner.co_ownerid)); 4920 sprintf(get_line(0, 0), " (%d) %s", 4921 args->eia_clientowner.co_ownerid.co_ownerid_len, 4922 tohex(args->eia_clientowner.co_ownerid.co_ownerid_val, 4923 args->eia_clientowner.co_ownerid.co_ownerid_len)); 4924 sprintf(get_line(0, 0), "Flag = %s", 4925 print_ei_flag(args->eia_flags)); 4926 detail_ei_state_protect4_a(&args->eia_state_protect); 4927 4928 n = args->eia_client_impl_id.eia_client_impl_id_len; 4929 impl = args->eia_client_impl_id.eia_client_impl_id_val; 4930 for (i = 0; i < n; i++) 4931 detail_nfs_impl_id4(impl + i); 4932 } 4933 4934 static void 4935 sumres_exchange_id(char *buf, size_t buflen, void *obj) 4936 { 4937 EXCHANGE_ID4res *res = (EXCHANGE_ID4res *)obj; 4938 EXCHANGE_ID4resok *resok; 4939 char *bp = buf; 4940 4941 strcpy(bp, status_name(res->eir_status)); 4942 if (res->eir_status != NFS4_OK) 4943 return; 4944 4945 resok = &res->EXCHANGE_ID4res_u.eir_resok4; 4946 bp += strlen(bp); 4947 snprintf(bp, buflen - (bp - buf), " %s", 4948 sum_clientid(resok->eir_clientid)); 4949 bp += strlen(bp); 4950 snprintf(bp, buflen - (bp - buf), " %s", 4951 sum_sequenceid(resok->eir_sequenceid)); 4952 bp += strlen(bp); 4953 snprintf(bp, buflen - (bp - buf), " %s", 4954 print_ei_flag(resok->eir_flags)); 4955 bp += strlen(bp); 4956 sum_ei_state_protect4_r(bp, buflen - (bp - buf), 4957 &resok->eir_state_protect); 4958 } 4959 4960 static void 4961 detail_server_owner(server_owner4 owner) 4962 { 4963 sprintf(get_line(0, 0), "Server owner minor ID = %llu", 4964 owner.so_minor_id); 4965 if (owner.so_major_id.so_major_id_len != 0) 4966 sprintf(get_line(0, 0), "Server owner major ID = %s", 4967 tohex(owner.so_major_id.so_major_id_val, 4968 owner.so_major_id.so_major_id_len)); 4969 else 4970 sprintf(get_line(0, 0), "Server owner major ID is not set"); 4971 } 4972 4973 static void 4974 dtlres_exchange_id(void *obj) 4975 { 4976 EXCHANGE_ID4res *res = (EXCHANGE_ID4res *)obj; 4977 EXCHANGE_ID4resok *resok; 4978 nfs_impl_id4 *impl; 4979 int i, n; 4980 4981 dtl_nfsstat4(obj); 4982 if (res->eir_status != NFS4_OK) 4983 return; 4984 4985 resok = &res->EXCHANGE_ID4res_u.eir_resok4; 4986 detail_clientid(resok->eir_clientid); 4987 detail_sequenceid(resok->eir_sequenceid); 4988 sprintf(get_line(0, 0), "Flag = %s", 4989 print_ei_flag(resok->eir_flags)); 4990 detail_ei_state_protect4_r(&resok->eir_state_protect); 4991 detail_server_owner(resok->eir_server_owner); 4992 if (resok->eir_server_scope.eir_server_scope_len == 0) { 4993 sprintf(get_line(0, 0), "Server scope is not set"); 4994 return; 4995 } 4996 sprintf(get_line(0, 0), "Server scope = %s", 4997 tohex(resok->eir_server_scope.eir_server_scope_val, 4998 resok->eir_server_scope.eir_server_scope_len)); 4999 5000 impl = resok->eir_server_impl_id.eir_server_impl_id_val; 5001 n = resok->eir_server_impl_id.eir_server_impl_id_len; 5002 for (i = 0; i < n; i++) 5003 detail_nfs_impl_id4(impl + i); 5004 } 5005 5006 static char * 5007 sum_bcts_dir_from_client(channel_dir_from_client4 type) 5008 { 5009 char *result; 5010 5011 switch (type) { 5012 case 0x1: 5013 result = "FORE"; 5014 break; 5015 case 0x2: 5016 result = "BACK"; 5017 break; 5018 case 0x3: 5019 result = "FORE or BOTH"; 5020 break; 5021 case 0x7: 5022 result = "BACK or BOTH"; 5023 break; 5024 default: 5025 result = "?"; 5026 break; 5027 } 5028 5029 return (result); 5030 } 5031 5032 static void 5033 detail_bcts_dir_from_client(channel_dir_from_client4 type) 5034 { 5035 char *bp = get_line(0, 0); 5036 5037 switch (type) { 5038 case 0x1: 5039 sprintf(bp, "Binding to fore channel"); 5040 break; 5041 case 0x2: 5042 sprintf(bp, "Binding to back channel"); 5043 break; 5044 case 0x3: 5045 sprintf(bp, "Binding to fore or both channel"); 5046 break; 5047 case 0x7: 5048 sprintf(bp, "Binding to back or both channel"); 5049 default: 5050 sprintf(bp, "Binding to invalid channel"); 5051 break; 5052 } 5053 } 5054 5055 static char * 5056 sum_bcts_dir_from_server(channel_dir_from_server4 type) 5057 { 5058 char *result; 5059 5060 switch (type) { 5061 case 0x1: 5062 result = "FORE"; 5063 break; 5064 case 0x2: 5065 result = "BACK"; 5066 break; 5067 case 0x3: 5068 result = "BOTH"; 5069 break; 5070 default: 5071 result = "?"; 5072 break; 5073 } 5074 5075 return (result); 5076 } 5077 5078 static void 5079 detail_bcts_dir_from_server(channel_dir_from_server4 type) 5080 { 5081 char *bp = get_line(0, 0); 5082 5083 switch (type) { 5084 case 0x1: 5085 sprintf(bp, "Binding to fore channel"); 5086 break; 5087 case 0x2: 5088 sprintf(bp, "Binding to back channel"); 5089 break; 5090 case 0x3: 5091 sprintf(bp, "Binding to both channel"); 5092 break; 5093 default: 5094 sprintf(bp, "Binding to invalid channel"); 5095 break; 5096 } 5097 } 5098 5099 static void 5100 detail_bcts_nonce(uint64_t val) 5101 { 5102 sprintf(get_line(0, 0), "Nonce value = %llu", val); 5103 } 5104 5105 static void 5106 sumarg_bind_conn_to_session(char *buf, size_t buflen, void *obj) 5107 { 5108 BIND_CONN_TO_SESSION4args *args = (BIND_CONN_TO_SESSION4args *)obj; 5109 char *bp = buf; 5110 5111 snprintf(bp, buflen, "%s", sum_sessionid(args->bctsa_sessid)); 5112 bp += strlen(bp); 5113 snprintf(bp, buflen - (bp - buf), " %s", 5114 sum_bcts_dir_from_client(args->bctsa_dir)); 5115 bp += strlen(bp); 5116 } 5117 5118 static void 5119 dtlarg_bind_conn_to_session(void *obj) 5120 { 5121 BIND_CONN_TO_SESSION4args *args = (BIND_CONN_TO_SESSION4args *)obj; 5122 5123 detail_sessionid(args->bctsa_sessid); 5124 detail_bcts_dir_from_client(args->bctsa_dir); 5125 detail_use_in_rdma_mode(args->bctsa_use_conn_in_rdma_mode); 5126 } 5127 5128 static void 5129 sumres_bind_conn_to_session(char *buf, size_t buflen, void *obj) 5130 { 5131 BIND_CONN_TO_SESSION4res *res = (BIND_CONN_TO_SESSION4res *)obj; 5132 BIND_CONN_TO_SESSION4resok *resok; 5133 char *bp = buf; 5134 5135 strcpy(bp, status_name(res->bctsr_status)); 5136 if (res->bctsr_status == NFS4_OK) { 5137 resok = &res->BIND_CONN_TO_SESSION4res_u.bctsr_resok4; 5138 snprintf(bp, buflen, "%s", sum_sessionid(resok->bctsr_sessid)); 5139 bp += strlen(bp); 5140 snprintf(bp, buflen - (bp - buf), " %s", 5141 sum_bcts_dir_from_server(resok->bctsr_dir)); 5142 bp += strlen(bp); 5143 } 5144 } 5145 5146 static void 5147 dtlres_bind_conn_to_session(void *obj) 5148 { 5149 BIND_CONN_TO_SESSION4res *res = (BIND_CONN_TO_SESSION4res *)obj; 5150 BIND_CONN_TO_SESSION4resok *resok; 5151 5152 dtl_nfsstat4(obj); 5153 if (res->bctsr_status == NFS4_OK) { 5154 resok = &res->BIND_CONN_TO_SESSION4res_u.bctsr_resok4; 5155 detail_sessionid(resok->bctsr_sessid); 5156 detail_bcts_dir_from_server(resok->bctsr_dir); 5157 detail_use_in_rdma_mode(resok->bctsr_use_conn_in_rdma_mode); 5158 } 5159 } 5160 5161 static void 5162 sumarg_backchannel_ctl(char *buf, size_t buflen, void *obj) 5163 { 5164 BACKCHANNEL_CTL4args *args = (BACKCHANNEL_CTL4args *)obj; 5165 char *bp = buf; 5166 uint_t i; 5167 5168 sprintf(bp, "CB=%u", args->bca_cb_program); 5169 for (i = 0; i < args->bca_sec_parms.bca_sec_parms_len; i++) { 5170 bp += strlen(bp); 5171 sum_sec_parm(bp, buflen - (bp - buf), 5172 args->bca_sec_parms.bca_sec_parms_val[i]); 5173 } 5174 } 5175 5176 static void 5177 dtlarg_backchannel_ctl(void *obj) 5178 { 5179 BACKCHANNEL_CTL4args *args = (BACKCHANNEL_CTL4args *)obj; 5180 uint_t i; 5181 5182 sprintf(get_line(0, 0), "Callback program ID = %u", 5183 args->bca_cb_program); 5184 for (i = 0; i < args->bca_sec_parms.bca_sec_parms_len; i++) 5185 detail_sec_parm(args->bca_sec_parms.bca_sec_parms_val[i]); 5186 } 5187 5188 static void 5189 sumarg_set_ssv(char *buf, size_t buflen, void *obj) 5190 { 5191 SET_SSV4args *args = (SET_SSV4args *)obj; 5192 5193 snprintf(buf, buflen, "SSV=%s DG=%s", 5194 tohex(args->ssa_ssv.ssa_ssv_val, args->ssa_ssv.ssa_ssv_len), 5195 tohex(args->ssa_digest.ssa_digest_val, 5196 args->ssa_digest.ssa_digest_len)); 5197 } 5198 5199 static void 5200 dtlarg_set_ssv(void *obj) 5201 { 5202 SET_SSV4args *args = (SET_SSV4args *)obj; 5203 5204 sprintf(get_line(0, 0), "SSV = %s", 5205 tohex(args->ssa_ssv.ssa_ssv_val, args->ssa_ssv.ssa_ssv_len)); 5206 sprintf(get_line(0, 0), "Digest = %s", 5207 tohex(args->ssa_digest.ssa_digest_val, 5208 args->ssa_digest.ssa_digest_len)); 5209 } 5210 5211 static void 5212 sumres_set_ssv(char *buf, size_t buflen, void *obj) 5213 { 5214 SET_SSV4res *res = (SET_SSV4res *)obj; 5215 SET_SSV4resok *resok; 5216 char *bp = buf; 5217 5218 strcpy(bp, status_name(res->ssr_status)); 5219 bp += strlen(bp); 5220 if (res->ssr_status == NFS4_OK) { 5221 resok = &res->SET_SSV4res_u.ssr_resok4; 5222 snprintf(bp, buflen - (bp - buf), "DG=%s", 5223 tohex(resok->ssr_digest.ssr_digest_val, 5224 resok->ssr_digest.ssr_digest_len)); 5225 } 5226 } 5227 5228 static void 5229 dtlres_set_ssv(void *obj) 5230 { 5231 SET_SSV4res *res = (SET_SSV4res *)obj; 5232 SET_SSV4resok *resok; 5233 5234 dtl_nfsstat4(obj); 5235 if (res->ssr_status == NFS4_OK) { 5236 resok = &res->SET_SSV4res_u.ssr_resok4; 5237 sprintf(get_line(0, 0), "Digest = %s", 5238 tohex(resok->ssr_digest.ssr_digest_val, 5239 resok->ssr_digest.ssr_digest_len)); 5240 } 5241 } 5242 5243 static void 5244 sumarg_destroy_session(char *buf, size_t buflen, void *obj) 5245 { 5246 DESTROY_SESSION4args *args = (DESTROY_SESSION4args *)obj; 5247 5248 snprintf(buf, buflen, "%s", sum_sessionid(args->dsa_sessionid)); 5249 } 5250 5251 static void 5252 dtlarg_destroy_session(void *obj) 5253 { 5254 DESTROY_SESSION4args *args = (DESTROY_SESSION4args *)obj; 5255 5256 detail_sessionid(args->dsa_sessionid); 5257 } 5258 5259 static void 5260 sumarg_sequence(char *buf, size_t buflen, void *obj) 5261 { 5262 SEQUENCE4args *args = (SEQUENCE4args *)obj; 5263 char *bp = buf; 5264 5265 snprintf(bp, buflen, "%s ", sum_sessionid(args->sa_sessionid)); 5266 bp += strlen(bp); 5267 snprintf(bp, buflen - (bp - buf), "%s ", 5268 sum_sequenceid(args->sa_sequenceid)); 5269 bp += strlen(bp); 5270 snprintf(bp, buflen - (bp - buf), "SLID=%u", args->sa_slotid); 5271 } 5272 5273 static void 5274 dtlarg_sequence(void *obj) 5275 { 5276 SEQUENCE4args *args = (SEQUENCE4args *)obj; 5277 5278 detail_sessionid(args->sa_sessionid); 5279 detail_sequenceid(args->sa_sequenceid); 5280 sprintf(get_line(0, 0), "Slot ID = %u", args->sa_slotid); 5281 sprintf(get_line(0, 0), "Highest slotid = %u", args->sa_highest_slotid); 5282 sprintf(get_line(0, 0), "Cache flag = %s", 5283 args->sa_cachethis? "TRUE" : "FALSE"); 5284 } 5285 5286 static char * 5287 sum_seq_status(uint32_t status) 5288 { 5289 static char buf[32]; 5290 5291 snprintf(buf, sizeof (buf), "ST=%x", status); 5292 return (buf); 5293 } 5294 5295 static void 5296 detail_seq_status(uint32_t status) 5297 { 5298 int bit; 5299 5300 sprintf(get_line(0, 0), "status = %x", status); 5301 for (bit = 0; bit < SEQ_STATUS_MAX; bit++) { 5302 if (status & (1 << bit)) { 5303 sprintf(get_line(0, 0), "\t%s", 5304 seq_status[bit]); 5305 } 5306 } 5307 } 5308 5309 static void 5310 sumres_sequence(char *buf, size_t buflen, void *obj) 5311 { 5312 SEQUENCE4res *res = (SEQUENCE4res *)obj; 5313 SEQUENCE4resok *resok; 5314 char *bp = buf; 5315 5316 strncpy(bp, status_name(res->sr_status), buflen); 5317 if (res->sr_status == NFS4_OK) { 5318 resok = &res->SEQUENCE4res_u.sr_resok4; 5319 bp += strlen(bp); 5320 snprintf(bp, buflen - (bp - buf), " %s", 5321 sum_sessionid(resok->sr_sessionid)); 5322 bp += strlen(bp); 5323 snprintf(bp, buflen - (bp - buf), " %s", 5324 sum_sequenceid(resok->sr_sequenceid)); 5325 bp += strlen(bp); 5326 snprintf(bp, buflen - (bp - buf), " SLID=%u", 5327 resok->sr_slotid); 5328 bp += strlen(bp); 5329 snprintf(bp, buflen - (bp - buf), " %s", 5330 sum_seq_status(resok->sr_status_flags)); 5331 } 5332 } 5333 5334 static void 5335 dtlres_sequence(void *obj) 5336 { 5337 SEQUENCE4res *res = (SEQUENCE4res *)obj; 5338 SEQUENCE4resok *resok; 5339 5340 dtl_nfsstat4(obj); 5341 if (res->sr_status == NFS4_OK) { 5342 resok = &res->SEQUENCE4res_u.sr_resok4; 5343 detail_sessionid(resok->sr_sessionid); 5344 detail_sequenceid(resok->sr_sequenceid); 5345 sprintf(get_line(0, 0), "Slot ID = %u", resok->sr_slotid); 5346 sprintf(get_line(0, 0), "Highest slotid = %u", 5347 resok->sr_highest_slotid); 5348 sprintf(get_line(0, 0), "Target highest slotid = %u", 5349 resok->sr_target_highest_slotid); 5350 detail_seq_status(resok->sr_status_flags); 5351 } 5352 } 5353 5354 static void 5355 sumarg_cb_sequence(char *buf, size_t buflen, void *obj) 5356 { 5357 CB_SEQUENCE4args *args = (CB_SEQUENCE4args *)obj; 5358 char *bp = buf; 5359 5360 snprintf(bp, buflen, "%s ", sum_sessionid(args->csa_sessionid)); 5361 bp += strlen(bp); 5362 snprintf(bp, buflen - (bp - buf), "%s ", 5363 sum_sequenceid(args->csa_sequenceid)); 5364 bp += strlen(bp); 5365 snprintf(bp, buflen - (bp - buf), "SLID=%u", args->csa_slotid); 5366 bp += strlen(bp); 5367 snprintf(bp, buflen - (bp - buf), "cachethis=%d", 5368 args->csa_cachethis); 5369 bp += strlen(bp); 5370 snprintf(bp, buflen - (bp - buf), "num calls = %d", 5371 args->csa_referring_call_lists.csa_referring_call_lists_len); 5372 bp += strlen(bp); 5373 } 5374 5375 static void 5376 detail_referring_call_list(uint_t ref, referring_call_list4 list) 5377 { 5378 referring_call4 *call; 5379 uint_t i; 5380 5381 sprintf(get_line(0, 0), 5382 "Referring call list[%u]: Session ID = %s", 5383 i, tohex(list.rcl_sessionid, 16)); 5384 5385 for (i = 0; 5386 i < list.rcl_referring_calls.rcl_referring_calls_len; 5387 i++) { 5388 5389 call = &list.rcl_referring_calls.rcl_referring_calls_val[i]; 5390 sprintf(get_line(0, 0), 5391 " Sequence ID = %u Slot ID = %u", 5392 call->rc_sequenceid, call->rc_slotid); 5393 } 5394 } 5395 5396 static void 5397 dtlarg_cb_sequence(void *obj) 5398 { 5399 CB_SEQUENCE4args *args = (CB_SEQUENCE4args *)obj; 5400 referring_call_list4 *list; 5401 uint_t i; 5402 5403 detail_sessionid(args->csa_sessionid); 5404 detail_sequenceid(args->csa_sequenceid); 5405 sprintf(get_line(0, 0), "Slot ID = %u", args->csa_slotid); 5406 sprintf(get_line(0, 0), "Highest slot = %u", args->csa_highest_slotid); 5407 sprintf(get_line(0, 0), "Cache this = %s", 5408 args->csa_cachethis ? "TRUE" : "FALSE"); 5409 5410 list = args->csa_referring_call_lists.csa_referring_call_lists_val; 5411 for (i = 0; 5412 i < args->csa_referring_call_lists.csa_referring_call_lists_len; 5413 i++) { 5414 detail_referring_call_list(i, list[i]); 5415 } 5416 } 5417 5418 static void 5419 sumres_cb_sequence(char *buf, size_t buflen, void *obj) 5420 { 5421 CB_SEQUENCE4res *res = (CB_SEQUENCE4res *)obj; 5422 CB_SEQUENCE4resok *resok; 5423 char *bp = buf; 5424 5425 strcpy(bp, status_name(res->csr_status)); 5426 if (res->csr_status != NFS4_OK) 5427 return; 5428 5429 resok = &res->CB_SEQUENCE4res_u.csr_resok4; 5430 bp += strlen(bp); 5431 snprintf(bp, buflen - (bp - buf), "%s ", 5432 sum_sessionid(resok->csr_sessionid)); 5433 bp += strlen(bp); 5434 snprintf(bp, buflen - (bp - buf), "%s ", 5435 sum_sequenceid(resok->csr_sequenceid)); 5436 bp += strlen(bp); 5437 snprintf(bp, buflen - (bp - buf), "SLID=%u ", 5438 resok->csr_slotid); 5439 bp += strlen(bp); 5440 snprintf(bp, buflen - (bp - buf), "Highest SLID=%u ", 5441 resok->csr_highest_slotid); 5442 bp += strlen(bp); 5443 snprintf(bp, buflen - (bp - buf), "Target highest SLID=%u ", 5444 resok->csr_target_highest_slotid); 5445 bp += strlen(bp); 5446 } 5447 5448 static void 5449 dtlres_cb_sequence(void *obj) 5450 { 5451 CB_SEQUENCE4res *res = (CB_SEQUENCE4res *)obj; 5452 CB_SEQUENCE4resok *resok; 5453 5454 dtl_nfsstat4(obj); 5455 if (res->csr_status == NFS4_OK) { 5456 resok = &res->CB_SEQUENCE4res_u.csr_resok4; 5457 detail_sessionid(resok->csr_sessionid); 5458 detail_sequenceid(resok->csr_sequenceid); 5459 sprintf(get_line(0, 0), "Slot ID = %u", resok->csr_slotid); 5460 sprintf(get_line(0, 0), "Highest slotid = %u", 5461 resok->csr_highest_slotid); 5462 sprintf(get_line(0, 0), "Target highest slotid = %u", 5463 resok->csr_target_highest_slotid); 5464 } 5465 } 5466 5467 static void 5468 sumarg_test_stateid(char *buf, size_t buflen, void *obj) 5469 { 5470 TEST_STATEID4args *args = (TEST_STATEID4args *)obj; 5471 stateid4 *stateid; 5472 char prefix[32]; 5473 char *bp = buf; 5474 uint_t i; 5475 5476 for (i = 0; i < args->ts_stateids.ts_stateids_len; i++) { 5477 stateid = &args->ts_stateids.ts_stateids_val[i]; 5478 sprintf(prefix, "ST[%u]=", i); 5479 snprintf(bp, buflen - (bp - buf), "%s ", 5480 cmn_sum_stateid(stateid, prefix)); 5481 bp += strlen(bp); 5482 } 5483 } 5484 5485 static void 5486 dtlarg_test_stateid(void *obj) 5487 { 5488 TEST_STATEID4args *args = (TEST_STATEID4args *)obj; 5489 stateid4 *stateid; 5490 char prefix[32]; 5491 uint_t i; 5492 5493 for (i = 0; i < args->ts_stateids.ts_stateids_len; i++) { 5494 stateid = &args->ts_stateids.ts_stateids_val[i]; 5495 sprintf(prefix, "[%u] : ", i); 5496 cmn_detail_stateid(stateid, prefix); 5497 } 5498 } 5499 5500 static void 5501 sum_ts_resok(char *buf, size_t buflen, TEST_STATEID4resok *resok) 5502 { 5503 nfsstat4 status; 5504 char *bp = buf; 5505 uint_t i; 5506 5507 for (i = 0; 5508 i < resok->tsr_status_codes.tsr_status_codes_len; 5509 i++) { 5510 5511 status = resok->tsr_status_codes.tsr_status_codes_val[i]; 5512 if (i == 0) 5513 snprintf(bp, buflen - (bp - buf), " "); 5514 if (i > 0) 5515 snprintf(bp, buflen - (bp - buf), ","); 5516 bp += strlen(bp); 5517 sum_nfsstat4(bp, buflen - (bp -buf), &status); 5518 bp += strlen(bp); 5519 } 5520 } 5521 5522 static void 5523 sumres_test_stateid(char *buf, size_t buflen, void *obj) 5524 { 5525 TEST_STATEID4res *res = (TEST_STATEID4res *)obj; 5526 char *bp = buf; 5527 5528 strncpy(bp, status_name(res->tsr_status), buflen); 5529 if (res->tsr_status == NFS4_OK) { 5530 bp += strlen(bp); 5531 sum_ts_resok(bp, buflen - (bp - buf), 5532 &res->TEST_STATEID4res_u.tsr_resok4); 5533 } 5534 } 5535 5536 static void 5537 detail_ts_resok(TEST_STATEID4resok *resok) 5538 { 5539 nfsstat4 status; 5540 uint_t i; 5541 5542 for (i = 0; 5543 i < resok->tsr_status_codes.tsr_status_codes_len; 5544 i++) { 5545 5546 status = resok->tsr_status_codes.tsr_status_codes_val[i]; 5547 sprintf(get_line(0, 0), "[%u] : Status %d (%s)", 5548 i, status, status_name(status)); 5549 } 5550 } 5551 5552 static void 5553 dtlres_test_stateid(void *obj) 5554 { 5555 TEST_STATEID4res *res = (TEST_STATEID4res *)obj; 5556 nfsstat4 status; 5557 5558 dtl_nfsstat4(obj); 5559 if (res->tsr_status == NFS4_OK) 5560 detail_ts_resok(&res->TEST_STATEID4res_u.tsr_resok4); 5561 } 5562 5563 static void 5564 sumarg_free_stateid(char *buf, size_t buflen, void *obj) 5565 { 5566 FREE_STATEID4args *args = (FREE_STATEID4args *)obj; 5567 5568 snprintf(buf, buflen, "%s", cmn_sum_stateid(&args->fsa_stateid, "ST=")); 5569 } 5570 5571 static void 5572 dtlarg_free_stateid(void *obj) 5573 { 5574 FREE_STATEID4args *args = (FREE_STATEID4args *)obj; 5575 5576 cmn_detail_stateid(&args->fsa_stateid, ""); 5577 } 5578 5579 static void 5580 sumarg_get_dir_delegation(char *buf, size_t buflen, void *obj) 5581 { 5582 } 5583 5584 static void 5585 dtlarg_get_dir_delegation(void *obj) 5586 { 5587 } 5588 5589 static void 5590 sumres_get_dir_delegation(char *buf, size_t buflen, void *obj) 5591 { 5592 } 5593 5594 static void 5595 dtlres_get_dir_delegation(void *obj) 5596 { 5597 } 5598 5599 static char * 5600 detail_lortype_name(layoutrecall_type4 lortype) 5601 { 5602 static char buf[32]; 5603 5604 if (lortype < num_lortypes) 5605 return (lortype_names[lortype].long_name); 5606 5607 sprintf(buf, "lorec_type=%d", lortype); 5608 return (buf); 5609 } 5610 5611 5612 static char * 5613 sum_lortype_name(layoutrecall_type4 lortype) 5614 { 5615 static char buf[32]; 5616 5617 if (lortype < num_lortypes) 5618 return (lortype_names[lortype].short_name); 5619 5620 sprintf(buf, "lorec_type=%d", lortype); 5621 return (buf); 5622 } 5623 5624 static char * 5625 sum_lotype_name(layouttype4 type) 5626 { 5627 static char buf[32]; 5628 5629 if (type < num_lotypes) 5630 return (lotype_names[type].short_name); 5631 else { 5632 sprintf(buf, "lotype=%d", type); 5633 return (buf); 5634 } 5635 } 5636 5637 char * 5638 detail_lotype_name(layouttype4 type) 5639 { 5640 static char buf[64]; 5641 5642 if (type >= 0 && type < num_lotypes) 5643 return (lotype_names[type].long_name); 5644 else { 5645 sprintf(buf, "Unknown layout type(%d)", type); 5646 return (buf); 5647 } 5648 } 5649 5650 static char * 5651 sum_iomode_name(layoutiomode4 mode) 5652 { 5653 static char buf[32]; 5654 5655 if (mode < num_iomodes) 5656 return (iomode_names[mode].short_name); 5657 else { 5658 sprintf(buf, "iomode=%d", mode); 5659 return (buf); 5660 } 5661 } 5662 5663 char * 5664 detail_iomode_name(layoutiomode4 mode) 5665 { 5666 static char buf[64]; 5667 5668 if (mode < num_iomodes) 5669 return (iomode_names[mode].long_name); 5670 else { 5671 sprintf(buf, "Unknown layout iomode = %d", mode); 5672 return (buf); 5673 } 5674 } 5675 5676 static char * 5677 sum_lrtype_name(layoutreturn_type4 type) 5678 { 5679 static char buf[32]; 5680 5681 if (type < num_lrtypes) 5682 return (lrtype_names[type].short_name); 5683 else { 5684 sprintf(buf, "lrtype=%d", type); 5685 return (buf); 5686 } 5687 } 5688 5689 static char * 5690 detail_lrtype_name(layoutreturn_type4 type) 5691 { 5692 static char buf[64]; 5693 5694 if (type < num_lrtypes) 5695 return (lrtype_names[type].long_name); 5696 else { 5697 sprintf(buf, "Unkown layoutreturn type = %d", type); 5698 return (buf); 5699 } 5700 } 5701 5702 static void 5703 print_netaddr4(char *buf, size_t buflen, netaddr4 *na) 5704 { 5705 char *copy = NULL; 5706 char *bp = buf; 5707 5708 /* 5709 * We are always able to print addr/net. We try to print 5710 * more helpful formats for the more common netids. 5711 * 5712 * For "tcp", which is tcp/IPv4, we try to print hostname:portnumber, 5713 * or if hostname cannot be determined, we try to print 5714 * ipaddr:portnumber. 5715 */ 5716 if (strcmp("tcp", na->na_r_netid) == 0) { 5717 #ifdef REVERSE_DNS 5718 char *copy = strdup(na->na_r_addr); 5719 struct hostent *host; 5720 struct in_addr addr; 5721 char *penultimate; 5722 char *ultimate; 5723 int port; 5724 5725 /* chop off final two octets */ 5726 ultimate = strrchr(copy, '.'); 5727 if (ultimate == NULL) 5728 goto failsafe; 5729 *(ultimate++) = '\0'; 5730 penultimate = strrchr(copy, '.'); 5731 if (penultimate == NULL) 5732 goto failsafe; 5733 *(penultimate++) = '\0'; 5734 5735 /* convert final two octets into port number */ 5736 errno = 0; 5737 port = strtol(penultimate, NULL, 0) << 8 + 5738 strtol(ultimate, NULL, 0); 5739 if (errno != 0) 5740 goto failsafe; 5741 5742 /* try to convert IPv4 into host name */ 5743 if ((inet_aton(copy, &addr)) && 5744 ((host = gethostbyaddr((char *)&addr, 5745 4, AF_INET)) != NULL)) { 5746 snprintf(bp, buflen - (bp - buf), " %s", host->h_name); 5747 /* otherwise, use IP address */ 5748 } else { 5749 snprintf(bp, buflen - (bp - buf), " %s", copy); 5750 } 5751 bp += strlen(bp); 5752 snprintf(bp, buflen - (bp - buf), ":%d/tcp", port); 5753 #endif 5754 snprintf(bp, buflen - (bp - buf), "tcp:%s", na->na_r_addr); 5755 5756 return; 5757 } 5758 5759 failsafe: 5760 /* just print "address/netid". */ 5761 if (copy != NULL) 5762 free(copy); 5763 snprintf(bp, buflen - (bp - buf), "%s/%s", 5764 na->na_r_addr, na->na_r_netid); 5765 } 5766 5767 static void 5768 print_multipath_list4(char *buf, size_t buflen, multipath_list4 *mpl) 5769 { 5770 char *bp = buf; 5771 netaddr4 *addr; 5772 int i, n; 5773 5774 n = mpl->multipath_list4_len; 5775 addr = mpl->multipath_list4_val; 5776 5777 for (i = 0; i < n; i++) { 5778 sprintf(bp, " [%u] ", i); 5779 bp += strlen(bp); 5780 print_netaddr4(bp, buflen - (bp - buf), addr + i); 5781 bp += strlen(bp); 5782 } 5783 } 5784 5785 5786 static void 5787 sum_devaddr(char *buf, size_t buflen, 5788 device_addr4 *d_addr, layouttype4 type) 5789 { 5790 nfsv4_1_file_layout_ds_addr4 devi; 5791 netaddr4 *addr; 5792 multipath_list4 *mpl; 5793 XDR xdr; 5794 int i, n; 5795 uint32_t *index; 5796 char *bp = buf; 5797 5798 if (type == LAYOUT4_NFSV4_1_FILES) { 5799 xdrmem_create(&xdr, 5800 d_addr->da_addr_body.da_addr_body_val, 5801 d_addr->da_addr_body.da_addr_body_len, XDR_DECODE); 5802 bzero(&devi, sizeof (devi)); 5803 if (! xdr_nfsv4_1_file_layout_ds_addr4(&xdr, &devi)) 5804 longjmp(xdr_err, 1); 5805 5806 n = devi.nflda_stripe_indices.nflda_stripe_indices_len; 5807 index = devi.nflda_stripe_indices.nflda_stripe_indices_val; 5808 for (i = 0; i < n; i++) { 5809 snprintf(bp, buflen - (bp - buf), "%s%u", 5810 i ? "," : " ", index[i]); 5811 bp += strlen(bp); 5812 } 5813 5814 n = devi.nflda_multipath_ds_list.nflda_multipath_ds_list_len; 5815 mpl = devi.nflda_multipath_ds_list.nflda_multipath_ds_list_val; 5816 for (i = 0; i < n; i++) { 5817 print_multipath_list4(bp, buflen - (bp - buf), mpl + i); 5818 bp += strlen(bp); 5819 } 5820 5821 xdr_free(xdr_nfsv4_1_file_layout_ds_addr4, (char *)&devi); 5822 } 5823 } 5824 5825 static void 5826 detail_devaddr(device_addr4 *d_addr, layouttype4 type) 5827 { 5828 nfsv4_1_file_layout_ds_addr4 devi; 5829 netaddr4 *addr; 5830 multipath_list4 *mpl; 5831 XDR xdr; 5832 int i, n; 5833 uint32_t *index; 5834 char *bp, *buf; 5835 size_t buflen; 5836 5837 if (type == LAYOUT4_NFSV4_1_FILES) { 5838 xdrmem_create(&xdr, 5839 d_addr->da_addr_body.da_addr_body_val, 5840 d_addr->da_addr_body.da_addr_body_len, XDR_DECODE); 5841 bzero(&devi, sizeof (devi)); 5842 if (! xdr_nfsv4_1_file_layout_ds_addr4(&xdr, &devi)) 5843 longjmp(xdr_err, 1); 5844 5845 n = devi.nflda_stripe_indices.nflda_stripe_indices_len; 5846 index = devi.nflda_stripe_indices.nflda_stripe_indices_val; 5847 buf = get_line(0, 0); 5848 buflen = SUM_COMPND_MAX; 5849 sprintf(buf, " stripe_indices:"); 5850 bp = buf + strlen(buf); 5851 for (i = 0; i < n; i++) { 5852 snprintf(bp, buflen - (bp - buf), "%s%u", 5853 i ? ", " : " ", index[i]); 5854 bp += strlen(bp); 5855 } 5856 5857 n = devi.nflda_multipath_ds_list.nflda_multipath_ds_list_len; 5858 mpl = devi.nflda_multipath_ds_list.nflda_multipath_ds_list_val; 5859 for (i = 0; i < n; i++) { 5860 buf = get_line(0, 0); 5861 buflen = SUM_COMPND_MAX; 5862 sprintf(buf, " multipath_ds_list[%u]:", i); 5863 bp = buf + strlen(buf); 5864 print_multipath_list4(bp, buflen - (bp - buf), mpl + i); 5865 } 5866 5867 xdr_free(xdr_nfsv4_1_file_layout_ds_addr4, (char *)&devi); 5868 } 5869 } 5870 5871 static void 5872 detail_deviceid(deviceid4 did) 5873 { 5874 sprintf(get_line(0, 0), "Device ID hash = [%04X] ", 5875 deviceid_hash(did)); 5876 sprintf(get_line(0, 0), " (16) %s", 5877 tohex(did, 16)); 5878 } 5879 5880 static void 5881 sumarg_getdeviceinfo(char *buf, size_t buflen, void *obj) 5882 { 5883 GETDEVICEINFO4args *args = (GETDEVICEINFO4args *)obj; 5884 char *bp = buf; 5885 5886 snprintf(bp, buflen, "DID=%04X", 5887 deviceid_hash(args->gdia_device_id)); 5888 5889 bp += strlen(bp); 5890 snprintf(bp, buflen - (bp - buf), " %s", 5891 sum_lotype_name(args->gdia_layout_type)); 5892 5893 bp += strlen(bp); 5894 snprintf(bp, buflen - (bp - buf), " MAX=%u", 5895 args->gdia_maxcount); 5896 } 5897 5898 static void 5899 dtlarg_getdeviceinfo(void *obj) 5900 { 5901 GETDEVICEINFO4args *args = (GETDEVICEINFO4args *)obj; 5902 bitmap4 *bp; 5903 int i; 5904 5905 detail_deviceid(args->gdia_device_id); 5906 sprintf(get_line(0, 0), "Layout Type = %s", 5907 detail_lotype_name(args->gdia_layout_type)); 5908 sprintf(get_line(0, 0), "Max count = %u", args->gdia_maxcount); 5909 bp = &args->gdia_notify_types; 5910 sprintf(get_line(0, 0), "bitmap4_len = %u", bp->bitmap4_len); 5911 for (i = 0; i < bp->bitmap4_len; i++) 5912 sprintf(get_line(0, 0), "value: 0x%x", bp->bitmap4_val[i]); 5913 } 5914 5915 static void 5916 sumres_getdeviceinfo(char *buf, size_t buflen, void *obj) 5917 { 5918 GETDEVICEINFO4res *res = (GETDEVICEINFO4res *)obj; 5919 GETDEVICEINFO4resok *resok; 5920 char *bp = buf; 5921 layouttype4 lotype; 5922 5923 strcpy(bp, status_name(res->gdir_status)); 5924 if (res->gdir_status == NFS4_OK) { 5925 resok = &res->GETDEVICEINFO4res_u.gdir_resok4; 5926 lotype = resok->gdir_device_addr.da_layout_type; 5927 bp += strlen(bp); 5928 if (lotype == LAYOUT4_NFSV4_1_FILES) { 5929 snprintf(bp, buflen - (bp - buf), " DEV="); 5930 bp += strlen(bp); 5931 sum_devaddr(bp, buflen - (bp - buf), 5932 &resok->gdir_device_addr, lotype); 5933 } 5934 } 5935 } 5936 5937 static void 5938 dtlres_getdeviceinfo(void *obj) 5939 { 5940 GETDEVICEINFO4res *res = (GETDEVICEINFO4res *)obj; 5941 GETDEVICEINFO4resok *resok; 5942 layouttype4 lotype; 5943 char *buf; 5944 5945 dtl_nfsstat4(obj); 5946 if (res->gdir_status == NFS4_OK) { 5947 resok = &res->GETDEVICEINFO4res_u.gdir_resok4; 5948 lotype = resok->gdir_device_addr.da_layout_type; 5949 sprintf(get_line(0, 0), "Layout type = %s", 5950 detail_lotype_name(lotype)); 5951 if (lotype == LAYOUT4_NFSV4_1_FILES) { 5952 sprintf(get_line(0, 0), "Device address: "); 5953 detail_devaddr(&resok->gdir_device_addr, lotype); 5954 } 5955 } 5956 } 5957 5958 static void 5959 sumarg_getdevicelist(char *buf, size_t buflen, void *obj) 5960 { 5961 GETDEVICELIST4args *args = (GETDEVICELIST4args *)obj; 5962 char *bp = buf; 5963 5964 snprintf(bp, buflen - (bp - buf), "%s", 5965 sum_lotype_name(args->gdla_layout_type)); 5966 bp += strlen(bp); 5967 snprintf(bp, buflen - (bp - buf), " Max=%u", args->gdla_maxdevices); 5968 bp += strlen(bp); 5969 snprintf(bp, buflen - (bp - buf), " CK=%llx", args->gdla_cookie); 5970 bp += strlen(bp); 5971 snprintf(bp, buflen - (bp - buf), " %s", 5972 sum_verifier(args->gdla_cookieverf)); 5973 } 5974 5975 static void 5976 dtlarg_getdevicelist(void *obj) 5977 { 5978 GETDEVICELIST4args *args = (GETDEVICELIST4args *)obj; 5979 5980 sprintf(get_line(0, 0), "%s", 5981 detail_lotype_name(args->gdla_layout_type)); 5982 sprintf(get_line(0, 0), "Max device count = %u", args->gdla_maxdevices); 5983 sprintf(get_line(0, 0), "NFS Cookie = %llx", args->gdla_cookie); 5984 detail_verifier(args->gdla_cookieverf); 5985 } 5986 5987 static void 5988 sum_devicelist(char *buf, size_t buflen, GETDEVICELIST4resok *resok) 5989 { 5990 deviceid4 *devid; 5991 char *bp = buf; 5992 uint_t i, len; 5993 5994 len = resok->gdlr_deviceid_list.gdlr_deviceid_list_len; 5995 if (!len) { 5996 snprintf(bp, buflen, "NO_DEV"); 5997 return; 5998 } 5999 for (i = 0; i < len; i++) { 6000 devid = &resok->gdlr_deviceid_list.gdlr_deviceid_list_val[i]; 6001 snprintf(bp, buflen - (bp - buf), " DEV[i]=%04X ", 6002 deviceid_hash(*devid)); 6003 bp += strlen(bp); 6004 } 6005 } 6006 6007 static void 6008 sumres_getdevicelist(char *buf, size_t buflen, void *obj) 6009 { 6010 GETDEVICELIST4res *res = (GETDEVICELIST4res *)obj; 6011 GETDEVICELIST4resok *resok; 6012 char *bp = buf; 6013 6014 strcpy(bp, status_name(res->gdlr_status)); 6015 if (res->gdlr_status == NFS4_OK) { 6016 resok = &res->GETDEVICELIST4res_u.gdlr_resok4; 6017 bp += strlen(bp); 6018 snprintf(bp, buflen - (bp - buf), " CK=%llx", 6019 resok->gdlr_cookie); 6020 bp += strlen(bp); 6021 snprintf(bp, buflen - (bp - buf), " %s", 6022 sum_verifier(resok->gdlr_cookieverf)); 6023 bp += strlen(bp); 6024 sum_devicelist(bp, buflen - (bp - buf), resok); 6025 } 6026 } 6027 6028 static void 6029 detail_devicelist(GETDEVICELIST4resok *resok) 6030 { 6031 deviceid4 *devid; 6032 uint_t i, len; 6033 char *buf; 6034 layouttype4 lotype; 6035 6036 len = resok->gdlr_deviceid_list.gdlr_deviceid_list_len; 6037 if (!len) { 6038 sprintf(get_line(0, 0), "No device list"); 6039 return; 6040 } 6041 for (i = 0; i < len; i++) { 6042 devid = &resok->gdlr_deviceid_list.gdlr_deviceid_list_val[i]; 6043 detail_deviceid(*devid); 6044 } 6045 } 6046 6047 static void 6048 dtlres_getdevicelist(void *obj) 6049 { 6050 GETDEVICELIST4res *res = (GETDEVICELIST4res *)obj; 6051 GETDEVICELIST4resok *resok; 6052 6053 dtl_nfsstat4(obj); 6054 if (res->gdlr_status == NFS4_OK) { 6055 resok = &res->GETDEVICELIST4res_u.gdlr_resok4; 6056 sprintf(get_line(0, 0), "NFS Cookie = %llx", 6057 resok->gdlr_cookie); 6058 detail_verifier(resok->gdlr_cookieverf); 6059 detail_devicelist(resok); 6060 sprintf(get_line(0, 0), "EOF flag = %s", 6061 resok->gdlr_eof ? "TRUE" : "FALSE"); 6062 } 6063 } 6064 6065 static void 6066 sumarg_layoutcommit(char *buf, size_t buflen, void *obj) 6067 { 6068 LAYOUTCOMMIT4args *args = (LAYOUTCOMMIT4args *)obj; 6069 newoffset4 *noff; 6070 nfstime4 *time; 6071 char *bp = buf; 6072 6073 snprintf(bp, buflen - (bp - buf), "%s", 6074 sum_stateid(&args->loca_stateid)); 6075 } 6076 6077 static void 6078 dtlarg_layoutcommit(void *obj) 6079 { 6080 LAYOUTCOMMIT4args *args = (LAYOUTCOMMIT4args *)obj; 6081 newoffset4 *noff; 6082 nfstime4 *time; 6083 6084 sprintf(get_line(0, 0), "Offset = %llu", 6085 args->loca_offset); 6086 sprintf(get_line(0, 0), "Length = %llu", 6087 args->loca_length); 6088 6089 sprintf(get_line(0, 0), "Reclaim = %s", 6090 args->loca_reclaim ? "TRUE" : "FALSE"); 6091 6092 detail_stateid(&args->loca_stateid); 6093 6094 if (args->loca_last_write_offset.no_newoffset) { 6095 noff = &args->loca_last_write_offset; 6096 sprintf(get_line(0, 0), "Last write offset = %llu", 6097 noff->newoffset4_u.no_offset); 6098 } else 6099 sprintf(get_line(0, 0), "No last_write_offset provided"); 6100 6101 if (args->loca_time_modify.nt_timechanged) { 6102 time = &args->loca_time_modify.newtime4_u.nt_time; 6103 sprintf(get_line(0, 0), "Time modify = %s", 6104 format_time(time->seconds, time->nseconds)); 6105 } else 6106 sprintf(get_line(0, 0), "No time_modify provided"); 6107 6108 sprintf(get_line(0, 0), "Layoutupdate type = %s", 6109 detail_lotype_name(args->loca_layoutupdate.lou_type)); 6110 sprintf(get_line(0, 0), "Layoutupdate data = %s", 6111 tohex(args->loca_layoutupdate.lou_body.lou_body_val, 6112 args->loca_layoutupdate.lou_body.lou_body_len)); 6113 } 6114 6115 static void 6116 sumres_layoutcommit(char *buf, size_t buflen, void *obj) 6117 { 6118 LAYOUTCOMMIT4res *res = (LAYOUTCOMMIT4res *)obj; 6119 LAYOUTCOMMIT4resok *resok; 6120 char *bp = buf; 6121 6122 strcpy(bp, status_name(res->locr_status)); 6123 if (res->locr_status == NFS4_OK) { 6124 resok = &res->LAYOUTCOMMIT4res_u.locr_resok4; 6125 bp += strlen(bp); 6126 if (resok->locr_newsize.ns_sizechanged) 6127 snprintf(bp, buflen - (bp - buf), " NSIZE=%llu", 6128 resok->locr_newsize.newsize4_u.ns_size); 6129 else 6130 snprintf(bp, buflen - (bp - buf), " NO_CHANGE"); 6131 } 6132 } 6133 6134 static void 6135 dtlres_layoutcommit(void *obj) 6136 { 6137 LAYOUTCOMMIT4res *res = (LAYOUTCOMMIT4res *)obj; 6138 LAYOUTCOMMIT4resok *resok; 6139 6140 dtl_nfsstat4(obj); 6141 if (res->locr_status == NFS4_OK) { 6142 resok = &res->LAYOUTCOMMIT4res_u.locr_resok4; 6143 if (resok->locr_newsize.ns_sizechanged) 6144 sprintf(get_line(0, 0), "Changed size = %llu", 6145 resok->locr_newsize.newsize4_u.ns_size); 6146 else 6147 sprintf(get_line(0, 0), "The size is not changed"); 6148 } 6149 } 6150 6151 static void 6152 sumarg_layoutget(char *buf, size_t buflen, void *obj) 6153 { 6154 LAYOUTGET4args *args = (LAYOUTGET4args *)obj; 6155 char *bp = buf; 6156 6157 snprintf(bp, buflen - (bp - buf), "%s", 6158 sum_stateid(&args->loga_stateid)); 6159 } 6160 6161 static void 6162 dtlarg_layoutget(void *obj) 6163 { 6164 LAYOUTGET4args *args = (LAYOUTGET4args *)obj; 6165 6166 sprintf(get_line(0, 0), "Signal layout available = %s", 6167 args->loga_signal_layout_avail ? "TRUE" : "FALSE"); 6168 sprintf(get_line(0, 0), "Layout type = %s", 6169 detail_lotype_name(args->loga_layout_type)); 6170 sprintf(get_line(0, 0), "Layout iomode = %s", 6171 detail_iomode_name(args->loga_iomode)); 6172 sprintf(get_line(0, 0), "Offset = %llu", 6173 args->loga_offset); 6174 sprintf(get_line(0, 0), "Length = %llu", 6175 args->loga_length); 6176 sprintf(get_line(0, 0), "Minimum size overlap = %llu", 6177 args->loga_minlength); 6178 detail_stateid(&args->loga_stateid); 6179 sprintf(get_line(0, 0), "Max count = %u", 6180 args->loga_maxcount); 6181 } 6182 6183 static void 6184 sum_file_layout(char *buf, size_t buflen, layout4 *lo) 6185 { 6186 static nfsv4_1_file_layout4 fl; 6187 char *bp = buf; 6188 uint_t i, n; 6189 nfs_fh4 *fh; 6190 XDR xdr; 6191 6192 bzero(&fl, sizeof (fl)); 6193 xdrmem_create(&xdr, 6194 lo->lo_content.loc_body.loc_body_val, 6195 lo->lo_content.loc_body.loc_body_len, 6196 XDR_DECODE); 6197 if (! xdr_nfsv4_1_file_layout4(&xdr, &fl)) 6198 longjmp(xdr_err, 1); 6199 6200 snprintf(bp, buflen, " %04X 0x%x", 6201 deviceid_hash(fl.nfl_deviceid), fl.nfl_util); 6202 bp += strlen(bp); 6203 n = fl.nfl_fh_list.nfl_fh_list_len; 6204 fh = fl.nfl_fh_list.nfl_fh_list_val; 6205 for (i = 0; i < n; i++) { 6206 strncat(bp, " ", buflen - (bp - buf)); 6207 bp += strlen(bp); 6208 if (i == fl.nfl_first_stripe_index) { 6209 strncat(bp, "<start>", buflen - (bp - buf)); 6210 bp += strlen(bp); 6211 } 6212 snprintf(bp, buflen - (bp - buf), "%04X", fh4_hash(fh + i)); 6213 bp += strlen(bp); 6214 } 6215 6216 xdr_free(xdr_nfsv4_1_file_layout4, (char *)&fl); 6217 } 6218 6219 static void 6220 sumres_layoutget(char *buf, size_t buflen, void *obj) 6221 { 6222 LAYOUTGET4res *res = (LAYOUTGET4res *)obj; 6223 LAYOUTGET4resok *resok; 6224 layout4 *lo; 6225 char *bp = buf; 6226 6227 strcpy(bp, status_name(res->logr_status)); 6228 if (res->logr_status == NFS4_OK) { 6229 resok = &res->LAYOUTGET4res_u.logr_resok4; 6230 bp += strlen(bp); 6231 snprintf(bp, buflen - (bp - buf), "%s", 6232 sum_stateid(&resok->logr_stateid)); 6233 } else if (res->logr_status == NFS4ERR_LAYOUTTRYLATER) { 6234 bp += strlen(bp); 6235 snprintf(bp, buflen - (bp - buf), "%s", 6236 res->LAYOUTGET4res_u.logr_will_signal_layout_avail ? 6237 "SIGNAL" : "NO_SIGNAL"); 6238 } 6239 } 6240 6241 void 6242 detail_file_layout(layout4 *lo) 6243 { 6244 nfsv4_1_file_layout4 fl; 6245 uint_t i; 6246 XDR xdr; 6247 6248 bzero(&fl, sizeof (fl)); 6249 xdrmem_create(&xdr, 6250 lo->lo_content.loc_body.loc_body_val, 6251 lo->lo_content.loc_body.loc_body_len, 6252 XDR_DECODE); 6253 if (! xdr_nfsv4_1_file_layout4(&xdr, &fl)) 6254 longjmp(xdr_err, 1); 6255 6256 detail_deviceid(fl.nfl_deviceid); 6257 sprintf(get_line(0, 0), "Util = 0x%x", fl.nfl_util); 6258 sprintf(get_line(0, 0), " stripe_unit = %d", fl.nfl_util >> 6); 6259 if (fl.nfl_util & NFL4_UFLG_DENSE) 6260 sprintf(get_line(0, 0), " UFLG_DENSE"); 6261 if (fl.nfl_util & NFL4_UFLG_COMMIT_THRU_MDS) 6262 sprintf(get_line(0, 0), " UFLG_COMMIT_THRU_MDS"); 6263 sprintf(get_line(0, 0), "First stripe = %d", fl.nfl_first_stripe_index); 6264 for (i = 0; i < fl.nfl_fh_list.nfl_fh_list_len; i++) { 6265 sprintf(get_line(0, 0), "fh[%u] = (%u) %s", 6266 i, fl.nfl_fh_list.nfl_fh_list_val[i].nfs_fh4_len, 6267 tohex(fl.nfl_fh_list.nfl_fh_list_val[i].nfs_fh4_val, 6268 fl.nfl_fh_list.nfl_fh_list_val[i].nfs_fh4_len)); 6269 } 6270 xdr_free(xdr_nfsv4_1_file_layout4, (char *)&fl); 6271 } 6272 6273 static void 6274 dtlres_layoutget(void *obj) 6275 { 6276 LAYOUTGET4res *res = (LAYOUTGET4res *)obj; 6277 LAYOUTGET4resok *resok; 6278 layout4 *lo; 6279 int i; 6280 6281 dtl_nfsstat4(obj); 6282 if (res->logr_status == NFS4_OK) { 6283 resok = &res->LAYOUTGET4res_u.logr_resok4; 6284 detail_stateid(&resok->logr_stateid); 6285 for (i = 0; i < resok->logr_layout.logr_layout_len; i++) { 6286 lo = &resok->logr_layout.logr_layout_val[i]; 6287 sprintf(get_line(0, 0), "Layout [%u]:", i); 6288 sprintf(get_line(0, 0), "Return layout on close = %s", 6289 resok->logr_return_on_close ? "TRUE" : "FALSE"); 6290 sprintf(get_line(0, 0), "Layout offset = %llu", 6291 lo->lo_offset); 6292 sprintf(get_line(0, 0), "Layout length = %llu", 6293 lo->lo_length); 6294 sprintf(get_line(0, 0), "Layout iomode = %s", 6295 detail_iomode_name(lo->lo_iomode)); 6296 sprintf(get_line(0, 0), "Layout type = %s", 6297 detail_lotype_name(lo->lo_content.loc_type)); 6298 if (lo->lo_content.loc_type == LAYOUT4_NFSV4_1_FILES) { 6299 detail_file_layout(lo); 6300 } else 6301 sprintf(get_line(0, 0), "Non-file layout = %s", 6302 tohex(lo->lo_content.loc_body.loc_body_val, 6303 lo->lo_content.loc_body.loc_body_len)); 6304 } 6305 } else if (res->logr_status == NFS4ERR_LAYOUTTRYLATER) { 6306 sprintf(get_line(0, 0), "Will signal layout avail = %s", 6307 res->LAYOUTGET4res_u.logr_will_signal_layout_avail ? 6308 "TRUE" : "FALSE"); 6309 } 6310 } 6311 6312 static void 6313 sumarg_layoutreturn(char *buf, size_t buflen, void *obj) 6314 { 6315 LAYOUTRETURN4args *args = (LAYOUTRETURN4args *)obj; 6316 layoutreturn4 *lr = &args->lora_layoutreturn; 6317 char *bp = buf; 6318 6319 if (lr->lr_returntype == LAYOUTRETURN4_FILE) 6320 snprintf(bp, buflen - (bp - buf), "%s", 6321 sum_stateid(&lr->layoutreturn4_u.lr_layout.lrf_stateid)); 6322 else 6323 snprintf(bp, buflen - (bp - buf), "Returntype=%s", 6324 sum_lrtype_name(lr->lr_returntype)); 6325 } 6326 6327 static void 6328 dtlarg_layoutreturn(void *obj) 6329 { 6330 LAYOUTRETURN4args *args = (LAYOUTRETURN4args *)obj; 6331 layoutreturn4 *lr = &args->lora_layoutreturn; 6332 6333 sprintf(get_line(0, 0), "Reclaim = %s", 6334 args->lora_reclaim ? "TRUE" : "FALSE"); 6335 sprintf(get_line(0, 0), "Layout type = %s", 6336 detail_lotype_name(args->lora_layout_type)); 6337 sprintf(get_line(0, 0), "Layout iomode = %s", 6338 detail_iomode_name(args->lora_iomode)); 6339 sprintf(get_line(0, 0), "Layoutreturn type = %s", 6340 detail_lrtype_name(lr->lr_returntype)); 6341 if (lr->lr_returntype == LAYOUTRETURN4_FILE) { 6342 sprintf(get_line(0, 0), "Layoutreturn Offset = %llu", 6343 lr->layoutreturn4_u.lr_layout.lrf_offset); 6344 sprintf(get_line(0, 0), "Layoutreturn Length = %llu", 6345 lr->layoutreturn4_u.lr_layout.lrf_length); 6346 detail_stateid(&lr->layoutreturn4_u.lr_layout.lrf_stateid); 6347 } 6348 } 6349 6350 6351 static void 6352 sumarg_secinfo_no_name(char *buf, size_t buflen, void *obj) 6353 { 6354 char style; 6355 6356 switch (*(SECINFO_NO_NAME4args *)obj) { 6357 case SECINFO_STYLE4_CURRENT_FH: 6358 style = 'C'; 6359 break; 6360 case SECINFO_STYLE4_PARENT: 6361 style = 'P'; 6362 break; 6363 default: 6364 style = '?'; 6365 break; 6366 } 6367 snprintf(buf, buflen, " ST=%c", style); 6368 } 6369 6370 static void 6371 dtlarg_secinfo_no_name(void *obj) 6372 { 6373 char *style; 6374 6375 switch (*(SECINFO_NO_NAME4args *)obj) { 6376 case SECINFO_STYLE4_CURRENT_FH: 6377 style = "CURRENT_FH"; 6378 break; 6379 case SECINFO_STYLE4_PARENT: 6380 style = "PARENT"; 6381 break; 6382 default: 6383 style = "???"; 6384 break; 6385 } 6386 sprintf(get_line(0, 0), "Style = %s", style); 6387 } 6388 6389 static void 6390 sumarg_want_delegation(char *buf, size_t buflen, void *obj) 6391 { 6392 } 6393 6394 static void 6395 dtlarg_want_delegation(void *obj) 6396 { 6397 } 6398 6399 static void 6400 sumres_want_delegation(char *buf, size_t buflen, void *obj) 6401 { 6402 } 6403 6404 static void 6405 dtlres_want_delegation(void *obj) 6406 { 6407 } 6408 6409 static void 6410 sumarg_destroy_clientid(char *buf, size_t buflen, void *obj) 6411 { 6412 DESTROY_CLIENTID4args *a = obj; 6413 6414 snprintf(buf, buflen, "%s", 6415 sum_clientid(a->dca_clientid)); 6416 } 6417 6418 static void 6419 dtlarg_destroy_clientid(void *obj) 6420 { 6421 DESTROY_CLIENTID4args *a = obj; 6422 6423 detail_clientid(a->dca_clientid); 6424 } 6425 6426 static void 6427 sumres_destroy_clientid(char *buf, size_t buflen, void *obj) 6428 { 6429 } 6430 6431 static void 6432 dtlres_destroy_clientid(void *obj) 6433 { 6434 } 6435 6436 static void 6437 sumarg_reclaim_complete(char *buf, size_t buflen, void *obj) 6438 { 6439 RECLAIM_COMPLETE4args *a = obj; 6440 char *bp = buf; 6441 6442 snprintf(bp, buflen - (bp - buf), "%s", 6443 (a->rca_one_fs) ? "<one-fs>" : "<all-fs>"); 6444 bp += strlen(bp); 6445 } 6446 6447 static void 6448 dtlarg_reclaim_complete(void *obj) 6449 { 6450 RECLAIM_COMPLETE4args *a = obj; 6451 6452 sprintf(get_line(0, 0), "One_FS = %d", a->rca_one_fs); 6453 } 6454 6455 static void 6456 sumres_reclaim_complete(char *buf, size_t buflen, void *obj) 6457 { 6458 } 6459 6460 static void 6461 dtlres_reclaim_complete(void *obj) 6462 { 6463 } 6464 6465 static void 6466 sumarg_cb_layoutrecall(char *buf, size_t buflen, void *obj) 6467 { 6468 CB_LAYOUTRECALL4args *args = (CB_LAYOUTRECALL4args *)obj; 6469 layoutrecall_file4 *lor_file; 6470 fsid4 *lor_fsid; 6471 char *bp = buf; 6472 6473 switch (args->clora_recall.lor_recalltype) { 6474 case LAYOUTRECALL4_FILE: 6475 lor_file = &args->clora_recall.layoutrecall4_u.lor_layout; 6476 snprintf(bp, buflen - (bp - buf), " %s", 6477 sum_stateid(&lor_file->lor_stateid)); 6478 break; 6479 case LAYOUTRECALL4_FSID: 6480 lor_fsid = &args->clora_recall.layoutrecall4_u.lor_fsid; 6481 snprintf(bp, buflen - (bp - buf), " (%llx, %llx)", 6482 lor_fsid->major, lor_fsid->minor); 6483 break; 6484 } 6485 } 6486 6487 static void 6488 dtlarg_cb_layoutrecall(void *obj) 6489 { 6490 CB_LAYOUTRECALL4args *args = (CB_LAYOUTRECALL4args *)obj; 6491 layoutrecall_file4 *lor_file; 6492 fsid4 *lor_fsid; 6493 6494 sprintf(get_line(0, 0), "Layout type = %s", 6495 detail_lotype_name(args->clora_type)); 6496 6497 sprintf(get_line(0, 0), "Layout iomode = %s", 6498 detail_iomode_name(args->clora_iomode)); 6499 6500 sprintf(get_line(0, 0), "Changed = %s", 6501 args->clora_changed ? "TRUE" : "FALSE"); 6502 6503 sprintf(get_line(0, 0), "Layout Recall type = %s", 6504 detail_lortype_name(args->clora_recall.lor_recalltype)); 6505 6506 switch (args->clora_recall.lor_recalltype) { 6507 case LAYOUTRECALL4_FILE: 6508 lor_file = &args->clora_recall.layoutrecall4_u.lor_layout; 6509 sprintf(get_line(0, 0), "Layout associated with FILE"); 6510 detail_fh4(&lor_file->lor_fh, ""); 6511 sprintf(get_line(0, 0), "Offset = %llu", 6512 lor_file->lor_offset); 6513 sprintf(get_line(0, 0), "Length = %llu", 6514 lor_file->lor_length); 6515 detail_stateid(&lor_file->lor_stateid); 6516 break; 6517 case LAYOUTRECALL4_FSID: 6518 lor_fsid = &args->clora_recall.layoutrecall4_u.lor_fsid; 6519 sprintf(get_line(0, 0), "Layouts associated with FSID"); 6520 sprintf(get_line(0, 0), "FS ID: Major = %llx, Minor = %llx", 6521 lor_fsid->major, lor_fsid->minor); 6522 break; 6523 case LAYOUTRECALL4_ALL: 6524 sprintf(get_line(0, 0), "ALL Layouts"); 6525 break; 6526 } 6527 } 6528 6529 static void 6530 sumres_cb_layoutrecall(char *buf, size_t buflen, void *obj) 6531 { 6532 CB_LAYOUTRECALL4res *res = (CB_LAYOUTRECALL4res *)obj; 6533 char *bp = buf; 6534 6535 snprintf(bp, buflen - (bp - buf), "%s ", 6536 status_name(res->clorr_status)); 6537 } 6538 6539 static void 6540 dtlres_cb_layoutrecall(void *obj) 6541 { 6542 dtl_nfsstat4(obj); 6543 } 6544 6545 static void 6546 sumarg_cb_notify(char *buf, size_t buflen, void *obj) 6547 { 6548 } 6549 6550 static void 6551 dtlarg_cb_notify(void *obj) 6552 { 6553 } 6554 6555 static void 6556 sumres_cb_notify(char *buf, size_t buflen, void *obj) 6557 { 6558 } 6559 6560 static void 6561 dtlres_cb_notify(void *obj) 6562 { 6563 } 6564 6565 static void 6566 sumarg_cb_push_deleg(char *buf, size_t buflen, void *obj) 6567 { 6568 } 6569 6570 static void 6571 dtlarg_cb_push_deleg(void *obj) 6572 { 6573 } 6574 6575 static void 6576 sumres_cb_push_deleg(char *buf, size_t buflen, void *obj) 6577 { 6578 } 6579 6580 static void 6581 dtlres_cb_push_deleg(void *obj) 6582 { 6583 } 6584 6585 static void 6586 sumarg_cb_recall_any(char *buf, size_t buflen, void *obj) 6587 { 6588 } 6589 6590 static void 6591 dtlarg_cb_recall_any(void *obj) 6592 { 6593 } 6594 6595 static void 6596 sumres_cb_recall_any(char *buf, size_t buflen, void *obj) 6597 { 6598 } 6599 6600 static void 6601 dtlres_cb_recall_any(void *obj) 6602 { 6603 } 6604 6605 static void 6606 sumarg_cb_recallable_obj_avail(char *buf, size_t buflen, void *obj) 6607 { 6608 } 6609 6610 static void 6611 dtlarg_cb_recallable_obj_avail(void *obj) 6612 { 6613 } 6614 6615 static void 6616 sumres_cb_recallable_obj_avail(char *buf, size_t buflen, void *obj) 6617 { 6618 } 6619 6620 static void 6621 dtlres_cb_recallable_obj_avail(void *obj) 6622 { 6623 } 6624 6625 static void 6626 sumarg_cb_recall_slot(char *buf, size_t buflen, void *obj) 6627 { 6628 } 6629 6630 static void 6631 dtlarg_cb_recall_slot(void *obj) 6632 { 6633 } 6634 6635 static void 6636 sumres_cb_recall_slot(char *buf, size_t buflen, void *obj) 6637 { 6638 } 6639 6640 static void 6641 dtlres_cb_recall_slot(void *obj) 6642 { 6643 } 6644 6645 static void 6646 sumarg_cb_wants_cancelled(char *buf, size_t buflen, void *obj) 6647 { 6648 } 6649 6650 static void 6651 dtlarg_cb_wants_cancelled(void *obj) 6652 { 6653 } 6654 6655 static void 6656 sumres_cb_wants_cancelled(char *buf, size_t buflen, void *obj) 6657 { 6658 } 6659 6660 static void 6661 dtlres_cb_wants_cancelled(void *obj) 6662 { 6663 } 6664 6665 static void 6666 sumarg_cb_notify_lock(char *buf, size_t buflen, void *obj) 6667 { 6668 } 6669 6670 static void 6671 dtlarg_cb_notify_lock(void *obj) 6672 { 6673 } 6674 6675 static void 6676 sumres_cb_notify_lock(char *buf, size_t buflen, void *obj) 6677 { 6678 } 6679 6680 static void 6681 dtlres_cb_notify_lock(void *obj) 6682 { 6683 } 6684 6685 6686 /* 6687 * Attribute print functions. See attr_info_t. 6688 */ 6689 6690 static void 6691 prt_supported_attrs(XDR *xdr) 6692 { 6693 static bitmap4 val; 6694 6695 if (!xdr_bitmap4(xdr, &val)) 6696 longjmp(xdr_err, 1); 6697 sprintf(get_line(0, 0), "Supported Attributes:"); 6698 detail_attr_bitmap("\t", &val, NULL); 6699 xdr_free(xdr_bitmap4, (char *)&val); 6700 } 6701 6702 static void 6703 prt_type(XDR *xdr) 6704 { 6705 nfs_ftype4 val; 6706 6707 if (!xdr_nfs_ftype4(xdr, &val)) 6708 longjmp(xdr_err, 1); 6709 sprintf(get_line(0, 0), "Type = %s", sum_type_name(val)); 6710 } 6711 6712 static void 6713 prt_fh_expire_type(XDR *xdr) 6714 { 6715 fattr4_fh_expire_type