1 /* 2 * This file and its contents are supplied under the terms of the 3 * Common Development and Distribution License ("CDDL"), version 1.0. 4 * You may only use this file in accordance with the terms of version 5 * 1.0 of the CDDL. 6 * 7 * A full copy of the text of the CDDL should have accompanied this 8 * source. A copy of the CDDL is also available via the Internet at 9 * http://www.illumos.org/license/CDDL. 10 */ 11 /* 12 * Copyright 2021 Tintri by DDN, Inc. All rights reserved. 13 */ 14 15 #include <sys/mdb_modapi.h> 16 #include <mdb/mdb_types.h> 17 #include <sys/refstr.h> 18 #include <sys/kstat.h> 19 #include <sys/refstr_impl.h> 20 #include <nfs/nfs4_clnt.h> 21 #include <nfs/nfs_clnt.h> 22 #include <nfs/nfs4_db_impl.h> 23 #include <nfs/nfs4.h> 24 #include <nfs/rnode.h> 25 #include <nfs/rnode4.h> 26 #include <rpc/clnt.h> 27 #include <nfs/nfs4_idmap_impl.h> 28 #include <mdb/mdb_ks.h> 29 30 #include "svc.h" 31 #include "rfs4.h" 32 #include "nfssrv.h" 33 #include "idmap.h" 34 #include "nfs_clnt.h" 35 36 typedef struct nfs_rnode_cbdata { 37 int printed_hdr; 38 uintptr_t vfs_addr; /* for nfs_rnode4find */ 39 } nfs_rnode_cbdata_t; 40 41 static const mdb_bitmask_t vfs_flags[] = { 42 { "VFS_RDONLY", VFS_RDONLY, VFS_RDONLY }, 43 { "VFS_NOMNTTAB", VFS_NOMNTTAB, VFS_NOMNTTAB }, 44 { "VFS_NOSETUID", VFS_NOSETUID, VFS_NOSETUID }, 45 { "VFS_REMOUNT", VFS_REMOUNT, VFS_REMOUNT }, 46 { "VFS_NOTRUNC", VFS_NOTRUNC, VFS_NOTRUNC }, 47 { "VFS_PXFS", VFS_PXFS, VFS_PXFS }, 48 { "VFS_NBMAND", VFS_NBMAND, VFS_NBMAND }, 49 { "VFS_XATTR", VFS_XATTR, VFS_XATTR }, 50 { "VFS_NOEXEC", VFS_NOEXEC, VFS_NOEXEC }, 51 { "VFS_STATS", VFS_STATS, VFS_STATS }, 52 { "VFS_XID", VFS_XID, VFS_XID }, 53 { "VFS_UNLINKABLE", VFS_UNLINKABLE, VFS_UNLINKABLE }, 54 { "VFS_UNMOUNTED", VFS_UNMOUNTED, VFS_UNMOUNTED }, 55 { NULL, 0, 0 } 56 }; 57 58 static const mdb_bitmask_t nfs_mi4_flags[] = { 59 { "MI4_HARD", MI4_HARD, MI4_HARD }, 60 { "MI4_PRINTED", MI4_PRINTED, MI4_PRINTED }, 61 { "MI4_INT", MI4_INT, MI4_INT }, 62 { "MI4_DOWN", MI4_DOWN, MI4_DOWN }, 63 { "MI4_NOAC", MI4_NOAC, MI4_NOAC }, 64 { "MI4_NOCTO", MI4_NOCTO, MI4_NOCTO }, 65 { "MI4_LLOCK", MI4_LLOCK, MI4_LLOCK }, 66 { "MI4_GRPID", MI4_GRPID, MI4_GRPID }, 67 { "MI4_SHUTDOWN", MI4_SHUTDOWN, MI4_SHUTDOWN }, 68 { "MI4_LINK", MI4_LINK, MI4_LINK }, 69 { "MI4_SYMLINK", MI4_SYMLINK, MI4_SYMLINK }, 70 { "MI4_ACL", MI4_ACL, MI4_ACL }, 71 { "MI4_REFERRAL", MI4_REFERRAL, MI4_REFERRAL }, 72 { "MI4_NOPRINT", MI4_NOPRINT, MI4_NOPRINT }, 73 { "MI4_DIRECTIO", MI4_DIRECTIO, MI4_DIRECTIO }, 74 { "MI4_PUBLIC", MI4_PUBLIC, MI4_PUBLIC }, 75 { "MI4_MOUNTING", MI4_MOUNTING, MI4_MOUNTING }, 76 { "MI4_DEAD", MI4_DEAD, MI4_DEAD }, 77 { "MI4_TIMEDOUT", MI4_TIMEDOUT, MI4_TIMEDOUT }, 78 { "MI4_MIRRORMOUNT", MI4_MIRRORMOUNT, MI4_MIRRORMOUNT }, 79 { "MI4_RECOV_ACTIV", MI4_RECOV_ACTIV, MI4_RECOV_ACTIV }, 80 { "MI4_RECOV_FAIL", MI4_RECOV_FAIL, MI4_RECOV_FAIL }, 81 { "MI4_POSIX_LOCK", MI4_POSIX_LOCK, MI4_POSIX_LOCK }, 82 { "MI4_LOCK_DEBUG", MI4_LOCK_DEBUG, MI4_LOCK_DEBUG }, 83 { "MI4_INACTIVE_IDLE", MI4_INACTIVE_IDLE, MI4_INACTIVE_IDLE }, 84 { "MI4_BADOWNER_DEBUG", MI4_BADOWNER_DEBUG, MI4_BADOWNER_DEBUG }, 85 { "MI4_ASYNC_MGR_STOP", MI4_ASYNC_MGR_STOP, MI4_ASYNC_MGR_STOP }, 86 { "MI4_EPHEMERAL", MI4_EPHEMERAL, MI4_EPHEMERAL }, 87 { "MI4_REMOVE_ON_LAST_CLOSE", MI4_REMOVE_ON_LAST_CLOSE, 88 MI4_REMOVE_ON_LAST_CLOSE }, 89 { NULL, 0, 0 } 90 }; 91 92 static const mdb_bitmask_t nfs_mi4_recover[] = { 93 { "MI4R_NEED_CLIENTID", MI4R_NEED_CLIENTID, MI4R_NEED_CLIENTID }, 94 { "MI4R_REOPEN_FILES", MI4R_REOPEN_FILES, MI4R_REOPEN_FILES }, 95 { "MI4R_NEED_SECINFO", MI4R_NEED_SECINFO, MI4R_NEED_SECINFO }, 96 { "MI4R_REOPEN_FILES", MI4R_REOPEN_FILES, MI4R_REOPEN_FILES }, 97 { "MI4R_SRV_REBOOT", MI4R_SRV_REBOOT, MI4R_SRV_REBOOT }, 98 { "MI4R_LOST_STATE", MI4R_LOST_STATE, MI4R_LOST_STATE }, 99 { "MI4R_BAD_SEQID", MI4R_BAD_SEQID, MI4R_BAD_SEQID }, 100 { "MI4R_MOVED", MI4R_MOVED, MI4R_MOVED }, 101 { "MI4R_NEED_NEW_SERVER", MI4R_NEED_NEW_SERVER, MI4R_NEED_NEW_SERVER }, 102 { NULL, 0, 0 } 103 }; 104 105 static const char * 106 nfs4_tag_str(int tag) 107 { 108 switch (tag) { 109 case TAG_NONE: 110 return ("TAG_NONE"); 111 case TAG_ACCESS: 112 return ("TAG_ACCESS"); 113 case TAG_CLOSE: 114 return ("TAG_CLOSE"); 115 case TAG_CLOSE_LOST: 116 return ("TAG_CLOSE_LOST"); 117 case TAG_CLOSE_UNDO: 118 return ("TAG_CLOSE_UNDO"); 119 case TAG_COMMIT: 120 return ("TAG_COMMIT"); 121 case TAG_DELEGRETURN: 122 return ("TAG_DELEGRETURN"); 123 case TAG_FSINFO: 124 return ("TAG_FSINFO"); 125 case TAG_GET_SYMLINK: 126 return ("TAG_GET_SYMLINK"); 127 case TAG_GETATTR: 128 return ("TAG_GETATTR"); 129 case TAG_GETATTR_FSLOCATION: 130 return ("TAG_GETATTR_FSLOCATION"); 131 case TAG_INACTIVE: 132 return ("TAG_INACTIVE"); 133 case TAG_LINK: 134 return ("TAG_LINK"); 135 case TAG_LOCK: 136 return ("TAG_LOCK"); 137 case TAG_LOCK_RECLAIM: 138 return ("TAG_LOCK_RECLAIM"); 139 case TAG_LOCK_RESEND: 140 return ("TAG_LOCK_RESEND"); 141 case TAG_LOCK_REINSTATE: 142 return ("TAG_LOCK_REINSTATE"); 143 case TAG_LOCK_UNKNOWN: 144 return ("TAG_LOCK_UNKNOWN"); 145 case TAG_LOCKT: 146 return ("TAG_LOCKT"); 147 case TAG_LOCKU: 148 return ("TAG_LOCKU"); 149 case TAG_LOCKU_RESEND: 150 return ("TAG_LOCKU_RESEND"); 151 case TAG_LOCKU_REINSTATE: 152 return ("TAG_LOCKU_REINSTATE"); 153 case TAG_LOOKUP: 154 return ("TAG_LOOKUP"); 155 case TAG_LOOKUP_PARENT: 156 return ("TAG_LOOKUP_PARENT"); 157 case TAG_LOOKUP_VALID: 158 return ("TAG_LOOKUP_VALID"); 159 case TAG_LOOKUP_VPARENT: 160 return ("TAG_LOOKUP_VPARENT"); 161 case TAG_MKDIR: 162 return ("TAG_MKDIR"); 163 case TAG_MKNOD: 164 return ("TAG_MKNOD"); 165 case TAG_MOUNT: 166 return ("TAG_MOUNT"); 167 case TAG_OPEN: 168 return ("TAG_OPEN"); 169 case TAG_OPEN_CONFIRM: 170 return ("TAG_OPEN_CONFIRM"); 171 case TAG_OPEN_CONFIRM_LOST: 172 return ("TAG_OPEN_CONFIRM_LOST"); 173 case TAG_OPEN_DG: 174 return ("TAG_OPEN_DG"); 175 case TAG_OPEN_DG_LOST: 176 return ("TAG_OPEN_DG_LOST"); 177 case TAG_OPEN_LOST: 178 return ("TAG_OPEN_LOST"); 179 case TAG_OPENATTR: 180 return ("TAG_OPENATTR"); 181 case TAG_PATHCONF: 182 return ("TAG_PATHCONF"); 183 case TAG_PUTROOTFH: 184 return ("TAG_PUTROOTFH"); 185 case TAG_READ: 186 return ("TAG_READ"); 187 case TAG_READAHEAD: 188 return ("TAG_READAHEAD"); 189 case TAG_READDIR: 190 return ("TAG_READDIR"); 191 case TAG_READLINK: 192 return ("TAG_READLINK"); 193 case TAG_RELOCK: 194 return ("TAG_RELOCK"); 195 case TAG_REMAP_LOOKUP: 196 return ("TAG_REMAP_LOOKUP"); 197 case TAG_REMAP_LOOKUP_AD: 198 return ("TAG_REMAP_LOOKUP_AD"); 199 case TAG_REMAP_LOOKUP_NA: 200 return ("TAG_REMAP_LOOKUP_NA"); 201 case TAG_REMAP_MOUNT: 202 return ("TAG_REMAP_MOUNT"); 203 case TAG_RMDIR: 204 return ("TAG_RMDIR"); 205 case TAG_REMOVE: 206 return ("TAG_REMOVE"); 207 case TAG_RENAME: 208 return ("TAG_RENAME"); 209 case TAG_RENAME_VFH: 210 return ("TAG_RENAME_VFH"); 211 case TAG_RENEW: 212 return ("TAG_RENEW"); 213 case TAG_REOPEN: 214 return ("TAG_REOPEN"); 215 case TAG_REOPEN_LOST: 216 return ("TAG_REOPEN_LOST"); 217 case TAG_SECINFO: 218 return ("TAG_SECINFO"); 219 case TAG_SETATTR: 220 return ("TAG_SETATTR"); 221 case TAG_SETCLIENTID: 222 return ("TAG_SETCLIENTID"); 223 case TAG_SETCLIENTID_CF: 224 return ("TAG_SETCLIENTID_CF"); 225 case TAG_SYMLINK: 226 return ("TAG_SYMLINK"); 227 case TAG_WRITE: 228 return ("TAG_WRITE"); 229 default: 230 return ("Undefined"); 231 } 232 } 233 234 /* 235 * Return stringified NFS4 error. 236 * Note, it may return pointer to static buffer (in case of unknown error) 237 */ 238 static const char * 239 nfs4_stat_str(nfsstat4 err) 240 { 241 static char str[64]; 242 243 switch (err) { 244 case NFS4_OK: 245 return ("NFS4_OK"); 246 case NFS4ERR_PERM: 247 return ("NFS4ERR_PERM"); 248 case NFS4ERR_NOENT: 249 return ("NFS4ERR_NOENT"); 250 case NFS4ERR_IO: 251 return ("NFS4ERR_IO"); 252 case NFS4ERR_NXIO: 253 return ("NFS4ERR_NXIO"); 254 case NFS4ERR_ACCESS: 255 return ("NFS4ERR_ACCESS"); 256 case NFS4ERR_EXIST: 257 return ("NFS4ERR_EXIST"); 258 case NFS4ERR_XDEV: 259 return ("NFS4ERR_XDEV"); 260 case NFS4ERR_NOTDIR: 261 return ("NFS4ERR_NOTDIR"); 262 case NFS4ERR_ISDIR: 263 return ("NFS4ERR_ISDIR"); 264 case NFS4ERR_INVAL: 265 return ("NFS4ERR_INVAL"); 266 case NFS4ERR_FBIG: 267 return ("NFS4ERR_FBIG"); 268 case NFS4ERR_NOSPC: 269 return ("NFS4ERR_NOSPC"); 270 case NFS4ERR_ROFS: 271 return ("NFS4ERR_ROFS"); 272 case NFS4ERR_MLINK: 273 return ("NFS4ERR_MLINK"); 274 case NFS4ERR_NAMETOOLONG: 275 return ("NFS4ERR_NAMETOOLONG"); 276 case NFS4ERR_NOTEMPTY: 277 return ("NFS4ERR_NOTEMPTY"); 278 case NFS4ERR_DQUOT: 279 return ("NFS4ERR_DQUOT"); 280 case NFS4ERR_STALE: 281 return ("NFS4ERR_STALE"); 282 case NFS4ERR_BADHANDLE: 283 return ("NFS4ERR_BADHANDLE"); 284 case NFS4ERR_BAD_COOKIE: 285 return ("NFS4ERR_BAD_COOKIE"); 286 case NFS4ERR_NOTSUPP: 287 return ("NFS4ERR_NOTSUPP"); 288 case NFS4ERR_TOOSMALL: 289 return ("NFS4ERR_TOOSMALL"); 290 case NFS4ERR_SERVERFAULT: 291 return ("NFS4ERR_SERVERFAULT"); 292 case NFS4ERR_BADTYPE: 293 return ("NFS4ERR_BADTYPE"); 294 case NFS4ERR_DELAY: 295 return ("NFS4ERR_DELAY"); 296 case NFS4ERR_SAME: 297 return ("NFS4ERR_SAME"); 298 case NFS4ERR_DENIED: 299 return ("NFS4ERR_DENIED"); 300 case NFS4ERR_EXPIRED: 301 return ("NFS4ERR_EXPIRED"); 302 case NFS4ERR_LOCKED: 303 return ("NFS4ERR_LOCKED"); 304 case NFS4ERR_GRACE: 305 return ("NFS4ERR_GRACE"); 306 case NFS4ERR_FHEXPIRED: 307 return ("NFS4ERR_FHEXPIRED"); 308 case NFS4ERR_SHARE_DENIED: 309 return ("NFS4ERR_SHARE_DENIED"); 310 case NFS4ERR_WRONGSEC: 311 return ("NFS4ERR_WRONGSEC"); 312 case NFS4ERR_CLID_INUSE: 313 return ("NFS4ERR_CLID_INUSE"); 314 case NFS4ERR_RESOURCE: 315 return ("NFS4ERR_RESOURCE"); 316 case NFS4ERR_MOVED: 317 return ("NFS4ERR_MOVED"); 318 case NFS4ERR_NOFILEHANDLE: 319 return ("NFS4ERR_NOFILEHANDLE"); 320 case NFS4ERR_MINOR_VERS_MISMATCH: 321 return ("NFS4ERR_MINOR_VERS_MISMATCH"); 322 case NFS4ERR_STALE_CLIENTID: 323 return ("NFS4ERR_STALE_CLIENTID"); 324 case NFS4ERR_STALE_STATEID: 325 return ("NFS4ERR_STALE_STATEID"); 326 case NFS4ERR_OLD_STATEID: 327 return ("NFS4ERR_OLD_STATEID"); 328 case NFS4ERR_BAD_STATEID: 329 return ("NFS4ERR_BAD_STATEID"); 330 case NFS4ERR_BAD_SEQID: 331 return ("NFS4ERR_BAD_SEQID"); 332 case NFS4ERR_NOT_SAME: 333 return ("NFS4ERR_NOT_SAME"); 334 case NFS4ERR_LOCK_RANGE: 335 return ("NFS4ERR_LOCK_RANGE"); 336 case NFS4ERR_SYMLINK: 337 return ("NFS4ERR_SYMLINK"); 338 case NFS4ERR_RESTOREFH: 339 return ("NFS4ERR_RESTOREFH"); 340 case NFS4ERR_LEASE_MOVED: 341 return ("NFS4ERR_LEASE_MOVED"); 342 case NFS4ERR_ATTRNOTSUPP: 343 return ("NFS4ERR_ATTRNOTSUPP"); 344 case NFS4ERR_NO_GRACE: 345 return ("NFS4ERR_NO_GRACE"); 346 case NFS4ERR_RECLAIM_BAD: 347 return ("NFS4ERR_RECLAIM_BAD"); 348 case NFS4ERR_RECLAIM_CONFLICT: 349 return ("NFS4ERR_RECLAIM_CONFLICT"); 350 case NFS4ERR_BADXDR: 351 return ("NFS4ERR_BADXDR"); 352 case NFS4ERR_LOCKS_HELD: 353 return ("NFS4ERR_LOCKS_HELD"); 354 case NFS4ERR_OPENMODE: 355 return ("NFS4ERR_OPENMODE"); 356 case NFS4ERR_BADOWNER: 357 return ("NFS4ERR_BADOWNER"); 358 case NFS4ERR_BADCHAR: 359 return ("NFS4ERR_BADCHAR"); 360 case NFS4ERR_BADNAME: 361 return ("NFS4ERR_BADNAME"); 362 case NFS4ERR_BAD_RANGE: 363 return ("NFS4ERR_BAD_RANGE"); 364 case NFS4ERR_LOCK_NOTSUPP: 365 return ("NFS4ERR_LOCK_NOTSUPP"); 366 case NFS4ERR_OP_ILLEGAL: 367 return ("NFS4ERR_OP_ILLEGAL"); 368 case NFS4ERR_DEADLOCK: 369 return ("NFS4ERR_DEADLOCK"); 370 case NFS4ERR_FILE_OPEN: 371 return ("NFS4ERR_FILE_OPEN"); 372 case NFS4ERR_ADMIN_REVOKED: 373 return ("NFS4ERR_ADMIN_REVOKED"); 374 case NFS4ERR_CB_PATH_DOWN: 375 return ("NFS4ERR_CB_PATH_DOWN"); 376 default: 377 mdb_snprintf(str, sizeof (str), "Unknown %d", err); 378 return (str); 379 } 380 } 381 382 static const char * 383 nfs4_op_str(uint_t op) 384 { 385 switch (op) { 386 case OP_ACCESS: 387 return ("OP_ACCESS"); 388 case OP_CLOSE: 389 return ("OP_CLOSE"); 390 case OP_COMMIT: 391 return ("OP_COMMIT"); 392 case OP_CREATE: 393 return ("OP_CREATE"); 394 case OP_DELEGPURGE: 395 return ("OP_DELEGPURGE"); 396 case OP_DELEGRETURN: 397 return ("OP_DELEGRETURN"); 398 case OP_GETATTR: 399 return ("OP_GETATTR"); 400 case OP_GETFH: 401 return ("OP_GETFH"); 402 case OP_LINK: 403 return ("OP_LINK"); 404 case OP_LOCK: 405 return ("OP_LOCK"); 406 case OP_LOCKT: 407 return ("OP_LOCKT"); 408 case OP_LOCKU: 409 return ("OP_LOCKU"); 410 case OP_LOOKUP: 411 return ("OP_LOOKUP"); 412 case OP_LOOKUPP: 413 return ("OP_LOOKUPP"); 414 case OP_NVERIFY: 415 return ("OP_NVERIFY"); 416 case OP_OPEN: 417 return ("OP_OPEN"); 418 case OP_OPENATTR: 419 return ("OP_OPENATTR"); 420 case OP_OPEN_CONFIRM: 421 return ("OP_OPEN_CONFIRM"); 422 case OP_OPEN_DOWNGRADE: 423 return ("OP_OPEN_DOWNGRADE"); 424 case OP_PUTFH: 425 return ("OP_PUTFH"); 426 case OP_PUTPUBFH: 427 return ("OP_PUTPUBFH"); 428 case OP_PUTROOTFH: 429 return ("OP_PUTROOTFH"); 430 case OP_READ: 431 return ("OP_READ"); 432 case OP_READDIR: 433 return ("OP_READDIR"); 434 case OP_READLINK: 435 return ("OP_READLINK"); 436 case OP_REMOVE: 437 return ("OP_REMOVE"); 438 case OP_RENAME: 439 return ("OP_RENAME"); 440 case OP_RENEW: 441 return ("OP_RENEW"); 442 case OP_RESTOREFH: 443 return ("OP_RESTOREFH"); 444 case OP_SAVEFH: 445 return ("OP_SAVEFH"); 446 case OP_SECINFO: 447 return ("OP_SECINFO"); 448 case OP_SETATTR: 449 return ("OP_SETATTR"); 450 case OP_SETCLIENTID: 451 return ("OP_SETCLIENTID"); 452 case OP_SETCLIENTID_CONFIRM: 453 return ("OP_SETCLIENTID_CONFIRM"); 454 case OP_VERIFY: 455 return ("OP_VERIFY"); 456 case OP_WRITE: 457 return ("OP_WRITE"); 458 case OP_RELEASE_LOCKOWNER: 459 return ("OP_RELEASE_LOCKOWNER"); 460 case OP_ILLEGAL: 461 return ("OP_ILLEGAL"); 462 default: 463 return ("Unknown"); 464 } 465 } 466 467 static const char * 468 nfs4_recov_str(uint_t act) 469 { 470 switch (act) { 471 case NR_UNUSED: 472 return ("NR_UNUSED"); 473 case NR_STALE: 474 return ("NR_STALE"); 475 case NR_FAILOVER: 476 return ("NR_FAILOVER"); 477 case NR_CLIENTID: 478 return ("NR_CLIENTID"); 479 case NR_OPENFILES: 480 return ("NR_OPENFILES"); 481 case NR_WRONGSEC: 482 return ("NR_WRONGSEC"); 483 case NR_EXPIRED: 484 return ("NR_EXPIRED"); 485 case NR_BAD_STATEID: 486 return ("NR_BAD_STATEID"); 487 case NR_FHEXPIRED: 488 return ("NR_FHEXPIRED"); 489 case NR_BADHANDLE: 490 return ("NR_BADHANDLE"); 491 case NR_BAD_SEQID: 492 return ("NR_BAD_SEQID"); 493 case NR_OLDSTATEID: 494 return ("NR_OLDSTATEID"); 495 case NR_GRACE: 496 return ("NR_GRACE"); 497 case NR_DELAY: 498 return ("NR_DELAY"); 499 case NR_LOST_LOCK: 500 return ("NR_LOST_LOCK"); 501 case NR_LOST_STATE_RQST: 502 return ("NR_LOST_STATE_RQST"); 503 case NR_MOVED: 504 return ("NR_MOVED"); 505 default: 506 return ("Unknown"); 507 } 508 } 509 510 static void 511 nfs_addr_by_conf(uintptr_t knconf, struct netbuf *addr, 512 char *s, size_t nbytes) 513 { 514 struct knetconfig conf; 515 char buf[16]; 516 517 if (mdb_vread(&conf, sizeof (conf), knconf) == -1) { 518 mdb_warn("can't read sv_knconf"); 519 return; 520 } 521 522 if (mdb_readstr(buf, sizeof (buf), 523 (uintptr_t)conf.knc_protofmly) == -1) { 524 mdb_warn("can't read knc_protofmly"); 525 return; 526 } 527 /* Support only IPv4 addresses */ 528 if (strcmp(NC_INET, buf) == 0) { 529 struct sockaddr_in *in; 530 531 in = mdb_alloc(addr->len + 1, UM_SLEEP | UM_GC); 532 if (mdb_vread(in, addr->len, (uintptr_t)addr->buf) == -1) 533 return; 534 535 mdb_nhconvert(&in->sin_port, &in->sin_port, 536 sizeof (in->sin_port)); 537 538 (void) mdb_snprintf(s, nbytes, "%I:%d", in->sin_addr.s_addr, 539 in->sin_port); 540 } 541 } 542 543 /* 544 * Get IPv4 string address by servinfo4_t 545 * 546 * in case of error does not modify 's' 547 */ 548 static void 549 nfs_addr_by_servinfo4(uintptr_t addr, char *s, size_t nbytes) 550 { 551 struct servinfo4 *si; 552 553 si = mdb_alloc(sizeof (*si), UM_SLEEP | UM_GC); 554 if (mdb_vread(si, sizeof (*si), addr) == -1) { 555 mdb_warn("can't read servinfo4"); 556 return; 557 } 558 559 nfs_addr_by_conf((uintptr_t)si->sv_knconf, &si->sv_addr, 560 s, nbytes); 561 } 562 563 564 /* 565 * Get IPv4 string address by servinfo_t 566 * 567 * in case of error does not modify 's' 568 */ 569 static void 570 nfs_addr_by_servinfo(uintptr_t addr, char *s, size_t nbytes) 571 { 572 struct servinfo *si; 573 574 si = mdb_alloc(sizeof (*si), UM_SLEEP | UM_GC); 575 if (mdb_vread(si, sizeof (*si), addr) == -1) { 576 mdb_warn("can't read servinfo"); 577 return; 578 } 579 580 nfs_addr_by_conf((uintptr_t)si->sv_knconf, &si->sv_addr, 581 s, nbytes); 582 } 583 584 static void 585 nfs_queue_show_event(const nfs4_debug_msg_t *msg) 586 { 587 const nfs4_revent_t *re; 588 time_t time; 589 char *re_char1 = "<unknown>", *re_char2 = "<unknown>"; 590 591 re = &msg->rmsg_u.msg_event; 592 time = msg->msg_time.tv_sec; 593 594 if (re->re_char1 != NULL) { 595 char *s; 596 597 s = mdb_alloc(MAXPATHLEN, UM_SLEEP | UM_GC); 598 if (mdb_readstr(s, MAXPATHLEN, (uintptr_t)re->re_char1) != -1) 599 re_char1 = s; 600 else 601 mdb_warn("can't read re_char1"); 602 } 603 604 if (re->re_char2 != NULL) { 605 char *s; 606 607 s = mdb_alloc(MAXPATHLEN, UM_SLEEP | UM_GC); 608 609 if (mdb_readstr(s, MAXPATHLEN, (uintptr_t)re->re_char2) != -1) 610 re_char2 = s; 611 else 612 mdb_warn("can't read re_char2"); 613 } 614 615 switch (re->re_type) { 616 case RE_BAD_SEQID: 617 mdb_printf("[NFS4]%Y: Op %s for file %s rnode_pt %p\n" 618 "pid %d using seqid %d got %s. Last good seqid was %d " 619 "for operation %s\n", 620 time, nfs4_tag_str(re->re_tag1), re->re_char1, re->re_rp1, 621 re->re_pid, re->re_seqid1, nfs4_stat_str(re->re_stat4), 622 re->re_seqid2, nfs4_tag_str(re->re_tag2)); 623 break; 624 case RE_BADHANDLE: 625 mdb_printf("[NFS4]%Y: server said filehandle was " 626 "invalid for file: %s rnode_pt 0x%p\n", time, 627 re_char1, re->re_rp1); 628 break; 629 case RE_CLIENTID: 630 mdb_printf("[NFS4]%Y: Can't recover clientid on mountpoint %s\n" 631 "mi %p due to error %d (%s). Marking file system " 632 "as unusable\n", time, msg->msg_mntpt, 633 re->re_mi, re->re_uint, nfs4_stat_str(re->re_stat4)); 634 break; 635 case RE_DEAD_FILE: 636 mdb_printf("[NFS4]%Y: File: %s rnode_pt: %p was closed on NFS\n" 637 "recovery error [%s %s]\n", time, re_char1, re->re_rp1, 638 re_char2, nfs4_stat_str(re->re_stat4)); 639 break; 640 case RE_END: 641 mdb_printf("[NFS4]%Y: NFS Recovery done for mi %p " 642 "rnode_pt1 %s (%p), rnode_pt2 %s (%p)\n", time, re->re_mi, 643 re_char1, re->re_rp1, re_char2, re->re_rp2); 644 break; 645 646 case RE_FAIL_RELOCK: 647 mdb_printf("[NFS4]%Y: Couldn't reclaim lock for pid %d for\n" 648 "file %s (rnode_pt %p) error %d\n", time, re->re_pid, 649 re_char1, re->re_rp1, 650 re->re_uint ? re->re_uint : re->re_stat4); 651 break; 652 case RE_FAIL_REMAP_LEN: 653 mdb_printf("[NFS4]%Y: remap_lookup: returned bad\n" 654 "fhandle length %d\n", time, re->re_uint); 655 break; 656 case RE_FAIL_REMAP_OP: 657 mdb_printf("[NFS4]%Y: remap_lookup: didn't get expected " 658 " OP_GETFH\n", time); 659 break; 660 case RE_FAILOVER: 661 mdb_printf("[NFS4]%Y: failing over to %s\n", time, re_char1); 662 break; 663 664 case RE_FILE_DIFF: 665 mdb_printf("[NFS4]%Y: File %s rnode_pt: %p was closed\n" 666 "and failed attempted failover since its is different\n" 667 "than the original file\n", time, re_char1, re->re_rp1); 668 break; 669 670 case RE_LOST_STATE: 671 mdb_printf("[NFS4]%Y: Lost %s request file %s\n" 672 "rnode_pt: %p, dir %s (%p)\n", time, 673 nfs4_op_str(re->re_uint), re_char1, 674 re->re_rp1, re_char2, re->re_rp2); 675 break; 676 case RE_OPENS_CHANGED: 677 mdb_printf("[NFS4]%Y: The number of open files to reopen\n" 678 "changed for mount %s mi %p old %d, new %d\n", time, 679 msg->msg_mntpt, re->re_mi, re->re_uint, re->re_pid); 680 break; 681 case RE_SIGLOST: 682 case RE_SIGLOST_NO_DUMP: 683 mdb_printf("[NFS4]%Y: Process %d lost its locks on file %s\n" 684 "rnode_pt: %p due to NFS recovery error (%d:%s)\n", 685 time, re->re_pid, re_char1, 686 re->re_rp1, re->re_uint, nfs4_stat_str(re->re_stat4)); 687 break; 688 case RE_START: 689 mdb_printf("[NFS4]%Y: NFS Starting recovery for\n" 690 "mi %p mi_recovflags [0x%x] rnode_pt1 %s %p " 691 "rnode_pt2 %s %p\n", time, 692 re->re_mi, re->re_uint, re_char1, re->re_rp1, 693 re_char2, re->re_rp2); 694 break; 695 case RE_UNEXPECTED_ACTION: 696 mdb_printf("[NFS4]%Y: NFS recovery: unexpected action %s\n", 697 time, nfs4_recov_str(re->re_uint)); 698 break; 699 case RE_UNEXPECTED_ERRNO: 700 mdb_printf("[NFS4]%Y: NFS recovery: unexpected errno %d\n", 701 time, re->re_uint); 702 break; 703 case RE_UNEXPECTED_STATUS: 704 mdb_printf("[NFS4]%Y: NFS recovery: unexpected status" 705 "code (%s)\n", time, nfs4_stat_str(re->re_stat4)); 706 break; 707 case RE_WRONGSEC: 708 mdb_printf("[NFS4]%Y: NFS can't recover from NFS4ERR_WRONGSEC\n" 709 "error %d rnode_pt1 %s (%p) rnode_pt2 %s (0x%p)\n", time, 710 re->re_uint, re_char1, re->re_rp1, re_char2, re->re_rp2); 711 break; 712 case RE_LOST_STATE_BAD_OP: 713 mdb_printf("[NFS4]%Y: NFS lost state with unrecognized op %d\n" 714 "fs %s, pid %d, file %s (rnode_pt: %p) dir %s (%p)\n", 715 time, re->re_uint, msg->msg_mntpt, re->re_pid, re_char1, 716 re->re_rp1, re_char2, re->re_rp2); 717 break; 718 case RE_REFERRAL: 719 mdb_printf("[NFS4]%Y: being referred to %s\n", 720 time, re_char1); 721 break; 722 default: 723 mdb_printf("illegal event %d\n", re->re_type); 724 break; 725 } 726 } 727 728 static void 729 nfs_queue_show_fact(const nfs4_debug_msg_t *msg) 730 { 731 time_t time; 732 const nfs4_rfact_t *rf; 733 char *rf_char1 = "<unknown>"; 734 735 rf = &msg->rmsg_u.msg_fact; 736 time = msg->msg_time.tv_sec; 737 738 if (rf->rf_char1 != NULL) { 739 char *s; 740 741 s = mdb_alloc(MAXPATHLEN, UM_SLEEP | UM_GC); 742 if (mdb_readstr(s, MAXPATHLEN, (uintptr_t)rf->rf_char1) != -1) 743 rf_char1 = s; 744 else 745 mdb_warn("can't read rf_char1"); 746 } 747 748 switch (rf->rf_type) { 749 case RF_ERR: 750 mdb_printf("[NFS4]%Y: NFS op %s got " 751 "error %s:%d causing recovery action %s.%s\n", 752 time, nfs4_op_str(rf->rf_op), 753 rf->rf_error ? "" : nfs4_stat_str(rf->rf_stat4), 754 rf->rf_error, 755 nfs4_recov_str(rf->rf_action), 756 rf->rf_reboot ? 757 " Client also suspects that the server rebooted," 758 " or experienced a network partition." : ""); 759 break; 760 case RF_RENEW_EXPIRED: 761 mdb_printf("[NFS4]%Y: NFS4 renew thread detected client's " 762 "lease has expired. Current open files/locks/IO may fail\n", 763 time); 764 break; 765 case RF_SRV_NOT_RESPOND: 766 mdb_printf("[NFS4]%Y: NFS server not responding;" 767 "still trying\n", time); 768 break; 769 case RF_SRV_OK: 770 mdb_printf("[NFS4]%Y: NFS server ok\n", time); 771 break; 772 case RF_SRVS_NOT_RESPOND: 773 mdb_printf("[NFS4]%Y: NFS servers not responding; " 774 "still trying\n", time); 775 break; 776 case RF_SRVS_OK: 777 mdb_printf("[NFS4]%Y: NFS servers ok\n", time); 778 break; 779 case RF_DELMAP_CB_ERR: 780 mdb_printf("[NFS4]%Y: NFS op %s got error %s when executing " 781 "delmap on file %s rnode_pt %p\n", time, 782 nfs4_op_str(rf->rf_op), nfs4_stat_str(rf->rf_stat4), 783 rf_char1, rf->rf_rp1); 784 break; 785 case RF_SENDQ_FULL: 786 mdb_printf("[NFS4]%Y: sending queue to NFS server is full; " 787 "still trying\n", time); 788 break; 789 790 default: 791 mdb_printf("queue_print_fact: illegal fact %d\n", rf->rf_type); 792 } 793 } 794 795 static int 796 nfs4_show_message(uintptr_t addr, const void *arg, void *data) 797 { 798 nfs4_debug_msg_t msg; 799 if (mdb_vread(&msg, sizeof (msg), addr) == -1) { 800 mdb_warn("failed to read nfs4_debug_msg_t at %p", addr); 801 return (WALK_ERR); 802 } 803 804 if (msg.msg_type == RM_EVENT) 805 nfs_queue_show_event(&msg); 806 else if (msg.msg_type == RM_FACT) 807 nfs_queue_show_fact(&msg); 808 else 809 mdb_printf("Wrong msg_type %d\n", msg.msg_type); 810 return (WALK_NEXT); 811 } 812 813 static void 814 nfs4_print_messages(uintptr_t head) 815 { 816 mdb_printf("-----------------------------\n"); 817 mdb_printf("Messages queued:\n"); 818 mdb_inc_indent(2); 819 mdb_pwalk("list", nfs4_show_message, NULL, (uintptr_t)head); 820 mdb_dec_indent(2); 821 mdb_printf("-----------------------------\n"); 822 } 823 824 825 static void 826 nfs_print_mi4(uintptr_t miaddr, int verbose) 827 { 828 mntinfo4_t *mi; 829 char str[INET6_ADDRSTRLEN] = ""; 830 831 mi = mdb_alloc(sizeof (*mi), UM_SLEEP | UM_GC); 832 if (mdb_vread(mi, sizeof (*mi), miaddr) == -1) { 833 mdb_warn("can't read mntinfo"); 834 return; 835 } 836 837 mdb_printf("mntinfo4_t: %p\n", miaddr); 838 mdb_printf("NFS Version: 4\n"); 839 mdb_printf("mi_flags: %b\n", mi->mi_flags, nfs_mi4_flags); 840 mdb_printf("mi_error: %x\n", mi->mi_error); 841 mdb_printf("mi_open_files: %d\n", mi->mi_open_files); 842 mdb_printf("mi_msg_count: %d\n", mi->mi_msg_count); 843 mdb_printf("mi_recovflags: %b\n", mi->mi_recovflags, 844 nfs_mi4_recover); 845 mdb_printf("mi_recovthread: %p\n", mi->mi_recovthread); 846 mdb_printf("mi_in_recovery: %d\n", mi->mi_in_recovery); 847 848 if (verbose == 0) 849 return; 850 851 mdb_printf("mi_zone: %p\n", mi->mi_zone); 852 mdb_printf("mi_curread: %d\n", mi->mi_curread); 853 mdb_printf("mi_curwrite: %d\n", mi->mi_curwrite); 854 mdb_printf("mi_retrans: %d\n", mi->mi_retrans); 855 mdb_printf("mi_timeo: %d\n", mi->mi_timeo); 856 mdb_printf("mi_acregmin: %llu\n", mi->mi_acregmin); 857 mdb_printf("mi_acregmax: %llu\n", mi->mi_acregmax); 858 mdb_printf("mi_acdirmin: %llu\n", mi->mi_acdirmin); 859 mdb_printf("mi_acdirmax: %llu\n", mi->mi_acdirmax); 860 mdb_printf("mi_count: %u\n", mi->mi_count); 861 mdb_printf("\nServer list: %p\n", mi->mi_servers); 862 nfs_addr_by_servinfo4((uintptr_t)mi->mi_curr_serv, str, sizeof (str)); 863 mdb_printf("Curr Server: %p %s\n", mi->mi_curr_serv, str); 864 mdb_printf("Total:\n"); 865 mdb_inc_indent(2); 866 mdb_printf("Server Non-responses: %u\n", mi->mi_noresponse); 867 mdb_printf("Server Failovers: %u\n\n", mi->mi_failover); 868 mdb_dec_indent(2); 869 870 mdb_printf("\nAsync Request queue:\n"); 871 mdb_inc_indent(2); 872 mdb_printf("max threads: %u\n", mi->mi_max_threads); 873 mdb_printf("active threads: %u\n", mi->mi_threads[NFS_ASYNC_QUEUE]); 874 mdb_dec_indent(2); 875 876 nfs4_print_messages(miaddr + OFFSETOF(mntinfo4_t, mi_msg_list)); 877 } 878 879 static void 880 nfs_print_mi(uintptr_t miaddr, uint_t vers) 881 { 882 mntinfo_t *mi; 883 char str[INET6_ADDRSTRLEN] = ""; 884 885 mi = mdb_alloc(sizeof (*mi), UM_SLEEP | UM_GC); 886 if (mdb_vread(mi, sizeof (*mi), miaddr) == -1) { 887 mdb_warn("can't read mntinfo"); 888 return; 889 } 890 891 mdb_printf("\nServer list: %p\n", mi->mi_servers); 892 nfs_addr_by_servinfo((uintptr_t)mi->mi_curr_serv, str, sizeof (str)); 893 mdb_printf("Curr Server: %p %s\n", mi->mi_curr_serv, str); 894 mdb_printf("Total:\n"); 895 mdb_inc_indent(2); 896 mdb_printf("Server Non-responses: %u\n", mi->mi_noresponse); 897 mdb_printf("Server Failovers: %u\n\n", mi->mi_failover); 898 mdb_dec_indent(2); 899 900 mdb_printf("\nAsync Request queue:\n"); 901 mdb_inc_indent(2); 902 mdb_printf("max threads: %u\n", mi->mi_max_threads); 903 mdb_printf("active threads: %u\n", mi->mi_threads[NFS_ASYNC_QUEUE]); 904 mdb_dec_indent(2); 905 } 906 907 static int 908 nfs_vfs_dcmd(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv) 909 { 910 vfs_t *vfs; 911 char buf[MAXNAMELEN]; 912 int verbose = 0; 913 914 if ((flags & DCMD_ADDRSPEC) == 0) { 915 if (mdb_walk_dcmd("nfs_vfs", "nfs_vfs", argc, argv) == -1) { 916 mdb_warn("failed to walk nfs_vfs"); 917 return (DCMD_ERR); 918 } 919 return (DCMD_OK); 920 } 921 922 if (mdb_getopts(argc, argv, 923 'v', MDB_OPT_SETBITS, TRUE, &verbose, NULL) != argc) 924 return (DCMD_USAGE); 925 926 vfs = mdb_alloc(sizeof (*vfs), UM_SLEEP | UM_GC); 927 928 if (mdb_vread(vfs, sizeof (*vfs), addr) == -1) { 929 mdb_warn("failed to read vfs"); 930 return (DCMD_ERR); 931 } 932 933 mdb_printf("vfs_t->%p, data = %p, ops = %p\n", 934 addr, vfs->vfs_data, vfs->vfs_op); 935 936 /* do not need do vread for vfs_mntpt because take address */ 937 if (mdb_readstr(buf, MAXNAMELEN, 938 (uintptr_t)&vfs->vfs_mntpt->rs_string) == -1) 939 return (DCMD_ERR); 940 941 mdb_inc_indent(2); 942 943 mdb_printf("mount point: %s\n", buf); 944 if (mdb_readstr(buf, MAXNAMELEN, 945 (uintptr_t)&vfs->vfs_resource->rs_string) == -1) { 946 mdb_warn("can't read rs_string"); 947 goto err; 948 } 949 mdb_printf("mount from: %s\n", buf); 950 951 if (verbose) { 952 uintptr_t nfs4_ops; 953 mntopt_t m; 954 uint_t i; 955 956 mdb_printf("vfs_flags: %b\n", vfs->vfs_flag, vfs_flags); 957 mdb_printf("mount opts: "); 958 for (i = 0; i < vfs->vfs_mntopts.mo_count; i++) { 959 uintptr_t a = (uintptr_t)(vfs->vfs_mntopts.mo_list + i); 960 961 if (mdb_vread(&m, sizeof (m), a) == -1) { 962 mdb_warn("can't read mntopt"); 963 continue; 964 } 965 if (m.mo_flags & MO_EMPTY) 966 continue; 967 968 if (mdb_readstr(buf, sizeof (buf), 969 (uintptr_t)m.mo_name) == -1) { 970 mdb_warn("can't read mo_name"); 971 continue; 972 } 973 if (m.mo_flags & MO_HASVALUE) { 974 char val[64]; 975 976 if (mdb_readstr(val, sizeof (val), 977 (uintptr_t)m.mo_arg) == -1) { 978 mdb_warn("can't read mo_arg"); 979 continue; 980 } 981 mdb_printf("%s(%s), ", buf, val); 982 } else 983 mdb_printf("%s, ", buf); 984 } 985 mdb_printf("\n+--------------------------------------+\n"); 986 987 if (mdb_readvar(&nfs4_ops, "nfs4_vfsops") == -1) { 988 mdb_warn("failed read %s", "nfs4_vfsops"); 989 goto err; 990 } 991 if (nfs4_ops == (uintptr_t)vfs->vfs_op) { 992 nfs_print_mi4((uintptr_t)VFTOMI4(vfs), 1); 993 } else { 994 int vers = 3; 995 uintptr_t nfs3_ops; 996 997 if (mdb_readvar(&nfs3_ops, "nfs3_vfsops") == -1) { 998 mdb_warn("failed read %s", "nfs3_vfsops"); 999 goto err; 1000 } 1001 if (nfs3_ops != (uintptr_t)vfs->vfs_op) 1002 vers = 2; 1003 1004 nfs_print_mi((uintptr_t)VFTOMI(vfs), vers); 1005 } 1006 } 1007 mdb_dec_indent(2); 1008 mdb_printf("\n"); 1009 return (DCMD_OK); 1010 err: 1011 mdb_dec_indent(2); 1012 mdb_printf("\n"); 1013 return (DCMD_ERR); 1014 } 1015 1016 1017 static int 1018 nfs4_diag_dcmd(uintptr_t addr, uint_t flags, int argc, 1019 const mdb_arg_t *argv) 1020 { 1021 mntinfo4_t *mi; 1022 vfs_t *vfs; 1023 char buf[MAXNAMELEN]; 1024 1025 if ((flags & DCMD_ADDRSPEC) == 0) { 1026 if (mdb_walk_dcmd("nfs4_mnt", "nfs4_diag", argc, 1027 argv) == -1) { 1028 mdb_warn("failed to walk nfs4_mnt"); 1029 return (DCMD_ERR); 1030 } 1031 return (DCMD_OK); 1032 } 1033 1034 mi = mdb_alloc(sizeof (*mi), UM_SLEEP | UM_GC); 1035 if (mdb_vread(mi, sizeof (*mi), addr) == -1) { 1036 mdb_warn("can't read mntinfo4"); 1037 return (WALK_ERR); 1038 } 1039 1040 vfs = mdb_alloc(sizeof (*vfs), UM_SLEEP | UM_GC); 1041 if (mdb_vread(vfs, sizeof (*vfs), (uintptr_t)mi->mi_vfsp) == -1) { 1042 mdb_warn("failed to read vfs"); 1043 return (DCMD_ERR); 1044 } 1045 1046 mdb_printf("****************************************\n"); 1047 mdb_printf("vfs: %-16p mi: %-16p\n", mi->mi_vfsp, addr); 1048 1049 if (mdb_readstr(buf, MAXNAMELEN, 1050 (uintptr_t)&vfs->vfs_mntpt->rs_string) == -1) 1051 return (DCMD_ERR); 1052 1053 mdb_inc_indent(2); 1054 mdb_printf("mount point: %s\n", buf); 1055 if (mdb_readstr(buf, MAXNAMELEN, 1056 (uintptr_t)&vfs->vfs_resource->rs_string) == -1) { 1057 mdb_warn("can't read rs_string"); 1058 mdb_dec_indent(2); 1059 return (DCMD_ERR); 1060 } 1061 mdb_printf("mount from: %s\n", buf); 1062 nfs4_print_messages(addr + OFFSETOF(mntinfo4_t, mi_msg_list)); 1063 mdb_dec_indent(2); 1064 mdb_printf("\n"); 1065 return (DCMD_OK); 1066 } 1067 1068 static void 1069 nfs4_diag_help(void) 1070 { 1071 mdb_printf(" <mntinfo4_t>::nfs4_diag <-s>\n" 1072 " -> assumes client is an illumos NFSv4 client\n"); 1073 } 1074 1075 static int 1076 nfs_rnode4_cb(uintptr_t addr, const void *data, void *arg) 1077 { 1078 const rnode4_t *rp = data; 1079 nfs_rnode_cbdata_t *cbd = arg; 1080 vnode_t *vp; 1081 1082 if (addr == 0) 1083 return (WALK_DONE); 1084 1085 vp = mdb_alloc(sizeof (*vp), UM_SLEEP | UM_GC); 1086 if (mdb_vread(vp, sizeof (*vp), (uintptr_t)rp->r_vnode) == -1) { 1087 mdb_warn("can't read vnode_t %p", (uintptr_t)rp->r_vnode); 1088 return (WALK_ERR); 1089 } 1090 1091 if (cbd->vfs_addr != 0 && 1092 cbd->vfs_addr != (uintptr_t)vp->v_vfsp) 1093 return (WALK_NEXT); 1094 1095 if (cbd->printed_hdr == 0) { 1096 mdb_printf("%-16s %-16s %-16s %-8s\n" 1097 "%-16s %-8s %-8s %s\n", 1098 "Address", "r_vnode", "vfsp", "r_fh", 1099 "r_server", "r_error", "r_flags", "r_count"); 1100 cbd->printed_hdr = 1; 1101 } 1102 1103 mdb_printf("%-?p %-8p %-8p %-8p\n" 1104 "%-16p %-8u %-8x %u\n", 1105 addr, rp->r_vnode, vp->v_vfsp, rp->r_fh, 1106 rp->r_server, (int)rp->r_error, rp->r_flags, rp->r_count); 1107 1108 return (WALK_NEXT); 1109 } 1110 1111 static int 1112 nfs_rnode4_dcmd(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv) 1113 { 1114 nfs_rnode_cbdata_t *cbd; 1115 rnode4_t *rp; 1116 1117 cbd = mdb_zalloc(sizeof (*cbd), UM_SLEEP | UM_GC); 1118 1119 if ((flags & DCMD_ADDRSPEC) == 0) { 1120 if (mdb_walk("nfs_rtable4", nfs_rnode4_cb, cbd) == -1) { 1121 mdb_warn("failed to walk nfs_rnode4"); 1122 return (DCMD_ERR); 1123 } 1124 return (DCMD_OK); 1125 } 1126 1127 /* address was specified */ 1128 rp = mdb_alloc(sizeof (*rp), UM_SLEEP | UM_GC); 1129 if (mdb_vread(rp, sizeof (*rp), addr) == -1) { 1130 mdb_warn("can't read rnode4_t"); 1131 return (DCMD_ERR); 1132 } 1133 1134 nfs_rnode4_cb(addr, rp, cbd); 1135 return (DCMD_OK); 1136 } 1137 1138 static void 1139 nfs_rnode4_help(void) 1140 { 1141 mdb_printf("<rnode4 addr>::nfs_rnode4\n\n" 1142 "This prints NFSv4 rnode at address specified. If address\n" 1143 "is not specified, walks entire NFSv4 rnode table.\n"); 1144 } 1145 1146 static int 1147 nfs_rnode4find_dcmd(uintptr_t addr, uint_t flags, int argc, 1148 const mdb_arg_t *argv) 1149 { 1150 nfs_rnode_cbdata_t *cbd; 1151 1152 cbd = mdb_zalloc(sizeof (*cbd), UM_SLEEP | UM_GC); 1153 1154 if ((flags & DCMD_ADDRSPEC) == 0) { 1155 mdb_printf("requires address of vfs_t\n"); 1156 return (DCMD_USAGE); 1157 } 1158 1159 cbd->vfs_addr = addr; 1160 if (mdb_walk("nfs_rtable4", nfs_rnode4_cb, cbd) == -1) { 1161 mdb_warn("failed to walk nfs_rnode4"); 1162 return (DCMD_ERR); 1163 } 1164 return (DCMD_OK); 1165 } 1166 1167 static void 1168 nfs_rnode4find_help(void) 1169 { 1170 mdb_printf("<vfs addr>::nfs_rnode4find\n\n" 1171 "This prints all NFSv4 rnodes that belong to\n" 1172 "the VFS address specified\n"); 1173 } 1174 1175 static int nfs_help_dcmd(uintptr_t, uint_t, int, const mdb_arg_t *); 1176 1177 extern int nfs_stat_dcmd(uintptr_t, uint_t, int, const mdb_arg_t *); 1178 1179 static const mdb_dcmd_t dcmds[] = { 1180 /* svc */ 1181 { 1182 "svc_pool", "?[-v] [poolid ...]", 1183 "display SVCPOOL information\n" 1184 "\t\t\t(Optional address of SVCPOOL)", 1185 svc_pool_dcmd, svc_pool_help 1186 }, 1187 { 1188 "svc_mxprt", ":[-w]", 1189 "display master xprt info given SVCMASTERXPRT", 1190 svc_mxprt_dcmd, svc_mxprt_help 1191 }, 1192 /* rfs4 */ 1193 { 1194 "rfs4_db", "?", 1195 "dump NFSv4 server database\n" 1196 "\t\t\t(Optional address of zone_t)", 1197 rfs4_db_dcmd 1198 }, 1199 { 1200 "rfs4_tbl", ":[-vw]", 1201 "dump NFSv4 server table given rfs4_table_t", 1202 rfs4_tbl_dcmd, rfs4_tbl_help 1203 }, 1204 { 1205 "rfs4_idx", ":[-w]", 1206 "dump NFSv4 server index given rfs4_index_t", 1207 rfs4_idx_dcmd, rfs4_idx_help 1208 }, 1209 { 1210 "rfs4_bkt", ":", 1211 "dump NFSv4 server index buckets given rfs4_index_t", 1212 rfs4_bkt_dcmd 1213 }, 1214 { 1215 "rfs4_oo", "?", 1216 "dump NFSv4 rfs4_openowner_t structures from bucket data\n" 1217 "\t\t\t(Optional address of rfs4_openowner_t)", 1218 rfs4_oo_dcmd 1219 }, 1220 { 1221 "rfs4_osid", "?[-v]", 1222 "dump NFSv4 rfs4_state_t structures from bucket data\n" 1223 "\t\t\t(Optional address of rfs4_state_t)", 1224 rfs4_osid_dcmd 1225 }, 1226 { 1227 "rfs4_file", "?[-v]", 1228 "dump NFSv4 rfs4_file_t structures from bucket data\n" 1229 "\t\t\t(Optional address of rfs4_file_t)", 1230 rfs4_file_dcmd 1231 }, 1232 { 1233 "rfs4_deleg", "?[-v]", 1234 "dump NFSv4 rfs4_deleg_state_t structures from bucket data\n" 1235 "\t\t\t(Optional address of rfs4_deleg_state_t)", 1236 rfs4_deleg_dcmd 1237 }, 1238 { 1239 "rfs4_lo", "?", 1240 "dump NFSv4 rfs4_lockowner_t structures from bucket data\n" 1241 "\t\t\t(Optional address of rfs4_lockowner_t)", 1242 rfs4_lo_dcmd 1243 }, 1244 { 1245 "rfs4_lsid", "?[-v]", 1246 "dump NFSv4 rfs4_lo_state_t structures from bucket data\n" 1247 "\t\t\t(Optional address of rfs4_lo_state_t)", 1248 rfs4_lsid_dcmd 1249 }, 1250 { 1251 "rfs4_client", "?[-c <clientid>]", 1252 "dump NFSv4 rfs4_client_t structures from bucket data\n" 1253 "\t\t\t(Optional address of rfs4_client_t)", 1254 rfs4_client_dcmd, rfs4_client_help 1255 }, 1256 /* NFS server */ 1257 { 1258 "nfs_expvis", ":", 1259 "dump exp_visible_t structure", 1260 nfs_expvis_dcmd 1261 }, 1262 { 1263 "nfs_expinfo", ":", 1264 "dump struct exportinfo", 1265 nfs_expinfo_dcmd 1266 }, 1267 { 1268 "nfs_exptable", "?", 1269 "dump exportinfo structures for a zone\n" 1270 "\t\t\t(Optional address of zone_t)", 1271 nfs_exptable_dcmd 1272 }, 1273 { 1274 "nfs_exptable_path", "?", 1275 "dump exportinfo structures for a zone\n" 1276 "\t\t\t(Optional address of zone_t)", 1277 nfs_exptable_path_dcmd 1278 }, 1279 { 1280 "nfs_nstree", "?[-v]", 1281 "dump NFS server pseudo namespace tree for a zone\n" 1282 "\t\t\t(Optional address of zone_t)", 1283 nfs_nstree_dcmd, nfs_nstree_help 1284 }, 1285 { 1286 "nfs_fid_hashdist", ":[-v]", 1287 "show fid hash distribution of the exportinfo table", 1288 nfs_fid_hashdist_dcmd, nfs_hashdist_help 1289 }, 1290 { 1291 "nfs_path_hashdist", "[-v]", 1292 "show path hash distribution of the exportinfo table", 1293 nfs_path_hashdist_dcmd, nfs_hashdist_help 1294 }, 1295 /* NFSv4 idmap */ 1296 { 1297 "nfs4_idmap", ":", 1298 "dump nfsidmap_t", 1299 nfs4_idmap_dcmd 1300 }, 1301 { 1302 "nfs4_idmap_info", "?[u2s | g2s | s2u | s2g ...]", 1303 "dump NFSv4 idmap information\n" 1304 "\t\t\t(Optional address of zone_t)", 1305 nfs4_idmap_info_dcmd, nfs4_idmap_info_help 1306 }, 1307 /* NFS client */ 1308 { 1309 "nfs_mntinfo", "?[-v]", 1310 "print mntinfo_t information\n" 1311 "\t\t\t(Optional address of mntinfo_t)", 1312 nfs_mntinfo_dcmd, nfs_mntinfo_help 1313 }, 1314 { 1315 "nfs_servinfo", ":[-v]", 1316 "print servinfo_t information", 1317 nfs_servinfo_dcmd, nfs_servinfo_help 1318 }, 1319 /* WIP */ 1320 { 1321 "nfs4_mntinfo", "?[-mv]", 1322 "print mntinfo4_t information\n" 1323 "\t\t\t(Optional address of mntinfo4_t)", 1324 nfs4_mntinfo_dcmd, nfs4_mntinfo_help 1325 }, 1326 { 1327 "nfs4_servinfo", ":[-v]", 1328 "print servinfo4_t information", 1329 nfs4_servinfo_dcmd, nfs4_servinfo_help 1330 }, 1331 { 1332 "nfs4_server_info", "?[-cs]", 1333 "print nfs4_server_t information", 1334 nfs4_server_info_dcmd, nfs4_server_info_help 1335 }, 1336 /* WIP */ 1337 { 1338 "nfs4_mimsg", ":[-s]", 1339 "print queued messages for given address of mi_msg_list", 1340 nfs4_mimsg_dcmd, nfs4_mimsg_help 1341 }, 1342 { 1343 "nfs4_fname", ":", 1344 "print path name of nfs4_fname_t specified", 1345 nfs4_fname_dcmd 1346 }, 1347 { 1348 "nfs4_svnode", ":", 1349 "print svnode_t info at specified address", 1350 nfs4_svnode_dcmd 1351 }, 1352 1353 1354 /* NFSv2/3/4 clnt */ 1355 { 1356 "nfs_vfs", "?[-v]", 1357 "print all nfs vfs struct (-v for mntinfo)\n" 1358 "\t\t\t(Optional address of vfs_t)", 1359 nfs_vfs_dcmd 1360 }, 1361 1362 1363 /* NFSv4 clnt */ 1364 { 1365 "nfs_rnode4", "?", 1366 "dump NFSv4 rnodes\n" 1367 "\t\t\t(Optional address of rnode4_t)", 1368 nfs_rnode4_dcmd, nfs_rnode4_help 1369 }, 1370 { 1371 "nfs4_diag", "?[-s]", 1372 "print queued recovery messages for NFSv4 client\n" 1373 "\t\t\t(Optional address of mntinfo4_t)", 1374 nfs4_diag_dcmd, nfs4_diag_help 1375 }, 1376 { 1377 "nfs_rnode4find", ":", 1378 "dump NFSv4 rnodes for given vfs_t", 1379 nfs_rnode4find_dcmd, nfs_rnode4find_help 1380 }, 1381 { 1382 "nfs4_foo", ":[-v]", 1383 "dump free open owners for NFSv4 client", 1384 nfs4_foo_dcmd 1385 }, 1386 { 1387 "nfs4_oob", ":[-v]", 1388 "dump open owners for NFSv4 client", 1389 nfs4_oob_dcmd 1390 }, 1391 { 1392 "nfs4_os", "?[-v]", 1393 "dump open streams for NFSv4 Client\n" 1394 "\t\t\t(Optional address of rnode4_t)", 1395 nfs4_os_dcmd 1396 }, 1397 1398 /* generic commands */ 1399 { 1400 "nfs_stat", "?[-csb][-234][-anr] | $[count]", 1401 "Print NFS statistics for zone\n" 1402 "\t\t\t(Optional address of zone_t)", 1403 nfs_stat_dcmd 1404 }, 1405 { 1406 "nfs_help", "[-dw]", 1407 "Show nfs commands", 1408 nfs_help_dcmd 1409 }, 1410 1411 {NULL, NULL, NULL, NULL} 1412 }; 1413 1414 static const mdb_walker_t walkers[] = { 1415 /* svc */ 1416 { 1417 "svc_pool", "walk SVCPOOL structs for given zone", 1418 svc_pool_walk_init, svc_pool_walk_step 1419 }, 1420 { 1421 "svc_mxprt", "walk master xprts", 1422 svc_mxprt_walk_init, svc_mxprt_walk_step 1423 }, 1424 /* rfs4 */ 1425 { 1426 "rfs4_db_tbl", "walk NFSv4 server rfs4_table_t structs", 1427 rfs4_db_tbl_walk_init, rfs4_db_tbl_walk_step 1428 }, 1429 { 1430 "rfs4_db_idx", "walk NFSv4 server rfs4_index_t structs", 1431 rfs4_db_idx_walk_init, rfs4_db_idx_walk_step 1432 }, 1433 { 1434 "rfs4_db_bkt", "walk NFSv4 server buckets for given index", 1435 rfs4_db_bkt_walk_init, rfs4_db_bkt_walk_step, 1436 rfs4_db_bkt_walk_fini 1437 }, 1438 /* NFS server */ 1439 { 1440 "nfs_expinfo", "walk exportinfo structures from the exptable", 1441 nfs_expinfo_walk_init, hash_table_walk_step, 1442 nfs_expinfo_walk_fini, &nfs_expinfo_arg 1443 }, 1444 { 1445 "nfs_expinfo_path", 1446 "walk exportinfo structures from the exptable_path_hash", 1447 nfs_expinfo_walk_init, hash_table_walk_step, 1448 nfs_expinfo_walk_fini, &nfs_expinfo_path_arg 1449 }, 1450 { 1451 "nfs_expvis", "walk list of exp_visible structs", 1452 nfs_expvis_walk_init, nfs_expvis_walk_step 1453 }, 1454 { 1455 "nfssrv_globals", "walk list of zones NFS globals", 1456 nfssrv_globals_walk_init, nfssrv_globals_walk_step 1457 }, 1458 /* NFSv4 idmap */ 1459 { 1460 "nfs4_u2s", "walk uid-to-string idmap cache for given zone", 1461 nfs4_idmap_walk_init, hash_table_walk_step, 1462 nfs4_idmap_walk_fini, 1463 (void *)OFFSETOF(struct nfsidmap_globals, u2s_ci) 1464 }, 1465 { 1466 "nfs4_s2u", "walk string-to-uid idmap cache for given zone", 1467 nfs4_idmap_walk_init, hash_table_walk_step, 1468 nfs4_idmap_walk_fini, 1469 (void *)OFFSETOF(struct nfsidmap_globals, s2u_ci) 1470 }, 1471 { 1472 "nfs4_g2s", "walk gid-to-string idmap cache for given zone", 1473 nfs4_idmap_walk_init, hash_table_walk_step, 1474 nfs4_idmap_walk_fini, 1475 (void *)OFFSETOF(struct nfsidmap_globals, g2s_ci) 1476 }, 1477 { 1478 "nfs4_s2g", "walk string-to-gid idmap cache for given zone", 1479 nfs4_idmap_walk_init, hash_table_walk_step, 1480 nfs4_idmap_walk_fini, 1481 (void *)OFFSETOF(struct nfsidmap_globals, s2g_ci) 1482 }, 1483 /* NFS client */ 1484 { 1485 "nfs_rtable", "walk rnodes in rtable cache", 1486 nfs_rtable_walk_init, hash_table_walk_step, 1487 hash_table_walk_fini, &nfs_rtable_arg 1488 }, 1489 { 1490 "nfs_rtable4", "walk rnode4s in rtable4 cache", 1491 nfs_rtable4_walk_init, hash_table_walk_step, 1492 hash_table_walk_fini, &nfs_rtable4_arg 1493 }, 1494 { 1495 "nfs_vfs", "walk NFS-mounted vfs structs", 1496 nfs_vfs_walk_init, nfs_vfs_walk_step, nfs_vfs_walk_fini 1497 }, 1498 { 1499 "nfs_mnt", "walk NFSv2/3-mounted vfs structs, pass mntinfo", 1500 nfs_mnt_walk_init, nfs_mnt_walk_step, nfs_mnt_walk_fini 1501 }, 1502 { 1503 "nfs4_mnt", "walk NFSv4-mounted vfs structs, pass mntinfo4", 1504 nfs4_mnt_walk_init, nfs4_mnt_walk_step, nfs4_mnt_walk_fini 1505 }, 1506 { 1507 "nfs_serv", "walk linkedlist of servinfo structs", 1508 nfs_serv_walk_init, nfs_serv_walk_step 1509 }, 1510 { 1511 "nfs4_serv", "walk linkedlist of servinfo4 structs", 1512 nfs4_serv_walk_init, nfs4_serv_walk_step 1513 }, 1514 { 1515 "nfs4_svnode", "walk svnode list at given svnode address", 1516 nfs4_svnode_walk_init, nfs4_svnode_walk_step 1517 }, 1518 { 1519 "nfs4_server", "walk nfs4_server_t structs", 1520 nfs4_server_walk_init, nfs4_server_walk_step 1521 }, 1522 { 1523 "nfs_async", "walk list of async requests", 1524 nfs_async_walk_init, nfs_async_walk_step 1525 }, 1526 { 1527 "nfs4_async", "walk list of NFSv4 async requests", 1528 nfs4_async_walk_init, nfs4_async_walk_step 1529 }, 1530 { 1531 "nfs_acache_rnode", "walk acache entries for a given rnode", 1532 nfs_acache_rnode_walk_init, nfs_acache_rnode_walk_step 1533 }, 1534 { 1535 "nfs_acache", "walk entire nfs_access_cache", 1536 nfs_acache_walk_init, hash_table_walk_step, nfs_acache_walk_fini 1537 }, 1538 { 1539 "nfs_acache4_rnode", 1540 "walk acache4 entries for a given NFSv4 rnode", 1541 nfs_acache4_rnode_walk_init, nfs_acache4_rnode_walk_step 1542 }, 1543 { 1544 "nfs_acache4", "walk entire nfs4_access_cache", 1545 nfs_acache4_walk_init, hash_table_walk_step, 1546 nfs_acache4_walk_fini 1547 }, 1548 1549 {NULL, NULL, NULL, NULL} 1550 }; 1551 1552 1553 static int 1554 nfs_help_dcmd(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv) 1555 { 1556 int i = 0; 1557 uint_t opt_d = FALSE; 1558 uint_t opt_w = FALSE; 1559 1560 if ((flags & DCMD_ADDRSPEC) != 0) 1561 return (DCMD_USAGE); 1562 1563 if (argc == 0) { 1564 mdb_printf("::nfs_help -w -d\n"); 1565 mdb_printf(" -w Will show nfs specific walkers\n"); 1566 mdb_printf(" -d Will show nfs specific dcmds\n"); 1567 return (DCMD_ERR); 1568 } 1569 1570 if (mdb_getopts(argc, argv, 1571 'd', MDB_OPT_SETBITS, TRUE, &opt_d, 1572 'w', MDB_OPT_SETBITS, TRUE, &opt_w, NULL) != argc) 1573 return (DCMD_USAGE); 1574 1575 if (opt_d) { 1576 for (i = 0; dcmds[i].dc_name != NULL; i++) 1577 mdb_printf("%-20s %s\n", dcmds[i].dc_name, 1578 dcmds[i].dc_descr); 1579 } 1580 if (opt_w) { 1581 for (i = 0; walkers[i].walk_name != NULL; i++) 1582 mdb_printf("%-20s %s\n", walkers[i].walk_name, 1583 walkers[i].walk_descr); 1584 } 1585 return (DCMD_OK); 1586 1587 } 1588 1589 static const mdb_modinfo_t modinfo = { 1590 MDB_API_VERSION, 1591 dcmds, 1592 walkers 1593 }; 1594 1595 const mdb_modinfo_t * 1596 _mdb_init(void) 1597 { 1598 return (&modinfo); 1599 } 1600