1*7c478bd9Sstevel@tonic-gate /* 2*7c478bd9Sstevel@tonic-gate * CDDL HEADER START 3*7c478bd9Sstevel@tonic-gate * 4*7c478bd9Sstevel@tonic-gate * The contents of this file are subject to the terms of the 5*7c478bd9Sstevel@tonic-gate * Common Development and Distribution License, Version 1.0 only 6*7c478bd9Sstevel@tonic-gate * (the "License"). You may not use this file except in compliance 7*7c478bd9Sstevel@tonic-gate * with the License. 8*7c478bd9Sstevel@tonic-gate * 9*7c478bd9Sstevel@tonic-gate * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 10*7c478bd9Sstevel@tonic-gate * or http://www.opensolaris.org/os/licensing. 11*7c478bd9Sstevel@tonic-gate * See the License for the specific language governing permissions 12*7c478bd9Sstevel@tonic-gate * and limitations under the License. 13*7c478bd9Sstevel@tonic-gate * 14*7c478bd9Sstevel@tonic-gate * When distributing Covered Code, include this CDDL HEADER in each 15*7c478bd9Sstevel@tonic-gate * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 16*7c478bd9Sstevel@tonic-gate * If applicable, add the following below this CDDL HEADER, with the 17*7c478bd9Sstevel@tonic-gate * fields enclosed by brackets "[]" replaced with your own identifying 18*7c478bd9Sstevel@tonic-gate * information: Portions Copyright [yyyy] [name of copyright owner] 19*7c478bd9Sstevel@tonic-gate * 20*7c478bd9Sstevel@tonic-gate * CDDL HEADER END 21*7c478bd9Sstevel@tonic-gate */ 22*7c478bd9Sstevel@tonic-gate /* 23*7c478bd9Sstevel@tonic-gate * Copyright 2005 Sun Microsystems, Inc. All rights reserved. 24*7c478bd9Sstevel@tonic-gate * Use is subject to license terms. 25*7c478bd9Sstevel@tonic-gate */ 26*7c478bd9Sstevel@tonic-gate 27*7c478bd9Sstevel@tonic-gate #pragma ident "%Z%%M% %I% %E% SMI" 28*7c478bd9Sstevel@tonic-gate 29*7c478bd9Sstevel@tonic-gate #include <sys/cred.h> 30*7c478bd9Sstevel@tonic-gate #include <sys/kstat.h> 31*7c478bd9Sstevel@tonic-gate #include <sys/list.h> 32*7c478bd9Sstevel@tonic-gate #include <sys/systm.h> 33*7c478bd9Sstevel@tonic-gate #include <sys/vfs.h> 34*7c478bd9Sstevel@tonic-gate #include <sys/vnode.h> 35*7c478bd9Sstevel@tonic-gate #include <sys/cmn_err.h> 36*7c478bd9Sstevel@tonic-gate 37*7c478bd9Sstevel@tonic-gate #include <nfs/nfs4_clnt.h> 38*7c478bd9Sstevel@tonic-gate #include <nfs/rnode4.h> 39*7c478bd9Sstevel@tonic-gate 40*7c478bd9Sstevel@tonic-gate /* 41*7c478bd9Sstevel@tonic-gate * Recovery kstats 42*7c478bd9Sstevel@tonic-gate */ 43*7c478bd9Sstevel@tonic-gate typedef struct rkstat { 44*7c478bd9Sstevel@tonic-gate kstat_named_t badhandle; 45*7c478bd9Sstevel@tonic-gate kstat_named_t badowner; 46*7c478bd9Sstevel@tonic-gate kstat_named_t clientid; 47*7c478bd9Sstevel@tonic-gate kstat_named_t dead_file; 48*7c478bd9Sstevel@tonic-gate kstat_named_t delay; 49*7c478bd9Sstevel@tonic-gate kstat_named_t fail_relock; 50*7c478bd9Sstevel@tonic-gate kstat_named_t file_diff; 51*7c478bd9Sstevel@tonic-gate kstat_named_t no_grace; 52*7c478bd9Sstevel@tonic-gate kstat_named_t not_responding; 53*7c478bd9Sstevel@tonic-gate kstat_named_t opens_changed; 54*7c478bd9Sstevel@tonic-gate kstat_named_t siglost; 55*7c478bd9Sstevel@tonic-gate kstat_named_t unexp_action; 56*7c478bd9Sstevel@tonic-gate kstat_named_t unexp_errno; 57*7c478bd9Sstevel@tonic-gate kstat_named_t unexp_status; 58*7c478bd9Sstevel@tonic-gate kstat_named_t wrongsec; 59*7c478bd9Sstevel@tonic-gate kstat_named_t lost_state_bad_op; 60*7c478bd9Sstevel@tonic-gate } rkstat_t; 61*7c478bd9Sstevel@tonic-gate 62*7c478bd9Sstevel@tonic-gate static rkstat_t rkstat_template = { 63*7c478bd9Sstevel@tonic-gate { "badhandle", KSTAT_DATA_ULONG }, 64*7c478bd9Sstevel@tonic-gate { "badowner", KSTAT_DATA_ULONG }, 65*7c478bd9Sstevel@tonic-gate { "clientid", KSTAT_DATA_ULONG }, 66*7c478bd9Sstevel@tonic-gate { "dead_file", KSTAT_DATA_ULONG }, 67*7c478bd9Sstevel@tonic-gate { "delay", KSTAT_DATA_ULONG }, 68*7c478bd9Sstevel@tonic-gate { "fail_relock", KSTAT_DATA_ULONG }, 69*7c478bd9Sstevel@tonic-gate { "file_diff", KSTAT_DATA_ULONG }, 70*7c478bd9Sstevel@tonic-gate { "no_grace", KSTAT_DATA_ULONG }, 71*7c478bd9Sstevel@tonic-gate { "not_responding", KSTAT_DATA_ULONG }, 72*7c478bd9Sstevel@tonic-gate { "opens_changed", KSTAT_DATA_ULONG }, 73*7c478bd9Sstevel@tonic-gate { "siglost", KSTAT_DATA_ULONG }, 74*7c478bd9Sstevel@tonic-gate { "unexp_action", KSTAT_DATA_ULONG }, 75*7c478bd9Sstevel@tonic-gate { "unexp_errno", KSTAT_DATA_ULONG }, 76*7c478bd9Sstevel@tonic-gate { "unexp_status", KSTAT_DATA_ULONG }, 77*7c478bd9Sstevel@tonic-gate { "wrongsec", KSTAT_DATA_ULONG }, 78*7c478bd9Sstevel@tonic-gate { "bad_op", KSTAT_DATA_ULONG }, 79*7c478bd9Sstevel@tonic-gate }; 80*7c478bd9Sstevel@tonic-gate 81*7c478bd9Sstevel@tonic-gate /* maximum number of messages allowed on the mi's mi_msg_list */ 82*7c478bd9Sstevel@tonic-gate int nfs4_msg_max = NFS4_MSG_MAX; 83*7c478bd9Sstevel@tonic-gate #define DEFAULT_LEASE 180 84*7c478bd9Sstevel@tonic-gate 85*7c478bd9Sstevel@tonic-gate static char *strdup(const char *); 86*7c478bd9Sstevel@tonic-gate 87*7c478bd9Sstevel@tonic-gate /* 88*7c478bd9Sstevel@tonic-gate * Sets the appropiate fields of "ep", given "id" and various parameters. 89*7c478bd9Sstevel@tonic-gate * Assumes that ep's fields have been initialized to zero/null, except for 90*7c478bd9Sstevel@tonic-gate * re_type and mount point info, which are already set. 91*7c478bd9Sstevel@tonic-gate */ 92*7c478bd9Sstevel@tonic-gate static void 93*7c478bd9Sstevel@tonic-gate set_event(nfs4_event_type_t id, nfs4_revent_t *ep, mntinfo4_t *mi, 94*7c478bd9Sstevel@tonic-gate rnode4_t *rp1, rnode4_t *rp2, uint_t count, pid_t pid, nfsstat4 nfs4_error, 95*7c478bd9Sstevel@tonic-gate char *server1, char *why, nfs4_tag_type_t tag1, nfs4_tag_type_t tag2, 96*7c478bd9Sstevel@tonic-gate seqid4 seqid1, seqid4 seqid2) 97*7c478bd9Sstevel@tonic-gate { 98*7c478bd9Sstevel@tonic-gate int len; 99*7c478bd9Sstevel@tonic-gate 100*7c478bd9Sstevel@tonic-gate switch (id) { 101*7c478bd9Sstevel@tonic-gate case RE_BAD_SEQID: 102*7c478bd9Sstevel@tonic-gate ep->re_mi = mi; 103*7c478bd9Sstevel@tonic-gate 104*7c478bd9Sstevel@tonic-gate /* bad seqid'd file <path/component name> */ 105*7c478bd9Sstevel@tonic-gate if (rp1 && rp1->r_svnode.sv_name) 106*7c478bd9Sstevel@tonic-gate ep->re_char1 = fn_path(rp1->r_svnode.sv_name); 107*7c478bd9Sstevel@tonic-gate else 108*7c478bd9Sstevel@tonic-gate ep->re_char1 = NULL; 109*7c478bd9Sstevel@tonic-gate ep->re_rp1 = rp1; 110*7c478bd9Sstevel@tonic-gate 111*7c478bd9Sstevel@tonic-gate /* for LOCK/LOCKU */ 112*7c478bd9Sstevel@tonic-gate ep->re_pid = pid; 113*7c478bd9Sstevel@tonic-gate 114*7c478bd9Sstevel@tonic-gate ep->re_stat4 = nfs4_error; 115*7c478bd9Sstevel@tonic-gate ep->re_tag1 = tag1; 116*7c478bd9Sstevel@tonic-gate ep->re_tag2 = tag2; 117*7c478bd9Sstevel@tonic-gate ep->re_seqid1 = seqid1; 118*7c478bd9Sstevel@tonic-gate ep->re_seqid2 = seqid2; 119*7c478bd9Sstevel@tonic-gate break; 120*7c478bd9Sstevel@tonic-gate case RE_BADHANDLE: 121*7c478bd9Sstevel@tonic-gate ASSERT(rp1 != NULL); 122*7c478bd9Sstevel@tonic-gate 123*7c478bd9Sstevel@tonic-gate /* dead file <path/component name> */ 124*7c478bd9Sstevel@tonic-gate if (rp1->r_svnode.sv_name) 125*7c478bd9Sstevel@tonic-gate ep->re_char1 = fn_path(rp1->r_svnode.sv_name); 126*7c478bd9Sstevel@tonic-gate else 127*7c478bd9Sstevel@tonic-gate ep->re_char1 = NULL; 128*7c478bd9Sstevel@tonic-gate ep->re_rp1 = rp1; 129*7c478bd9Sstevel@tonic-gate break; 130*7c478bd9Sstevel@tonic-gate case RE_CLIENTID: 131*7c478bd9Sstevel@tonic-gate ep->re_mi = mi; 132*7c478bd9Sstevel@tonic-gate 133*7c478bd9Sstevel@tonic-gate /* the error we failed with */ 134*7c478bd9Sstevel@tonic-gate ep->re_uint = count; 135*7c478bd9Sstevel@tonic-gate ep->re_stat4 = nfs4_error; 136*7c478bd9Sstevel@tonic-gate break; 137*7c478bd9Sstevel@tonic-gate case RE_DEAD_FILE: 138*7c478bd9Sstevel@tonic-gate ASSERT(rp1 != NULL); 139*7c478bd9Sstevel@tonic-gate 140*7c478bd9Sstevel@tonic-gate /* dead file <path/component name> */ 141*7c478bd9Sstevel@tonic-gate if (rp1->r_svnode.sv_name) 142*7c478bd9Sstevel@tonic-gate ep->re_char1 = fn_path(rp1->r_svnode.sv_name); 143*7c478bd9Sstevel@tonic-gate else 144*7c478bd9Sstevel@tonic-gate ep->re_char1 = NULL; 145*7c478bd9Sstevel@tonic-gate ep->re_rp1 = rp1; 146*7c478bd9Sstevel@tonic-gate 147*7c478bd9Sstevel@tonic-gate /* why the file got killed */ 148*7c478bd9Sstevel@tonic-gate if (why) { 149*7c478bd9Sstevel@tonic-gate len = strlen(why); 150*7c478bd9Sstevel@tonic-gate ep->re_char2 = kmem_alloc(len + 1, KM_SLEEP); 151*7c478bd9Sstevel@tonic-gate bcopy(why, ep->re_char2, len); 152*7c478bd9Sstevel@tonic-gate ep->re_char2[len] = '\0'; 153*7c478bd9Sstevel@tonic-gate } else 154*7c478bd9Sstevel@tonic-gate ep->re_char2 = NULL; 155*7c478bd9Sstevel@tonic-gate 156*7c478bd9Sstevel@tonic-gate ep->re_stat4 = nfs4_error; 157*7c478bd9Sstevel@tonic-gate break; 158*7c478bd9Sstevel@tonic-gate case RE_END: 159*7c478bd9Sstevel@tonic-gate /* first rnode */ 160*7c478bd9Sstevel@tonic-gate if (rp1 && rp1->r_svnode.sv_name) 161*7c478bd9Sstevel@tonic-gate ep->re_char1 = fn_path(rp1->r_svnode.sv_name); 162*7c478bd9Sstevel@tonic-gate else 163*7c478bd9Sstevel@tonic-gate ep->re_char1 = NULL; 164*7c478bd9Sstevel@tonic-gate ep->re_rp1 = rp1; 165*7c478bd9Sstevel@tonic-gate 166*7c478bd9Sstevel@tonic-gate /* second rnode */ 167*7c478bd9Sstevel@tonic-gate if (rp2 && rp2->r_svnode.sv_name) 168*7c478bd9Sstevel@tonic-gate ep->re_char2 = fn_path(rp2->r_svnode.sv_name); 169*7c478bd9Sstevel@tonic-gate else 170*7c478bd9Sstevel@tonic-gate ep->re_char2 = NULL; 171*7c478bd9Sstevel@tonic-gate ep->re_rp2 = rp2; 172*7c478bd9Sstevel@tonic-gate 173*7c478bd9Sstevel@tonic-gate ep->re_mi = mi; 174*7c478bd9Sstevel@tonic-gate break; 175*7c478bd9Sstevel@tonic-gate case RE_FAIL_RELOCK: 176*7c478bd9Sstevel@tonic-gate ASSERT(rp1 != NULL); 177*7c478bd9Sstevel@tonic-gate 178*7c478bd9Sstevel@tonic-gate /* error on fail relock */ 179*7c478bd9Sstevel@tonic-gate ep->re_uint = count; 180*7c478bd9Sstevel@tonic-gate 181*7c478bd9Sstevel@tonic-gate /* process that failed */ 182*7c478bd9Sstevel@tonic-gate ep->re_pid = pid; 183*7c478bd9Sstevel@tonic-gate 184*7c478bd9Sstevel@tonic-gate /* nfs4 error */ 185*7c478bd9Sstevel@tonic-gate ep->re_stat4 = nfs4_error; 186*7c478bd9Sstevel@tonic-gate 187*7c478bd9Sstevel@tonic-gate /* file <path/component name> */ 188*7c478bd9Sstevel@tonic-gate if (rp1->r_svnode.sv_name) 189*7c478bd9Sstevel@tonic-gate ep->re_char1 = fn_path(rp1->r_svnode.sv_name); 190*7c478bd9Sstevel@tonic-gate else 191*7c478bd9Sstevel@tonic-gate ep->re_char1 = NULL; 192*7c478bd9Sstevel@tonic-gate ep->re_rp1 = rp1; 193*7c478bd9Sstevel@tonic-gate break; 194*7c478bd9Sstevel@tonic-gate case RE_FAIL_REMAP_LEN: 195*7c478bd9Sstevel@tonic-gate /* length of returned filehandle */ 196*7c478bd9Sstevel@tonic-gate ep->re_uint = count; 197*7c478bd9Sstevel@tonic-gate break; 198*7c478bd9Sstevel@tonic-gate case RE_FAIL_REMAP_OP: 199*7c478bd9Sstevel@tonic-gate break; 200*7c478bd9Sstevel@tonic-gate case RE_FAILOVER: 201*7c478bd9Sstevel@tonic-gate /* server we're failing over to (if not picking original) */ 202*7c478bd9Sstevel@tonic-gate if (server1 != NULL) { 203*7c478bd9Sstevel@tonic-gate len = strlen(server1); 204*7c478bd9Sstevel@tonic-gate ep->re_char1 = kmem_alloc(len + 1, KM_SLEEP); 205*7c478bd9Sstevel@tonic-gate bcopy(server1, ep->re_char1, len); 206*7c478bd9Sstevel@tonic-gate ep->re_char1[len] = '\0'; 207*7c478bd9Sstevel@tonic-gate } else { 208*7c478bd9Sstevel@tonic-gate ep->re_char1 = NULL; 209*7c478bd9Sstevel@tonic-gate } 210*7c478bd9Sstevel@tonic-gate break; 211*7c478bd9Sstevel@tonic-gate case RE_FILE_DIFF: 212*7c478bd9Sstevel@tonic-gate ASSERT(rp1 != NULL); 213*7c478bd9Sstevel@tonic-gate 214*7c478bd9Sstevel@tonic-gate /* dead file <path/component name> */ 215*7c478bd9Sstevel@tonic-gate if (rp1->r_svnode.sv_name) 216*7c478bd9Sstevel@tonic-gate ep->re_char1 = fn_path(rp1->r_svnode.sv_name); 217*7c478bd9Sstevel@tonic-gate else 218*7c478bd9Sstevel@tonic-gate ep->re_char1 = NULL; 219*7c478bd9Sstevel@tonic-gate ep->re_rp1 = rp1; 220*7c478bd9Sstevel@tonic-gate break; 221*7c478bd9Sstevel@tonic-gate case RE_LOST_STATE: 222*7c478bd9Sstevel@tonic-gate ep->re_uint = count; /* op number */ 223*7c478bd9Sstevel@tonic-gate if (rp1 && rp1->r_svnode.sv_name) 224*7c478bd9Sstevel@tonic-gate ep->re_char1 = fn_path(rp1->r_svnode.sv_name); 225*7c478bd9Sstevel@tonic-gate else 226*7c478bd9Sstevel@tonic-gate ep->re_char1 = NULL; 227*7c478bd9Sstevel@tonic-gate ep->re_rp1 = rp1; 228*7c478bd9Sstevel@tonic-gate if (rp2 && rp2->r_svnode.sv_name) 229*7c478bd9Sstevel@tonic-gate ep->re_char2 = fn_path(rp2->r_svnode.sv_name); 230*7c478bd9Sstevel@tonic-gate else 231*7c478bd9Sstevel@tonic-gate ep->re_char2 = NULL; 232*7c478bd9Sstevel@tonic-gate ep->re_rp2 = rp2; 233*7c478bd9Sstevel@tonic-gate break; 234*7c478bd9Sstevel@tonic-gate case RE_OPENS_CHANGED: 235*7c478bd9Sstevel@tonic-gate ep->re_mi = mi; 236*7c478bd9Sstevel@tonic-gate 237*7c478bd9Sstevel@tonic-gate /* original number of open files */ 238*7c478bd9Sstevel@tonic-gate ep->re_uint = count; 239*7c478bd9Sstevel@tonic-gate /* new number of open files */ 240*7c478bd9Sstevel@tonic-gate ep->re_pid = pid; 241*7c478bd9Sstevel@tonic-gate break; 242*7c478bd9Sstevel@tonic-gate case RE_SIGLOST: 243*7c478bd9Sstevel@tonic-gate case RE_SIGLOST_NO_DUMP: 244*7c478bd9Sstevel@tonic-gate ASSERT(rp1 != NULL); 245*7c478bd9Sstevel@tonic-gate 246*7c478bd9Sstevel@tonic-gate /* file <path/component name> */ 247*7c478bd9Sstevel@tonic-gate if (rp1->r_svnode.sv_name) 248*7c478bd9Sstevel@tonic-gate ep->re_char1 = fn_path(rp1->r_svnode.sv_name); 249*7c478bd9Sstevel@tonic-gate else 250*7c478bd9Sstevel@tonic-gate ep->re_char1 = NULL; 251*7c478bd9Sstevel@tonic-gate ep->re_rp1 = rp1; 252*7c478bd9Sstevel@tonic-gate ep->re_pid = pid; 253*7c478bd9Sstevel@tonic-gate ep->re_uint = count; 254*7c478bd9Sstevel@tonic-gate ep->re_stat4 = nfs4_error; 255*7c478bd9Sstevel@tonic-gate break; 256*7c478bd9Sstevel@tonic-gate case RE_START: 257*7c478bd9Sstevel@tonic-gate /* file <path/component name> */ 258*7c478bd9Sstevel@tonic-gate if (rp1 && rp1->r_svnode.sv_name) 259*7c478bd9Sstevel@tonic-gate ep->re_char1 = fn_path(rp1->r_svnode.sv_name); 260*7c478bd9Sstevel@tonic-gate else 261*7c478bd9Sstevel@tonic-gate ep->re_char1 = NULL; 262*7c478bd9Sstevel@tonic-gate ep->re_rp1 = rp1; 263*7c478bd9Sstevel@tonic-gate 264*7c478bd9Sstevel@tonic-gate /* file <path/component name> */ 265*7c478bd9Sstevel@tonic-gate if (rp2 && rp2->r_svnode.sv_name) 266*7c478bd9Sstevel@tonic-gate ep->re_char2 = fn_path(rp2->r_svnode.sv_name); 267*7c478bd9Sstevel@tonic-gate else 268*7c478bd9Sstevel@tonic-gate ep->re_char2 = NULL; 269*7c478bd9Sstevel@tonic-gate ep->re_rp2 = rp2; 270*7c478bd9Sstevel@tonic-gate 271*7c478bd9Sstevel@tonic-gate ep->re_mi = mi; 272*7c478bd9Sstevel@tonic-gate ep->re_uint = count; 273*7c478bd9Sstevel@tonic-gate break; 274*7c478bd9Sstevel@tonic-gate case RE_UNEXPECTED_ACTION: 275*7c478bd9Sstevel@tonic-gate case RE_UNEXPECTED_ERRNO: 276*7c478bd9Sstevel@tonic-gate /* the error that is unexpected */ 277*7c478bd9Sstevel@tonic-gate ep->re_uint = count; 278*7c478bd9Sstevel@tonic-gate break; 279*7c478bd9Sstevel@tonic-gate case RE_UNEXPECTED_STATUS: 280*7c478bd9Sstevel@tonic-gate /* nfsstat4 error */ 281*7c478bd9Sstevel@tonic-gate ep->re_stat4 = nfs4_error; 282*7c478bd9Sstevel@tonic-gate break; 283*7c478bd9Sstevel@tonic-gate case RE_WRONGSEC: 284*7c478bd9Sstevel@tonic-gate /* the error we failed with */ 285*7c478bd9Sstevel@tonic-gate ep->re_uint = count; 286*7c478bd9Sstevel@tonic-gate 287*7c478bd9Sstevel@tonic-gate /* file <path/component name> */ 288*7c478bd9Sstevel@tonic-gate if (rp1 && rp1->r_svnode.sv_name) 289*7c478bd9Sstevel@tonic-gate ep->re_char1 = fn_path(rp1->r_svnode.sv_name); 290*7c478bd9Sstevel@tonic-gate else 291*7c478bd9Sstevel@tonic-gate ep->re_char1 = NULL; 292*7c478bd9Sstevel@tonic-gate ep->re_rp1 = rp1; 293*7c478bd9Sstevel@tonic-gate 294*7c478bd9Sstevel@tonic-gate /* file <path/component name> */ 295*7c478bd9Sstevel@tonic-gate if (rp2 && rp2->r_svnode.sv_name) 296*7c478bd9Sstevel@tonic-gate ep->re_char2 = fn_path(rp2->r_svnode.sv_name); 297*7c478bd9Sstevel@tonic-gate else 298*7c478bd9Sstevel@tonic-gate ep->re_char2 = NULL; 299*7c478bd9Sstevel@tonic-gate ep->re_rp2 = rp2; 300*7c478bd9Sstevel@tonic-gate break; 301*7c478bd9Sstevel@tonic-gate case RE_LOST_STATE_BAD_OP: 302*7c478bd9Sstevel@tonic-gate ep->re_uint = count; /* the unexpected op */ 303*7c478bd9Sstevel@tonic-gate ep->re_pid = pid; 304*7c478bd9Sstevel@tonic-gate ep->re_rp1 = rp1; 305*7c478bd9Sstevel@tonic-gate if (rp1 != NULL && rp1->r_svnode.sv_name != NULL) 306*7c478bd9Sstevel@tonic-gate ep->re_char1 = fn_path(rp1->r_svnode.sv_name); 307*7c478bd9Sstevel@tonic-gate ep->re_rp2 = rp2; 308*7c478bd9Sstevel@tonic-gate if (rp2 != NULL && rp2->r_svnode.sv_name != NULL) 309*7c478bd9Sstevel@tonic-gate ep->re_char2 = fn_path(rp2->r_svnode.sv_name); 310*7c478bd9Sstevel@tonic-gate break; 311*7c478bd9Sstevel@tonic-gate default: 312*7c478bd9Sstevel@tonic-gate break; 313*7c478bd9Sstevel@tonic-gate } 314*7c478bd9Sstevel@tonic-gate } 315*7c478bd9Sstevel@tonic-gate 316*7c478bd9Sstevel@tonic-gate /* 317*7c478bd9Sstevel@tonic-gate * Sets the appropiate fields of the 'fact' for this 'id'. 318*7c478bd9Sstevel@tonic-gate */ 319*7c478bd9Sstevel@tonic-gate static void 320*7c478bd9Sstevel@tonic-gate set_fact(nfs4_fact_type_t id, nfs4_rfact_t *fp, nfsstat4 stat4, 321*7c478bd9Sstevel@tonic-gate nfs4_recov_t raction, nfs_opnum4 op, bool_t reboot, int error, 322*7c478bd9Sstevel@tonic-gate vnode_t *vp) 323*7c478bd9Sstevel@tonic-gate { 324*7c478bd9Sstevel@tonic-gate rnode4_t *rp1; 325*7c478bd9Sstevel@tonic-gate 326*7c478bd9Sstevel@tonic-gate switch (id) { 327*7c478bd9Sstevel@tonic-gate case RF_BADOWNER: 328*7c478bd9Sstevel@tonic-gate fp->rf_op = op; 329*7c478bd9Sstevel@tonic-gate fp->rf_reboot = reboot; 330*7c478bd9Sstevel@tonic-gate fp->rf_stat4 = stat4; 331*7c478bd9Sstevel@tonic-gate break; 332*7c478bd9Sstevel@tonic-gate case RF_RENEW_EXPIRED: 333*7c478bd9Sstevel@tonic-gate break; 334*7c478bd9Sstevel@tonic-gate case RF_ERR: 335*7c478bd9Sstevel@tonic-gate fp->rf_op = op; 336*7c478bd9Sstevel@tonic-gate fp->rf_reboot = reboot; 337*7c478bd9Sstevel@tonic-gate fp->rf_stat4 = stat4; 338*7c478bd9Sstevel@tonic-gate fp->rf_action = raction; 339*7c478bd9Sstevel@tonic-gate fp->rf_error = error; 340*7c478bd9Sstevel@tonic-gate break; 341*7c478bd9Sstevel@tonic-gate case RF_SRV_OK: 342*7c478bd9Sstevel@tonic-gate break; 343*7c478bd9Sstevel@tonic-gate case RF_SRV_NOT_RESPOND: 344*7c478bd9Sstevel@tonic-gate break; 345*7c478bd9Sstevel@tonic-gate case RF_SRVS_OK: 346*7c478bd9Sstevel@tonic-gate break; 347*7c478bd9Sstevel@tonic-gate case RF_SRVS_NOT_RESPOND: 348*7c478bd9Sstevel@tonic-gate gethrestime(&fp->rf_time); 349*7c478bd9Sstevel@tonic-gate break; 350*7c478bd9Sstevel@tonic-gate case RF_DELMAP_CB_ERR: 351*7c478bd9Sstevel@tonic-gate fp->rf_op = op; 352*7c478bd9Sstevel@tonic-gate fp->rf_stat4 = stat4; 353*7c478bd9Sstevel@tonic-gate 354*7c478bd9Sstevel@tonic-gate rp1 = VTOR4(vp); 355*7c478bd9Sstevel@tonic-gate fp->rf_rp1 = rp1; 356*7c478bd9Sstevel@tonic-gate if (rp1 && rp1->r_svnode.sv_name) 357*7c478bd9Sstevel@tonic-gate fp->rf_char1 = fn_path(rp1->r_svnode.sv_name); 358*7c478bd9Sstevel@tonic-gate else 359*7c478bd9Sstevel@tonic-gate fp->rf_char1 = NULL; 360*7c478bd9Sstevel@tonic-gate break; 361*7c478bd9Sstevel@tonic-gate default: 362*7c478bd9Sstevel@tonic-gate zcmn_err(getzoneid(), CE_NOTE, "illegal fact %d", id); 363*7c478bd9Sstevel@tonic-gate break; 364*7c478bd9Sstevel@tonic-gate } 365*7c478bd9Sstevel@tonic-gate } 366*7c478bd9Sstevel@tonic-gate 367*7c478bd9Sstevel@tonic-gate /* 368*7c478bd9Sstevel@tonic-gate * Returns 1 if the event/fact is of a successful communication 369*7c478bd9Sstevel@tonic-gate * from the server; 0 otherwise. 370*7c478bd9Sstevel@tonic-gate */ 371*7c478bd9Sstevel@tonic-gate static int 372*7c478bd9Sstevel@tonic-gate successful_comm(nfs4_debug_msg_t *msgp) 373*7c478bd9Sstevel@tonic-gate { 374*7c478bd9Sstevel@tonic-gate if (msgp->msg_type == RM_EVENT) { 375*7c478bd9Sstevel@tonic-gate switch (msgp->rmsg_u.msg_event.re_type) { 376*7c478bd9Sstevel@tonic-gate case RE_BAD_SEQID: 377*7c478bd9Sstevel@tonic-gate case RE_BADHANDLE: 378*7c478bd9Sstevel@tonic-gate case RE_FAIL_REMAP_LEN: 379*7c478bd9Sstevel@tonic-gate case RE_FAIL_REMAP_OP: 380*7c478bd9Sstevel@tonic-gate case RE_FILE_DIFF: 381*7c478bd9Sstevel@tonic-gate case RE_START: 382*7c478bd9Sstevel@tonic-gate case RE_UNEXPECTED_ACTION: 383*7c478bd9Sstevel@tonic-gate case RE_UNEXPECTED_ERRNO: 384*7c478bd9Sstevel@tonic-gate case RE_UNEXPECTED_STATUS: 385*7c478bd9Sstevel@tonic-gate case RE_WRONGSEC: 386*7c478bd9Sstevel@tonic-gate return (1); 387*7c478bd9Sstevel@tonic-gate case RE_CLIENTID: 388*7c478bd9Sstevel@tonic-gate case RE_DEAD_FILE: 389*7c478bd9Sstevel@tonic-gate case RE_END: 390*7c478bd9Sstevel@tonic-gate case RE_FAIL_RELOCK: 391*7c478bd9Sstevel@tonic-gate case RE_FAILOVER: 392*7c478bd9Sstevel@tonic-gate case RE_LOST_STATE: 393*7c478bd9Sstevel@tonic-gate case RE_OPENS_CHANGED: 394*7c478bd9Sstevel@tonic-gate case RE_SIGLOST: 395*7c478bd9Sstevel@tonic-gate case RE_SIGLOST_NO_DUMP: 396*7c478bd9Sstevel@tonic-gate case RE_LOST_STATE_BAD_OP: 397*7c478bd9Sstevel@tonic-gate return (0); 398*7c478bd9Sstevel@tonic-gate default: 399*7c478bd9Sstevel@tonic-gate return (0); 400*7c478bd9Sstevel@tonic-gate } 401*7c478bd9Sstevel@tonic-gate } else { 402*7c478bd9Sstevel@tonic-gate switch (msgp->rmsg_u.msg_fact.rf_type) { 403*7c478bd9Sstevel@tonic-gate case RF_BADOWNER: 404*7c478bd9Sstevel@tonic-gate case RF_ERR: 405*7c478bd9Sstevel@tonic-gate case RF_RENEW_EXPIRED: 406*7c478bd9Sstevel@tonic-gate case RF_SRV_OK: 407*7c478bd9Sstevel@tonic-gate case RF_SRVS_OK: 408*7c478bd9Sstevel@tonic-gate case RF_DELMAP_CB_ERR: 409*7c478bd9Sstevel@tonic-gate return (1); 410*7c478bd9Sstevel@tonic-gate case RF_SRV_NOT_RESPOND: 411*7c478bd9Sstevel@tonic-gate case RF_SRVS_NOT_RESPOND: 412*7c478bd9Sstevel@tonic-gate return (0); 413*7c478bd9Sstevel@tonic-gate default: 414*7c478bd9Sstevel@tonic-gate return (0); 415*7c478bd9Sstevel@tonic-gate } 416*7c478bd9Sstevel@tonic-gate } 417*7c478bd9Sstevel@tonic-gate } 418*7c478bd9Sstevel@tonic-gate 419*7c478bd9Sstevel@tonic-gate /* 420*7c478bd9Sstevel@tonic-gate * Iterate backwards through the mi's mi_msg_list to find the earliest 421*7c478bd9Sstevel@tonic-gate * message that we should find relevant facts to investigate. 422*7c478bd9Sstevel@tonic-gate */ 423*7c478bd9Sstevel@tonic-gate static nfs4_debug_msg_t * 424*7c478bd9Sstevel@tonic-gate find_beginning(nfs4_debug_msg_t *first_msg, mntinfo4_t *mi) 425*7c478bd9Sstevel@tonic-gate { 426*7c478bd9Sstevel@tonic-gate nfs4_debug_msg_t *oldest_msg, *cur_msg; 427*7c478bd9Sstevel@tonic-gate time_t lease; 428*7c478bd9Sstevel@tonic-gate 429*7c478bd9Sstevel@tonic-gate ASSERT(mutex_owned(&mi->mi_msg_list_lock)); 430*7c478bd9Sstevel@tonic-gate if (mi->mi_lease_period > 0) 431*7c478bd9Sstevel@tonic-gate lease = 2 * mi->mi_lease_period; 432*7c478bd9Sstevel@tonic-gate else 433*7c478bd9Sstevel@tonic-gate lease = DEFAULT_LEASE; 434*7c478bd9Sstevel@tonic-gate 435*7c478bd9Sstevel@tonic-gate oldest_msg = first_msg; 436*7c478bd9Sstevel@tonic-gate cur_msg = list_prev(&mi->mi_msg_list, first_msg); 437*7c478bd9Sstevel@tonic-gate while (cur_msg && 438*7c478bd9Sstevel@tonic-gate first_msg->msg_time.tv_sec - cur_msg->msg_time.tv_sec < lease) { 439*7c478bd9Sstevel@tonic-gate oldest_msg = cur_msg; 440*7c478bd9Sstevel@tonic-gate if ((cur_msg->msg_type == RM_FACT) && 441*7c478bd9Sstevel@tonic-gate (cur_msg->rmsg_u.msg_fact.rf_type == RF_SRV_OK)) { 442*7c478bd9Sstevel@tonic-gate /* find where we lost contact with the server */ 443*7c478bd9Sstevel@tonic-gate while (cur_msg) { 444*7c478bd9Sstevel@tonic-gate if ((cur_msg->msg_type == RM_FACT) && 445*7c478bd9Sstevel@tonic-gate (cur_msg->rmsg_u.msg_fact.rf_type == 446*7c478bd9Sstevel@tonic-gate RF_SRV_NOT_RESPOND)) 447*7c478bd9Sstevel@tonic-gate break; 448*7c478bd9Sstevel@tonic-gate oldest_msg = cur_msg; 449*7c478bd9Sstevel@tonic-gate cur_msg = list_prev(&mi->mi_msg_list, cur_msg); 450*7c478bd9Sstevel@tonic-gate } 451*7c478bd9Sstevel@tonic-gate /* 452*7c478bd9Sstevel@tonic-gate * Find the first successful message before 453*7c478bd9Sstevel@tonic-gate * we lost contact with the server. 454*7c478bd9Sstevel@tonic-gate */ 455*7c478bd9Sstevel@tonic-gate if (cur_msg) { 456*7c478bd9Sstevel@tonic-gate cur_msg = list_prev(&mi->mi_msg_list, cur_msg); 457*7c478bd9Sstevel@tonic-gate while (cur_msg && !successful_comm(cur_msg)) { 458*7c478bd9Sstevel@tonic-gate oldest_msg = cur_msg; 459*7c478bd9Sstevel@tonic-gate cur_msg = list_prev(&mi->mi_msg_list, 460*7c478bd9Sstevel@tonic-gate cur_msg); 461*7c478bd9Sstevel@tonic-gate } 462*7c478bd9Sstevel@tonic-gate } 463*7c478bd9Sstevel@tonic-gate /* 464*7c478bd9Sstevel@tonic-gate * If we're not at the dummy head pointer, 465*7c478bd9Sstevel@tonic-gate * set the oldest and current message. 466*7c478bd9Sstevel@tonic-gate */ 467*7c478bd9Sstevel@tonic-gate if (cur_msg) { 468*7c478bd9Sstevel@tonic-gate first_msg = cur_msg; 469*7c478bd9Sstevel@tonic-gate oldest_msg = cur_msg; 470*7c478bd9Sstevel@tonic-gate cur_msg = list_prev(&mi->mi_msg_list, cur_msg); 471*7c478bd9Sstevel@tonic-gate } 472*7c478bd9Sstevel@tonic-gate } else 473*7c478bd9Sstevel@tonic-gate cur_msg = list_prev(&mi->mi_msg_list, cur_msg); 474*7c478bd9Sstevel@tonic-gate } 475*7c478bd9Sstevel@tonic-gate 476*7c478bd9Sstevel@tonic-gate return (oldest_msg); 477*7c478bd9Sstevel@tonic-gate } 478*7c478bd9Sstevel@tonic-gate 479*7c478bd9Sstevel@tonic-gate /* 480*7c478bd9Sstevel@tonic-gate * Returns 1 if facts have been found; 0 otherwise. 481*7c478bd9Sstevel@tonic-gate */ 482*7c478bd9Sstevel@tonic-gate static int 483*7c478bd9Sstevel@tonic-gate get_facts(nfs4_debug_msg_t *msgp, nfs4_rfact_t *ret_fp, char **mnt_pt, 484*7c478bd9Sstevel@tonic-gate mntinfo4_t *mi) 485*7c478bd9Sstevel@tonic-gate { 486*7c478bd9Sstevel@tonic-gate nfs4_debug_msg_t *cur_msg, *oldest_msg; 487*7c478bd9Sstevel@tonic-gate nfs4_rfact_t *cur_fp; 488*7c478bd9Sstevel@tonic-gate int found_a_fact = 0; 489*7c478bd9Sstevel@tonic-gate int len; 490*7c478bd9Sstevel@tonic-gate 491*7c478bd9Sstevel@tonic-gate cur_msg = msgp; 492*7c478bd9Sstevel@tonic-gate 493*7c478bd9Sstevel@tonic-gate /* find the oldest msg to search backwards to */ 494*7c478bd9Sstevel@tonic-gate oldest_msg = find_beginning(cur_msg, mi); 495*7c478bd9Sstevel@tonic-gate ASSERT(oldest_msg != NULL); 496*7c478bd9Sstevel@tonic-gate 497*7c478bd9Sstevel@tonic-gate /* 498*7c478bd9Sstevel@tonic-gate * Create a fact sheet by searching from our current message 499*7c478bd9Sstevel@tonic-gate * backwards to the 'oldest_msg', recording facts along the way 500*7c478bd9Sstevel@tonic-gate * until we found facts that have been inspected by another time. 501*7c478bd9Sstevel@tonic-gate */ 502*7c478bd9Sstevel@tonic-gate while (cur_msg && cur_msg != list_prev(&mi->mi_msg_list, oldest_msg)) { 503*7c478bd9Sstevel@tonic-gate if (cur_msg->msg_type != RM_FACT) { 504*7c478bd9Sstevel@tonic-gate cur_msg = list_prev(&mi->mi_msg_list, cur_msg); 505*7c478bd9Sstevel@tonic-gate continue; 506*7c478bd9Sstevel@tonic-gate } 507*7c478bd9Sstevel@tonic-gate 508*7c478bd9Sstevel@tonic-gate cur_fp = &cur_msg->rmsg_u.msg_fact; 509*7c478bd9Sstevel@tonic-gate /* 510*7c478bd9Sstevel@tonic-gate * If this fact has already been looked at, then so 511*7c478bd9Sstevel@tonic-gate * have all preceding facts. Return Now. 512*7c478bd9Sstevel@tonic-gate */ 513*7c478bd9Sstevel@tonic-gate if (cur_fp->rf_status == RFS_INSPECT) 514*7c478bd9Sstevel@tonic-gate return (found_a_fact); 515*7c478bd9Sstevel@tonic-gate 516*7c478bd9Sstevel@tonic-gate cur_fp->rf_status = RFS_INSPECT; 517*7c478bd9Sstevel@tonic-gate found_a_fact = 1; 518*7c478bd9Sstevel@tonic-gate switch (cur_fp->rf_type) { 519*7c478bd9Sstevel@tonic-gate case RF_BADOWNER: 520*7c478bd9Sstevel@tonic-gate break; 521*7c478bd9Sstevel@tonic-gate case RF_ERR: 522*7c478bd9Sstevel@tonic-gate /* 523*7c478bd9Sstevel@tonic-gate * Don't want to overwrite a fact that was 524*7c478bd9Sstevel@tonic-gate * previously found during our current search. 525*7c478bd9Sstevel@tonic-gate */ 526*7c478bd9Sstevel@tonic-gate if (!ret_fp->rf_reboot) 527*7c478bd9Sstevel@tonic-gate ret_fp->rf_reboot = cur_fp->rf_reboot; 528*7c478bd9Sstevel@tonic-gate if (!ret_fp->rf_stat4) 529*7c478bd9Sstevel@tonic-gate ret_fp->rf_stat4 = cur_fp->rf_stat4; 530*7c478bd9Sstevel@tonic-gate if (!ret_fp->rf_action) 531*7c478bd9Sstevel@tonic-gate ret_fp->rf_action = cur_fp->rf_action; 532*7c478bd9Sstevel@tonic-gate break; 533*7c478bd9Sstevel@tonic-gate case RF_RENEW_EXPIRED: 534*7c478bd9Sstevel@tonic-gate if (cur_msg->msg_mntpt && !(*mnt_pt)) { 535*7c478bd9Sstevel@tonic-gate len = strlen(cur_msg->msg_mntpt) + 1; 536*7c478bd9Sstevel@tonic-gate *mnt_pt = kmem_alloc(len, KM_SLEEP); 537*7c478bd9Sstevel@tonic-gate bcopy(cur_msg->msg_mntpt, *mnt_pt, len); 538*7c478bd9Sstevel@tonic-gate } 539*7c478bd9Sstevel@tonic-gate break; 540*7c478bd9Sstevel@tonic-gate case RF_SRV_OK: 541*7c478bd9Sstevel@tonic-gate break; 542*7c478bd9Sstevel@tonic-gate case RF_SRV_NOT_RESPOND: 543*7c478bd9Sstevel@tonic-gate /* 544*7c478bd9Sstevel@tonic-gate * Okay to overwrite this fact as 545*7c478bd9Sstevel@tonic-gate * we want the earliest time. 546*7c478bd9Sstevel@tonic-gate */ 547*7c478bd9Sstevel@tonic-gate ret_fp->rf_time = cur_fp->rf_time; 548*7c478bd9Sstevel@tonic-gate break; 549*7c478bd9Sstevel@tonic-gate case RF_SRVS_OK: 550*7c478bd9Sstevel@tonic-gate break; 551*7c478bd9Sstevel@tonic-gate case RF_SRVS_NOT_RESPOND: 552*7c478bd9Sstevel@tonic-gate break; 553*7c478bd9Sstevel@tonic-gate case RF_DELMAP_CB_ERR: 554*7c478bd9Sstevel@tonic-gate break; 555*7c478bd9Sstevel@tonic-gate default: 556*7c478bd9Sstevel@tonic-gate zcmn_err(getzoneid(), CE_NOTE, 557*7c478bd9Sstevel@tonic-gate "get facts: illegal fact %d", cur_fp->rf_type); 558*7c478bd9Sstevel@tonic-gate break; 559*7c478bd9Sstevel@tonic-gate } 560*7c478bd9Sstevel@tonic-gate cur_msg = list_prev(&mi->mi_msg_list, cur_msg); 561*7c478bd9Sstevel@tonic-gate } 562*7c478bd9Sstevel@tonic-gate 563*7c478bd9Sstevel@tonic-gate return (found_a_fact); 564*7c478bd9Sstevel@tonic-gate } 565*7c478bd9Sstevel@tonic-gate 566*7c478bd9Sstevel@tonic-gate /* 567*7c478bd9Sstevel@tonic-gate * Returns 1 if this fact is identical to the last fact recorded 568*7c478bd9Sstevel@tonic-gate * (only checks for a match within the last 2 lease periods). 569*7c478bd9Sstevel@tonic-gate */ 570*7c478bd9Sstevel@tonic-gate static int 571*7c478bd9Sstevel@tonic-gate facts_same(nfs4_debug_msg_t *cur_msg, nfs4_debug_msg_t *new_msg, 572*7c478bd9Sstevel@tonic-gate mntinfo4_t *mi) 573*7c478bd9Sstevel@tonic-gate { 574*7c478bd9Sstevel@tonic-gate nfs4_rfact_t *fp1, *fp2; 575*7c478bd9Sstevel@tonic-gate int lease, len; 576*7c478bd9Sstevel@tonic-gate 577*7c478bd9Sstevel@tonic-gate ASSERT(mutex_owned(&mi->mi_msg_list_lock)); 578*7c478bd9Sstevel@tonic-gate if (mi->mi_lease_period > 0) 579*7c478bd9Sstevel@tonic-gate lease = 2 * mi->mi_lease_period; 580*7c478bd9Sstevel@tonic-gate else 581*7c478bd9Sstevel@tonic-gate lease = DEFAULT_LEASE; 582*7c478bd9Sstevel@tonic-gate 583*7c478bd9Sstevel@tonic-gate fp2 = &new_msg->rmsg_u.msg_fact; 584*7c478bd9Sstevel@tonic-gate 585*7c478bd9Sstevel@tonic-gate while (cur_msg && 586*7c478bd9Sstevel@tonic-gate new_msg->msg_time.tv_sec - cur_msg->msg_time.tv_sec < lease) { 587*7c478bd9Sstevel@tonic-gate if (cur_msg->msg_type != RM_FACT) { 588*7c478bd9Sstevel@tonic-gate cur_msg = list_prev(&mi->mi_msg_list, cur_msg); 589*7c478bd9Sstevel@tonic-gate continue; 590*7c478bd9Sstevel@tonic-gate } 591*7c478bd9Sstevel@tonic-gate fp1 = &cur_msg->rmsg_u.msg_fact; 592*7c478bd9Sstevel@tonic-gate if (fp1->rf_type != fp2->rf_type) 593*7c478bd9Sstevel@tonic-gate return (0); 594*7c478bd9Sstevel@tonic-gate 595*7c478bd9Sstevel@tonic-gate /* now actually compare the facts */ 596*7c478bd9Sstevel@tonic-gate if (fp1->rf_action != fp2->rf_action) 597*7c478bd9Sstevel@tonic-gate return (0); 598*7c478bd9Sstevel@tonic-gate if (fp1->rf_stat4 != fp2->rf_stat4) 599*7c478bd9Sstevel@tonic-gate return (0); 600*7c478bd9Sstevel@tonic-gate if (fp1->rf_reboot != fp2->rf_reboot) 601*7c478bd9Sstevel@tonic-gate return (0); 602*7c478bd9Sstevel@tonic-gate if (fp1->rf_op != fp2->rf_op) 603*7c478bd9Sstevel@tonic-gate return (0); 604*7c478bd9Sstevel@tonic-gate if (fp1->rf_time.tv_sec != fp2->rf_time.tv_sec) 605*7c478bd9Sstevel@tonic-gate return (0); 606*7c478bd9Sstevel@tonic-gate if (fp1->rf_error != fp2->rf_error) 607*7c478bd9Sstevel@tonic-gate return (0); 608*7c478bd9Sstevel@tonic-gate if (fp1->rf_rp1 != fp2->rf_rp1) 609*7c478bd9Sstevel@tonic-gate return (0); 610*7c478bd9Sstevel@tonic-gate if (cur_msg->msg_srv != NULL) { 611*7c478bd9Sstevel@tonic-gate if (new_msg->msg_srv == NULL) 612*7c478bd9Sstevel@tonic-gate return (0); 613*7c478bd9Sstevel@tonic-gate len = strlen(cur_msg->msg_srv); 614*7c478bd9Sstevel@tonic-gate if (strncmp(cur_msg->msg_srv, new_msg->msg_srv, 615*7c478bd9Sstevel@tonic-gate len) != 0) 616*7c478bd9Sstevel@tonic-gate return (0); 617*7c478bd9Sstevel@tonic-gate } else if (new_msg->msg_srv != NULL) { 618*7c478bd9Sstevel@tonic-gate return (0); 619*7c478bd9Sstevel@tonic-gate } 620*7c478bd9Sstevel@tonic-gate if (cur_msg->msg_mntpt != NULL) { 621*7c478bd9Sstevel@tonic-gate if (new_msg->msg_mntpt == NULL) 622*7c478bd9Sstevel@tonic-gate return (0); 623*7c478bd9Sstevel@tonic-gate len = strlen(cur_msg->msg_mntpt); 624*7c478bd9Sstevel@tonic-gate if (strncmp(cur_msg->msg_mntpt, new_msg->msg_mntpt, 625*7c478bd9Sstevel@tonic-gate len) != 0) 626*7c478bd9Sstevel@tonic-gate return (0); 627*7c478bd9Sstevel@tonic-gate } else if (new_msg->msg_mntpt != NULL) { 628*7c478bd9Sstevel@tonic-gate return (0); 629*7c478bd9Sstevel@tonic-gate } 630*7c478bd9Sstevel@tonic-gate if (fp1->rf_char1 != NULL) { 631*7c478bd9Sstevel@tonic-gate if (fp2->rf_char1 == NULL) 632*7c478bd9Sstevel@tonic-gate return (0); 633*7c478bd9Sstevel@tonic-gate len = strlen(fp1->rf_char1); 634*7c478bd9Sstevel@tonic-gate if (strncmp(fp1->rf_char1, fp2->rf_char1, len) != 0) 635*7c478bd9Sstevel@tonic-gate return (0); 636*7c478bd9Sstevel@tonic-gate } else if (fp2->rf_char1 != NULL) { 637*7c478bd9Sstevel@tonic-gate return (0); 638*7c478bd9Sstevel@tonic-gate } 639*7c478bd9Sstevel@tonic-gate return (1); 640*7c478bd9Sstevel@tonic-gate } 641*7c478bd9Sstevel@tonic-gate 642*7c478bd9Sstevel@tonic-gate return (0); 643*7c478bd9Sstevel@tonic-gate } 644*7c478bd9Sstevel@tonic-gate 645*7c478bd9Sstevel@tonic-gate /* 646*7c478bd9Sstevel@tonic-gate * Returns 1 if these two messages are identical; 0 otherwise. 647*7c478bd9Sstevel@tonic-gate */ 648*7c478bd9Sstevel@tonic-gate static int 649*7c478bd9Sstevel@tonic-gate events_same(nfs4_debug_msg_t *cur_msg, nfs4_debug_msg_t *new_msg, 650*7c478bd9Sstevel@tonic-gate mntinfo4_t *mi) 651*7c478bd9Sstevel@tonic-gate { 652*7c478bd9Sstevel@tonic-gate nfs4_revent_t *ep1, *ep2; 653*7c478bd9Sstevel@tonic-gate int len; 654*7c478bd9Sstevel@tonic-gate 655*7c478bd9Sstevel@tonic-gate /* find the last event, bypassing all facts */ 656*7c478bd9Sstevel@tonic-gate while (cur_msg && cur_msg->msg_type != RM_EVENT) 657*7c478bd9Sstevel@tonic-gate cur_msg = list_prev(&mi->mi_msg_list, cur_msg); 658*7c478bd9Sstevel@tonic-gate 659*7c478bd9Sstevel@tonic-gate if (!cur_msg) 660*7c478bd9Sstevel@tonic-gate return (0); 661*7c478bd9Sstevel@tonic-gate 662*7c478bd9Sstevel@tonic-gate if (cur_msg->msg_type != RM_EVENT) 663*7c478bd9Sstevel@tonic-gate return (0); 664*7c478bd9Sstevel@tonic-gate 665*7c478bd9Sstevel@tonic-gate ep1 = &cur_msg->rmsg_u.msg_event; 666*7c478bd9Sstevel@tonic-gate ep2 = &new_msg->rmsg_u.msg_event; 667*7c478bd9Sstevel@tonic-gate if (ep1->re_type != ep2->re_type) 668*7c478bd9Sstevel@tonic-gate return (0); 669*7c478bd9Sstevel@tonic-gate 670*7c478bd9Sstevel@tonic-gate /* 671*7c478bd9Sstevel@tonic-gate * Since we zalloc the buffer, then the two nfs4_debug_msg's 672*7c478bd9Sstevel@tonic-gate * must match up even if all the fields weren't filled in 673*7c478bd9Sstevel@tonic-gate * the first place. 674*7c478bd9Sstevel@tonic-gate */ 675*7c478bd9Sstevel@tonic-gate if (ep1->re_mi != ep2->re_mi) 676*7c478bd9Sstevel@tonic-gate return (0); 677*7c478bd9Sstevel@tonic-gate if (ep1->re_uint != ep2->re_uint) 678*7c478bd9Sstevel@tonic-gate return (0); 679*7c478bd9Sstevel@tonic-gate if (ep1->re_stat4 != ep2->re_stat4) 680*7c478bd9Sstevel@tonic-gate return (0); 681*7c478bd9Sstevel@tonic-gate if (ep1->re_pid != ep2->re_pid) 682*7c478bd9Sstevel@tonic-gate return (0); 683*7c478bd9Sstevel@tonic-gate if (ep1->re_rp1 != ep2->re_rp1) 684*7c478bd9Sstevel@tonic-gate return (0); 685*7c478bd9Sstevel@tonic-gate if (ep1->re_rp2 != ep2->re_rp2) 686*7c478bd9Sstevel@tonic-gate return (0); 687*7c478bd9Sstevel@tonic-gate if (ep1->re_tag1 != ep2->re_tag1) 688*7c478bd9Sstevel@tonic-gate return (0); 689*7c478bd9Sstevel@tonic-gate if (ep1->re_tag2 != ep2->re_tag2) 690*7c478bd9Sstevel@tonic-gate return (0); 691*7c478bd9Sstevel@tonic-gate if (ep1->re_seqid1 != ep2->re_seqid1) 692*7c478bd9Sstevel@tonic-gate return (0); 693*7c478bd9Sstevel@tonic-gate if (ep1->re_seqid2 != ep2->re_seqid2) 694*7c478bd9Sstevel@tonic-gate return (0); 695*7c478bd9Sstevel@tonic-gate 696*7c478bd9Sstevel@tonic-gate if (cur_msg->msg_srv != NULL) { 697*7c478bd9Sstevel@tonic-gate if (new_msg->msg_srv == NULL) 698*7c478bd9Sstevel@tonic-gate return (0); 699*7c478bd9Sstevel@tonic-gate len = strlen(cur_msg->msg_srv); 700*7c478bd9Sstevel@tonic-gate if (strncmp(cur_msg->msg_srv, new_msg->msg_srv, len) != 0) 701*7c478bd9Sstevel@tonic-gate return (0); 702*7c478bd9Sstevel@tonic-gate } else if (new_msg->msg_srv != NULL) { 703*7c478bd9Sstevel@tonic-gate return (0); 704*7c478bd9Sstevel@tonic-gate } 705*7c478bd9Sstevel@tonic-gate 706*7c478bd9Sstevel@tonic-gate if (ep1->re_char1 != NULL) { 707*7c478bd9Sstevel@tonic-gate if (ep2->re_char1 == NULL) 708*7c478bd9Sstevel@tonic-gate return (0); 709*7c478bd9Sstevel@tonic-gate len = strlen(ep1->re_char1); 710*7c478bd9Sstevel@tonic-gate if (strncmp(ep1->re_char1, ep2->re_char1, len) != 0) 711*7c478bd9Sstevel@tonic-gate return (0); 712*7c478bd9Sstevel@tonic-gate } else if (ep2->re_char1 != NULL) { 713*7c478bd9Sstevel@tonic-gate return (0); 714*7c478bd9Sstevel@tonic-gate } 715*7c478bd9Sstevel@tonic-gate 716*7c478bd9Sstevel@tonic-gate if (ep1->re_char2 != NULL) { 717*7c478bd9Sstevel@tonic-gate if (ep2->re_char2 == NULL) 718*7c478bd9Sstevel@tonic-gate return (0); 719*7c478bd9Sstevel@tonic-gate len = strlen(ep1->re_char2); 720*7c478bd9Sstevel@tonic-gate if (strncmp(ep1->re_char2, ep2->re_char2, len) != 0) 721*7c478bd9Sstevel@tonic-gate return (0); 722*7c478bd9Sstevel@tonic-gate } else if (ep2->re_char2 != NULL) { 723*7c478bd9Sstevel@tonic-gate return (0); 724*7c478bd9Sstevel@tonic-gate } 725*7c478bd9Sstevel@tonic-gate 726*7c478bd9Sstevel@tonic-gate if (cur_msg->msg_mntpt != NULL) { 727*7c478bd9Sstevel@tonic-gate if (new_msg->msg_mntpt == NULL) 728*7c478bd9Sstevel@tonic-gate return (0); 729*7c478bd9Sstevel@tonic-gate len = strlen(cur_msg->msg_mntpt); 730*7c478bd9Sstevel@tonic-gate if (strncmp(cur_msg->msg_mntpt, cur_msg->msg_mntpt, len) != 0) 731*7c478bd9Sstevel@tonic-gate return (0); 732*7c478bd9Sstevel@tonic-gate } else if (new_msg->msg_mntpt != NULL) { 733*7c478bd9Sstevel@tonic-gate return (0); 734*7c478bd9Sstevel@tonic-gate } 735*7c478bd9Sstevel@tonic-gate 736*7c478bd9Sstevel@tonic-gate return (1); 737*7c478bd9Sstevel@tonic-gate } 738*7c478bd9Sstevel@tonic-gate 739*7c478bd9Sstevel@tonic-gate /* 740*7c478bd9Sstevel@tonic-gate * Free up a recovery event. 741*7c478bd9Sstevel@tonic-gate */ 742*7c478bd9Sstevel@tonic-gate static void 743*7c478bd9Sstevel@tonic-gate free_event(nfs4_revent_t *ep) 744*7c478bd9Sstevel@tonic-gate { 745*7c478bd9Sstevel@tonic-gate int len; 746*7c478bd9Sstevel@tonic-gate 747*7c478bd9Sstevel@tonic-gate if (ep->re_char1) { 748*7c478bd9Sstevel@tonic-gate len = strlen(ep->re_char1) + 1; 749*7c478bd9Sstevel@tonic-gate kmem_free(ep->re_char1, len); 750*7c478bd9Sstevel@tonic-gate } 751*7c478bd9Sstevel@tonic-gate if (ep->re_char2) { 752*7c478bd9Sstevel@tonic-gate len = strlen(ep->re_char2) + 1; 753*7c478bd9Sstevel@tonic-gate kmem_free(ep->re_char2, len); 754*7c478bd9Sstevel@tonic-gate } 755*7c478bd9Sstevel@tonic-gate } 756*7c478bd9Sstevel@tonic-gate 757*7c478bd9Sstevel@tonic-gate /* 758*7c478bd9Sstevel@tonic-gate * Free up a recovery fact. 759*7c478bd9Sstevel@tonic-gate */ 760*7c478bd9Sstevel@tonic-gate static void 761*7c478bd9Sstevel@tonic-gate free_fact(nfs4_rfact_t *fp) 762*7c478bd9Sstevel@tonic-gate { 763*7c478bd9Sstevel@tonic-gate int len; 764*7c478bd9Sstevel@tonic-gate 765*7c478bd9Sstevel@tonic-gate if (fp->rf_char1) { 766*7c478bd9Sstevel@tonic-gate len = strlen(fp->rf_char1) + 1; 767*7c478bd9Sstevel@tonic-gate kmem_free(fp->rf_char1, len); 768*7c478bd9Sstevel@tonic-gate } 769*7c478bd9Sstevel@tonic-gate } 770*7c478bd9Sstevel@tonic-gate 771*7c478bd9Sstevel@tonic-gate /* 772*7c478bd9Sstevel@tonic-gate * Free up the message. 773*7c478bd9Sstevel@tonic-gate */ 774*7c478bd9Sstevel@tonic-gate void 775*7c478bd9Sstevel@tonic-gate nfs4_free_msg(nfs4_debug_msg_t *msg) 776*7c478bd9Sstevel@tonic-gate { 777*7c478bd9Sstevel@tonic-gate int len; 778*7c478bd9Sstevel@tonic-gate 779*7c478bd9Sstevel@tonic-gate if (msg->msg_type == RM_EVENT) 780*7c478bd9Sstevel@tonic-gate free_event(&msg->rmsg_u.msg_event); 781*7c478bd9Sstevel@tonic-gate else 782*7c478bd9Sstevel@tonic-gate free_fact(&msg->rmsg_u.msg_fact); 783*7c478bd9Sstevel@tonic-gate 784*7c478bd9Sstevel@tonic-gate if (msg->msg_srv) { 785*7c478bd9Sstevel@tonic-gate len = strlen(msg->msg_srv) + 1; 786*7c478bd9Sstevel@tonic-gate kmem_free(msg->msg_srv, len); 787*7c478bd9Sstevel@tonic-gate } 788*7c478bd9Sstevel@tonic-gate 789*7c478bd9Sstevel@tonic-gate if (msg->msg_mntpt) { 790*7c478bd9Sstevel@tonic-gate len = strlen(msg->msg_mntpt) + 1; 791*7c478bd9Sstevel@tonic-gate kmem_free(msg->msg_mntpt, len); 792*7c478bd9Sstevel@tonic-gate } 793*7c478bd9Sstevel@tonic-gate 794*7c478bd9Sstevel@tonic-gate /* free up the data structure itself */ 795*7c478bd9Sstevel@tonic-gate kmem_free(msg, sizeof (*msg)); 796*7c478bd9Sstevel@tonic-gate } 797*7c478bd9Sstevel@tonic-gate 798*7c478bd9Sstevel@tonic-gate /* 799*7c478bd9Sstevel@tonic-gate * Prints out the interesting facts for recovery events: 800*7c478bd9Sstevel@tonic-gate * -DEAD_FILE 801*7c478bd9Sstevel@tonic-gate * -SIGLOST(_NO_DUMP) 802*7c478bd9Sstevel@tonic-gate */ 803*7c478bd9Sstevel@tonic-gate static void 804*7c478bd9Sstevel@tonic-gate print_facts(nfs4_debug_msg_t *msg, mntinfo4_t *mi) 805*7c478bd9Sstevel@tonic-gate { 806*7c478bd9Sstevel@tonic-gate nfs4_rfact_t *fp; 807*7c478bd9Sstevel@tonic-gate char *mount_pt; 808*7c478bd9Sstevel@tonic-gate int len; 809*7c478bd9Sstevel@tonic-gate 810*7c478bd9Sstevel@tonic-gate if (msg->rmsg_u.msg_event.re_type != RE_DEAD_FILE && 811*7c478bd9Sstevel@tonic-gate msg->rmsg_u.msg_event.re_type != RE_SIGLOST && 812*7c478bd9Sstevel@tonic-gate msg->rmsg_u.msg_event.re_type != RE_SIGLOST_NO_DUMP) 813*7c478bd9Sstevel@tonic-gate return; 814*7c478bd9Sstevel@tonic-gate 815*7c478bd9Sstevel@tonic-gate fp = kmem_zalloc(sizeof (*fp), KM_SLEEP); 816*7c478bd9Sstevel@tonic-gate mount_pt = NULL; 817*7c478bd9Sstevel@tonic-gate 818*7c478bd9Sstevel@tonic-gate if (get_facts(msg, fp, &mount_pt, mi)) { 819*7c478bd9Sstevel@tonic-gate char time[256]; 820*7c478bd9Sstevel@tonic-gate 821*7c478bd9Sstevel@tonic-gate 822*7c478bd9Sstevel@tonic-gate if (fp->rf_time.tv_sec) 823*7c478bd9Sstevel@tonic-gate (void) snprintf(time, 256, "%ld", 824*7c478bd9Sstevel@tonic-gate (gethrestime_sec() - fp->rf_time.tv_sec)/60); 825*7c478bd9Sstevel@tonic-gate zcmn_err(mi->mi_zone->zone_id, CE_NOTE, 826*7c478bd9Sstevel@tonic-gate "!NFS4 FACT SHEET: %s%s %s%s %s %s%s%s %s%s", 827*7c478bd9Sstevel@tonic-gate fp->rf_action ? "\n Action: " : "", 828*7c478bd9Sstevel@tonic-gate fp->rf_action ? nfs4_recov_action_to_str(fp->rf_action) : 829*7c478bd9Sstevel@tonic-gate "", 830*7c478bd9Sstevel@tonic-gate fp->rf_stat4 ? "\n NFS4 error: " : "", 831*7c478bd9Sstevel@tonic-gate fp->rf_stat4 ? nfs4_stat_to_str(fp->rf_stat4) : "", 832*7c478bd9Sstevel@tonic-gate fp->rf_reboot ? "\n Suspected server reboot. " : "", 833*7c478bd9Sstevel@tonic-gate fp->rf_time.tv_sec ? "\n Server was down for " : "", 834*7c478bd9Sstevel@tonic-gate fp->rf_time.tv_sec ? time : "", 835*7c478bd9Sstevel@tonic-gate fp->rf_time.tv_sec ? " minutes." : "", 836*7c478bd9Sstevel@tonic-gate mount_pt ? " \n Client's lease expired on mount " : "", 837*7c478bd9Sstevel@tonic-gate mount_pt ? mount_pt : ""); 838*7c478bd9Sstevel@tonic-gate } 839*7c478bd9Sstevel@tonic-gate 840*7c478bd9Sstevel@tonic-gate if (mount_pt) { 841*7c478bd9Sstevel@tonic-gate len = strlen(mount_pt) + 1; 842*7c478bd9Sstevel@tonic-gate kmem_free(mount_pt, len); 843*7c478bd9Sstevel@tonic-gate } 844*7c478bd9Sstevel@tonic-gate 845*7c478bd9Sstevel@tonic-gate /* free the fact struct itself */ 846*7c478bd9Sstevel@tonic-gate if (fp) 847*7c478bd9Sstevel@tonic-gate kmem_free(fp, sizeof (*fp)); 848*7c478bd9Sstevel@tonic-gate } 849*7c478bd9Sstevel@tonic-gate 850*7c478bd9Sstevel@tonic-gate /* 851*7c478bd9Sstevel@tonic-gate * Print an event message to /var/adm/messages 852*7c478bd9Sstevel@tonic-gate * The last argument to this fuction dictates the repeat status 853*7c478bd9Sstevel@tonic-gate * of the event. If set to 1, it means that we are dumping this 854*7c478bd9Sstevel@tonic-gate * event and it will _never_ be printed after this time. Else if 855*7c478bd9Sstevel@tonic-gate * set to 0 it will be printed again. 856*7c478bd9Sstevel@tonic-gate */ 857*7c478bd9Sstevel@tonic-gate static void 858*7c478bd9Sstevel@tonic-gate queue_print_event(nfs4_debug_msg_t *msg, mntinfo4_t *mi, int dump) 859*7c478bd9Sstevel@tonic-gate { 860*7c478bd9Sstevel@tonic-gate nfs4_revent_t *ep; 861*7c478bd9Sstevel@tonic-gate zoneid_t zoneid; 862*7c478bd9Sstevel@tonic-gate 863*7c478bd9Sstevel@tonic-gate ep = &msg->rmsg_u.msg_event; 864*7c478bd9Sstevel@tonic-gate zoneid = mi->mi_zone->zone_id; 865*7c478bd9Sstevel@tonic-gate 866*7c478bd9Sstevel@tonic-gate switch (ep->re_type) { 867*7c478bd9Sstevel@tonic-gate case RE_BAD_SEQID: 868*7c478bd9Sstevel@tonic-gate zcmn_err(zoneid, CE_NOTE, "![NFS4][Server: %s][Mntpt: %s]" 869*7c478bd9Sstevel@tonic-gate "Operation %s for file %s (rnode_pt 0x%p), pid %d using " 870*7c478bd9Sstevel@tonic-gate "seqid %d got %s. Last good seqid was %d for " 871*7c478bd9Sstevel@tonic-gate "operation %s.", 872*7c478bd9Sstevel@tonic-gate msg->msg_srv, msg->msg_mntpt, 873*7c478bd9Sstevel@tonic-gate nfs4_ctags[ep->re_tag1].ct_str, ep->re_char1, 874*7c478bd9Sstevel@tonic-gate (void *)ep->re_rp1, ep->re_pid, ep->re_seqid1, 875*7c478bd9Sstevel@tonic-gate nfs4_stat_to_str(ep->re_stat4), ep->re_seqid2, 876*7c478bd9Sstevel@tonic-gate nfs4_ctags[ep->re_tag2].ct_str); 877*7c478bd9Sstevel@tonic-gate break; 878*7c478bd9Sstevel@tonic-gate case RE_BADHANDLE: 879*7c478bd9Sstevel@tonic-gate ASSERT(ep->re_rp1 != NULL); 880*7c478bd9Sstevel@tonic-gate if (ep->re_char1 != NULL) { 881*7c478bd9Sstevel@tonic-gate zcmn_err(zoneid, CE_NOTE, 882*7c478bd9Sstevel@tonic-gate "![NFS4][Server: %s][Mntpt: %s]" 883*7c478bd9Sstevel@tonic-gate "server %s said filehandle was " 884*7c478bd9Sstevel@tonic-gate "invalid for file: %s (rnode_pt 0x%p) on mount %s", 885*7c478bd9Sstevel@tonic-gate msg->msg_srv, msg->msg_mntpt, msg->msg_srv, 886*7c478bd9Sstevel@tonic-gate ep->re_char1, (void *)ep->re_rp1, msg->msg_mntpt); 887*7c478bd9Sstevel@tonic-gate } else { 888*7c478bd9Sstevel@tonic-gate zcmn_err(zoneid, CE_NOTE, 889*7c478bd9Sstevel@tonic-gate "![NFS4][Server: %s][Mntpt: %s]" 890*7c478bd9Sstevel@tonic-gate "server %s said filehandle was " 891*7c478bd9Sstevel@tonic-gate "invalid for file: (rnode_pt 0x%p) on mount %s" 892*7c478bd9Sstevel@tonic-gate " for fh:", msg->msg_srv, msg->msg_mntpt, 893*7c478bd9Sstevel@tonic-gate msg->msg_srv, (void *)ep->re_rp1, msg->msg_mntpt); 894*7c478bd9Sstevel@tonic-gate sfh4_printfhandle(ep->re_rp1->r_fh); 895*7c478bd9Sstevel@tonic-gate } 896*7c478bd9Sstevel@tonic-gate break; 897*7c478bd9Sstevel@tonic-gate case RE_CLIENTID: 898*7c478bd9Sstevel@tonic-gate zcmn_err(zoneid, CE_NOTE, "![NFS4][Server: %s][Mntpt: %s]" 899*7c478bd9Sstevel@tonic-gate "Can't recover clientid on mount point %s " 900*7c478bd9Sstevel@tonic-gate "(mi 0x%p) due to error %d (%s), for server %s. Marking " 901*7c478bd9Sstevel@tonic-gate "file system as unusable.", 902*7c478bd9Sstevel@tonic-gate msg->msg_srv, msg->msg_mntpt, msg->msg_mntpt, 903*7c478bd9Sstevel@tonic-gate (void *)ep->re_mi, ep->re_uint, 904*7c478bd9Sstevel@tonic-gate nfs4_stat_to_str(ep->re_stat4), 905*7c478bd9Sstevel@tonic-gate msg->msg_srv); 906*7c478bd9Sstevel@tonic-gate break; 907*7c478bd9Sstevel@tonic-gate case RE_DEAD_FILE: 908*7c478bd9Sstevel@tonic-gate zcmn_err(zoneid, CE_NOTE, "![NFS4][Server: %s][Mntpt: %s]" 909*7c478bd9Sstevel@tonic-gate "File %s (rnode_pt: %p) was closed due to NFS " 910*7c478bd9Sstevel@tonic-gate "recovery error on server %s(%s %s)", msg->msg_srv, 911*7c478bd9Sstevel@tonic-gate msg->msg_mntpt, ep->re_char1, (void *)ep->re_rp1, 912*7c478bd9Sstevel@tonic-gate msg->msg_srv, ep->re_char2 ? ep->re_char2 : "", 913*7c478bd9Sstevel@tonic-gate ep->re_stat4 ? nfs4_stat_to_str(ep->re_stat4) : ""); 914*7c478bd9Sstevel@tonic-gate break; 915*7c478bd9Sstevel@tonic-gate case RE_END: 916*7c478bd9Sstevel@tonic-gate zcmn_err(zoneid, CE_NOTE, "![NFS4][Server: %s][Mntpt: %s]" 917*7c478bd9Sstevel@tonic-gate "NFS Recovery done for mount %s (mi 0x%p) " 918*7c478bd9Sstevel@tonic-gate "on server %s, rnode_pt1 %s (0x%p), " 919*7c478bd9Sstevel@tonic-gate "rnode_pt2 %s (0x%p)", msg->msg_srv, msg->msg_mntpt, 920*7c478bd9Sstevel@tonic-gate msg->msg_mntpt, (void *)ep->re_mi, msg->msg_srv, 921*7c478bd9Sstevel@tonic-gate ep->re_char1, (void *)ep->re_rp1, ep->re_char2, 922*7c478bd9Sstevel@tonic-gate (void *)ep->re_rp2); 923*7c478bd9Sstevel@tonic-gate break; 924*7c478bd9Sstevel@tonic-gate case RE_FAIL_RELOCK: 925*7c478bd9Sstevel@tonic-gate zcmn_err(zoneid, CE_NOTE, "![NFS4][Server: %s][Mntpt: %s]" 926*7c478bd9Sstevel@tonic-gate "Couldn't reclaim lock for pid %d for " 927*7c478bd9Sstevel@tonic-gate "file %s (rnode_pt 0x%p) on (server %s): error %d", 928*7c478bd9Sstevel@tonic-gate msg->msg_srv, msg->msg_mntpt, ep->re_pid, ep->re_char1, 929*7c478bd9Sstevel@tonic-gate (void *)ep->re_rp1, msg->msg_srv, 930*7c478bd9Sstevel@tonic-gate ep->re_uint ? ep->re_uint : ep->re_stat4); 931*7c478bd9Sstevel@tonic-gate break; 932*7c478bd9Sstevel@tonic-gate case RE_FAIL_REMAP_LEN: 933*7c478bd9Sstevel@tonic-gate zcmn_err(zoneid, CE_NOTE, "![NFS4][Server: %s][Mntpt: %s]" 934*7c478bd9Sstevel@tonic-gate "remap_lookup: server %s returned bad " 935*7c478bd9Sstevel@tonic-gate "fhandle length (%d)", msg->msg_srv, msg->msg_mntpt, 936*7c478bd9Sstevel@tonic-gate msg->msg_srv, ep->re_uint); 937*7c478bd9Sstevel@tonic-gate break; 938*7c478bd9Sstevel@tonic-gate case RE_FAIL_REMAP_OP: 939*7c478bd9Sstevel@tonic-gate zcmn_err(zoneid, CE_NOTE, "![NFS4][Server: %s][Mntpt: %s]" 940*7c478bd9Sstevel@tonic-gate "remap_lookup: didn't get expected OP_GETFH" 941*7c478bd9Sstevel@tonic-gate " for server %s", msg->msg_srv, msg->msg_mntpt, 942*7c478bd9Sstevel@tonic-gate msg->msg_srv); 943*7c478bd9Sstevel@tonic-gate break; 944*7c478bd9Sstevel@tonic-gate case RE_FAILOVER: 945*7c478bd9Sstevel@tonic-gate if (ep->re_char1) 946*7c478bd9Sstevel@tonic-gate zcmn_err(zoneid, CE_NOTE, 947*7c478bd9Sstevel@tonic-gate "![NFS4][Server: %s][Mntpt: %s]" 948*7c478bd9Sstevel@tonic-gate "failing over from %s to %s", msg->msg_srv, 949*7c478bd9Sstevel@tonic-gate msg->msg_mntpt, msg->msg_srv, ep->re_char1); 950*7c478bd9Sstevel@tonic-gate else 951*7c478bd9Sstevel@tonic-gate zcmn_err(zoneid, CE_NOTE, 952*7c478bd9Sstevel@tonic-gate "![NFS4][Server: %s][Mntpt: %s]" 953*7c478bd9Sstevel@tonic-gate "NFS4: failing over: selecting " 954*7c478bd9Sstevel@tonic-gate "original server %s", msg->msg_srv, msg->msg_mntpt, 955*7c478bd9Sstevel@tonic-gate msg->msg_srv); 956*7c478bd9Sstevel@tonic-gate break; 957*7c478bd9Sstevel@tonic-gate case RE_FILE_DIFF: 958*7c478bd9Sstevel@tonic-gate zcmn_err(zoneid, CE_NOTE, "![NFS4][Server: %s][Mntpt: %s]" 959*7c478bd9Sstevel@tonic-gate "File %s (rnode_pt: %p) on server %s was closed " 960*7c478bd9Sstevel@tonic-gate "and failed attempted failover since its is different than " 961*7c478bd9Sstevel@tonic-gate "the original file", msg->msg_srv, msg->msg_mntpt, 962*7c478bd9Sstevel@tonic-gate ep->re_char1, (void *)ep->re_rp1, msg->msg_srv); 963*7c478bd9Sstevel@tonic-gate break; 964*7c478bd9Sstevel@tonic-gate case RE_LOST_STATE: 965*7c478bd9Sstevel@tonic-gate zcmn_err(zoneid, CE_NOTE, "![NFS4][Server: %s][Mntpt: %s]" 966*7c478bd9Sstevel@tonic-gate "Lost %s request for fs %s, file %s (rnode_pt: 0x%p), " 967*7c478bd9Sstevel@tonic-gate "dir %s (0x%p) for server %s", msg->msg_srv, msg->msg_mntpt, 968*7c478bd9Sstevel@tonic-gate nfs4_op_to_str(ep->re_uint), msg->msg_mntpt, 969*7c478bd9Sstevel@tonic-gate ep->re_char1, (void *)ep->re_rp1, ep->re_char2, 970*7c478bd9Sstevel@tonic-gate (void *)ep->re_rp2, msg->msg_srv); 971*7c478bd9Sstevel@tonic-gate break; 972*7c478bd9Sstevel@tonic-gate case RE_OPENS_CHANGED: 973*7c478bd9Sstevel@tonic-gate zcmn_err(zoneid, CE_NOTE, "![NFS4][Server: %s][Mntpt: %s]" 974*7c478bd9Sstevel@tonic-gate "The number of open files to reopen changed " 975*7c478bd9Sstevel@tonic-gate "for mount %s mi 0x%p (old %d, new %d) on server %s", 976*7c478bd9Sstevel@tonic-gate msg->msg_srv, msg->msg_mntpt, msg->msg_mntpt, 977*7c478bd9Sstevel@tonic-gate (void *)ep->re_mi, ep->re_uint, ep->re_pid, msg->msg_srv); 978*7c478bd9Sstevel@tonic-gate break; 979*7c478bd9Sstevel@tonic-gate case RE_SIGLOST: 980*7c478bd9Sstevel@tonic-gate case RE_SIGLOST_NO_DUMP: 981*7c478bd9Sstevel@tonic-gate if (ep->re_uint) 982*7c478bd9Sstevel@tonic-gate zcmn_err(zoneid, CE_NOTE, 983*7c478bd9Sstevel@tonic-gate "![NFS4][Server: %s][Mntpt: %s]" 984*7c478bd9Sstevel@tonic-gate "Process %d lost its locks on " 985*7c478bd9Sstevel@tonic-gate "file %s (rnode_pt: %p) due to NFS recovery error " 986*7c478bd9Sstevel@tonic-gate "(%d) on server %s.", msg->msg_srv, msg->msg_mntpt, 987*7c478bd9Sstevel@tonic-gate ep->re_pid, ep->re_char1, (void *)ep->re_rp1, 988*7c478bd9Sstevel@tonic-gate ep->re_uint, msg->msg_srv); 989*7c478bd9Sstevel@tonic-gate else 990*7c478bd9Sstevel@tonic-gate zcmn_err(zoneid, CE_NOTE, 991*7c478bd9Sstevel@tonic-gate "![NFS4][Server: %s][Mntpt: %s]" 992*7c478bd9Sstevel@tonic-gate "Process %d lost its locks on " 993*7c478bd9Sstevel@tonic-gate "file %s (rnode_pt: %p) due to NFS recovery error " 994*7c478bd9Sstevel@tonic-gate "(%s) on server %s.", msg->msg_srv, msg->msg_mntpt, 995*7c478bd9Sstevel@tonic-gate ep->re_pid, ep->re_char1, (void *)ep->re_rp1, 996*7c478bd9Sstevel@tonic-gate nfs4_stat_to_str(ep->re_stat4), msg->msg_srv); 997*7c478bd9Sstevel@tonic-gate break; 998*7c478bd9Sstevel@tonic-gate case RE_START: 999*7c478bd9Sstevel@tonic-gate zcmn_err(zoneid, CE_NOTE, "![NFS4][Server: %s][Mntpt: %s]" 1000*7c478bd9Sstevel@tonic-gate "NFS Starting recovery for mount %s " 1001*7c478bd9Sstevel@tonic-gate "(mi 0x%p mi_recovflags [0x%x]) on server %s, " 1002*7c478bd9Sstevel@tonic-gate "rnode_pt1 %s (0x%p), rnode_pt2 %s (0x%p)", msg->msg_srv, 1003*7c478bd9Sstevel@tonic-gate msg->msg_mntpt, msg->msg_mntpt, (void *)ep->re_mi, 1004*7c478bd9Sstevel@tonic-gate ep->re_uint, msg->msg_srv, ep->re_char1, (void *)ep->re_rp1, 1005*7c478bd9Sstevel@tonic-gate ep->re_char2, (void *)ep->re_rp2); 1006*7c478bd9Sstevel@tonic-gate break; 1007*7c478bd9Sstevel@tonic-gate case RE_UNEXPECTED_ACTION: 1008*7c478bd9Sstevel@tonic-gate zcmn_err(zoneid, CE_NOTE, "![NFS4][Server: %s][Mntpt: %s]" 1009*7c478bd9Sstevel@tonic-gate "NFS recovery: unexpected action (%s) on server %s", 1010*7c478bd9Sstevel@tonic-gate msg->msg_srv, msg->msg_mntpt, 1011*7c478bd9Sstevel@tonic-gate nfs4_recov_action_to_str(ep->re_uint), msg->msg_srv); 1012*7c478bd9Sstevel@tonic-gate break; 1013*7c478bd9Sstevel@tonic-gate case RE_UNEXPECTED_ERRNO: 1014*7c478bd9Sstevel@tonic-gate zcmn_err(zoneid, CE_NOTE, "![NFS4][Server: %s][Mntpt: %s]" 1015*7c478bd9Sstevel@tonic-gate "NFS recovery: unexpected errno (%d) on server %s", 1016*7c478bd9Sstevel@tonic-gate msg->msg_srv, msg->msg_mntpt, ep->re_uint, msg->msg_srv); 1017*7c478bd9Sstevel@tonic-gate break; 1018*7c478bd9Sstevel@tonic-gate case RE_UNEXPECTED_STATUS: 1019*7c478bd9Sstevel@tonic-gate zcmn_err(zoneid, CE_NOTE, "![NFS4][Server: %s][Mntpt: %s]" 1020*7c478bd9Sstevel@tonic-gate "NFS recovery: unexpected NFS status code (%s) " 1021*7c478bd9Sstevel@tonic-gate "on server %s", msg->msg_srv, msg->msg_mntpt, 1022*7c478bd9Sstevel@tonic-gate nfs4_stat_to_str(ep->re_stat4), 1023*7c478bd9Sstevel@tonic-gate msg->msg_srv); 1024*7c478bd9Sstevel@tonic-gate break; 1025*7c478bd9Sstevel@tonic-gate case RE_WRONGSEC: 1026*7c478bd9Sstevel@tonic-gate zcmn_err(zoneid, CE_NOTE, "![NFS4][Server: %s][Mntpt: %s]" 1027*7c478bd9Sstevel@tonic-gate "NFS can't recover from NFS4ERR_WRONGSEC." 1028*7c478bd9Sstevel@tonic-gate " error %d for server %s: rnode_pt1 %s (0x%p)" 1029*7c478bd9Sstevel@tonic-gate " rnode_pt2 %s (0x%p)", msg->msg_srv, msg->msg_mntpt, 1030*7c478bd9Sstevel@tonic-gate ep->re_uint, msg->msg_srv, ep->re_char1, (void *)ep->re_rp1, 1031*7c478bd9Sstevel@tonic-gate ep->re_char2, (void *)ep->re_rp2); 1032*7c478bd9Sstevel@tonic-gate break; 1033*7c478bd9Sstevel@tonic-gate case RE_LOST_STATE_BAD_OP: 1034*7c478bd9Sstevel@tonic-gate zcmn_err(zoneid, CE_NOTE, "![NFS4][Server: %s][Mntpt: %s]" 1035*7c478bd9Sstevel@tonic-gate "NFS lost state with unrecognized op (%d)." 1036*7c478bd9Sstevel@tonic-gate " fs %s, server %s, pid %d, file %s (rnode_pt: 0x%p), " 1037*7c478bd9Sstevel@tonic-gate "dir %s (0x%p)", msg->msg_srv, msg->msg_mntpt, 1038*7c478bd9Sstevel@tonic-gate ep->re_uint, msg->msg_mntpt, msg->msg_srv, ep->re_pid, 1039*7c478bd9Sstevel@tonic-gate ep->re_char1, (void *)ep->re_rp1, ep->re_char2, 1040*7c478bd9Sstevel@tonic-gate (void *)ep->re_rp2); 1041*7c478bd9Sstevel@tonic-gate break; 1042*7c478bd9Sstevel@tonic-gate default: 1043*7c478bd9Sstevel@tonic-gate zcmn_err(zoneid, CE_WARN, 1044*7c478bd9Sstevel@tonic-gate "!queue_print_event: illegal event %d", ep->re_type); 1045*7c478bd9Sstevel@tonic-gate break; 1046*7c478bd9Sstevel@tonic-gate } 1047*7c478bd9Sstevel@tonic-gate 1048*7c478bd9Sstevel@tonic-gate print_facts(msg, mi); 1049*7c478bd9Sstevel@tonic-gate 1050*7c478bd9Sstevel@tonic-gate /* 1051*7c478bd9Sstevel@tonic-gate * If set this event will not be printed again and is considered 1052*7c478bd9Sstevel@tonic-gate * dumped. 1053*7c478bd9Sstevel@tonic-gate */ 1054*7c478bd9Sstevel@tonic-gate if (dump) 1055*7c478bd9Sstevel@tonic-gate msg->msg_status = NFS4_MS_NO_DUMP; 1056*7c478bd9Sstevel@tonic-gate } 1057*7c478bd9Sstevel@tonic-gate 1058*7c478bd9Sstevel@tonic-gate /* 1059*7c478bd9Sstevel@tonic-gate * Print a fact message to /var/adm/messages 1060*7c478bd9Sstevel@tonic-gate */ 1061*7c478bd9Sstevel@tonic-gate static void 1062*7c478bd9Sstevel@tonic-gate queue_print_fact(nfs4_debug_msg_t *msg, int dump) 1063*7c478bd9Sstevel@tonic-gate { 1064*7c478bd9Sstevel@tonic-gate nfs4_rfact_t *fp; 1065*7c478bd9Sstevel@tonic-gate zoneid_t zoneid; 1066*7c478bd9Sstevel@tonic-gate 1067*7c478bd9Sstevel@tonic-gate fp = &msg->rmsg_u.msg_fact; 1068*7c478bd9Sstevel@tonic-gate zoneid = getzoneid(); 1069*7c478bd9Sstevel@tonic-gate 1070*7c478bd9Sstevel@tonic-gate switch (fp->rf_type) { 1071*7c478bd9Sstevel@tonic-gate case RF_BADOWNER: 1072*7c478bd9Sstevel@tonic-gate zcmn_err(zoneid, CE_NOTE, "![NFS4][Server: %s][Mntpt: %s]" 1073*7c478bd9Sstevel@tonic-gate "NFSMAPID_DOMAIN does not match the server: %s domain\n" 1074*7c478bd9Sstevel@tonic-gate "Please check configuration", msg->msg_srv, msg->msg_mntpt, 1075*7c478bd9Sstevel@tonic-gate msg->msg_srv); 1076*7c478bd9Sstevel@tonic-gate break; 1077*7c478bd9Sstevel@tonic-gate case RF_ERR: 1078*7c478bd9Sstevel@tonic-gate if (fp->rf_error) 1079*7c478bd9Sstevel@tonic-gate zcmn_err(zoneid, CE_NOTE, 1080*7c478bd9Sstevel@tonic-gate "![NFS4][Server: %s][Mntpt: %s]NFS op %s got " 1081*7c478bd9Sstevel@tonic-gate "error %d causing recovery action %s.%s", 1082*7c478bd9Sstevel@tonic-gate msg->msg_srv, msg->msg_mntpt, 1083*7c478bd9Sstevel@tonic-gate nfs4_op_to_str(fp->rf_op), fp->rf_error, 1084*7c478bd9Sstevel@tonic-gate nfs4_recov_action_to_str(fp->rf_action), 1085*7c478bd9Sstevel@tonic-gate fp->rf_reboot ? 1086*7c478bd9Sstevel@tonic-gate " Client also suspects that the server rebooted," 1087*7c478bd9Sstevel@tonic-gate " or experienced a network partition." : ""); 1088*7c478bd9Sstevel@tonic-gate else 1089*7c478bd9Sstevel@tonic-gate zcmn_err(zoneid, CE_NOTE, 1090*7c478bd9Sstevel@tonic-gate "![NFS4][Server: %s][Mntpt: %s]NFS op %s got " 1091*7c478bd9Sstevel@tonic-gate "error %s causing recovery action %s.%s", 1092*7c478bd9Sstevel@tonic-gate msg->msg_srv, msg->msg_mntpt, 1093*7c478bd9Sstevel@tonic-gate nfs4_op_to_str(fp->rf_op), 1094*7c478bd9Sstevel@tonic-gate nfs4_stat_to_str(fp->rf_stat4), 1095*7c478bd9Sstevel@tonic-gate nfs4_recov_action_to_str(fp->rf_action), 1096*7c478bd9Sstevel@tonic-gate fp->rf_reboot ? 1097*7c478bd9Sstevel@tonic-gate " Client also suspects that the server rebooted," 1098*7c478bd9Sstevel@tonic-gate " or experienced a network partition." : ""); 1099*7c478bd9Sstevel@tonic-gate break; 1100*7c478bd9Sstevel@tonic-gate case RF_RENEW_EXPIRED: 1101*7c478bd9Sstevel@tonic-gate zcmn_err(zoneid, CE_NOTE, "![NFS4][Server: %s][Mntpt: %s]" 1102*7c478bd9Sstevel@tonic-gate "NFS4 renew thread detected client's " 1103*7c478bd9Sstevel@tonic-gate "lease has expired. Current open files/locks/IO may fail", 1104*7c478bd9Sstevel@tonic-gate msg->msg_srv, msg->msg_mntpt); 1105*7c478bd9Sstevel@tonic-gate break; 1106*7c478bd9Sstevel@tonic-gate case RF_SRV_NOT_RESPOND: 1107*7c478bd9Sstevel@tonic-gate zcmn_err(zoneid, CE_NOTE, "![NFS4][Server: %s][Mntpt: %s]" 1108*7c478bd9Sstevel@tonic-gate "NFS server %s not responding; still trying\n", 1109*7c478bd9Sstevel@tonic-gate msg->msg_srv, msg->msg_mntpt, msg->msg_srv); 1110*7c478bd9Sstevel@tonic-gate break; 1111*7c478bd9Sstevel@tonic-gate case RF_SRV_OK: 1112*7c478bd9Sstevel@tonic-gate zcmn_err(zoneid, CE_NOTE, "![NFS4][Server: %s][Mntpt: %s]" 1113*7c478bd9Sstevel@tonic-gate "NFS server %s ok", msg->msg_srv, msg->msg_mntpt, 1114*7c478bd9Sstevel@tonic-gate msg->msg_srv); 1115*7c478bd9Sstevel@tonic-gate break; 1116*7c478bd9Sstevel@tonic-gate case RF_SRVS_NOT_RESPOND: 1117*7c478bd9Sstevel@tonic-gate zcmn_err(zoneid, CE_NOTE, "![NFS4][Server: %s][Mntpt: %s]" 1118*7c478bd9Sstevel@tonic-gate "NFS servers %s not responding; still trying", msg->msg_srv, 1119*7c478bd9Sstevel@tonic-gate msg->msg_mntpt, msg->msg_srv); 1120*7c478bd9Sstevel@tonic-gate break; 1121*7c478bd9Sstevel@tonic-gate case RF_SRVS_OK: 1122*7c478bd9Sstevel@tonic-gate zcmn_err(zoneid, CE_NOTE, "![NFS4][Server: %s][Mntpt: %s]" 1123*7c478bd9Sstevel@tonic-gate "NFS servers %s ok", msg->msg_srv, msg->msg_mntpt, 1124*7c478bd9Sstevel@tonic-gate msg->msg_srv); 1125*7c478bd9Sstevel@tonic-gate break; 1126*7c478bd9Sstevel@tonic-gate case RF_DELMAP_CB_ERR: 1127*7c478bd9Sstevel@tonic-gate zcmn_err(zoneid, CE_NOTE, "![NFS4][Server: %s][Mntpt: %s]" 1128*7c478bd9Sstevel@tonic-gate "NFS op %s got error %s when executing delmap on file %s " 1129*7c478bd9Sstevel@tonic-gate "(rnode_pt 0x%p).", 1130*7c478bd9Sstevel@tonic-gate msg->msg_srv, msg->msg_mntpt, nfs4_op_to_str(fp->rf_op), 1131*7c478bd9Sstevel@tonic-gate nfs4_stat_to_str(fp->rf_stat4), fp->rf_char1, 1132*7c478bd9Sstevel@tonic-gate (void *)fp->rf_rp1); 1133*7c478bd9Sstevel@tonic-gate break; 1134*7c478bd9Sstevel@tonic-gate default: 1135*7c478bd9Sstevel@tonic-gate zcmn_err(zoneid, CE_WARN, "!queue_print_fact: illegal fact %d", 1136*7c478bd9Sstevel@tonic-gate fp->rf_type); 1137*7c478bd9Sstevel@tonic-gate } 1138*7c478bd9Sstevel@tonic-gate 1139*7c478bd9Sstevel@tonic-gate /* 1140*7c478bd9Sstevel@tonic-gate * If set this fact will not be printed again and is considered 1141*7c478bd9Sstevel@tonic-gate * dumped. 1142*7c478bd9Sstevel@tonic-gate */ 1143*7c478bd9Sstevel@tonic-gate if (dump) 1144*7c478bd9Sstevel@tonic-gate msg->msg_status = NFS4_MS_NO_DUMP; 1145*7c478bd9Sstevel@tonic-gate } 1146*7c478bd9Sstevel@tonic-gate 1147*7c478bd9Sstevel@tonic-gate /* 1148*7c478bd9Sstevel@tonic-gate * Returns 1 if the entire queue should be dumped, 0 otherwise. 1149*7c478bd9Sstevel@tonic-gate */ 1150*7c478bd9Sstevel@tonic-gate static int 1151*7c478bd9Sstevel@tonic-gate id_to_dump_queue(nfs4_event_type_t id) 1152*7c478bd9Sstevel@tonic-gate { 1153*7c478bd9Sstevel@tonic-gate switch (id) { 1154*7c478bd9Sstevel@tonic-gate case RE_DEAD_FILE: 1155*7c478bd9Sstevel@tonic-gate case RE_SIGLOST: 1156*7c478bd9Sstevel@tonic-gate case RE_WRONGSEC: 1157*7c478bd9Sstevel@tonic-gate case RE_CLIENTID: 1158*7c478bd9Sstevel@tonic-gate return (1); 1159*7c478bd9Sstevel@tonic-gate default: 1160*7c478bd9Sstevel@tonic-gate return (0); 1161*7c478bd9Sstevel@tonic-gate } 1162*7c478bd9Sstevel@tonic-gate } 1163*7c478bd9Sstevel@tonic-gate 1164*7c478bd9Sstevel@tonic-gate /* 1165*7c478bd9Sstevel@tonic-gate * Returns 1 if the event (but not the entire queue) should be printed; 1166*7c478bd9Sstevel@tonic-gate * 0 otherwise. 1167*7c478bd9Sstevel@tonic-gate */ 1168*7c478bd9Sstevel@tonic-gate static int 1169*7c478bd9Sstevel@tonic-gate id_to_dump_solo_event(nfs4_event_type_t id) 1170*7c478bd9Sstevel@tonic-gate { 1171*7c478bd9Sstevel@tonic-gate switch (id) { 1172*7c478bd9Sstevel@tonic-gate case RE_BAD_SEQID: 1173*7c478bd9Sstevel@tonic-gate case RE_BADHANDLE: 1174*7c478bd9Sstevel@tonic-gate case RE_FAIL_REMAP_LEN: 1175*7c478bd9Sstevel@tonic-gate case RE_FAIL_REMAP_OP: 1176*7c478bd9Sstevel@tonic-gate case RE_FAILOVER: 1177*7c478bd9Sstevel@tonic-gate case RE_OPENS_CHANGED: 1178*7c478bd9Sstevel@tonic-gate case RE_SIGLOST_NO_DUMP: 1179*7c478bd9Sstevel@tonic-gate case RE_UNEXPECTED_ACTION: 1180*7c478bd9Sstevel@tonic-gate case RE_UNEXPECTED_ERRNO: 1181*7c478bd9Sstevel@tonic-gate case RE_UNEXPECTED_STATUS: 1182*7c478bd9Sstevel@tonic-gate case RE_LOST_STATE_BAD_OP: 1183*7c478bd9Sstevel@tonic-gate return (1); 1184*7c478bd9Sstevel@tonic-gate default: 1185*7c478bd9Sstevel@tonic-gate return (0); 1186*7c478bd9Sstevel@tonic-gate } 1187*7c478bd9Sstevel@tonic-gate } 1188*7c478bd9Sstevel@tonic-gate 1189*7c478bd9Sstevel@tonic-gate /* 1190*7c478bd9Sstevel@tonic-gate * Returns 1 if the fact (but not the entire queue) should be printed; 1191*7c478bd9Sstevel@tonic-gate * 0 otherwise. 1192*7c478bd9Sstevel@tonic-gate */ 1193*7c478bd9Sstevel@tonic-gate static int 1194*7c478bd9Sstevel@tonic-gate id_to_dump_solo_fact(nfs4_fact_type_t id) 1195*7c478bd9Sstevel@tonic-gate { 1196*7c478bd9Sstevel@tonic-gate switch (id) { 1197*7c478bd9Sstevel@tonic-gate case RF_SRV_NOT_RESPOND: 1198*7c478bd9Sstevel@tonic-gate case RF_SRV_OK: 1199*7c478bd9Sstevel@tonic-gate case RF_SRVS_NOT_RESPOND: 1200*7c478bd9Sstevel@tonic-gate case RF_SRVS_OK: 1201*7c478bd9Sstevel@tonic-gate return (1); 1202*7c478bd9Sstevel@tonic-gate default: 1203*7c478bd9Sstevel@tonic-gate return (0); 1204*7c478bd9Sstevel@tonic-gate } 1205*7c478bd9Sstevel@tonic-gate } 1206*7c478bd9Sstevel@tonic-gate 1207*7c478bd9Sstevel@tonic-gate /* 1208*7c478bd9Sstevel@tonic-gate * Update a kernel stat 1209*7c478bd9Sstevel@tonic-gate */ 1210*7c478bd9Sstevel@tonic-gate static void 1211*7c478bd9Sstevel@tonic-gate update_recov_kstats(nfs4_debug_msg_t *msg, mntinfo4_t *mi) 1212*7c478bd9Sstevel@tonic-gate { 1213*7c478bd9Sstevel@tonic-gate rkstat_t *rsp; 1214*7c478bd9Sstevel@tonic-gate 1215*7c478bd9Sstevel@tonic-gate if (!mi->mi_recov_ksp) 1216*7c478bd9Sstevel@tonic-gate return; 1217*7c478bd9Sstevel@tonic-gate 1218*7c478bd9Sstevel@tonic-gate rsp = (rkstat_t *)mi->mi_recov_ksp->ks_data; 1219*7c478bd9Sstevel@tonic-gate 1220*7c478bd9Sstevel@tonic-gate if (msg->msg_type == RM_EVENT) { 1221*7c478bd9Sstevel@tonic-gate switch (msg->rmsg_u.msg_event.re_type) { 1222*7c478bd9Sstevel@tonic-gate case RE_BADHANDLE: 1223*7c478bd9Sstevel@tonic-gate rsp->badhandle.value.ul++; 1224*7c478bd9Sstevel@tonic-gate break; 1225*7c478bd9Sstevel@tonic-gate case RE_CLIENTID: 1226*7c478bd9Sstevel@tonic-gate rsp->clientid.value.ul++; 1227*7c478bd9Sstevel@tonic-gate break; 1228*7c478bd9Sstevel@tonic-gate case RE_DEAD_FILE: 1229*7c478bd9Sstevel@tonic-gate rsp->dead_file.value.ul++; 1230*7c478bd9Sstevel@tonic-gate break; 1231*7c478bd9Sstevel@tonic-gate case RE_FAIL_RELOCK: 1232*7c478bd9Sstevel@tonic-gate rsp->fail_relock.value.ul++; 1233*7c478bd9Sstevel@tonic-gate break; 1234*7c478bd9Sstevel@tonic-gate case RE_FILE_DIFF: 1235*7c478bd9Sstevel@tonic-gate rsp->file_diff.value.ul++; 1236*7c478bd9Sstevel@tonic-gate break; 1237*7c478bd9Sstevel@tonic-gate case RE_OPENS_CHANGED: 1238*7c478bd9Sstevel@tonic-gate rsp->opens_changed.value.ul++; 1239*7c478bd9Sstevel@tonic-gate break; 1240*7c478bd9Sstevel@tonic-gate case RE_SIGLOST: 1241*7c478bd9Sstevel@tonic-gate case RE_SIGLOST_NO_DUMP: 1242*7c478bd9Sstevel@tonic-gate rsp->siglost.value.ul++; 1243*7c478bd9Sstevel@tonic-gate break; 1244*7c478bd9Sstevel@tonic-gate case RE_UNEXPECTED_ACTION: 1245*7c478bd9Sstevel@tonic-gate rsp->unexp_action.value.ul++; 1246*7c478bd9Sstevel@tonic-gate break; 1247*7c478bd9Sstevel@tonic-gate case RE_UNEXPECTED_ERRNO: 1248*7c478bd9Sstevel@tonic-gate rsp->unexp_errno.value.ul++; 1249*7c478bd9Sstevel@tonic-gate break; 1250*7c478bd9Sstevel@tonic-gate case RE_UNEXPECTED_STATUS: 1251*7c478bd9Sstevel@tonic-gate rsp->unexp_status.value.ul++; 1252*7c478bd9Sstevel@tonic-gate break; 1253*7c478bd9Sstevel@tonic-gate case RE_WRONGSEC: 1254*7c478bd9Sstevel@tonic-gate rsp->wrongsec.value.ul++; 1255*7c478bd9Sstevel@tonic-gate break; 1256*7c478bd9Sstevel@tonic-gate case RE_LOST_STATE_BAD_OP: 1257*7c478bd9Sstevel@tonic-gate rsp->lost_state_bad_op.value.ul++; 1258*7c478bd9Sstevel@tonic-gate break; 1259*7c478bd9Sstevel@tonic-gate default: 1260*7c478bd9Sstevel@tonic-gate break; 1261*7c478bd9Sstevel@tonic-gate } 1262*7c478bd9Sstevel@tonic-gate } else if (msg->msg_type == RM_FACT) { 1263*7c478bd9Sstevel@tonic-gate switch (msg->rmsg_u.msg_fact.rf_type) { 1264*7c478bd9Sstevel@tonic-gate case RF_BADOWNER: 1265*7c478bd9Sstevel@tonic-gate rsp->badowner.value.ul++; 1266*7c478bd9Sstevel@tonic-gate break; 1267*7c478bd9Sstevel@tonic-gate case RF_SRV_NOT_RESPOND: 1268*7c478bd9Sstevel@tonic-gate rsp->not_responding.value.ul++; 1269*7c478bd9Sstevel@tonic-gate break; 1270*7c478bd9Sstevel@tonic-gate default: 1271*7c478bd9Sstevel@tonic-gate break; 1272*7c478bd9Sstevel@tonic-gate } 1273*7c478bd9Sstevel@tonic-gate } 1274*7c478bd9Sstevel@tonic-gate } 1275*7c478bd9Sstevel@tonic-gate 1276*7c478bd9Sstevel@tonic-gate /* 1277*7c478bd9Sstevel@tonic-gate * Dump the mi's mi_msg_list of recovery messages. 1278*7c478bd9Sstevel@tonic-gate */ 1279*7c478bd9Sstevel@tonic-gate static void 1280*7c478bd9Sstevel@tonic-gate dump_queue(mntinfo4_t *mi, nfs4_debug_msg_t *msg) 1281*7c478bd9Sstevel@tonic-gate { 1282*7c478bd9Sstevel@tonic-gate nfs4_debug_msg_t *tmp_msg; 1283*7c478bd9Sstevel@tonic-gate 1284*7c478bd9Sstevel@tonic-gate ASSERT(mutex_owned(&mi->mi_msg_list_lock)); 1285*7c478bd9Sstevel@tonic-gate 1286*7c478bd9Sstevel@tonic-gate /* update kstats */ 1287*7c478bd9Sstevel@tonic-gate update_recov_kstats(msg, mi); 1288*7c478bd9Sstevel@tonic-gate 1289*7c478bd9Sstevel@tonic-gate /* 1290*7c478bd9Sstevel@tonic-gate * If we aren't supposed to dump the queue then see if we 1291*7c478bd9Sstevel@tonic-gate * should just print this single message, then return. 1292*7c478bd9Sstevel@tonic-gate */ 1293*7c478bd9Sstevel@tonic-gate if (!id_to_dump_queue(msg->rmsg_u.msg_event.re_type)) { 1294*7c478bd9Sstevel@tonic-gate if (id_to_dump_solo_event(msg->rmsg_u.msg_event.re_type)) 1295*7c478bd9Sstevel@tonic-gate queue_print_event(msg, mi, 0); 1296*7c478bd9Sstevel@tonic-gate return; 1297*7c478bd9Sstevel@tonic-gate } 1298*7c478bd9Sstevel@tonic-gate 1299*7c478bd9Sstevel@tonic-gate /* 1300*7c478bd9Sstevel@tonic-gate * Write all events/facts in the queue that haven't been 1301*7c478bd9Sstevel@tonic-gate * previously written to disk. 1302*7c478bd9Sstevel@tonic-gate */ 1303*7c478bd9Sstevel@tonic-gate tmp_msg = list_head(&mi->mi_msg_list); 1304*7c478bd9Sstevel@tonic-gate while (tmp_msg) { 1305*7c478bd9Sstevel@tonic-gate if (tmp_msg->msg_status == NFS4_MS_DUMP) { 1306*7c478bd9Sstevel@tonic-gate if (tmp_msg->msg_type == RM_EVENT) 1307*7c478bd9Sstevel@tonic-gate queue_print_event(tmp_msg, mi, 1); 1308*7c478bd9Sstevel@tonic-gate else if (tmp_msg->msg_type == RM_FACT) 1309*7c478bd9Sstevel@tonic-gate queue_print_fact(tmp_msg, 1); 1310*7c478bd9Sstevel@tonic-gate } 1311*7c478bd9Sstevel@tonic-gate tmp_msg = list_next(&mi->mi_msg_list, tmp_msg); 1312*7c478bd9Sstevel@tonic-gate } 1313*7c478bd9Sstevel@tonic-gate } 1314*7c478bd9Sstevel@tonic-gate 1315*7c478bd9Sstevel@tonic-gate /* 1316*7c478bd9Sstevel@tonic-gate * Places the event into mi's debug recovery message queue. Some of the 1317*7c478bd9Sstevel@tonic-gate * fields can be overloaded to be a generic value, depending on the event 1318*7c478bd9Sstevel@tonic-gate * type. These include "count", "why". 1319*7c478bd9Sstevel@tonic-gate */ 1320*7c478bd9Sstevel@tonic-gate void 1321*7c478bd9Sstevel@tonic-gate nfs4_queue_event(nfs4_event_type_t id, mntinfo4_t *mi, char *server1, 1322*7c478bd9Sstevel@tonic-gate uint_t count, vnode_t *vp1, vnode_t *vp2, nfsstat4 nfs4_error, 1323*7c478bd9Sstevel@tonic-gate char *why, pid_t pid, nfs4_tag_type_t tag1, nfs4_tag_type_t tag2, 1324*7c478bd9Sstevel@tonic-gate seqid4 seqid1, seqid4 seqid2) 1325*7c478bd9Sstevel@tonic-gate { 1326*7c478bd9Sstevel@tonic-gate nfs4_debug_msg_t *msg; 1327*7c478bd9Sstevel@tonic-gate nfs4_revent_t *ep; 1328*7c478bd9Sstevel@tonic-gate char *cur_srv; 1329*7c478bd9Sstevel@tonic-gate rnode4_t *rp1 = NULL, *rp2 = NULL; 1330*7c478bd9Sstevel@tonic-gate refstr_t *mntpt; 1331*7c478bd9Sstevel@tonic-gate 1332*7c478bd9Sstevel@tonic-gate ASSERT(mi != NULL); 1333*7c478bd9Sstevel@tonic-gate if (vp1) 1334*7c478bd9Sstevel@tonic-gate rp1 = VTOR4(vp1); 1335*7c478bd9Sstevel@tonic-gate if (vp2) 1336*7c478bd9Sstevel@tonic-gate rp2 = VTOR4(vp2); 1337*7c478bd9Sstevel@tonic-gate 1338*7c478bd9Sstevel@tonic-gate /* 1339*7c478bd9Sstevel@tonic-gate * Initialize the message with the relevent server/mount_pt/time 1340*7c478bd9Sstevel@tonic-gate * information. Also place the relevent event related info. 1341*7c478bd9Sstevel@tonic-gate */ 1342*7c478bd9Sstevel@tonic-gate msg = kmem_zalloc(sizeof (*msg), KM_SLEEP); 1343*7c478bd9Sstevel@tonic-gate msg->msg_type = RM_EVENT; 1344*7c478bd9Sstevel@tonic-gate msg->msg_status = NFS4_MS_DUMP; 1345*7c478bd9Sstevel@tonic-gate ep = &msg->rmsg_u.msg_event; 1346*7c478bd9Sstevel@tonic-gate ep->re_type = id; 1347*7c478bd9Sstevel@tonic-gate gethrestime(&msg->msg_time); 1348*7c478bd9Sstevel@tonic-gate 1349*7c478bd9Sstevel@tonic-gate cur_srv = mi->mi_curr_serv->sv_hostname; 1350*7c478bd9Sstevel@tonic-gate msg->msg_srv = strdup(cur_srv); 1351*7c478bd9Sstevel@tonic-gate mntpt = vfs_getmntpoint(mi->mi_vfsp); 1352*7c478bd9Sstevel@tonic-gate msg->msg_mntpt = strdup(refstr_value(mntpt)); 1353*7c478bd9Sstevel@tonic-gate refstr_rele(mntpt); 1354*7c478bd9Sstevel@tonic-gate 1355*7c478bd9Sstevel@tonic-gate set_event(id, ep, mi, rp1, rp2, count, pid, nfs4_error, server1, 1356*7c478bd9Sstevel@tonic-gate why, tag1, tag2, seqid1, seqid2); 1357*7c478bd9Sstevel@tonic-gate 1358*7c478bd9Sstevel@tonic-gate mutex_enter(&mi->mi_msg_list_lock); 1359*7c478bd9Sstevel@tonic-gate 1360*7c478bd9Sstevel@tonic-gate /* if this event is the same as the last event, drop it */ 1361*7c478bd9Sstevel@tonic-gate if (events_same(list_tail(&mi->mi_msg_list), msg, mi)) { 1362*7c478bd9Sstevel@tonic-gate mutex_exit(&mi->mi_msg_list_lock); 1363*7c478bd9Sstevel@tonic-gate nfs4_free_msg(msg); 1364*7c478bd9Sstevel@tonic-gate return; 1365*7c478bd9Sstevel@tonic-gate } 1366*7c478bd9Sstevel@tonic-gate 1367*7c478bd9Sstevel@tonic-gate /* queue the message at the end of the list */ 1368*7c478bd9Sstevel@tonic-gate list_insert_tail(&mi->mi_msg_list, msg); 1369*7c478bd9Sstevel@tonic-gate 1370*7c478bd9Sstevel@tonic-gate dump_queue(mi, msg); 1371*7c478bd9Sstevel@tonic-gate 1372*7c478bd9Sstevel@tonic-gate if (mi->mi_msg_count == nfs4_msg_max) { 1373*7c478bd9Sstevel@tonic-gate nfs4_debug_msg_t *rm_msg; 1374*7c478bd9Sstevel@tonic-gate 1375*7c478bd9Sstevel@tonic-gate /* remove the queue'd message at the front of the list */ 1376*7c478bd9Sstevel@tonic-gate rm_msg = list_head(&mi->mi_msg_list); 1377*7c478bd9Sstevel@tonic-gate list_remove(&mi->mi_msg_list, rm_msg); 1378*7c478bd9Sstevel@tonic-gate mutex_exit(&mi->mi_msg_list_lock); 1379*7c478bd9Sstevel@tonic-gate nfs4_free_msg(rm_msg); 1380*7c478bd9Sstevel@tonic-gate } else { 1381*7c478bd9Sstevel@tonic-gate mi->mi_msg_count++; 1382*7c478bd9Sstevel@tonic-gate mutex_exit(&mi->mi_msg_list_lock); 1383*7c478bd9Sstevel@tonic-gate } 1384*7c478bd9Sstevel@tonic-gate } 1385*7c478bd9Sstevel@tonic-gate 1386*7c478bd9Sstevel@tonic-gate /* 1387*7c478bd9Sstevel@tonic-gate * Places the fact into mi's debug recovery messages queue. 1388*7c478bd9Sstevel@tonic-gate */ 1389*7c478bd9Sstevel@tonic-gate void 1390*7c478bd9Sstevel@tonic-gate nfs4_queue_fact(nfs4_fact_type_t fid, mntinfo4_t *mi, nfsstat4 stat4, 1391*7c478bd9Sstevel@tonic-gate nfs4_recov_t raction, nfs_opnum4 op, bool_t reboot, char *srvname, 1392*7c478bd9Sstevel@tonic-gate int error, vnode_t *vp) 1393*7c478bd9Sstevel@tonic-gate { 1394*7c478bd9Sstevel@tonic-gate nfs4_debug_msg_t *msg; 1395*7c478bd9Sstevel@tonic-gate nfs4_rfact_t *fp; 1396*7c478bd9Sstevel@tonic-gate char *cur_srv; 1397*7c478bd9Sstevel@tonic-gate refstr_t *mntpt; 1398*7c478bd9Sstevel@tonic-gate 1399*7c478bd9Sstevel@tonic-gate /* 1400*7c478bd9Sstevel@tonic-gate * Initialize the message with the relevent server/mount_pt/time 1401*7c478bd9Sstevel@tonic-gate * information. Also place the relevent fact related info. 1402*7c478bd9Sstevel@tonic-gate */ 1403*7c478bd9Sstevel@tonic-gate msg = kmem_zalloc(sizeof (*msg), KM_SLEEP); 1404*7c478bd9Sstevel@tonic-gate msg->msg_type = RM_FACT; 1405*7c478bd9Sstevel@tonic-gate msg->msg_status = NFS4_MS_DUMP; 1406*7c478bd9Sstevel@tonic-gate gethrestime(&msg->msg_time); 1407*7c478bd9Sstevel@tonic-gate 1408*7c478bd9Sstevel@tonic-gate if (srvname) 1409*7c478bd9Sstevel@tonic-gate cur_srv = srvname; 1410*7c478bd9Sstevel@tonic-gate else 1411*7c478bd9Sstevel@tonic-gate cur_srv = mi->mi_curr_serv->sv_hostname; 1412*7c478bd9Sstevel@tonic-gate 1413*7c478bd9Sstevel@tonic-gate msg->msg_srv = strdup(cur_srv); 1414*7c478bd9Sstevel@tonic-gate mntpt = vfs_getmntpoint(mi->mi_vfsp); 1415*7c478bd9Sstevel@tonic-gate msg->msg_mntpt = strdup(refstr_value(mntpt)); 1416*7c478bd9Sstevel@tonic-gate refstr_rele(mntpt); 1417*7c478bd9Sstevel@tonic-gate 1418*7c478bd9Sstevel@tonic-gate fp = &msg->rmsg_u.msg_fact; 1419*7c478bd9Sstevel@tonic-gate fp->rf_type = fid; 1420*7c478bd9Sstevel@tonic-gate fp->rf_status = RFS_NO_INSPECT; 1421*7c478bd9Sstevel@tonic-gate set_fact(fid, fp, stat4, raction, op, reboot, error, vp); 1422*7c478bd9Sstevel@tonic-gate 1423*7c478bd9Sstevel@tonic-gate update_recov_kstats(msg, mi); 1424*7c478bd9Sstevel@tonic-gate 1425*7c478bd9Sstevel@tonic-gate mutex_enter(&mi->mi_msg_list_lock); 1426*7c478bd9Sstevel@tonic-gate 1427*7c478bd9Sstevel@tonic-gate /* if this fact is the same as the last fact, drop it */ 1428*7c478bd9Sstevel@tonic-gate if (facts_same(list_tail(&mi->mi_msg_list), msg, mi)) { 1429*7c478bd9Sstevel@tonic-gate mutex_exit(&mi->mi_msg_list_lock); 1430*7c478bd9Sstevel@tonic-gate nfs4_free_msg(msg); 1431*7c478bd9Sstevel@tonic-gate return; 1432*7c478bd9Sstevel@tonic-gate } 1433*7c478bd9Sstevel@tonic-gate 1434*7c478bd9Sstevel@tonic-gate /* queue the message at the end of the list */ 1435*7c478bd9Sstevel@tonic-gate list_insert_tail(&mi->mi_msg_list, msg); 1436*7c478bd9Sstevel@tonic-gate 1437*7c478bd9Sstevel@tonic-gate if (id_to_dump_solo_fact(msg->rmsg_u.msg_fact.rf_type)) 1438*7c478bd9Sstevel@tonic-gate queue_print_fact(msg, 0); 1439*7c478bd9Sstevel@tonic-gate 1440*7c478bd9Sstevel@tonic-gate if (mi->mi_msg_count == nfs4_msg_max) { 1441*7c478bd9Sstevel@tonic-gate nfs4_debug_msg_t *rm_msg; 1442*7c478bd9Sstevel@tonic-gate 1443*7c478bd9Sstevel@tonic-gate /* remove the queue'd message at the front of the list */ 1444*7c478bd9Sstevel@tonic-gate rm_msg = list_head(&mi->mi_msg_list); 1445*7c478bd9Sstevel@tonic-gate list_remove(&mi->mi_msg_list, rm_msg); 1446*7c478bd9Sstevel@tonic-gate mutex_exit(&mi->mi_msg_list_lock); 1447*7c478bd9Sstevel@tonic-gate nfs4_free_msg(rm_msg); 1448*7c478bd9Sstevel@tonic-gate } else { 1449*7c478bd9Sstevel@tonic-gate mi->mi_msg_count++; 1450*7c478bd9Sstevel@tonic-gate mutex_exit(&mi->mi_msg_list_lock); 1451*7c478bd9Sstevel@tonic-gate } 1452*7c478bd9Sstevel@tonic-gate } 1453*7c478bd9Sstevel@tonic-gate 1454*7c478bd9Sstevel@tonic-gate /* 1455*7c478bd9Sstevel@tonic-gate * Initialize the 'mi_recov_kstat' kstat. 1456*7c478bd9Sstevel@tonic-gate */ 1457*7c478bd9Sstevel@tonic-gate void 1458*7c478bd9Sstevel@tonic-gate nfs4_mnt_recov_kstat_init(vfs_t *vfsp) 1459*7c478bd9Sstevel@tonic-gate { 1460*7c478bd9Sstevel@tonic-gate mntinfo4_t *mi = VFTOMI4(vfsp); 1461*7c478bd9Sstevel@tonic-gate kstat_t *ksp; 1462*7c478bd9Sstevel@tonic-gate zoneid_t zoneid = mi->mi_zone->zone_id; 1463*7c478bd9Sstevel@tonic-gate 1464*7c478bd9Sstevel@tonic-gate /* 1465*7c478bd9Sstevel@tonic-gate * Create the version specific kstats. 1466*7c478bd9Sstevel@tonic-gate * 1467*7c478bd9Sstevel@tonic-gate * PSARC 2001/697 Contract Private Interface 1468*7c478bd9Sstevel@tonic-gate * All nfs kstats are under SunMC contract 1469*7c478bd9Sstevel@tonic-gate * Please refer to the PSARC listed above and contact 1470*7c478bd9Sstevel@tonic-gate * SunMC before making any changes! 1471*7c478bd9Sstevel@tonic-gate * 1472*7c478bd9Sstevel@tonic-gate * Changes must be reviewed by Solaris File Sharing 1473*7c478bd9Sstevel@tonic-gate * Changes must be communicated to contract-2001-697@sun.com 1474*7c478bd9Sstevel@tonic-gate * 1475*7c478bd9Sstevel@tonic-gate */ 1476*7c478bd9Sstevel@tonic-gate 1477*7c478bd9Sstevel@tonic-gate if ((ksp = kstat_create_zone("nfs", getminor(vfsp->vfs_dev), 1478*7c478bd9Sstevel@tonic-gate "mi_recov_kstat", "misc", KSTAT_TYPE_NAMED, 1479*7c478bd9Sstevel@tonic-gate sizeof (rkstat_t) / sizeof (kstat_named_t), 1480*7c478bd9Sstevel@tonic-gate KSTAT_FLAG_WRITABLE, zoneid)) == NULL) { 1481*7c478bd9Sstevel@tonic-gate mi->mi_recov_ksp = NULL; 1482*7c478bd9Sstevel@tonic-gate zcmn_err(GLOBAL_ZONEID, CE_NOTE, 1483*7c478bd9Sstevel@tonic-gate "!mi_recov_kstat for mi %p failed\n", 1484*7c478bd9Sstevel@tonic-gate (void *)mi); 1485*7c478bd9Sstevel@tonic-gate return; 1486*7c478bd9Sstevel@tonic-gate } 1487*7c478bd9Sstevel@tonic-gate if (zoneid != GLOBAL_ZONEID) 1488*7c478bd9Sstevel@tonic-gate kstat_zone_add(ksp, GLOBAL_ZONEID); 1489*7c478bd9Sstevel@tonic-gate mi->mi_recov_ksp = ksp; 1490*7c478bd9Sstevel@tonic-gate bcopy(&rkstat_template, ksp->ks_data, sizeof (rkstat_t)); 1491*7c478bd9Sstevel@tonic-gate kstat_install(ksp); 1492*7c478bd9Sstevel@tonic-gate } 1493*7c478bd9Sstevel@tonic-gate 1494*7c478bd9Sstevel@tonic-gate /* 1495*7c478bd9Sstevel@tonic-gate * Increment the "delay" kstat. 1496*7c478bd9Sstevel@tonic-gate */ 1497*7c478bd9Sstevel@tonic-gate void 1498*7c478bd9Sstevel@tonic-gate nfs4_mi_kstat_inc_delay(mntinfo4_t *mi) 1499*7c478bd9Sstevel@tonic-gate { 1500*7c478bd9Sstevel@tonic-gate rkstat_t *rsp; 1501*7c478bd9Sstevel@tonic-gate 1502*7c478bd9Sstevel@tonic-gate if (!mi->mi_recov_ksp) 1503*7c478bd9Sstevel@tonic-gate return; 1504*7c478bd9Sstevel@tonic-gate 1505*7c478bd9Sstevel@tonic-gate rsp = (rkstat_t *)mi->mi_recov_ksp->ks_data; 1506*7c478bd9Sstevel@tonic-gate rsp->delay.value.ul++; 1507*7c478bd9Sstevel@tonic-gate } 1508*7c478bd9Sstevel@tonic-gate 1509*7c478bd9Sstevel@tonic-gate /* 1510*7c478bd9Sstevel@tonic-gate * Increment the "no_grace" kstat. 1511*7c478bd9Sstevel@tonic-gate */ 1512*7c478bd9Sstevel@tonic-gate void 1513*7c478bd9Sstevel@tonic-gate nfs4_mi_kstat_inc_no_grace(mntinfo4_t *mi) 1514*7c478bd9Sstevel@tonic-gate { 1515*7c478bd9Sstevel@tonic-gate rkstat_t *rsp; 1516*7c478bd9Sstevel@tonic-gate 1517*7c478bd9Sstevel@tonic-gate if (!mi->mi_recov_ksp) 1518*7c478bd9Sstevel@tonic-gate return; 1519*7c478bd9Sstevel@tonic-gate 1520*7c478bd9Sstevel@tonic-gate rsp = (rkstat_t *)mi->mi_recov_ksp->ks_data; 1521*7c478bd9Sstevel@tonic-gate rsp->no_grace.value.ul++; 1522*7c478bd9Sstevel@tonic-gate } 1523*7c478bd9Sstevel@tonic-gate 1524*7c478bd9Sstevel@tonic-gate /* 1525*7c478bd9Sstevel@tonic-gate * Allocate and copy a string. XXX There really ought to be a single 1526*7c478bd9Sstevel@tonic-gate * strdup() for the entire kernel. 1527*7c478bd9Sstevel@tonic-gate */ 1528*7c478bd9Sstevel@tonic-gate static char * 1529*7c478bd9Sstevel@tonic-gate strdup(const char *s) 1530*7c478bd9Sstevel@tonic-gate { 1531*7c478bd9Sstevel@tonic-gate size_t len; 1532*7c478bd9Sstevel@tonic-gate char *new; 1533*7c478bd9Sstevel@tonic-gate 1534*7c478bd9Sstevel@tonic-gate len = strlen(s); 1535*7c478bd9Sstevel@tonic-gate new = kmem_alloc(len + 1, KM_SLEEP); 1536*7c478bd9Sstevel@tonic-gate bcopy(s, new, len); 1537*7c478bd9Sstevel@tonic-gate new[len] = '\0'; 1538*7c478bd9Sstevel@tonic-gate 1539*7c478bd9Sstevel@tonic-gate return (new); 1540*7c478bd9Sstevel@tonic-gate } 1541