10Sstevel@tonic-gate /*
20Sstevel@tonic-gate * CDDL HEADER START
30Sstevel@tonic-gate *
40Sstevel@tonic-gate * The contents of this file are subject to the terms of the
58863SEdward.Pilatowicz@Sun.COM * Common Development and Distribution License (the "License").
68863SEdward.Pilatowicz@Sun.COM * You may not use this file except in compliance with the License.
70Sstevel@tonic-gate *
80Sstevel@tonic-gate * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
90Sstevel@tonic-gate * or http://www.opensolaris.org/os/licensing.
100Sstevel@tonic-gate * See the License for the specific language governing permissions
110Sstevel@tonic-gate * and limitations under the License.
120Sstevel@tonic-gate *
130Sstevel@tonic-gate * When distributing Covered Code, include this CDDL HEADER in each
140Sstevel@tonic-gate * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
150Sstevel@tonic-gate * If applicable, add the following below this CDDL HEADER, with the
160Sstevel@tonic-gate * fields enclosed by brackets "[]" replaced with your own identifying
170Sstevel@tonic-gate * information: Portions Copyright [yyyy] [name of copyright owner]
180Sstevel@tonic-gate *
190Sstevel@tonic-gate * CDDL HEADER END
200Sstevel@tonic-gate */
210Sstevel@tonic-gate /*
228863SEdward.Pilatowicz@Sun.COM * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
230Sstevel@tonic-gate * Use is subject to license terms.
240Sstevel@tonic-gate */
250Sstevel@tonic-gate
260Sstevel@tonic-gate #include <sys/cred.h>
270Sstevel@tonic-gate #include <sys/kstat.h>
280Sstevel@tonic-gate #include <sys/list.h>
290Sstevel@tonic-gate #include <sys/systm.h>
300Sstevel@tonic-gate #include <sys/vfs.h>
310Sstevel@tonic-gate #include <sys/vnode.h>
320Sstevel@tonic-gate #include <sys/cmn_err.h>
330Sstevel@tonic-gate
340Sstevel@tonic-gate #include <nfs/nfs4_clnt.h>
350Sstevel@tonic-gate #include <nfs/rnode4.h>
360Sstevel@tonic-gate
370Sstevel@tonic-gate /*
380Sstevel@tonic-gate * Recovery kstats
390Sstevel@tonic-gate */
400Sstevel@tonic-gate typedef struct rkstat {
410Sstevel@tonic-gate kstat_named_t badhandle;
420Sstevel@tonic-gate kstat_named_t badowner;
430Sstevel@tonic-gate kstat_named_t clientid;
440Sstevel@tonic-gate kstat_named_t dead_file;
450Sstevel@tonic-gate kstat_named_t delay;
460Sstevel@tonic-gate kstat_named_t fail_relock;
470Sstevel@tonic-gate kstat_named_t file_diff;
480Sstevel@tonic-gate kstat_named_t no_grace;
490Sstevel@tonic-gate kstat_named_t not_responding;
500Sstevel@tonic-gate kstat_named_t opens_changed;
510Sstevel@tonic-gate kstat_named_t siglost;
520Sstevel@tonic-gate kstat_named_t unexp_action;
530Sstevel@tonic-gate kstat_named_t unexp_errno;
540Sstevel@tonic-gate kstat_named_t unexp_status;
550Sstevel@tonic-gate kstat_named_t wrongsec;
560Sstevel@tonic-gate kstat_named_t lost_state_bad_op;
570Sstevel@tonic-gate } rkstat_t;
580Sstevel@tonic-gate
590Sstevel@tonic-gate static rkstat_t rkstat_template = {
600Sstevel@tonic-gate { "badhandle", KSTAT_DATA_ULONG },
610Sstevel@tonic-gate { "badowner", KSTAT_DATA_ULONG },
620Sstevel@tonic-gate { "clientid", KSTAT_DATA_ULONG },
630Sstevel@tonic-gate { "dead_file", KSTAT_DATA_ULONG },
640Sstevel@tonic-gate { "delay", KSTAT_DATA_ULONG },
650Sstevel@tonic-gate { "fail_relock", KSTAT_DATA_ULONG },
660Sstevel@tonic-gate { "file_diff", KSTAT_DATA_ULONG },
670Sstevel@tonic-gate { "no_grace", KSTAT_DATA_ULONG },
680Sstevel@tonic-gate { "not_responding", KSTAT_DATA_ULONG },
690Sstevel@tonic-gate { "opens_changed", KSTAT_DATA_ULONG },
700Sstevel@tonic-gate { "siglost", KSTAT_DATA_ULONG },
710Sstevel@tonic-gate { "unexp_action", KSTAT_DATA_ULONG },
720Sstevel@tonic-gate { "unexp_errno", KSTAT_DATA_ULONG },
730Sstevel@tonic-gate { "unexp_status", KSTAT_DATA_ULONG },
740Sstevel@tonic-gate { "wrongsec", KSTAT_DATA_ULONG },
750Sstevel@tonic-gate { "bad_op", KSTAT_DATA_ULONG },
760Sstevel@tonic-gate };
770Sstevel@tonic-gate
780Sstevel@tonic-gate /* maximum number of messages allowed on the mi's mi_msg_list */
790Sstevel@tonic-gate int nfs4_msg_max = NFS4_MSG_MAX;
800Sstevel@tonic-gate #define DEFAULT_LEASE 180
810Sstevel@tonic-gate
820Sstevel@tonic-gate /*
830Sstevel@tonic-gate * Sets the appropiate fields of "ep", given "id" and various parameters.
840Sstevel@tonic-gate * Assumes that ep's fields have been initialized to zero/null, except for
850Sstevel@tonic-gate * re_type and mount point info, which are already set.
860Sstevel@tonic-gate */
870Sstevel@tonic-gate static void
set_event(nfs4_event_type_t id,nfs4_revent_t * ep,mntinfo4_t * mi,rnode4_t * rp1,rnode4_t * rp2,uint_t count,pid_t pid,nfsstat4 nfs4_error,char * server1,char * why,nfs4_tag_type_t tag1,nfs4_tag_type_t tag2,seqid4 seqid1,seqid4 seqid2)880Sstevel@tonic-gate set_event(nfs4_event_type_t id, nfs4_revent_t *ep, mntinfo4_t *mi,
890Sstevel@tonic-gate rnode4_t *rp1, rnode4_t *rp2, uint_t count, pid_t pid, nfsstat4 nfs4_error,
900Sstevel@tonic-gate char *server1, char *why, nfs4_tag_type_t tag1, nfs4_tag_type_t tag2,
910Sstevel@tonic-gate seqid4 seqid1, seqid4 seqid2)
920Sstevel@tonic-gate {
930Sstevel@tonic-gate int len;
940Sstevel@tonic-gate
950Sstevel@tonic-gate switch (id) {
960Sstevel@tonic-gate case RE_BAD_SEQID:
970Sstevel@tonic-gate ep->re_mi = mi;
980Sstevel@tonic-gate
990Sstevel@tonic-gate /* bad seqid'd file <path/component name> */
1000Sstevel@tonic-gate if (rp1 && rp1->r_svnode.sv_name)
1010Sstevel@tonic-gate ep->re_char1 = fn_path(rp1->r_svnode.sv_name);
1020Sstevel@tonic-gate else
1030Sstevel@tonic-gate ep->re_char1 = NULL;
1040Sstevel@tonic-gate ep->re_rp1 = rp1;
1050Sstevel@tonic-gate
1060Sstevel@tonic-gate /* for LOCK/LOCKU */
1070Sstevel@tonic-gate ep->re_pid = pid;
1080Sstevel@tonic-gate
1090Sstevel@tonic-gate ep->re_stat4 = nfs4_error;
1100Sstevel@tonic-gate ep->re_tag1 = tag1;
1110Sstevel@tonic-gate ep->re_tag2 = tag2;
1120Sstevel@tonic-gate ep->re_seqid1 = seqid1;
1130Sstevel@tonic-gate ep->re_seqid2 = seqid2;
1140Sstevel@tonic-gate break;
1150Sstevel@tonic-gate case RE_BADHANDLE:
1160Sstevel@tonic-gate ASSERT(rp1 != NULL);
1170Sstevel@tonic-gate
1180Sstevel@tonic-gate /* dead file <path/component name> */
1190Sstevel@tonic-gate if (rp1->r_svnode.sv_name)
1200Sstevel@tonic-gate ep->re_char1 = fn_path(rp1->r_svnode.sv_name);
1210Sstevel@tonic-gate else
1220Sstevel@tonic-gate ep->re_char1 = NULL;
1230Sstevel@tonic-gate ep->re_rp1 = rp1;
1240Sstevel@tonic-gate break;
1250Sstevel@tonic-gate case RE_CLIENTID:
1260Sstevel@tonic-gate ep->re_mi = mi;
1270Sstevel@tonic-gate
1280Sstevel@tonic-gate /* the error we failed with */
1290Sstevel@tonic-gate ep->re_uint = count;
1300Sstevel@tonic-gate ep->re_stat4 = nfs4_error;
1310Sstevel@tonic-gate break;
1320Sstevel@tonic-gate case RE_DEAD_FILE:
1330Sstevel@tonic-gate ASSERT(rp1 != NULL);
1340Sstevel@tonic-gate
1350Sstevel@tonic-gate /* dead file <path/component name> */
1360Sstevel@tonic-gate if (rp1->r_svnode.sv_name)
1370Sstevel@tonic-gate ep->re_char1 = fn_path(rp1->r_svnode.sv_name);
1380Sstevel@tonic-gate else
1390Sstevel@tonic-gate ep->re_char1 = NULL;
1400Sstevel@tonic-gate ep->re_rp1 = rp1;
1410Sstevel@tonic-gate
1420Sstevel@tonic-gate /* why the file got killed */
1430Sstevel@tonic-gate if (why) {
1440Sstevel@tonic-gate len = strlen(why);
1450Sstevel@tonic-gate ep->re_char2 = kmem_alloc(len + 1, KM_SLEEP);
1460Sstevel@tonic-gate bcopy(why, ep->re_char2, len);
1470Sstevel@tonic-gate ep->re_char2[len] = '\0';
1480Sstevel@tonic-gate } else
1490Sstevel@tonic-gate ep->re_char2 = NULL;
1500Sstevel@tonic-gate
1510Sstevel@tonic-gate ep->re_stat4 = nfs4_error;
1520Sstevel@tonic-gate break;
1530Sstevel@tonic-gate case RE_END:
1540Sstevel@tonic-gate /* first rnode */
1550Sstevel@tonic-gate if (rp1 && rp1->r_svnode.sv_name)
1560Sstevel@tonic-gate ep->re_char1 = fn_path(rp1->r_svnode.sv_name);
1570Sstevel@tonic-gate else
1580Sstevel@tonic-gate ep->re_char1 = NULL;
1590Sstevel@tonic-gate ep->re_rp1 = rp1;
1600Sstevel@tonic-gate
1610Sstevel@tonic-gate /* second rnode */
1620Sstevel@tonic-gate if (rp2 && rp2->r_svnode.sv_name)
1630Sstevel@tonic-gate ep->re_char2 = fn_path(rp2->r_svnode.sv_name);
1640Sstevel@tonic-gate else
1650Sstevel@tonic-gate ep->re_char2 = NULL;
1660Sstevel@tonic-gate ep->re_rp2 = rp2;
1670Sstevel@tonic-gate
1680Sstevel@tonic-gate ep->re_mi = mi;
1690Sstevel@tonic-gate break;
1700Sstevel@tonic-gate case RE_FAIL_RELOCK:
1710Sstevel@tonic-gate ASSERT(rp1 != NULL);
1720Sstevel@tonic-gate
1730Sstevel@tonic-gate /* error on fail relock */
1740Sstevel@tonic-gate ep->re_uint = count;
1750Sstevel@tonic-gate
1760Sstevel@tonic-gate /* process that failed */
1770Sstevel@tonic-gate ep->re_pid = pid;
1780Sstevel@tonic-gate
1790Sstevel@tonic-gate /* nfs4 error */
1800Sstevel@tonic-gate ep->re_stat4 = nfs4_error;
1810Sstevel@tonic-gate
1820Sstevel@tonic-gate /* file <path/component name> */
1830Sstevel@tonic-gate if (rp1->r_svnode.sv_name)
1840Sstevel@tonic-gate ep->re_char1 = fn_path(rp1->r_svnode.sv_name);
1850Sstevel@tonic-gate else
1860Sstevel@tonic-gate ep->re_char1 = NULL;
1870Sstevel@tonic-gate ep->re_rp1 = rp1;
1880Sstevel@tonic-gate break;
1890Sstevel@tonic-gate case RE_FAIL_REMAP_LEN:
1900Sstevel@tonic-gate /* length of returned filehandle */
1910Sstevel@tonic-gate ep->re_uint = count;
1920Sstevel@tonic-gate break;
1930Sstevel@tonic-gate case RE_FAIL_REMAP_OP:
1940Sstevel@tonic-gate break;
1950Sstevel@tonic-gate case RE_FAILOVER:
1960Sstevel@tonic-gate /* server we're failing over to (if not picking original) */
1970Sstevel@tonic-gate if (server1 != NULL) {
1980Sstevel@tonic-gate len = strlen(server1);
1990Sstevel@tonic-gate ep->re_char1 = kmem_alloc(len + 1, KM_SLEEP);
2000Sstevel@tonic-gate bcopy(server1, ep->re_char1, len);
2010Sstevel@tonic-gate ep->re_char1[len] = '\0';
2020Sstevel@tonic-gate } else {
2030Sstevel@tonic-gate ep->re_char1 = NULL;
2040Sstevel@tonic-gate }
2050Sstevel@tonic-gate break;
2060Sstevel@tonic-gate case RE_FILE_DIFF:
2070Sstevel@tonic-gate ASSERT(rp1 != NULL);
2080Sstevel@tonic-gate
2090Sstevel@tonic-gate /* dead file <path/component name> */
2100Sstevel@tonic-gate if (rp1->r_svnode.sv_name)
2110Sstevel@tonic-gate ep->re_char1 = fn_path(rp1->r_svnode.sv_name);
2120Sstevel@tonic-gate else
2130Sstevel@tonic-gate ep->re_char1 = NULL;
2140Sstevel@tonic-gate ep->re_rp1 = rp1;
2150Sstevel@tonic-gate break;
2160Sstevel@tonic-gate case RE_LOST_STATE:
2170Sstevel@tonic-gate ep->re_uint = count; /* op number */
2180Sstevel@tonic-gate if (rp1 && rp1->r_svnode.sv_name)
2190Sstevel@tonic-gate ep->re_char1 = fn_path(rp1->r_svnode.sv_name);
2200Sstevel@tonic-gate else
2210Sstevel@tonic-gate ep->re_char1 = NULL;
2220Sstevel@tonic-gate ep->re_rp1 = rp1;
2230Sstevel@tonic-gate if (rp2 && rp2->r_svnode.sv_name)
2240Sstevel@tonic-gate ep->re_char2 = fn_path(rp2->r_svnode.sv_name);
2250Sstevel@tonic-gate else
2260Sstevel@tonic-gate ep->re_char2 = NULL;
2270Sstevel@tonic-gate ep->re_rp2 = rp2;
2280Sstevel@tonic-gate break;
2290Sstevel@tonic-gate case RE_OPENS_CHANGED:
2300Sstevel@tonic-gate ep->re_mi = mi;
2310Sstevel@tonic-gate
2320Sstevel@tonic-gate /* original number of open files */
2330Sstevel@tonic-gate ep->re_uint = count;
2340Sstevel@tonic-gate /* new number of open files */
2350Sstevel@tonic-gate ep->re_pid = pid;
2360Sstevel@tonic-gate break;
2370Sstevel@tonic-gate case RE_SIGLOST:
2380Sstevel@tonic-gate case RE_SIGLOST_NO_DUMP:
2390Sstevel@tonic-gate ASSERT(rp1 != NULL);
2400Sstevel@tonic-gate
2410Sstevel@tonic-gate /* file <path/component name> */
2420Sstevel@tonic-gate if (rp1->r_svnode.sv_name)
2430Sstevel@tonic-gate ep->re_char1 = fn_path(rp1->r_svnode.sv_name);
2440Sstevel@tonic-gate else
2450Sstevel@tonic-gate ep->re_char1 = NULL;
2460Sstevel@tonic-gate ep->re_rp1 = rp1;
2470Sstevel@tonic-gate ep->re_pid = pid;
2480Sstevel@tonic-gate ep->re_uint = count;
2490Sstevel@tonic-gate ep->re_stat4 = nfs4_error;
2500Sstevel@tonic-gate break;
2510Sstevel@tonic-gate case RE_START:
2520Sstevel@tonic-gate /* file <path/component name> */
2530Sstevel@tonic-gate if (rp1 && rp1->r_svnode.sv_name)
2540Sstevel@tonic-gate ep->re_char1 = fn_path(rp1->r_svnode.sv_name);
2550Sstevel@tonic-gate else
2560Sstevel@tonic-gate ep->re_char1 = NULL;
2570Sstevel@tonic-gate ep->re_rp1 = rp1;
2580Sstevel@tonic-gate
2590Sstevel@tonic-gate /* file <path/component name> */
2600Sstevel@tonic-gate if (rp2 && rp2->r_svnode.sv_name)
2610Sstevel@tonic-gate ep->re_char2 = fn_path(rp2->r_svnode.sv_name);
2620Sstevel@tonic-gate else
2630Sstevel@tonic-gate ep->re_char2 = NULL;
2640Sstevel@tonic-gate ep->re_rp2 = rp2;
2650Sstevel@tonic-gate
2660Sstevel@tonic-gate ep->re_mi = mi;
2670Sstevel@tonic-gate ep->re_uint = count;
2680Sstevel@tonic-gate break;
2690Sstevel@tonic-gate case RE_UNEXPECTED_ACTION:
2700Sstevel@tonic-gate case RE_UNEXPECTED_ERRNO:
2710Sstevel@tonic-gate /* the error that is unexpected */
2720Sstevel@tonic-gate ep->re_uint = count;
2730Sstevel@tonic-gate break;
2740Sstevel@tonic-gate case RE_UNEXPECTED_STATUS:
2750Sstevel@tonic-gate /* nfsstat4 error */
2760Sstevel@tonic-gate ep->re_stat4 = nfs4_error;
2770Sstevel@tonic-gate break;
2780Sstevel@tonic-gate case RE_WRONGSEC:
2790Sstevel@tonic-gate /* the error we failed with */
2800Sstevel@tonic-gate ep->re_uint = count;
2810Sstevel@tonic-gate
2820Sstevel@tonic-gate /* file <path/component name> */
2830Sstevel@tonic-gate if (rp1 && rp1->r_svnode.sv_name)
2840Sstevel@tonic-gate ep->re_char1 = fn_path(rp1->r_svnode.sv_name);
2850Sstevel@tonic-gate else
2860Sstevel@tonic-gate ep->re_char1 = NULL;
2870Sstevel@tonic-gate ep->re_rp1 = rp1;
2880Sstevel@tonic-gate
2890Sstevel@tonic-gate /* file <path/component name> */
2900Sstevel@tonic-gate if (rp2 && rp2->r_svnode.sv_name)
2910Sstevel@tonic-gate ep->re_char2 = fn_path(rp2->r_svnode.sv_name);
2920Sstevel@tonic-gate else
2930Sstevel@tonic-gate ep->re_char2 = NULL;
2940Sstevel@tonic-gate ep->re_rp2 = rp2;
2950Sstevel@tonic-gate break;
2960Sstevel@tonic-gate case RE_LOST_STATE_BAD_OP:
2970Sstevel@tonic-gate ep->re_uint = count; /* the unexpected op */
2980Sstevel@tonic-gate ep->re_pid = pid;
2990Sstevel@tonic-gate ep->re_rp1 = rp1;
3000Sstevel@tonic-gate if (rp1 != NULL && rp1->r_svnode.sv_name != NULL)
3010Sstevel@tonic-gate ep->re_char1 = fn_path(rp1->r_svnode.sv_name);
3020Sstevel@tonic-gate ep->re_rp2 = rp2;
3030Sstevel@tonic-gate if (rp2 != NULL && rp2->r_svnode.sv_name != NULL)
3040Sstevel@tonic-gate ep->re_char2 = fn_path(rp2->r_svnode.sv_name);
3050Sstevel@tonic-gate break;
306*11291SRobert.Thurlow@Sun.COM case RE_REFERRAL:
307*11291SRobert.Thurlow@Sun.COM /* server we're being referred to */
308*11291SRobert.Thurlow@Sun.COM if (server1 != NULL) {
309*11291SRobert.Thurlow@Sun.COM len = strlen(server1);
310*11291SRobert.Thurlow@Sun.COM ep->re_char1 = kmem_alloc(len + 1, KM_SLEEP);
311*11291SRobert.Thurlow@Sun.COM bcopy(server1, ep->re_char1, len);
312*11291SRobert.Thurlow@Sun.COM ep->re_char1[len] = '\0';
313*11291SRobert.Thurlow@Sun.COM } else {
314*11291SRobert.Thurlow@Sun.COM ep->re_char1 = NULL;
315*11291SRobert.Thurlow@Sun.COM }
316*11291SRobert.Thurlow@Sun.COM break;
3170Sstevel@tonic-gate default:
3180Sstevel@tonic-gate break;
3190Sstevel@tonic-gate }
3200Sstevel@tonic-gate }
3210Sstevel@tonic-gate
3220Sstevel@tonic-gate /*
3230Sstevel@tonic-gate * Sets the appropiate fields of the 'fact' for this 'id'.
3240Sstevel@tonic-gate */
3250Sstevel@tonic-gate static void
set_fact(nfs4_fact_type_t id,nfs4_rfact_t * fp,nfsstat4 stat4,nfs4_recov_t raction,nfs_opnum4 op,bool_t reboot,int error,vnode_t * vp)3260Sstevel@tonic-gate set_fact(nfs4_fact_type_t id, nfs4_rfact_t *fp, nfsstat4 stat4,
3270Sstevel@tonic-gate nfs4_recov_t raction, nfs_opnum4 op, bool_t reboot, int error,
3280Sstevel@tonic-gate vnode_t *vp)
3290Sstevel@tonic-gate {
3300Sstevel@tonic-gate rnode4_t *rp1;
3310Sstevel@tonic-gate
3320Sstevel@tonic-gate switch (id) {
3330Sstevel@tonic-gate case RF_BADOWNER:
3340Sstevel@tonic-gate fp->rf_op = op;
3350Sstevel@tonic-gate fp->rf_reboot = reboot;
3360Sstevel@tonic-gate fp->rf_stat4 = stat4;
3370Sstevel@tonic-gate break;
3380Sstevel@tonic-gate case RF_RENEW_EXPIRED:
3390Sstevel@tonic-gate break;
3400Sstevel@tonic-gate case RF_ERR:
3410Sstevel@tonic-gate fp->rf_op = op;
3420Sstevel@tonic-gate fp->rf_reboot = reboot;
3430Sstevel@tonic-gate fp->rf_stat4 = stat4;
3440Sstevel@tonic-gate fp->rf_action = raction;
3450Sstevel@tonic-gate fp->rf_error = error;
3460Sstevel@tonic-gate break;
3470Sstevel@tonic-gate case RF_SRV_OK:
3480Sstevel@tonic-gate break;
3490Sstevel@tonic-gate case RF_SRV_NOT_RESPOND:
3500Sstevel@tonic-gate break;
3510Sstevel@tonic-gate case RF_SRVS_OK:
3520Sstevel@tonic-gate break;
3530Sstevel@tonic-gate case RF_SRVS_NOT_RESPOND:
3540Sstevel@tonic-gate gethrestime(&fp->rf_time);
3550Sstevel@tonic-gate break;
3560Sstevel@tonic-gate case RF_DELMAP_CB_ERR:
3570Sstevel@tonic-gate fp->rf_op = op;
3580Sstevel@tonic-gate fp->rf_stat4 = stat4;
3590Sstevel@tonic-gate
3600Sstevel@tonic-gate rp1 = VTOR4(vp);
3610Sstevel@tonic-gate fp->rf_rp1 = rp1;
3620Sstevel@tonic-gate if (rp1 && rp1->r_svnode.sv_name)
3630Sstevel@tonic-gate fp->rf_char1 = fn_path(rp1->r_svnode.sv_name);
3640Sstevel@tonic-gate else
3650Sstevel@tonic-gate fp->rf_char1 = NULL;
3660Sstevel@tonic-gate break;
3679675Sdai.ngo@sun.com case RF_SENDQ_FULL:
3689675Sdai.ngo@sun.com break;
3690Sstevel@tonic-gate default:
3700Sstevel@tonic-gate zcmn_err(getzoneid(), CE_NOTE, "illegal fact %d", id);
3710Sstevel@tonic-gate break;
3720Sstevel@tonic-gate }
3730Sstevel@tonic-gate }
3740Sstevel@tonic-gate
3750Sstevel@tonic-gate /*
3760Sstevel@tonic-gate * Returns 1 if the event/fact is of a successful communication
3770Sstevel@tonic-gate * from the server; 0 otherwise.
3780Sstevel@tonic-gate */
3790Sstevel@tonic-gate static int
successful_comm(nfs4_debug_msg_t * msgp)3800Sstevel@tonic-gate successful_comm(nfs4_debug_msg_t *msgp)
3810Sstevel@tonic-gate {
3820Sstevel@tonic-gate if (msgp->msg_type == RM_EVENT) {
3830Sstevel@tonic-gate switch (msgp->rmsg_u.msg_event.re_type) {
3840Sstevel@tonic-gate case RE_BAD_SEQID:
3850Sstevel@tonic-gate case RE_BADHANDLE:
3860Sstevel@tonic-gate case RE_FAIL_REMAP_LEN:
3870Sstevel@tonic-gate case RE_FAIL_REMAP_OP:
3880Sstevel@tonic-gate case RE_FILE_DIFF:
3890Sstevel@tonic-gate case RE_START:
3900Sstevel@tonic-gate case RE_UNEXPECTED_ACTION:
3910Sstevel@tonic-gate case RE_UNEXPECTED_ERRNO:
3920Sstevel@tonic-gate case RE_UNEXPECTED_STATUS:
3930Sstevel@tonic-gate case RE_WRONGSEC:
3940Sstevel@tonic-gate return (1);
3950Sstevel@tonic-gate case RE_CLIENTID:
3960Sstevel@tonic-gate case RE_DEAD_FILE:
3970Sstevel@tonic-gate case RE_END:
3980Sstevel@tonic-gate case RE_FAIL_RELOCK:
3990Sstevel@tonic-gate case RE_FAILOVER:
4000Sstevel@tonic-gate case RE_LOST_STATE:
4010Sstevel@tonic-gate case RE_OPENS_CHANGED:
4020Sstevel@tonic-gate case RE_SIGLOST:
4030Sstevel@tonic-gate case RE_SIGLOST_NO_DUMP:
4040Sstevel@tonic-gate case RE_LOST_STATE_BAD_OP:
405*11291SRobert.Thurlow@Sun.COM case RE_REFERRAL:
406*11291SRobert.Thurlow@Sun.COM /* placeholder */
4070Sstevel@tonic-gate return (0);
4080Sstevel@tonic-gate default:
4090Sstevel@tonic-gate return (0);
4100Sstevel@tonic-gate }
4110Sstevel@tonic-gate } else {
4120Sstevel@tonic-gate switch (msgp->rmsg_u.msg_fact.rf_type) {
4130Sstevel@tonic-gate case RF_BADOWNER:
4140Sstevel@tonic-gate case RF_ERR:
4150Sstevel@tonic-gate case RF_RENEW_EXPIRED:
4160Sstevel@tonic-gate case RF_SRV_OK:
4170Sstevel@tonic-gate case RF_SRVS_OK:
4180Sstevel@tonic-gate case RF_DELMAP_CB_ERR:
4190Sstevel@tonic-gate return (1);
4200Sstevel@tonic-gate case RF_SRV_NOT_RESPOND:
4210Sstevel@tonic-gate case RF_SRVS_NOT_RESPOND:
4229675Sdai.ngo@sun.com case RF_SENDQ_FULL:
4230Sstevel@tonic-gate return (0);
4240Sstevel@tonic-gate default:
4250Sstevel@tonic-gate return (0);
4260Sstevel@tonic-gate }
4270Sstevel@tonic-gate }
4280Sstevel@tonic-gate }
4290Sstevel@tonic-gate
4300Sstevel@tonic-gate /*
4310Sstevel@tonic-gate * Iterate backwards through the mi's mi_msg_list to find the earliest
4320Sstevel@tonic-gate * message that we should find relevant facts to investigate.
4330Sstevel@tonic-gate */
4340Sstevel@tonic-gate static nfs4_debug_msg_t *
find_beginning(nfs4_debug_msg_t * first_msg,mntinfo4_t * mi)4350Sstevel@tonic-gate find_beginning(nfs4_debug_msg_t *first_msg, mntinfo4_t *mi)
4360Sstevel@tonic-gate {
4370Sstevel@tonic-gate nfs4_debug_msg_t *oldest_msg, *cur_msg;
4380Sstevel@tonic-gate time_t lease;
4390Sstevel@tonic-gate
4400Sstevel@tonic-gate ASSERT(mutex_owned(&mi->mi_msg_list_lock));
4410Sstevel@tonic-gate if (mi->mi_lease_period > 0)
4420Sstevel@tonic-gate lease = 2 * mi->mi_lease_period;
4430Sstevel@tonic-gate else
4440Sstevel@tonic-gate lease = DEFAULT_LEASE;
4450Sstevel@tonic-gate
4460Sstevel@tonic-gate oldest_msg = first_msg;
4470Sstevel@tonic-gate cur_msg = list_prev(&mi->mi_msg_list, first_msg);
4480Sstevel@tonic-gate while (cur_msg &&
4490Sstevel@tonic-gate first_msg->msg_time.tv_sec - cur_msg->msg_time.tv_sec < lease) {
4500Sstevel@tonic-gate oldest_msg = cur_msg;
4510Sstevel@tonic-gate if ((cur_msg->msg_type == RM_FACT) &&
4520Sstevel@tonic-gate (cur_msg->rmsg_u.msg_fact.rf_type == RF_SRV_OK)) {
4530Sstevel@tonic-gate /* find where we lost contact with the server */
4540Sstevel@tonic-gate while (cur_msg) {
4550Sstevel@tonic-gate if ((cur_msg->msg_type == RM_FACT) &&
4560Sstevel@tonic-gate (cur_msg->rmsg_u.msg_fact.rf_type ==
4570Sstevel@tonic-gate RF_SRV_NOT_RESPOND))
4580Sstevel@tonic-gate break;
4590Sstevel@tonic-gate oldest_msg = cur_msg;
4600Sstevel@tonic-gate cur_msg = list_prev(&mi->mi_msg_list, cur_msg);
4610Sstevel@tonic-gate }
4620Sstevel@tonic-gate /*
4630Sstevel@tonic-gate * Find the first successful message before
4640Sstevel@tonic-gate * we lost contact with the server.
4650Sstevel@tonic-gate */
4660Sstevel@tonic-gate if (cur_msg) {
4670Sstevel@tonic-gate cur_msg = list_prev(&mi->mi_msg_list, cur_msg);
4680Sstevel@tonic-gate while (cur_msg && !successful_comm(cur_msg)) {
4690Sstevel@tonic-gate oldest_msg = cur_msg;
4700Sstevel@tonic-gate cur_msg = list_prev(&mi->mi_msg_list,
4710Sstevel@tonic-gate cur_msg);
4720Sstevel@tonic-gate }
4730Sstevel@tonic-gate }
4740Sstevel@tonic-gate /*
4750Sstevel@tonic-gate * If we're not at the dummy head pointer,
4760Sstevel@tonic-gate * set the oldest and current message.
4770Sstevel@tonic-gate */
4780Sstevel@tonic-gate if (cur_msg) {
4790Sstevel@tonic-gate first_msg = cur_msg;
4800Sstevel@tonic-gate oldest_msg = cur_msg;
4810Sstevel@tonic-gate cur_msg = list_prev(&mi->mi_msg_list, cur_msg);
4820Sstevel@tonic-gate }
4830Sstevel@tonic-gate } else
4840Sstevel@tonic-gate cur_msg = list_prev(&mi->mi_msg_list, cur_msg);
4850Sstevel@tonic-gate }
4860Sstevel@tonic-gate
4870Sstevel@tonic-gate return (oldest_msg);
4880Sstevel@tonic-gate }
4890Sstevel@tonic-gate
4900Sstevel@tonic-gate /*
4910Sstevel@tonic-gate * Returns 1 if facts have been found; 0 otherwise.
4920Sstevel@tonic-gate */
4930Sstevel@tonic-gate static int
get_facts(nfs4_debug_msg_t * msgp,nfs4_rfact_t * ret_fp,char ** mnt_pt,mntinfo4_t * mi)4940Sstevel@tonic-gate get_facts(nfs4_debug_msg_t *msgp, nfs4_rfact_t *ret_fp, char **mnt_pt,
4950Sstevel@tonic-gate mntinfo4_t *mi)
4960Sstevel@tonic-gate {
4970Sstevel@tonic-gate nfs4_debug_msg_t *cur_msg, *oldest_msg;
4980Sstevel@tonic-gate nfs4_rfact_t *cur_fp;
4990Sstevel@tonic-gate int found_a_fact = 0;
5000Sstevel@tonic-gate int len;
5010Sstevel@tonic-gate
5020Sstevel@tonic-gate cur_msg = msgp;
5030Sstevel@tonic-gate
5040Sstevel@tonic-gate /* find the oldest msg to search backwards to */
5050Sstevel@tonic-gate oldest_msg = find_beginning(cur_msg, mi);
5060Sstevel@tonic-gate ASSERT(oldest_msg != NULL);
5070Sstevel@tonic-gate
5080Sstevel@tonic-gate /*
5090Sstevel@tonic-gate * Create a fact sheet by searching from our current message
5100Sstevel@tonic-gate * backwards to the 'oldest_msg', recording facts along the way
5110Sstevel@tonic-gate * until we found facts that have been inspected by another time.
5120Sstevel@tonic-gate */
5130Sstevel@tonic-gate while (cur_msg && cur_msg != list_prev(&mi->mi_msg_list, oldest_msg)) {
5140Sstevel@tonic-gate if (cur_msg->msg_type != RM_FACT) {
5150Sstevel@tonic-gate cur_msg = list_prev(&mi->mi_msg_list, cur_msg);
5160Sstevel@tonic-gate continue;
5170Sstevel@tonic-gate }
5180Sstevel@tonic-gate
5190Sstevel@tonic-gate cur_fp = &cur_msg->rmsg_u.msg_fact;
5200Sstevel@tonic-gate /*
5210Sstevel@tonic-gate * If this fact has already been looked at, then so
5220Sstevel@tonic-gate * have all preceding facts. Return Now.
5230Sstevel@tonic-gate */
5240Sstevel@tonic-gate if (cur_fp->rf_status == RFS_INSPECT)
5250Sstevel@tonic-gate return (found_a_fact);
5260Sstevel@tonic-gate
5270Sstevel@tonic-gate cur_fp->rf_status = RFS_INSPECT;
5280Sstevel@tonic-gate found_a_fact = 1;
5290Sstevel@tonic-gate switch (cur_fp->rf_type) {
5300Sstevel@tonic-gate case RF_BADOWNER:
5310Sstevel@tonic-gate break;
5320Sstevel@tonic-gate case RF_ERR:
5330Sstevel@tonic-gate /*
5340Sstevel@tonic-gate * Don't want to overwrite a fact that was
5350Sstevel@tonic-gate * previously found during our current search.
5360Sstevel@tonic-gate */
5370Sstevel@tonic-gate if (!ret_fp->rf_reboot)
5380Sstevel@tonic-gate ret_fp->rf_reboot = cur_fp->rf_reboot;
5390Sstevel@tonic-gate if (!ret_fp->rf_stat4)
5400Sstevel@tonic-gate ret_fp->rf_stat4 = cur_fp->rf_stat4;
5410Sstevel@tonic-gate if (!ret_fp->rf_action)
5420Sstevel@tonic-gate ret_fp->rf_action = cur_fp->rf_action;
5430Sstevel@tonic-gate break;
5440Sstevel@tonic-gate case RF_RENEW_EXPIRED:
5450Sstevel@tonic-gate if (cur_msg->msg_mntpt && !(*mnt_pt)) {
5460Sstevel@tonic-gate len = strlen(cur_msg->msg_mntpt) + 1;
5470Sstevel@tonic-gate *mnt_pt = kmem_alloc(len, KM_SLEEP);
5480Sstevel@tonic-gate bcopy(cur_msg->msg_mntpt, *mnt_pt, len);
5490Sstevel@tonic-gate }
5500Sstevel@tonic-gate break;
5510Sstevel@tonic-gate case RF_SRV_OK:
5520Sstevel@tonic-gate break;
5530Sstevel@tonic-gate case RF_SRV_NOT_RESPOND:
5540Sstevel@tonic-gate /*
5550Sstevel@tonic-gate * Okay to overwrite this fact as
5560Sstevel@tonic-gate * we want the earliest time.
5570Sstevel@tonic-gate */
5580Sstevel@tonic-gate ret_fp->rf_time = cur_fp->rf_time;
5590Sstevel@tonic-gate break;
5600Sstevel@tonic-gate case RF_SRVS_OK:
5610Sstevel@tonic-gate break;
5620Sstevel@tonic-gate case RF_SRVS_NOT_RESPOND:
5630Sstevel@tonic-gate break;
5640Sstevel@tonic-gate case RF_DELMAP_CB_ERR:
5650Sstevel@tonic-gate break;
5669675Sdai.ngo@sun.com case RF_SENDQ_FULL:
5679675Sdai.ngo@sun.com break;
5680Sstevel@tonic-gate default:
5690Sstevel@tonic-gate zcmn_err(getzoneid(), CE_NOTE,
5700Sstevel@tonic-gate "get facts: illegal fact %d", cur_fp->rf_type);
5710Sstevel@tonic-gate break;
5720Sstevel@tonic-gate }
5730Sstevel@tonic-gate cur_msg = list_prev(&mi->mi_msg_list, cur_msg);
5740Sstevel@tonic-gate }
5750Sstevel@tonic-gate
5760Sstevel@tonic-gate return (found_a_fact);
5770Sstevel@tonic-gate }
5780Sstevel@tonic-gate
5790Sstevel@tonic-gate /*
5800Sstevel@tonic-gate * Returns 1 if this fact is identical to the last fact recorded
5810Sstevel@tonic-gate * (only checks for a match within the last 2 lease periods).
5820Sstevel@tonic-gate */
5830Sstevel@tonic-gate static int
facts_same(nfs4_debug_msg_t * cur_msg,nfs4_debug_msg_t * new_msg,mntinfo4_t * mi)5840Sstevel@tonic-gate facts_same(nfs4_debug_msg_t *cur_msg, nfs4_debug_msg_t *new_msg,
5850Sstevel@tonic-gate mntinfo4_t *mi)
5860Sstevel@tonic-gate {
5870Sstevel@tonic-gate nfs4_rfact_t *fp1, *fp2;
5880Sstevel@tonic-gate int lease, len;
5890Sstevel@tonic-gate
5900Sstevel@tonic-gate ASSERT(mutex_owned(&mi->mi_msg_list_lock));
5910Sstevel@tonic-gate if (mi->mi_lease_period > 0)
5920Sstevel@tonic-gate lease = 2 * mi->mi_lease_period;
5930Sstevel@tonic-gate else
5940Sstevel@tonic-gate lease = DEFAULT_LEASE;
5950Sstevel@tonic-gate
5960Sstevel@tonic-gate fp2 = &new_msg->rmsg_u.msg_fact;
5970Sstevel@tonic-gate
5980Sstevel@tonic-gate while (cur_msg &&
5990Sstevel@tonic-gate new_msg->msg_time.tv_sec - cur_msg->msg_time.tv_sec < lease) {
6000Sstevel@tonic-gate if (cur_msg->msg_type != RM_FACT) {
6010Sstevel@tonic-gate cur_msg = list_prev(&mi->mi_msg_list, cur_msg);
6020Sstevel@tonic-gate continue;
6030Sstevel@tonic-gate }
6040Sstevel@tonic-gate fp1 = &cur_msg->rmsg_u.msg_fact;
6050Sstevel@tonic-gate if (fp1->rf_type != fp2->rf_type)
6060Sstevel@tonic-gate return (0);
6070Sstevel@tonic-gate
6080Sstevel@tonic-gate /* now actually compare the facts */
6090Sstevel@tonic-gate if (fp1->rf_action != fp2->rf_action)
6100Sstevel@tonic-gate return (0);
6110Sstevel@tonic-gate if (fp1->rf_stat4 != fp2->rf_stat4)
6120Sstevel@tonic-gate return (0);
6130Sstevel@tonic-gate if (fp1->rf_reboot != fp2->rf_reboot)
6140Sstevel@tonic-gate return (0);
6150Sstevel@tonic-gate if (fp1->rf_op != fp2->rf_op)
6160Sstevel@tonic-gate return (0);
6170Sstevel@tonic-gate if (fp1->rf_time.tv_sec != fp2->rf_time.tv_sec)
6180Sstevel@tonic-gate return (0);
6190Sstevel@tonic-gate if (fp1->rf_error != fp2->rf_error)
6200Sstevel@tonic-gate return (0);
6210Sstevel@tonic-gate if (fp1->rf_rp1 != fp2->rf_rp1)
6220Sstevel@tonic-gate return (0);
6230Sstevel@tonic-gate if (cur_msg->msg_srv != NULL) {
6240Sstevel@tonic-gate if (new_msg->msg_srv == NULL)
6250Sstevel@tonic-gate return (0);
6260Sstevel@tonic-gate len = strlen(cur_msg->msg_srv);
6270Sstevel@tonic-gate if (strncmp(cur_msg->msg_srv, new_msg->msg_srv,
6288863SEdward.Pilatowicz@Sun.COM len) != 0)
6290Sstevel@tonic-gate return (0);
6300Sstevel@tonic-gate } else if (new_msg->msg_srv != NULL) {
6310Sstevel@tonic-gate return (0);
6320Sstevel@tonic-gate }
6330Sstevel@tonic-gate if (cur_msg->msg_mntpt != NULL) {
6340Sstevel@tonic-gate if (new_msg->msg_mntpt == NULL)
6350Sstevel@tonic-gate return (0);
6360Sstevel@tonic-gate len = strlen(cur_msg->msg_mntpt);
6370Sstevel@tonic-gate if (strncmp(cur_msg->msg_mntpt, new_msg->msg_mntpt,
6388863SEdward.Pilatowicz@Sun.COM len) != 0)
6390Sstevel@tonic-gate return (0);
6400Sstevel@tonic-gate } else if (new_msg->msg_mntpt != NULL) {
6410Sstevel@tonic-gate return (0);
6420Sstevel@tonic-gate }
6430Sstevel@tonic-gate if (fp1->rf_char1 != NULL) {
6440Sstevel@tonic-gate if (fp2->rf_char1 == NULL)
6450Sstevel@tonic-gate return (0);
6460Sstevel@tonic-gate len = strlen(fp1->rf_char1);
6470Sstevel@tonic-gate if (strncmp(fp1->rf_char1, fp2->rf_char1, len) != 0)
6480Sstevel@tonic-gate return (0);
6490Sstevel@tonic-gate } else if (fp2->rf_char1 != NULL) {
6500Sstevel@tonic-gate return (0);
6510Sstevel@tonic-gate }
6520Sstevel@tonic-gate return (1);
6530Sstevel@tonic-gate }
6540Sstevel@tonic-gate
6550Sstevel@tonic-gate return (0);
6560Sstevel@tonic-gate }
6570Sstevel@tonic-gate
6580Sstevel@tonic-gate /*
6590Sstevel@tonic-gate * Returns 1 if these two messages are identical; 0 otherwise.
6600Sstevel@tonic-gate */
6610Sstevel@tonic-gate static int
events_same(nfs4_debug_msg_t * cur_msg,nfs4_debug_msg_t * new_msg,mntinfo4_t * mi)6620Sstevel@tonic-gate events_same(nfs4_debug_msg_t *cur_msg, nfs4_debug_msg_t *new_msg,
6630Sstevel@tonic-gate mntinfo4_t *mi)
6640Sstevel@tonic-gate {
6650Sstevel@tonic-gate nfs4_revent_t *ep1, *ep2;
6660Sstevel@tonic-gate int len;
6670Sstevel@tonic-gate
6680Sstevel@tonic-gate /* find the last event, bypassing all facts */
6690Sstevel@tonic-gate while (cur_msg && cur_msg->msg_type != RM_EVENT)
6700Sstevel@tonic-gate cur_msg = list_prev(&mi->mi_msg_list, cur_msg);
6710Sstevel@tonic-gate
6720Sstevel@tonic-gate if (!cur_msg)
6730Sstevel@tonic-gate return (0);
6740Sstevel@tonic-gate
6750Sstevel@tonic-gate if (cur_msg->msg_type != RM_EVENT)
6760Sstevel@tonic-gate return (0);
6770Sstevel@tonic-gate
6780Sstevel@tonic-gate ep1 = &cur_msg->rmsg_u.msg_event;
6790Sstevel@tonic-gate ep2 = &new_msg->rmsg_u.msg_event;
6800Sstevel@tonic-gate if (ep1->re_type != ep2->re_type)
6810Sstevel@tonic-gate return (0);
6820Sstevel@tonic-gate
6830Sstevel@tonic-gate /*
6840Sstevel@tonic-gate * Since we zalloc the buffer, then the two nfs4_debug_msg's
6850Sstevel@tonic-gate * must match up even if all the fields weren't filled in
6860Sstevel@tonic-gate * the first place.
6870Sstevel@tonic-gate */
6880Sstevel@tonic-gate if (ep1->re_mi != ep2->re_mi)
6890Sstevel@tonic-gate return (0);
6900Sstevel@tonic-gate if (ep1->re_uint != ep2->re_uint)
6910Sstevel@tonic-gate return (0);
6920Sstevel@tonic-gate if (ep1->re_stat4 != ep2->re_stat4)
6930Sstevel@tonic-gate return (0);
6940Sstevel@tonic-gate if (ep1->re_pid != ep2->re_pid)
6950Sstevel@tonic-gate return (0);
6960Sstevel@tonic-gate if (ep1->re_rp1 != ep2->re_rp1)
6970Sstevel@tonic-gate return (0);
6980Sstevel@tonic-gate if (ep1->re_rp2 != ep2->re_rp2)
6990Sstevel@tonic-gate return (0);
7000Sstevel@tonic-gate if (ep1->re_tag1 != ep2->re_tag1)
7010Sstevel@tonic-gate return (0);
7020Sstevel@tonic-gate if (ep1->re_tag2 != ep2->re_tag2)
7030Sstevel@tonic-gate return (0);
7040Sstevel@tonic-gate if (ep1->re_seqid1 != ep2->re_seqid1)
7050Sstevel@tonic-gate return (0);
7060Sstevel@tonic-gate if (ep1->re_seqid2 != ep2->re_seqid2)
7070Sstevel@tonic-gate return (0);
7080Sstevel@tonic-gate
7090Sstevel@tonic-gate if (cur_msg->msg_srv != NULL) {
7100Sstevel@tonic-gate if (new_msg->msg_srv == NULL)
7110Sstevel@tonic-gate return (0);
7120Sstevel@tonic-gate len = strlen(cur_msg->msg_srv);
7130Sstevel@tonic-gate if (strncmp(cur_msg->msg_srv, new_msg->msg_srv, len) != 0)
7140Sstevel@tonic-gate return (0);
7150Sstevel@tonic-gate } else if (new_msg->msg_srv != NULL) {
7160Sstevel@tonic-gate return (0);
7170Sstevel@tonic-gate }
7180Sstevel@tonic-gate
7190Sstevel@tonic-gate if (ep1->re_char1 != NULL) {
7200Sstevel@tonic-gate if (ep2->re_char1 == NULL)
7210Sstevel@tonic-gate return (0);
7220Sstevel@tonic-gate len = strlen(ep1->re_char1);
7230Sstevel@tonic-gate if (strncmp(ep1->re_char1, ep2->re_char1, len) != 0)
7240Sstevel@tonic-gate return (0);
7250Sstevel@tonic-gate } else if (ep2->re_char1 != NULL) {
7260Sstevel@tonic-gate return (0);
7270Sstevel@tonic-gate }
7280Sstevel@tonic-gate
7290Sstevel@tonic-gate if (ep1->re_char2 != NULL) {
7300Sstevel@tonic-gate if (ep2->re_char2 == NULL)
7310Sstevel@tonic-gate return (0);
7320Sstevel@tonic-gate len = strlen(ep1->re_char2);
7330Sstevel@tonic-gate if (strncmp(ep1->re_char2, ep2->re_char2, len) != 0)
7340Sstevel@tonic-gate return (0);
7350Sstevel@tonic-gate } else if (ep2->re_char2 != NULL) {
7360Sstevel@tonic-gate return (0);
7370Sstevel@tonic-gate }
7380Sstevel@tonic-gate
7390Sstevel@tonic-gate if (cur_msg->msg_mntpt != NULL) {
7400Sstevel@tonic-gate if (new_msg->msg_mntpt == NULL)
7410Sstevel@tonic-gate return (0);
7420Sstevel@tonic-gate len = strlen(cur_msg->msg_mntpt);
7430Sstevel@tonic-gate if (strncmp(cur_msg->msg_mntpt, cur_msg->msg_mntpt, len) != 0)
7440Sstevel@tonic-gate return (0);
7450Sstevel@tonic-gate } else if (new_msg->msg_mntpt != NULL) {
7460Sstevel@tonic-gate return (0);
7470Sstevel@tonic-gate }
7480Sstevel@tonic-gate
7490Sstevel@tonic-gate return (1);
7500Sstevel@tonic-gate }
7510Sstevel@tonic-gate
7520Sstevel@tonic-gate /*
7530Sstevel@tonic-gate * Free up a recovery event.
7540Sstevel@tonic-gate */
7550Sstevel@tonic-gate static void
free_event(nfs4_revent_t * ep)7560Sstevel@tonic-gate free_event(nfs4_revent_t *ep)
7570Sstevel@tonic-gate {
7580Sstevel@tonic-gate int len;
7590Sstevel@tonic-gate
7600Sstevel@tonic-gate if (ep->re_char1) {
7610Sstevel@tonic-gate len = strlen(ep->re_char1) + 1;
7620Sstevel@tonic-gate kmem_free(ep->re_char1, len);
7630Sstevel@tonic-gate }
7640Sstevel@tonic-gate if (ep->re_char2) {
7650Sstevel@tonic-gate len = strlen(ep->re_char2) + 1;
7660Sstevel@tonic-gate kmem_free(ep->re_char2, len);
7670Sstevel@tonic-gate }
7680Sstevel@tonic-gate }
7690Sstevel@tonic-gate
7700Sstevel@tonic-gate /*
7710Sstevel@tonic-gate * Free up a recovery fact.
7720Sstevel@tonic-gate */
7730Sstevel@tonic-gate static void
free_fact(nfs4_rfact_t * fp)7740Sstevel@tonic-gate free_fact(nfs4_rfact_t *fp)
7750Sstevel@tonic-gate {
7760Sstevel@tonic-gate int len;
7770Sstevel@tonic-gate
7780Sstevel@tonic-gate if (fp->rf_char1) {
7790Sstevel@tonic-gate len = strlen(fp->rf_char1) + 1;
7800Sstevel@tonic-gate kmem_free(fp->rf_char1, len);
7810Sstevel@tonic-gate }
7820Sstevel@tonic-gate }
7830Sstevel@tonic-gate
7840Sstevel@tonic-gate /*
7850Sstevel@tonic-gate * Free up the message.
7860Sstevel@tonic-gate */
7870Sstevel@tonic-gate void
nfs4_free_msg(nfs4_debug_msg_t * msg)7880Sstevel@tonic-gate nfs4_free_msg(nfs4_debug_msg_t *msg)
7890Sstevel@tonic-gate {
7900Sstevel@tonic-gate int len;
7910Sstevel@tonic-gate
7920Sstevel@tonic-gate if (msg->msg_type == RM_EVENT)
7930Sstevel@tonic-gate free_event(&msg->rmsg_u.msg_event);
7940Sstevel@tonic-gate else
7950Sstevel@tonic-gate free_fact(&msg->rmsg_u.msg_fact);
7960Sstevel@tonic-gate
7970Sstevel@tonic-gate if (msg->msg_srv) {
7980Sstevel@tonic-gate len = strlen(msg->msg_srv) + 1;
7990Sstevel@tonic-gate kmem_free(msg->msg_srv, len);
8000Sstevel@tonic-gate }
8010Sstevel@tonic-gate
8020Sstevel@tonic-gate if (msg->msg_mntpt) {
8030Sstevel@tonic-gate len = strlen(msg->msg_mntpt) + 1;
8040Sstevel@tonic-gate kmem_free(msg->msg_mntpt, len);
8050Sstevel@tonic-gate }
8060Sstevel@tonic-gate
8070Sstevel@tonic-gate /* free up the data structure itself */
8080Sstevel@tonic-gate kmem_free(msg, sizeof (*msg));
8090Sstevel@tonic-gate }
8100Sstevel@tonic-gate
8110Sstevel@tonic-gate /*
8120Sstevel@tonic-gate * Prints out the interesting facts for recovery events:
8130Sstevel@tonic-gate * -DEAD_FILE
8140Sstevel@tonic-gate * -SIGLOST(_NO_DUMP)
8150Sstevel@tonic-gate */
8160Sstevel@tonic-gate static void
print_facts(nfs4_debug_msg_t * msg,mntinfo4_t * mi)8170Sstevel@tonic-gate print_facts(nfs4_debug_msg_t *msg, mntinfo4_t *mi)
8180Sstevel@tonic-gate {
8190Sstevel@tonic-gate nfs4_rfact_t *fp;
8200Sstevel@tonic-gate char *mount_pt;
8210Sstevel@tonic-gate int len;
8220Sstevel@tonic-gate
8230Sstevel@tonic-gate if (msg->rmsg_u.msg_event.re_type != RE_DEAD_FILE &&
8240Sstevel@tonic-gate msg->rmsg_u.msg_event.re_type != RE_SIGLOST &&
8250Sstevel@tonic-gate msg->rmsg_u.msg_event.re_type != RE_SIGLOST_NO_DUMP)
8260Sstevel@tonic-gate return;
8270Sstevel@tonic-gate
8280Sstevel@tonic-gate fp = kmem_zalloc(sizeof (*fp), KM_SLEEP);
8290Sstevel@tonic-gate mount_pt = NULL;
8300Sstevel@tonic-gate
8310Sstevel@tonic-gate if (get_facts(msg, fp, &mount_pt, mi)) {
8320Sstevel@tonic-gate char time[256];
8330Sstevel@tonic-gate
8340Sstevel@tonic-gate
8350Sstevel@tonic-gate if (fp->rf_time.tv_sec)
8360Sstevel@tonic-gate (void) snprintf(time, 256, "%ld",
8370Sstevel@tonic-gate (gethrestime_sec() - fp->rf_time.tv_sec)/60);
8380Sstevel@tonic-gate zcmn_err(mi->mi_zone->zone_id, CE_NOTE,
8390Sstevel@tonic-gate "!NFS4 FACT SHEET: %s%s %s%s %s %s%s%s %s%s",
8400Sstevel@tonic-gate fp->rf_action ? "\n Action: " : "",
8410Sstevel@tonic-gate fp->rf_action ? nfs4_recov_action_to_str(fp->rf_action) :
8420Sstevel@tonic-gate "",
8430Sstevel@tonic-gate fp->rf_stat4 ? "\n NFS4 error: " : "",
8440Sstevel@tonic-gate fp->rf_stat4 ? nfs4_stat_to_str(fp->rf_stat4) : "",
8450Sstevel@tonic-gate fp->rf_reboot ? "\n Suspected server reboot. " : "",
8460Sstevel@tonic-gate fp->rf_time.tv_sec ? "\n Server was down for " : "",
8470Sstevel@tonic-gate fp->rf_time.tv_sec ? time : "",
8480Sstevel@tonic-gate fp->rf_time.tv_sec ? " minutes." : "",
8490Sstevel@tonic-gate mount_pt ? " \n Client's lease expired on mount " : "",
8500Sstevel@tonic-gate mount_pt ? mount_pt : "");
8510Sstevel@tonic-gate }
8520Sstevel@tonic-gate
8530Sstevel@tonic-gate if (mount_pt) {
8540Sstevel@tonic-gate len = strlen(mount_pt) + 1;
8550Sstevel@tonic-gate kmem_free(mount_pt, len);
8560Sstevel@tonic-gate }
8570Sstevel@tonic-gate
8580Sstevel@tonic-gate /* free the fact struct itself */
8590Sstevel@tonic-gate if (fp)
8600Sstevel@tonic-gate kmem_free(fp, sizeof (*fp));
8610Sstevel@tonic-gate }
8620Sstevel@tonic-gate
8630Sstevel@tonic-gate /*
8640Sstevel@tonic-gate * Print an event message to /var/adm/messages
8650Sstevel@tonic-gate * The last argument to this fuction dictates the repeat status
8660Sstevel@tonic-gate * of the event. If set to 1, it means that we are dumping this
8670Sstevel@tonic-gate * event and it will _never_ be printed after this time. Else if
8680Sstevel@tonic-gate * set to 0 it will be printed again.
8690Sstevel@tonic-gate */
8700Sstevel@tonic-gate static void
queue_print_event(nfs4_debug_msg_t * msg,mntinfo4_t * mi,int dump)8710Sstevel@tonic-gate queue_print_event(nfs4_debug_msg_t *msg, mntinfo4_t *mi, int dump)
8720Sstevel@tonic-gate {
8730Sstevel@tonic-gate nfs4_revent_t *ep;
8740Sstevel@tonic-gate zoneid_t zoneid;
8750Sstevel@tonic-gate
8760Sstevel@tonic-gate ep = &msg->rmsg_u.msg_event;
8770Sstevel@tonic-gate zoneid = mi->mi_zone->zone_id;
8780Sstevel@tonic-gate
8790Sstevel@tonic-gate switch (ep->re_type) {
8800Sstevel@tonic-gate case RE_BAD_SEQID:
8810Sstevel@tonic-gate zcmn_err(zoneid, CE_NOTE, "![NFS4][Server: %s][Mntpt: %s]"
8820Sstevel@tonic-gate "Operation %s for file %s (rnode_pt 0x%p), pid %d using "
8830Sstevel@tonic-gate "seqid %d got %s. Last good seqid was %d for "
8840Sstevel@tonic-gate "operation %s.",
8850Sstevel@tonic-gate msg->msg_srv, msg->msg_mntpt,
8860Sstevel@tonic-gate nfs4_ctags[ep->re_tag1].ct_str, ep->re_char1,
8870Sstevel@tonic-gate (void *)ep->re_rp1, ep->re_pid, ep->re_seqid1,
8880Sstevel@tonic-gate nfs4_stat_to_str(ep->re_stat4), ep->re_seqid2,
8890Sstevel@tonic-gate nfs4_ctags[ep->re_tag2].ct_str);
8900Sstevel@tonic-gate break;
8910Sstevel@tonic-gate case RE_BADHANDLE:
8920Sstevel@tonic-gate ASSERT(ep->re_rp1 != NULL);
8930Sstevel@tonic-gate if (ep->re_char1 != NULL) {
8940Sstevel@tonic-gate zcmn_err(zoneid, CE_NOTE,
8950Sstevel@tonic-gate "![NFS4][Server: %s][Mntpt: %s]"
8960Sstevel@tonic-gate "server %s said filehandle was "
8970Sstevel@tonic-gate "invalid for file: %s (rnode_pt 0x%p) on mount %s",
8980Sstevel@tonic-gate msg->msg_srv, msg->msg_mntpt, msg->msg_srv,
8990Sstevel@tonic-gate ep->re_char1, (void *)ep->re_rp1, msg->msg_mntpt);
9000Sstevel@tonic-gate } else {
9010Sstevel@tonic-gate zcmn_err(zoneid, CE_NOTE,
9020Sstevel@tonic-gate "![NFS4][Server: %s][Mntpt: %s]"
9030Sstevel@tonic-gate "server %s said filehandle was "
9040Sstevel@tonic-gate "invalid for file: (rnode_pt 0x%p) on mount %s"
9050Sstevel@tonic-gate " for fh:", msg->msg_srv, msg->msg_mntpt,
9060Sstevel@tonic-gate msg->msg_srv, (void *)ep->re_rp1, msg->msg_mntpt);
9070Sstevel@tonic-gate sfh4_printfhandle(ep->re_rp1->r_fh);
9080Sstevel@tonic-gate }
9090Sstevel@tonic-gate break;
9100Sstevel@tonic-gate case RE_CLIENTID:
9110Sstevel@tonic-gate zcmn_err(zoneid, CE_NOTE, "![NFS4][Server: %s][Mntpt: %s]"
9120Sstevel@tonic-gate "Can't recover clientid on mount point %s "
9130Sstevel@tonic-gate "(mi 0x%p) due to error %d (%s), for server %s. Marking "
9140Sstevel@tonic-gate "file system as unusable.",
9150Sstevel@tonic-gate msg->msg_srv, msg->msg_mntpt, msg->msg_mntpt,
9160Sstevel@tonic-gate (void *)ep->re_mi, ep->re_uint,
9170Sstevel@tonic-gate nfs4_stat_to_str(ep->re_stat4),
9180Sstevel@tonic-gate msg->msg_srv);
9190Sstevel@tonic-gate break;
9200Sstevel@tonic-gate case RE_DEAD_FILE:
9210Sstevel@tonic-gate zcmn_err(zoneid, CE_NOTE, "![NFS4][Server: %s][Mntpt: %s]"
9220Sstevel@tonic-gate "File %s (rnode_pt: %p) was closed due to NFS "
9230Sstevel@tonic-gate "recovery error on server %s(%s %s)", msg->msg_srv,
9240Sstevel@tonic-gate msg->msg_mntpt, ep->re_char1, (void *)ep->re_rp1,
9250Sstevel@tonic-gate msg->msg_srv, ep->re_char2 ? ep->re_char2 : "",
9260Sstevel@tonic-gate ep->re_stat4 ? nfs4_stat_to_str(ep->re_stat4) : "");
9270Sstevel@tonic-gate break;
9280Sstevel@tonic-gate case RE_END:
9290Sstevel@tonic-gate zcmn_err(zoneid, CE_NOTE, "![NFS4][Server: %s][Mntpt: %s]"
9300Sstevel@tonic-gate "NFS Recovery done for mount %s (mi 0x%p) "
9310Sstevel@tonic-gate "on server %s, rnode_pt1 %s (0x%p), "
9320Sstevel@tonic-gate "rnode_pt2 %s (0x%p)", msg->msg_srv, msg->msg_mntpt,
9330Sstevel@tonic-gate msg->msg_mntpt, (void *)ep->re_mi, msg->msg_srv,
9340Sstevel@tonic-gate ep->re_char1, (void *)ep->re_rp1, ep->re_char2,
9350Sstevel@tonic-gate (void *)ep->re_rp2);
9360Sstevel@tonic-gate break;
9370Sstevel@tonic-gate case RE_FAIL_RELOCK:
9380Sstevel@tonic-gate zcmn_err(zoneid, CE_NOTE, "![NFS4][Server: %s][Mntpt: %s]"
9390Sstevel@tonic-gate "Couldn't reclaim lock for pid %d for "
9400Sstevel@tonic-gate "file %s (rnode_pt 0x%p) on (server %s): error %d",
9410Sstevel@tonic-gate msg->msg_srv, msg->msg_mntpt, ep->re_pid, ep->re_char1,
9420Sstevel@tonic-gate (void *)ep->re_rp1, msg->msg_srv,
9430Sstevel@tonic-gate ep->re_uint ? ep->re_uint : ep->re_stat4);
9440Sstevel@tonic-gate break;
9450Sstevel@tonic-gate case RE_FAIL_REMAP_LEN:
9460Sstevel@tonic-gate zcmn_err(zoneid, CE_NOTE, "![NFS4][Server: %s][Mntpt: %s]"
9470Sstevel@tonic-gate "remap_lookup: server %s returned bad "
9480Sstevel@tonic-gate "fhandle length (%d)", msg->msg_srv, msg->msg_mntpt,
9490Sstevel@tonic-gate msg->msg_srv, ep->re_uint);
9500Sstevel@tonic-gate break;
9510Sstevel@tonic-gate case RE_FAIL_REMAP_OP:
9520Sstevel@tonic-gate zcmn_err(zoneid, CE_NOTE, "![NFS4][Server: %s][Mntpt: %s]"
9530Sstevel@tonic-gate "remap_lookup: didn't get expected OP_GETFH"
9540Sstevel@tonic-gate " for server %s", msg->msg_srv, msg->msg_mntpt,
9550Sstevel@tonic-gate msg->msg_srv);
9560Sstevel@tonic-gate break;
9570Sstevel@tonic-gate case RE_FAILOVER:
9580Sstevel@tonic-gate if (ep->re_char1)
9590Sstevel@tonic-gate zcmn_err(zoneid, CE_NOTE,
9600Sstevel@tonic-gate "![NFS4][Server: %s][Mntpt: %s]"
9610Sstevel@tonic-gate "failing over from %s to %s", msg->msg_srv,
9620Sstevel@tonic-gate msg->msg_mntpt, msg->msg_srv, ep->re_char1);
9630Sstevel@tonic-gate else
9640Sstevel@tonic-gate zcmn_err(zoneid, CE_NOTE,
9650Sstevel@tonic-gate "![NFS4][Server: %s][Mntpt: %s]"
9660Sstevel@tonic-gate "NFS4: failing over: selecting "
9670Sstevel@tonic-gate "original server %s", msg->msg_srv, msg->msg_mntpt,
9680Sstevel@tonic-gate msg->msg_srv);
9690Sstevel@tonic-gate break;
9700Sstevel@tonic-gate case RE_FILE_DIFF:
9710Sstevel@tonic-gate zcmn_err(zoneid, CE_NOTE, "![NFS4][Server: %s][Mntpt: %s]"
9720Sstevel@tonic-gate "File %s (rnode_pt: %p) on server %s was closed "
9730Sstevel@tonic-gate "and failed attempted failover since its is different than "
9740Sstevel@tonic-gate "the original file", msg->msg_srv, msg->msg_mntpt,
9750Sstevel@tonic-gate ep->re_char1, (void *)ep->re_rp1, msg->msg_srv);
9760Sstevel@tonic-gate break;
9770Sstevel@tonic-gate case RE_LOST_STATE:
9780Sstevel@tonic-gate zcmn_err(zoneid, CE_NOTE, "![NFS4][Server: %s][Mntpt: %s]"
9790Sstevel@tonic-gate "Lost %s request for fs %s, file %s (rnode_pt: 0x%p), "
9800Sstevel@tonic-gate "dir %s (0x%p) for server %s", msg->msg_srv, msg->msg_mntpt,
9810Sstevel@tonic-gate nfs4_op_to_str(ep->re_uint), msg->msg_mntpt,
9820Sstevel@tonic-gate ep->re_char1, (void *)ep->re_rp1, ep->re_char2,
9830Sstevel@tonic-gate (void *)ep->re_rp2, msg->msg_srv);
9840Sstevel@tonic-gate break;
9850Sstevel@tonic-gate case RE_OPENS_CHANGED:
9860Sstevel@tonic-gate zcmn_err(zoneid, CE_NOTE, "![NFS4][Server: %s][Mntpt: %s]"
9870Sstevel@tonic-gate "The number of open files to reopen changed "
9880Sstevel@tonic-gate "for mount %s mi 0x%p (old %d, new %d) on server %s",
9890Sstevel@tonic-gate msg->msg_srv, msg->msg_mntpt, msg->msg_mntpt,
9900Sstevel@tonic-gate (void *)ep->re_mi, ep->re_uint, ep->re_pid, msg->msg_srv);
9910Sstevel@tonic-gate break;
9920Sstevel@tonic-gate case RE_SIGLOST:
9930Sstevel@tonic-gate case RE_SIGLOST_NO_DUMP:
9940Sstevel@tonic-gate if (ep->re_uint)
9950Sstevel@tonic-gate zcmn_err(zoneid, CE_NOTE,
9960Sstevel@tonic-gate "![NFS4][Server: %s][Mntpt: %s]"
9970Sstevel@tonic-gate "Process %d lost its locks on "
9980Sstevel@tonic-gate "file %s (rnode_pt: %p) due to NFS recovery error "
9990Sstevel@tonic-gate "(%d) on server %s.", msg->msg_srv, msg->msg_mntpt,
10000Sstevel@tonic-gate ep->re_pid, ep->re_char1, (void *)ep->re_rp1,
10010Sstevel@tonic-gate ep->re_uint, msg->msg_srv);
10020Sstevel@tonic-gate else
10030Sstevel@tonic-gate zcmn_err(zoneid, CE_NOTE,
10040Sstevel@tonic-gate "![NFS4][Server: %s][Mntpt: %s]"
10050Sstevel@tonic-gate "Process %d lost its locks on "
10060Sstevel@tonic-gate "file %s (rnode_pt: %p) due to NFS recovery error "
10070Sstevel@tonic-gate "(%s) on server %s.", msg->msg_srv, msg->msg_mntpt,
10080Sstevel@tonic-gate ep->re_pid, ep->re_char1, (void *)ep->re_rp1,
10090Sstevel@tonic-gate nfs4_stat_to_str(ep->re_stat4), msg->msg_srv);
10100Sstevel@tonic-gate break;
10110Sstevel@tonic-gate case RE_START:
10120Sstevel@tonic-gate zcmn_err(zoneid, CE_NOTE, "![NFS4][Server: %s][Mntpt: %s]"
10130Sstevel@tonic-gate "NFS Starting recovery for mount %s "
10140Sstevel@tonic-gate "(mi 0x%p mi_recovflags [0x%x]) on server %s, "
10150Sstevel@tonic-gate "rnode_pt1 %s (0x%p), rnode_pt2 %s (0x%p)", msg->msg_srv,
10160Sstevel@tonic-gate msg->msg_mntpt, msg->msg_mntpt, (void *)ep->re_mi,
10170Sstevel@tonic-gate ep->re_uint, msg->msg_srv, ep->re_char1, (void *)ep->re_rp1,
10180Sstevel@tonic-gate ep->re_char2, (void *)ep->re_rp2);
10190Sstevel@tonic-gate break;
10200Sstevel@tonic-gate case RE_UNEXPECTED_ACTION:
10210Sstevel@tonic-gate zcmn_err(zoneid, CE_NOTE, "![NFS4][Server: %s][Mntpt: %s]"
10220Sstevel@tonic-gate "NFS recovery: unexpected action (%s) on server %s",
10230Sstevel@tonic-gate msg->msg_srv, msg->msg_mntpt,
10240Sstevel@tonic-gate nfs4_recov_action_to_str(ep->re_uint), msg->msg_srv);
10250Sstevel@tonic-gate break;
10260Sstevel@tonic-gate case RE_UNEXPECTED_ERRNO:
10270Sstevel@tonic-gate zcmn_err(zoneid, CE_NOTE, "![NFS4][Server: %s][Mntpt: %s]"
10280Sstevel@tonic-gate "NFS recovery: unexpected errno (%d) on server %s",
10290Sstevel@tonic-gate msg->msg_srv, msg->msg_mntpt, ep->re_uint, msg->msg_srv);
10300Sstevel@tonic-gate break;
10310Sstevel@tonic-gate case RE_UNEXPECTED_STATUS:
10320Sstevel@tonic-gate zcmn_err(zoneid, CE_NOTE, "![NFS4][Server: %s][Mntpt: %s]"
10330Sstevel@tonic-gate "NFS recovery: unexpected NFS status code (%s) "
10340Sstevel@tonic-gate "on server %s", msg->msg_srv, msg->msg_mntpt,
10350Sstevel@tonic-gate nfs4_stat_to_str(ep->re_stat4),
10360Sstevel@tonic-gate msg->msg_srv);
10370Sstevel@tonic-gate break;
10380Sstevel@tonic-gate case RE_WRONGSEC:
10390Sstevel@tonic-gate zcmn_err(zoneid, CE_NOTE, "![NFS4][Server: %s][Mntpt: %s]"
10400Sstevel@tonic-gate "NFS can't recover from NFS4ERR_WRONGSEC."
10410Sstevel@tonic-gate " error %d for server %s: rnode_pt1 %s (0x%p)"
10420Sstevel@tonic-gate " rnode_pt2 %s (0x%p)", msg->msg_srv, msg->msg_mntpt,
10430Sstevel@tonic-gate ep->re_uint, msg->msg_srv, ep->re_char1, (void *)ep->re_rp1,
10440Sstevel@tonic-gate ep->re_char2, (void *)ep->re_rp2);
10450Sstevel@tonic-gate break;
10460Sstevel@tonic-gate case RE_LOST_STATE_BAD_OP:
10470Sstevel@tonic-gate zcmn_err(zoneid, CE_NOTE, "![NFS4][Server: %s][Mntpt: %s]"
10480Sstevel@tonic-gate "NFS lost state with unrecognized op (%d)."
10490Sstevel@tonic-gate " fs %s, server %s, pid %d, file %s (rnode_pt: 0x%p), "
10500Sstevel@tonic-gate "dir %s (0x%p)", msg->msg_srv, msg->msg_mntpt,
10510Sstevel@tonic-gate ep->re_uint, msg->msg_mntpt, msg->msg_srv, ep->re_pid,
10520Sstevel@tonic-gate ep->re_char1, (void *)ep->re_rp1, ep->re_char2,
10530Sstevel@tonic-gate (void *)ep->re_rp2);
10540Sstevel@tonic-gate break;
1055*11291SRobert.Thurlow@Sun.COM case RE_REFERRAL:
1056*11291SRobert.Thurlow@Sun.COM if (ep->re_char1)
1057*11291SRobert.Thurlow@Sun.COM zcmn_err(zoneid, CE_NOTE,
1058*11291SRobert.Thurlow@Sun.COM "![NFS4][Server: %s][Mntpt: %s]"
1059*11291SRobert.Thurlow@Sun.COM "being referred from %s to %s", msg->msg_srv,
1060*11291SRobert.Thurlow@Sun.COM msg->msg_mntpt, msg->msg_srv, ep->re_char1);
1061*11291SRobert.Thurlow@Sun.COM else
1062*11291SRobert.Thurlow@Sun.COM zcmn_err(zoneid, CE_NOTE,
1063*11291SRobert.Thurlow@Sun.COM "![NFS4][Server: %s][Mntpt: %s]"
1064*11291SRobert.Thurlow@Sun.COM "NFS4: being referred from %s to unknown server",
1065*11291SRobert.Thurlow@Sun.COM msg->msg_srv, msg->msg_mntpt, msg->msg_srv);
1066*11291SRobert.Thurlow@Sun.COM break;
10670Sstevel@tonic-gate default:
10680Sstevel@tonic-gate zcmn_err(zoneid, CE_WARN,
10690Sstevel@tonic-gate "!queue_print_event: illegal event %d", ep->re_type);
10700Sstevel@tonic-gate break;
10710Sstevel@tonic-gate }
10720Sstevel@tonic-gate
10730Sstevel@tonic-gate print_facts(msg, mi);
10740Sstevel@tonic-gate
10750Sstevel@tonic-gate /*
10760Sstevel@tonic-gate * If set this event will not be printed again and is considered
10770Sstevel@tonic-gate * dumped.
10780Sstevel@tonic-gate */
10790Sstevel@tonic-gate if (dump)
10800Sstevel@tonic-gate msg->msg_status = NFS4_MS_NO_DUMP;
10810Sstevel@tonic-gate }
10820Sstevel@tonic-gate
10830Sstevel@tonic-gate /*
10840Sstevel@tonic-gate * Print a fact message to /var/adm/messages
10850Sstevel@tonic-gate */
10860Sstevel@tonic-gate static void
queue_print_fact(nfs4_debug_msg_t * msg,int dump)10870Sstevel@tonic-gate queue_print_fact(nfs4_debug_msg_t *msg, int dump)
10880Sstevel@tonic-gate {
10890Sstevel@tonic-gate nfs4_rfact_t *fp;
10900Sstevel@tonic-gate zoneid_t zoneid;
10910Sstevel@tonic-gate
10920Sstevel@tonic-gate fp = &msg->rmsg_u.msg_fact;
10930Sstevel@tonic-gate zoneid = getzoneid();
10940Sstevel@tonic-gate
10950Sstevel@tonic-gate switch (fp->rf_type) {
10960Sstevel@tonic-gate case RF_BADOWNER:
10970Sstevel@tonic-gate zcmn_err(zoneid, CE_NOTE, "![NFS4][Server: %s][Mntpt: %s]"
10980Sstevel@tonic-gate "NFSMAPID_DOMAIN does not match the server: %s domain\n"
10990Sstevel@tonic-gate "Please check configuration", msg->msg_srv, msg->msg_mntpt,
11000Sstevel@tonic-gate msg->msg_srv);
11010Sstevel@tonic-gate break;
11020Sstevel@tonic-gate case RF_ERR:
11030Sstevel@tonic-gate if (fp->rf_error)
11040Sstevel@tonic-gate zcmn_err(zoneid, CE_NOTE,
11050Sstevel@tonic-gate "![NFS4][Server: %s][Mntpt: %s]NFS op %s got "
11060Sstevel@tonic-gate "error %d causing recovery action %s.%s",
11070Sstevel@tonic-gate msg->msg_srv, msg->msg_mntpt,
11080Sstevel@tonic-gate nfs4_op_to_str(fp->rf_op), fp->rf_error,
11090Sstevel@tonic-gate nfs4_recov_action_to_str(fp->rf_action),
11100Sstevel@tonic-gate fp->rf_reboot ?
11110Sstevel@tonic-gate " Client also suspects that the server rebooted,"
11120Sstevel@tonic-gate " or experienced a network partition." : "");
11130Sstevel@tonic-gate else
11140Sstevel@tonic-gate zcmn_err(zoneid, CE_NOTE,
11150Sstevel@tonic-gate "![NFS4][Server: %s][Mntpt: %s]NFS op %s got "
11160Sstevel@tonic-gate "error %s causing recovery action %s.%s",
11170Sstevel@tonic-gate msg->msg_srv, msg->msg_mntpt,
11180Sstevel@tonic-gate nfs4_op_to_str(fp->rf_op),
11190Sstevel@tonic-gate nfs4_stat_to_str(fp->rf_stat4),
11200Sstevel@tonic-gate nfs4_recov_action_to_str(fp->rf_action),
11210Sstevel@tonic-gate fp->rf_reboot ?
11220Sstevel@tonic-gate " Client also suspects that the server rebooted,"
11230Sstevel@tonic-gate " or experienced a network partition." : "");
11240Sstevel@tonic-gate break;
11250Sstevel@tonic-gate case RF_RENEW_EXPIRED:
11260Sstevel@tonic-gate zcmn_err(zoneid, CE_NOTE, "![NFS4][Server: %s][Mntpt: %s]"
11270Sstevel@tonic-gate "NFS4 renew thread detected client's "
11280Sstevel@tonic-gate "lease has expired. Current open files/locks/IO may fail",
11290Sstevel@tonic-gate msg->msg_srv, msg->msg_mntpt);
11300Sstevel@tonic-gate break;
11310Sstevel@tonic-gate case RF_SRV_NOT_RESPOND:
11320Sstevel@tonic-gate zcmn_err(zoneid, CE_NOTE, "![NFS4][Server: %s][Mntpt: %s]"
11330Sstevel@tonic-gate "NFS server %s not responding; still trying\n",
11340Sstevel@tonic-gate msg->msg_srv, msg->msg_mntpt, msg->msg_srv);
11350Sstevel@tonic-gate break;
11360Sstevel@tonic-gate case RF_SRV_OK:
11370Sstevel@tonic-gate zcmn_err(zoneid, CE_NOTE, "![NFS4][Server: %s][Mntpt: %s]"
11380Sstevel@tonic-gate "NFS server %s ok", msg->msg_srv, msg->msg_mntpt,
11390Sstevel@tonic-gate msg->msg_srv);
11400Sstevel@tonic-gate break;
11410Sstevel@tonic-gate case RF_SRVS_NOT_RESPOND:
11420Sstevel@tonic-gate zcmn_err(zoneid, CE_NOTE, "![NFS4][Server: %s][Mntpt: %s]"
11430Sstevel@tonic-gate "NFS servers %s not responding; still trying", msg->msg_srv,
11440Sstevel@tonic-gate msg->msg_mntpt, msg->msg_srv);
11450Sstevel@tonic-gate break;
11460Sstevel@tonic-gate case RF_SRVS_OK:
11470Sstevel@tonic-gate zcmn_err(zoneid, CE_NOTE, "![NFS4][Server: %s][Mntpt: %s]"
11480Sstevel@tonic-gate "NFS servers %s ok", msg->msg_srv, msg->msg_mntpt,
11490Sstevel@tonic-gate msg->msg_srv);
11500Sstevel@tonic-gate break;
11510Sstevel@tonic-gate case RF_DELMAP_CB_ERR:
11520Sstevel@tonic-gate zcmn_err(zoneid, CE_NOTE, "![NFS4][Server: %s][Mntpt: %s]"
11530Sstevel@tonic-gate "NFS op %s got error %s when executing delmap on file %s "
11540Sstevel@tonic-gate "(rnode_pt 0x%p).",
11550Sstevel@tonic-gate msg->msg_srv, msg->msg_mntpt, nfs4_op_to_str(fp->rf_op),
11560Sstevel@tonic-gate nfs4_stat_to_str(fp->rf_stat4), fp->rf_char1,
11570Sstevel@tonic-gate (void *)fp->rf_rp1);
11580Sstevel@tonic-gate break;
11599675Sdai.ngo@sun.com case RF_SENDQ_FULL:
11609675Sdai.ngo@sun.com zcmn_err(zoneid, CE_NOTE, "![NFS4][Server: %s][Mntpt: %s]"
11619675Sdai.ngo@sun.com "send queue to NFS server %s is full; still trying\n",
11629675Sdai.ngo@sun.com msg->msg_srv, msg->msg_mntpt, msg->msg_srv);
11639675Sdai.ngo@sun.com break;
11649675Sdai.ngo@sun.com
11650Sstevel@tonic-gate default:
11660Sstevel@tonic-gate zcmn_err(zoneid, CE_WARN, "!queue_print_fact: illegal fact %d",
11670Sstevel@tonic-gate fp->rf_type);
11680Sstevel@tonic-gate }
11690Sstevel@tonic-gate
11700Sstevel@tonic-gate /*
11710Sstevel@tonic-gate * If set this fact will not be printed again and is considered
11720Sstevel@tonic-gate * dumped.
11730Sstevel@tonic-gate */
11740Sstevel@tonic-gate if (dump)
11750Sstevel@tonic-gate msg->msg_status = NFS4_MS_NO_DUMP;
11760Sstevel@tonic-gate }
11770Sstevel@tonic-gate
11780Sstevel@tonic-gate /*
11790Sstevel@tonic-gate * Returns 1 if the entire queue should be dumped, 0 otherwise.
11800Sstevel@tonic-gate */
11810Sstevel@tonic-gate static int
id_to_dump_queue(nfs4_event_type_t id)11820Sstevel@tonic-gate id_to_dump_queue(nfs4_event_type_t id)
11830Sstevel@tonic-gate {
11840Sstevel@tonic-gate switch (id) {
11850Sstevel@tonic-gate case RE_DEAD_FILE:
11860Sstevel@tonic-gate case RE_SIGLOST:
11870Sstevel@tonic-gate case RE_WRONGSEC:
11880Sstevel@tonic-gate case RE_CLIENTID:
11890Sstevel@tonic-gate return (1);
11900Sstevel@tonic-gate default:
11910Sstevel@tonic-gate return (0);
11920Sstevel@tonic-gate }
11930Sstevel@tonic-gate }
11940Sstevel@tonic-gate
11950Sstevel@tonic-gate /*
11960Sstevel@tonic-gate * Returns 1 if the event (but not the entire queue) should be printed;
11970Sstevel@tonic-gate * 0 otherwise.
11980Sstevel@tonic-gate */
11990Sstevel@tonic-gate static int
id_to_dump_solo_event(nfs4_event_type_t id)12000Sstevel@tonic-gate id_to_dump_solo_event(nfs4_event_type_t id)
12010Sstevel@tonic-gate {
12020Sstevel@tonic-gate switch (id) {
12030Sstevel@tonic-gate case RE_BAD_SEQID:
12040Sstevel@tonic-gate case RE_BADHANDLE:
12050Sstevel@tonic-gate case RE_FAIL_REMAP_LEN:
12060Sstevel@tonic-gate case RE_FAIL_REMAP_OP:
12070Sstevel@tonic-gate case RE_FAILOVER:
12080Sstevel@tonic-gate case RE_OPENS_CHANGED:
12090Sstevel@tonic-gate case RE_SIGLOST_NO_DUMP:
12100Sstevel@tonic-gate case RE_UNEXPECTED_ACTION:
12110Sstevel@tonic-gate case RE_UNEXPECTED_ERRNO:
12120Sstevel@tonic-gate case RE_UNEXPECTED_STATUS:
12130Sstevel@tonic-gate case RE_LOST_STATE_BAD_OP:
1214*11291SRobert.Thurlow@Sun.COM case RE_REFERRAL:
12150Sstevel@tonic-gate return (1);
12160Sstevel@tonic-gate default:
12170Sstevel@tonic-gate return (0);
12180Sstevel@tonic-gate }
12190Sstevel@tonic-gate }
12200Sstevel@tonic-gate
12210Sstevel@tonic-gate /*
12220Sstevel@tonic-gate * Returns 1 if the fact (but not the entire queue) should be printed;
12230Sstevel@tonic-gate * 0 otherwise.
12240Sstevel@tonic-gate */
12250Sstevel@tonic-gate static int
id_to_dump_solo_fact(nfs4_fact_type_t id)12260Sstevel@tonic-gate id_to_dump_solo_fact(nfs4_fact_type_t id)
12270Sstevel@tonic-gate {
12280Sstevel@tonic-gate switch (id) {
12290Sstevel@tonic-gate case RF_SRV_NOT_RESPOND:
12300Sstevel@tonic-gate case RF_SRV_OK:
12310Sstevel@tonic-gate case RF_SRVS_NOT_RESPOND:
12320Sstevel@tonic-gate case RF_SRVS_OK:
12339675Sdai.ngo@sun.com case RF_SENDQ_FULL:
12340Sstevel@tonic-gate return (1);
12350Sstevel@tonic-gate default:
12360Sstevel@tonic-gate return (0);
12370Sstevel@tonic-gate }
12380Sstevel@tonic-gate }
12390Sstevel@tonic-gate
12400Sstevel@tonic-gate /*
12410Sstevel@tonic-gate * Update a kernel stat
12420Sstevel@tonic-gate */
12430Sstevel@tonic-gate static void
update_recov_kstats(nfs4_debug_msg_t * msg,mntinfo4_t * mi)12440Sstevel@tonic-gate update_recov_kstats(nfs4_debug_msg_t *msg, mntinfo4_t *mi)
12450Sstevel@tonic-gate {
12460Sstevel@tonic-gate rkstat_t *rsp;
12470Sstevel@tonic-gate
12480Sstevel@tonic-gate if (!mi->mi_recov_ksp)
12490Sstevel@tonic-gate return;
12500Sstevel@tonic-gate
12510Sstevel@tonic-gate rsp = (rkstat_t *)mi->mi_recov_ksp->ks_data;
12520Sstevel@tonic-gate
12530Sstevel@tonic-gate if (msg->msg_type == RM_EVENT) {
12540Sstevel@tonic-gate switch (msg->rmsg_u.msg_event.re_type) {
12550Sstevel@tonic-gate case RE_BADHANDLE:
12560Sstevel@tonic-gate rsp->badhandle.value.ul++;
12570Sstevel@tonic-gate break;
12580Sstevel@tonic-gate case RE_CLIENTID:
12590Sstevel@tonic-gate rsp->clientid.value.ul++;
12600Sstevel@tonic-gate break;
12610Sstevel@tonic-gate case RE_DEAD_FILE:
12620Sstevel@tonic-gate rsp->dead_file.value.ul++;
12630Sstevel@tonic-gate break;
12640Sstevel@tonic-gate case RE_FAIL_RELOCK:
12650Sstevel@tonic-gate rsp->fail_relock.value.ul++;
12660Sstevel@tonic-gate break;
12670Sstevel@tonic-gate case RE_FILE_DIFF:
12680Sstevel@tonic-gate rsp->file_diff.value.ul++;
12690Sstevel@tonic-gate break;
12700Sstevel@tonic-gate case RE_OPENS_CHANGED:
12710Sstevel@tonic-gate rsp->opens_changed.value.ul++;
12720Sstevel@tonic-gate break;
12730Sstevel@tonic-gate case RE_SIGLOST:
12740Sstevel@tonic-gate case RE_SIGLOST_NO_DUMP:
12750Sstevel@tonic-gate rsp->siglost.value.ul++;
12760Sstevel@tonic-gate break;
12770Sstevel@tonic-gate case RE_UNEXPECTED_ACTION:
12780Sstevel@tonic-gate rsp->unexp_action.value.ul++;
12790Sstevel@tonic-gate break;
12800Sstevel@tonic-gate case RE_UNEXPECTED_ERRNO:
12810Sstevel@tonic-gate rsp->unexp_errno.value.ul++;
12820Sstevel@tonic-gate break;
12830Sstevel@tonic-gate case RE_UNEXPECTED_STATUS:
12840Sstevel@tonic-gate rsp->unexp_status.value.ul++;
12850Sstevel@tonic-gate break;
12860Sstevel@tonic-gate case RE_WRONGSEC:
12870Sstevel@tonic-gate rsp->wrongsec.value.ul++;
12880Sstevel@tonic-gate break;
12890Sstevel@tonic-gate case RE_LOST_STATE_BAD_OP:
12900Sstevel@tonic-gate rsp->lost_state_bad_op.value.ul++;
12910Sstevel@tonic-gate break;
12920Sstevel@tonic-gate default:
12930Sstevel@tonic-gate break;
12940Sstevel@tonic-gate }
12950Sstevel@tonic-gate } else if (msg->msg_type == RM_FACT) {
12960Sstevel@tonic-gate switch (msg->rmsg_u.msg_fact.rf_type) {
12970Sstevel@tonic-gate case RF_BADOWNER:
12980Sstevel@tonic-gate rsp->badowner.value.ul++;
12990Sstevel@tonic-gate break;
13000Sstevel@tonic-gate case RF_SRV_NOT_RESPOND:
13010Sstevel@tonic-gate rsp->not_responding.value.ul++;
13020Sstevel@tonic-gate break;
13030Sstevel@tonic-gate default:
13040Sstevel@tonic-gate break;
13050Sstevel@tonic-gate }
13060Sstevel@tonic-gate }
13070Sstevel@tonic-gate }
13080Sstevel@tonic-gate
13090Sstevel@tonic-gate /*
13100Sstevel@tonic-gate * Dump the mi's mi_msg_list of recovery messages.
13110Sstevel@tonic-gate */
13120Sstevel@tonic-gate static void
dump_queue(mntinfo4_t * mi,nfs4_debug_msg_t * msg)13130Sstevel@tonic-gate dump_queue(mntinfo4_t *mi, nfs4_debug_msg_t *msg)
13140Sstevel@tonic-gate {
13150Sstevel@tonic-gate nfs4_debug_msg_t *tmp_msg;
13160Sstevel@tonic-gate
13170Sstevel@tonic-gate ASSERT(mutex_owned(&mi->mi_msg_list_lock));
13180Sstevel@tonic-gate
13190Sstevel@tonic-gate /* update kstats */
13200Sstevel@tonic-gate update_recov_kstats(msg, mi);
13210Sstevel@tonic-gate
13220Sstevel@tonic-gate /*
13230Sstevel@tonic-gate * If we aren't supposed to dump the queue then see if we
13240Sstevel@tonic-gate * should just print this single message, then return.
13250Sstevel@tonic-gate */
13260Sstevel@tonic-gate if (!id_to_dump_queue(msg->rmsg_u.msg_event.re_type)) {
13270Sstevel@tonic-gate if (id_to_dump_solo_event(msg->rmsg_u.msg_event.re_type))
13280Sstevel@tonic-gate queue_print_event(msg, mi, 0);
13290Sstevel@tonic-gate return;
13300Sstevel@tonic-gate }
13310Sstevel@tonic-gate
13320Sstevel@tonic-gate /*
13330Sstevel@tonic-gate * Write all events/facts in the queue that haven't been
13340Sstevel@tonic-gate * previously written to disk.
13350Sstevel@tonic-gate */
13360Sstevel@tonic-gate tmp_msg = list_head(&mi->mi_msg_list);
13370Sstevel@tonic-gate while (tmp_msg) {
13380Sstevel@tonic-gate if (tmp_msg->msg_status == NFS4_MS_DUMP) {
13390Sstevel@tonic-gate if (tmp_msg->msg_type == RM_EVENT)
13400Sstevel@tonic-gate queue_print_event(tmp_msg, mi, 1);
13410Sstevel@tonic-gate else if (tmp_msg->msg_type == RM_FACT)
13420Sstevel@tonic-gate queue_print_fact(tmp_msg, 1);
13430Sstevel@tonic-gate }
13440Sstevel@tonic-gate tmp_msg = list_next(&mi->mi_msg_list, tmp_msg);
13450Sstevel@tonic-gate }
13460Sstevel@tonic-gate }
13470Sstevel@tonic-gate
13480Sstevel@tonic-gate /*
13490Sstevel@tonic-gate * Places the event into mi's debug recovery message queue. Some of the
13500Sstevel@tonic-gate * fields can be overloaded to be a generic value, depending on the event
13510Sstevel@tonic-gate * type. These include "count", "why".
13520Sstevel@tonic-gate */
13530Sstevel@tonic-gate void
nfs4_queue_event(nfs4_event_type_t id,mntinfo4_t * mi,char * server1,uint_t count,vnode_t * vp1,vnode_t * vp2,nfsstat4 nfs4_error,char * why,pid_t pid,nfs4_tag_type_t tag1,nfs4_tag_type_t tag2,seqid4 seqid1,seqid4 seqid2)13540Sstevel@tonic-gate nfs4_queue_event(nfs4_event_type_t id, mntinfo4_t *mi, char *server1,
13550Sstevel@tonic-gate uint_t count, vnode_t *vp1, vnode_t *vp2, nfsstat4 nfs4_error,
13560Sstevel@tonic-gate char *why, pid_t pid, nfs4_tag_type_t tag1, nfs4_tag_type_t tag2,
13570Sstevel@tonic-gate seqid4 seqid1, seqid4 seqid2)
13580Sstevel@tonic-gate {
13590Sstevel@tonic-gate nfs4_debug_msg_t *msg;
13600Sstevel@tonic-gate nfs4_revent_t *ep;
13610Sstevel@tonic-gate char *cur_srv;
13620Sstevel@tonic-gate rnode4_t *rp1 = NULL, *rp2 = NULL;
13630Sstevel@tonic-gate refstr_t *mntpt;
13640Sstevel@tonic-gate
13650Sstevel@tonic-gate ASSERT(mi != NULL);
13660Sstevel@tonic-gate if (vp1)
13670Sstevel@tonic-gate rp1 = VTOR4(vp1);
13680Sstevel@tonic-gate if (vp2)
13690Sstevel@tonic-gate rp2 = VTOR4(vp2);
13700Sstevel@tonic-gate
13710Sstevel@tonic-gate /*
13723517Smp204432 * Initialize the message with the relevant server/mount_pt/time
13730Sstevel@tonic-gate * information. Also place the relevent event related info.
13740Sstevel@tonic-gate */
13750Sstevel@tonic-gate msg = kmem_zalloc(sizeof (*msg), KM_SLEEP);
13760Sstevel@tonic-gate msg->msg_type = RM_EVENT;
13770Sstevel@tonic-gate msg->msg_status = NFS4_MS_DUMP;
13780Sstevel@tonic-gate ep = &msg->rmsg_u.msg_event;
13790Sstevel@tonic-gate ep->re_type = id;
13800Sstevel@tonic-gate gethrestime(&msg->msg_time);
13810Sstevel@tonic-gate
13820Sstevel@tonic-gate cur_srv = mi->mi_curr_serv->sv_hostname;
13830Sstevel@tonic-gate msg->msg_srv = strdup(cur_srv);
13840Sstevel@tonic-gate mntpt = vfs_getmntpoint(mi->mi_vfsp);
13850Sstevel@tonic-gate msg->msg_mntpt = strdup(refstr_value(mntpt));
13860Sstevel@tonic-gate refstr_rele(mntpt);
13870Sstevel@tonic-gate
13880Sstevel@tonic-gate set_event(id, ep, mi, rp1, rp2, count, pid, nfs4_error, server1,
13890Sstevel@tonic-gate why, tag1, tag2, seqid1, seqid2);
13900Sstevel@tonic-gate
13910Sstevel@tonic-gate mutex_enter(&mi->mi_msg_list_lock);
13920Sstevel@tonic-gate
13930Sstevel@tonic-gate /* if this event is the same as the last event, drop it */
13940Sstevel@tonic-gate if (events_same(list_tail(&mi->mi_msg_list), msg, mi)) {
13950Sstevel@tonic-gate mutex_exit(&mi->mi_msg_list_lock);
13960Sstevel@tonic-gate nfs4_free_msg(msg);
13970Sstevel@tonic-gate return;
13980Sstevel@tonic-gate }
13990Sstevel@tonic-gate
14000Sstevel@tonic-gate /* queue the message at the end of the list */
14010Sstevel@tonic-gate list_insert_tail(&mi->mi_msg_list, msg);
14020Sstevel@tonic-gate
14030Sstevel@tonic-gate dump_queue(mi, msg);
14040Sstevel@tonic-gate
14050Sstevel@tonic-gate if (mi->mi_msg_count == nfs4_msg_max) {
14060Sstevel@tonic-gate nfs4_debug_msg_t *rm_msg;
14070Sstevel@tonic-gate
14080Sstevel@tonic-gate /* remove the queue'd message at the front of the list */
14090Sstevel@tonic-gate rm_msg = list_head(&mi->mi_msg_list);
14100Sstevel@tonic-gate list_remove(&mi->mi_msg_list, rm_msg);
14110Sstevel@tonic-gate mutex_exit(&mi->mi_msg_list_lock);
14120Sstevel@tonic-gate nfs4_free_msg(rm_msg);
14130Sstevel@tonic-gate } else {
14140Sstevel@tonic-gate mi->mi_msg_count++;
14150Sstevel@tonic-gate mutex_exit(&mi->mi_msg_list_lock);
14160Sstevel@tonic-gate }
14170Sstevel@tonic-gate }
14180Sstevel@tonic-gate
14190Sstevel@tonic-gate /*
14200Sstevel@tonic-gate * Places the fact into mi's debug recovery messages queue.
14210Sstevel@tonic-gate */
14220Sstevel@tonic-gate void
nfs4_queue_fact(nfs4_fact_type_t fid,mntinfo4_t * mi,nfsstat4 stat4,nfs4_recov_t raction,nfs_opnum4 op,bool_t reboot,char * srvname,int error,vnode_t * vp)14230Sstevel@tonic-gate nfs4_queue_fact(nfs4_fact_type_t fid, mntinfo4_t *mi, nfsstat4 stat4,
14240Sstevel@tonic-gate nfs4_recov_t raction, nfs_opnum4 op, bool_t reboot, char *srvname,
14250Sstevel@tonic-gate int error, vnode_t *vp)
14260Sstevel@tonic-gate {
14270Sstevel@tonic-gate nfs4_debug_msg_t *msg;
14280Sstevel@tonic-gate nfs4_rfact_t *fp;
14290Sstevel@tonic-gate char *cur_srv;
14300Sstevel@tonic-gate refstr_t *mntpt;
14310Sstevel@tonic-gate
14320Sstevel@tonic-gate /*
14333517Smp204432 * Initialize the message with the relevant server/mount_pt/time
14343517Smp204432 * information. Also place the relevant fact related info.
14350Sstevel@tonic-gate */
14360Sstevel@tonic-gate msg = kmem_zalloc(sizeof (*msg), KM_SLEEP);
14370Sstevel@tonic-gate msg->msg_type = RM_FACT;
14380Sstevel@tonic-gate msg->msg_status = NFS4_MS_DUMP;
14390Sstevel@tonic-gate gethrestime(&msg->msg_time);
14400Sstevel@tonic-gate
14410Sstevel@tonic-gate if (srvname)
14420Sstevel@tonic-gate cur_srv = srvname;
14430Sstevel@tonic-gate else
14440Sstevel@tonic-gate cur_srv = mi->mi_curr_serv->sv_hostname;
14450Sstevel@tonic-gate
14460Sstevel@tonic-gate msg->msg_srv = strdup(cur_srv);
14470Sstevel@tonic-gate mntpt = vfs_getmntpoint(mi->mi_vfsp);
14480Sstevel@tonic-gate msg->msg_mntpt = strdup(refstr_value(mntpt));
14490Sstevel@tonic-gate refstr_rele(mntpt);
14500Sstevel@tonic-gate
14510Sstevel@tonic-gate fp = &msg->rmsg_u.msg_fact;
14520Sstevel@tonic-gate fp->rf_type = fid;
14530Sstevel@tonic-gate fp->rf_status = RFS_NO_INSPECT;
14540Sstevel@tonic-gate set_fact(fid, fp, stat4, raction, op, reboot, error, vp);
14550Sstevel@tonic-gate
14560Sstevel@tonic-gate update_recov_kstats(msg, mi);
14570Sstevel@tonic-gate
14580Sstevel@tonic-gate mutex_enter(&mi->mi_msg_list_lock);
14590Sstevel@tonic-gate
14600Sstevel@tonic-gate /* if this fact is the same as the last fact, drop it */
14610Sstevel@tonic-gate if (facts_same(list_tail(&mi->mi_msg_list), msg, mi)) {
14620Sstevel@tonic-gate mutex_exit(&mi->mi_msg_list_lock);
14630Sstevel@tonic-gate nfs4_free_msg(msg);
14640Sstevel@tonic-gate return;
14650Sstevel@tonic-gate }
14660Sstevel@tonic-gate
14670Sstevel@tonic-gate /* queue the message at the end of the list */
14680Sstevel@tonic-gate list_insert_tail(&mi->mi_msg_list, msg);
14690Sstevel@tonic-gate
14700Sstevel@tonic-gate if (id_to_dump_solo_fact(msg->rmsg_u.msg_fact.rf_type))
14710Sstevel@tonic-gate queue_print_fact(msg, 0);
14720Sstevel@tonic-gate
14730Sstevel@tonic-gate if (mi->mi_msg_count == nfs4_msg_max) {
14740Sstevel@tonic-gate nfs4_debug_msg_t *rm_msg;
14750Sstevel@tonic-gate
14760Sstevel@tonic-gate /* remove the queue'd message at the front of the list */
14770Sstevel@tonic-gate rm_msg = list_head(&mi->mi_msg_list);
14780Sstevel@tonic-gate list_remove(&mi->mi_msg_list, rm_msg);
14790Sstevel@tonic-gate mutex_exit(&mi->mi_msg_list_lock);
14800Sstevel@tonic-gate nfs4_free_msg(rm_msg);
14810Sstevel@tonic-gate } else {
14820Sstevel@tonic-gate mi->mi_msg_count++;
14830Sstevel@tonic-gate mutex_exit(&mi->mi_msg_list_lock);
14840Sstevel@tonic-gate }
14850Sstevel@tonic-gate }
14860Sstevel@tonic-gate
14870Sstevel@tonic-gate /*
14880Sstevel@tonic-gate * Initialize the 'mi_recov_kstat' kstat.
14890Sstevel@tonic-gate */
14900Sstevel@tonic-gate void
nfs4_mnt_recov_kstat_init(vfs_t * vfsp)14910Sstevel@tonic-gate nfs4_mnt_recov_kstat_init(vfs_t *vfsp)
14920Sstevel@tonic-gate {
14930Sstevel@tonic-gate mntinfo4_t *mi = VFTOMI4(vfsp);
14940Sstevel@tonic-gate kstat_t *ksp;
14950Sstevel@tonic-gate zoneid_t zoneid = mi->mi_zone->zone_id;
14960Sstevel@tonic-gate
14970Sstevel@tonic-gate /*
14980Sstevel@tonic-gate * Create the version specific kstats.
14990Sstevel@tonic-gate *
15000Sstevel@tonic-gate * PSARC 2001/697 Contract Private Interface
15010Sstevel@tonic-gate * All nfs kstats are under SunMC contract
15020Sstevel@tonic-gate * Please refer to the PSARC listed above and contact
15030Sstevel@tonic-gate * SunMC before making any changes!
15040Sstevel@tonic-gate *
15050Sstevel@tonic-gate * Changes must be reviewed by Solaris File Sharing
15060Sstevel@tonic-gate * Changes must be communicated to contract-2001-697@sun.com
15070Sstevel@tonic-gate *
15080Sstevel@tonic-gate */
15090Sstevel@tonic-gate
15100Sstevel@tonic-gate if ((ksp = kstat_create_zone("nfs", getminor(vfsp->vfs_dev),
15110Sstevel@tonic-gate "mi_recov_kstat", "misc", KSTAT_TYPE_NAMED,
15120Sstevel@tonic-gate sizeof (rkstat_t) / sizeof (kstat_named_t),
15130Sstevel@tonic-gate KSTAT_FLAG_WRITABLE, zoneid)) == NULL) {
15140Sstevel@tonic-gate mi->mi_recov_ksp = NULL;
15150Sstevel@tonic-gate zcmn_err(GLOBAL_ZONEID, CE_NOTE,
15160Sstevel@tonic-gate "!mi_recov_kstat for mi %p failed\n",
15170Sstevel@tonic-gate (void *)mi);
15180Sstevel@tonic-gate return;
15190Sstevel@tonic-gate }
15200Sstevel@tonic-gate if (zoneid != GLOBAL_ZONEID)
15210Sstevel@tonic-gate kstat_zone_add(ksp, GLOBAL_ZONEID);
15220Sstevel@tonic-gate mi->mi_recov_ksp = ksp;
15230Sstevel@tonic-gate bcopy(&rkstat_template, ksp->ks_data, sizeof (rkstat_t));
15240Sstevel@tonic-gate kstat_install(ksp);
15250Sstevel@tonic-gate }
15260Sstevel@tonic-gate
15270Sstevel@tonic-gate /*
15280Sstevel@tonic-gate * Increment the "delay" kstat.
15290Sstevel@tonic-gate */
15300Sstevel@tonic-gate void
nfs4_mi_kstat_inc_delay(mntinfo4_t * mi)15310Sstevel@tonic-gate nfs4_mi_kstat_inc_delay(mntinfo4_t *mi)
15320Sstevel@tonic-gate {
15330Sstevel@tonic-gate rkstat_t *rsp;
15340Sstevel@tonic-gate
15350Sstevel@tonic-gate if (!mi->mi_recov_ksp)
15360Sstevel@tonic-gate return;
15370Sstevel@tonic-gate
15380Sstevel@tonic-gate rsp = (rkstat_t *)mi->mi_recov_ksp->ks_data;
15390Sstevel@tonic-gate rsp->delay.value.ul++;
15400Sstevel@tonic-gate }
15410Sstevel@tonic-gate
15420Sstevel@tonic-gate /*
15430Sstevel@tonic-gate * Increment the "no_grace" kstat.
15440Sstevel@tonic-gate */
15450Sstevel@tonic-gate void
nfs4_mi_kstat_inc_no_grace(mntinfo4_t * mi)15460Sstevel@tonic-gate nfs4_mi_kstat_inc_no_grace(mntinfo4_t *mi)
15470Sstevel@tonic-gate {
15480Sstevel@tonic-gate rkstat_t *rsp;
15490Sstevel@tonic-gate
15500Sstevel@tonic-gate if (!mi->mi_recov_ksp)
15510Sstevel@tonic-gate return;
15520Sstevel@tonic-gate
15530Sstevel@tonic-gate rsp = (rkstat_t *)mi->mi_recov_ksp->ks_data;
15540Sstevel@tonic-gate rsp->no_grace.value.ul++;
15550Sstevel@tonic-gate }
1556