#include <sys/types.h>
#include <sys/kstat.h>
#include <sys/zone.h>
#include <sys/kmem.h>
#include <sys/systm.h>
#include <nfs/nfs.h>
#include <nfs/nfs4_kprot.h>
zone_key_t nfsstat_zone_key;
static kstat_named_t *
nfsstat_zone_init_common(zoneid_t zoneid, const char *module, int vers,
const char *name, const kstat_named_t *template,
size_t template_size)
{
kstat_t *ksp;
kstat_named_t *ks_data;
ks_data = kmem_alloc(template_size, KM_SLEEP);
bcopy(template, ks_data, template_size);
if ((ksp = kstat_create_zone(module, vers, name, "misc",
KSTAT_TYPE_NAMED, template_size / sizeof (kstat_named_t),
KSTAT_FLAG_VIRTUAL | KSTAT_FLAG_WRITABLE, zoneid)) != NULL) {
ksp->ks_data = ks_data;
kstat_install(ksp);
}
return (ks_data);
}
static void
nfsstat_zone_fini_common(zoneid_t zoneid, const char *module, int vers,
const char *name)
{
kstat_delete_byname_zone(module, vers, name, zoneid);
}
static const kstat_named_t svstat_tmpl[] = {
{ "calls", KSTAT_DATA_UINT64 },
{ "badcalls", KSTAT_DATA_UINT64 },
{ "referrals", KSTAT_DATA_UINT64 },
{ "referlinks", KSTAT_DATA_UINT64 },
};
static void
nfsstat_zone_init_server(zoneid_t zoneid, kstat_named_t *svstatp[])
{
int vers;
for (vers = NFS_VERSION; vers <= NFS_V4; vers++) {
svstatp[vers] = nfsstat_zone_init_common(zoneid, "nfs", vers,
"nfs_server", svstat_tmpl, sizeof (svstat_tmpl));
}
}
static void
nfsstat_zone_fini_server(zoneid_t zoneid, kstat_named_t *svstatp[])
{
int vers;
for (vers = NFS_VERSION; vers <= NFS_V4; vers++) {
nfsstat_zone_fini_common(zoneid, "nfs", vers, "nfs_server");
kmem_free(svstatp[vers], sizeof (svstat_tmpl));
}
}
static const kstat_named_t rfsreqcnt_v2_tmpl[] = {
{ "null", KSTAT_DATA_UINT64 },
{ "getattr", KSTAT_DATA_UINT64 },
{ "setattr", KSTAT_DATA_UINT64 },
{ "root", KSTAT_DATA_UINT64 },
{ "lookup", KSTAT_DATA_UINT64 },
{ "readlink", KSTAT_DATA_UINT64 },
{ "read", KSTAT_DATA_UINT64 },
{ "wrcache", KSTAT_DATA_UINT64 },
{ "write", KSTAT_DATA_UINT64 },
{ "create", KSTAT_DATA_UINT64 },
{ "remove", KSTAT_DATA_UINT64 },
{ "rename", KSTAT_DATA_UINT64 },
{ "link", KSTAT_DATA_UINT64 },
{ "symlink", KSTAT_DATA_UINT64 },
{ "mkdir", KSTAT_DATA_UINT64 },
{ "rmdir", KSTAT_DATA_UINT64 },
{ "readdir", KSTAT_DATA_UINT64 },
{ "statfs", KSTAT_DATA_UINT64 }
};
static void
nfsstat_zone_init_rfsreq_v2(zoneid_t zoneid, struct nfs_version_stats *statsp)
{
statsp->rfsreqcnt_ptr = nfsstat_zone_init_common(zoneid, "nfs", 0,
"rfsreqcnt_v2", rfsreqcnt_v2_tmpl, sizeof (rfsreqcnt_v2_tmpl));
}
static void
nfsstat_zone_fini_rfsreq_v2(zoneid_t zoneid, struct nfs_version_stats *statsp)
{
nfsstat_zone_fini_common(zoneid, "nfs", 0, "rfsreqcnt_v2");
kmem_free(statsp->rfsreqcnt_ptr, sizeof (rfsreqcnt_v2_tmpl));
}
static const kstat_named_t rfsproccnt_v2_tmpl[] = {
{ "null", KSTAT_DATA_UINT64 },
{ "getattr", KSTAT_DATA_UINT64 },
{ "setattr", KSTAT_DATA_UINT64 },
{ "root", KSTAT_DATA_UINT64 },
{ "lookup", KSTAT_DATA_UINT64 },
{ "readlink", KSTAT_DATA_UINT64 },
{ "read", KSTAT_DATA_UINT64 },
{ "wrcache", KSTAT_DATA_UINT64 },
{ "write", KSTAT_DATA_UINT64 },
{ "create", KSTAT_DATA_UINT64 },
{ "remove", KSTAT_DATA_UINT64 },
{ "rename", KSTAT_DATA_UINT64 },
{ "link", KSTAT_DATA_UINT64 },
{ "symlink", KSTAT_DATA_UINT64 },
{ "mkdir", KSTAT_DATA_UINT64 },
{ "rmdir", KSTAT_DATA_UINT64 },
{ "readdir", KSTAT_DATA_UINT64 },
{ "statfs", KSTAT_DATA_UINT64 }
};
static const kstat_named_t aclreqcnt_v2_tmpl[] = {
{ "null", KSTAT_DATA_UINT64 },
{ "getacl", KSTAT_DATA_UINT64 },
{ "setacl", KSTAT_DATA_UINT64 },
{ "getattr", KSTAT_DATA_UINT64 },
{ "access", KSTAT_DATA_UINT64 },
{ "getxattrdir", KSTAT_DATA_UINT64 }
};
static void
nfsstat_zone_init_aclreq_v2(zoneid_t zoneid, struct nfs_version_stats *statsp)
{
statsp->aclreqcnt_ptr = nfsstat_zone_init_common(zoneid, "nfs_acl", 0,
"aclreqcnt_v2", aclreqcnt_v2_tmpl, sizeof (aclreqcnt_v2_tmpl));
}
static void
nfsstat_zone_fini_aclreq_v2(zoneid_t zoneid, struct nfs_version_stats *statsp)
{
nfsstat_zone_fini_common(zoneid, "nfs_acl", 0, "aclreqcnt_v2");
kmem_free(statsp->aclreqcnt_ptr, sizeof (aclreqcnt_v2_tmpl));
}
static const kstat_named_t aclproccnt_v2_tmpl[] = {
{ "null", KSTAT_DATA_UINT64 },
{ "getacl", KSTAT_DATA_UINT64 },
{ "setacl", KSTAT_DATA_UINT64 },
{ "getattr", KSTAT_DATA_UINT64 },
{ "access", KSTAT_DATA_UINT64 },
{ "getxattrdir", KSTAT_DATA_UINT64 }
};
static const kstat_named_t rfsreqcnt_v3_tmpl[] = {
{ "null", KSTAT_DATA_UINT64 },
{ "getattr", KSTAT_DATA_UINT64 },
{ "setattr", KSTAT_DATA_UINT64 },
{ "lookup", KSTAT_DATA_UINT64 },
{ "access", KSTAT_DATA_UINT64 },
{ "readlink", KSTAT_DATA_UINT64 },
{ "read", KSTAT_DATA_UINT64 },
{ "write", KSTAT_DATA_UINT64 },
{ "create", KSTAT_DATA_UINT64 },
{ "mkdir", KSTAT_DATA_UINT64 },
{ "symlink", KSTAT_DATA_UINT64 },
{ "mknod", KSTAT_DATA_UINT64 },
{ "remove", KSTAT_DATA_UINT64 },
{ "rmdir", KSTAT_DATA_UINT64 },
{ "rename", KSTAT_DATA_UINT64 },
{ "link", KSTAT_DATA_UINT64 },
{ "readdir", KSTAT_DATA_UINT64 },
{ "readdirplus", KSTAT_DATA_UINT64 },
{ "fsstat", KSTAT_DATA_UINT64 },
{ "fsinfo", KSTAT_DATA_UINT64 },
{ "pathconf", KSTAT_DATA_UINT64 },
{ "commit", KSTAT_DATA_UINT64 }
};
static void
nfsstat_zone_init_rfsreq_v3(zoneid_t zoneid, struct nfs_version_stats *statsp)
{
statsp->rfsreqcnt_ptr = nfsstat_zone_init_common(zoneid, "nfs", 0,
"rfsreqcnt_v3", rfsreqcnt_v3_tmpl, sizeof (rfsreqcnt_v3_tmpl));
}
static void
nfsstat_zone_fini_rfsreq_v3(zoneid_t zoneid, struct nfs_version_stats *statsp)
{
nfsstat_zone_fini_common(zoneid, "nfs", 0, "rfsreqcnt_v3");
kmem_free(statsp->rfsreqcnt_ptr, sizeof (rfsreqcnt_v3_tmpl));
}
static const kstat_named_t rfsproccnt_v3_tmpl[] = {
{ "null", KSTAT_DATA_UINT64 },
{ "getattr", KSTAT_DATA_UINT64 },
{ "setattr", KSTAT_DATA_UINT64 },
{ "lookup", KSTAT_DATA_UINT64 },
{ "access", KSTAT_DATA_UINT64 },
{ "readlink", KSTAT_DATA_UINT64 },
{ "read", KSTAT_DATA_UINT64 },
{ "write", KSTAT_DATA_UINT64 },
{ "create", KSTAT_DATA_UINT64 },
{ "mkdir", KSTAT_DATA_UINT64 },
{ "symlink", KSTAT_DATA_UINT64 },
{ "mknod", KSTAT_DATA_UINT64 },
{ "remove", KSTAT_DATA_UINT64 },
{ "rmdir", KSTAT_DATA_UINT64 },
{ "rename", KSTAT_DATA_UINT64 },
{ "link", KSTAT_DATA_UINT64 },
{ "readdir", KSTAT_DATA_UINT64 },
{ "readdirplus", KSTAT_DATA_UINT64 },
{ "fsstat", KSTAT_DATA_UINT64 },
{ "fsinfo", KSTAT_DATA_UINT64 },
{ "pathconf", KSTAT_DATA_UINT64 },
{ "commit", KSTAT_DATA_UINT64 }
};
static const kstat_named_t aclreqcnt_v3_tmpl[] = {
{ "null", KSTAT_DATA_UINT64 },
{ "getacl", KSTAT_DATA_UINT64 },
{ "setacl", KSTAT_DATA_UINT64 },
{ "getxattrdir", KSTAT_DATA_UINT64 }
};
static void
nfsstat_zone_init_aclreq_v3(zoneid_t zoneid, struct nfs_version_stats *statsp)
{
statsp->aclreqcnt_ptr = nfsstat_zone_init_common(zoneid, "nfs_acl", 0,
"aclreqcnt_v3", aclreqcnt_v3_tmpl, sizeof (aclreqcnt_v3_tmpl));
}
static void
nfsstat_zone_fini_aclreq_v3(zoneid_t zoneid, struct nfs_version_stats *statsp)
{
nfsstat_zone_fini_common(zoneid, "nfs_acl", 0, "aclreqcnt_v3");
kmem_free(statsp->aclreqcnt_ptr, sizeof (aclreqcnt_v3_tmpl));
}
static const kstat_named_t aclproccnt_v3_tmpl[] = {
{ "null", KSTAT_DATA_UINT64 },
{ "getacl", KSTAT_DATA_UINT64 },
{ "setacl", KSTAT_DATA_UINT64 },
{ "getxattrdir", KSTAT_DATA_UINT64 }
};
static const kstat_named_t rfsreqcnt_v4_tmpl[] = {
{ "null", KSTAT_DATA_UINT64 },
{ "compound", KSTAT_DATA_UINT64 },
{ "reserved", KSTAT_DATA_UINT64 },
{ "access", KSTAT_DATA_UINT64 },
{ "close", KSTAT_DATA_UINT64 },
{ "commit", KSTAT_DATA_UINT64 },
{ "create", KSTAT_DATA_UINT64 },
{ "delegpurge", KSTAT_DATA_UINT64 },
{ "delegreturn", KSTAT_DATA_UINT64 },
{ "getattr", KSTAT_DATA_UINT64 },
{ "getfh", KSTAT_DATA_UINT64 },
{ "link", KSTAT_DATA_UINT64 },
{ "lock", KSTAT_DATA_UINT64 },
{ "lockt", KSTAT_DATA_UINT64 },
{ "locku", KSTAT_DATA_UINT64 },
{ "lookup", KSTAT_DATA_UINT64 },
{ "lookupp", KSTAT_DATA_UINT64 },
{ "nverify", KSTAT_DATA_UINT64 },
{ "open", KSTAT_DATA_UINT64 },
{ "openattr", KSTAT_DATA_UINT64 },
{ "open_confirm", KSTAT_DATA_UINT64 },
{ "open_downgrade", KSTAT_DATA_UINT64 },
{ "putfh", KSTAT_DATA_UINT64 },
{ "putpubfh", KSTAT_DATA_UINT64 },
{ "putrootfh", KSTAT_DATA_UINT64 },
{ "read", KSTAT_DATA_UINT64 },
{ "readdir", KSTAT_DATA_UINT64 },
{ "readlink", KSTAT_DATA_UINT64 },
{ "remove", KSTAT_DATA_UINT64 },
{ "rename", KSTAT_DATA_UINT64 },
{ "renew", KSTAT_DATA_UINT64 },
{ "restorefh", KSTAT_DATA_UINT64 },
{ "savefh", KSTAT_DATA_UINT64 },
{ "secinfo", KSTAT_DATA_UINT64 },
{ "setattr", KSTAT_DATA_UINT64 },
{ "setclientid", KSTAT_DATA_UINT64 },
{ "setclientid_confirm", KSTAT_DATA_UINT64 },
{ "verify", KSTAT_DATA_UINT64 },
{ "write", KSTAT_DATA_UINT64 }
};
static void
nfsstat_zone_init_rfsreq_v4(zoneid_t zoneid, struct nfs_version_stats *statsp)
{
statsp->rfsreqcnt_ptr = nfsstat_zone_init_common(zoneid, "nfs", 0,
"rfsreqcnt_v4", rfsreqcnt_v4_tmpl, sizeof (rfsreqcnt_v4_tmpl));
}
static void
nfsstat_zone_fini_rfsreq_v4(zoneid_t zoneid, struct nfs_version_stats *statsp)
{
nfsstat_zone_fini_common(zoneid, "nfs", 0, "rfsreqcnt_v4");
kmem_free(statsp->rfsreqcnt_ptr, sizeof (rfsreqcnt_v4_tmpl));
}
static const kstat_named_t rfsproccnt_v4_tmpl[] = {
{ "null", KSTAT_DATA_UINT64 },
{ "compound", KSTAT_DATA_UINT64 },
{ "reserved", KSTAT_DATA_UINT64 },
{ "access", KSTAT_DATA_UINT64 },
{ "close", KSTAT_DATA_UINT64 },
{ "commit", KSTAT_DATA_UINT64 },
{ "create", KSTAT_DATA_UINT64 },
{ "delegpurge", KSTAT_DATA_UINT64 },
{ "delegreturn", KSTAT_DATA_UINT64 },
{ "getattr", KSTAT_DATA_UINT64 },
{ "getfh", KSTAT_DATA_UINT64 },
{ "link", KSTAT_DATA_UINT64 },
{ "lock", KSTAT_DATA_UINT64 },
{ "lockt", KSTAT_DATA_UINT64 },
{ "locku", KSTAT_DATA_UINT64 },
{ "lookup", KSTAT_DATA_UINT64 },
{ "lookupp", KSTAT_DATA_UINT64 },
{ "nverify", KSTAT_DATA_UINT64 },
{ "open", KSTAT_DATA_UINT64 },
{ "openattr", KSTAT_DATA_UINT64 },
{ "open_confirm", KSTAT_DATA_UINT64 },
{ "open_downgrade", KSTAT_DATA_UINT64 },
{ "putfh", KSTAT_DATA_UINT64 },
{ "putpubfh", KSTAT_DATA_UINT64 },
{ "putrootfh", KSTAT_DATA_UINT64 },
{ "read", KSTAT_DATA_UINT64 },
{ "readdir", KSTAT_DATA_UINT64 },
{ "readlink", KSTAT_DATA_UINT64 },
{ "remove", KSTAT_DATA_UINT64 },
{ "rename", KSTAT_DATA_UINT64 },
{ "renew", KSTAT_DATA_UINT64 },
{ "restorefh", KSTAT_DATA_UINT64 },
{ "savefh", KSTAT_DATA_UINT64 },
{ "secinfo", KSTAT_DATA_UINT64 },
{ "setattr", KSTAT_DATA_UINT64 },
{ "setclientid", KSTAT_DATA_UINT64 },
{ "setclientid_confirm", KSTAT_DATA_UINT64 },
{ "verify", KSTAT_DATA_UINT64 },
{ "write", KSTAT_DATA_UINT64 },
{ "release_lockowner", KSTAT_DATA_UINT64 },
{ "backchannel_ctl", KSTAT_DATA_UINT64 },
{ "bind_conn_to_session", KSTAT_DATA_UINT64 },
{ "exchange_id", KSTAT_DATA_UINT64 },
{ "create_session", KSTAT_DATA_UINT64 },
{ "destroy_session", KSTAT_DATA_UINT64 },
{ "free_stateid", KSTAT_DATA_UINT64 },
{ "get_dir_delegation", KSTAT_DATA_UINT64 },
{ "getdeviceinfo", KSTAT_DATA_UINT64 },
{ "getdevicelist", KSTAT_DATA_UINT64 },
{ "layoutcommit", KSTAT_DATA_UINT64 },
{ "layoutget", KSTAT_DATA_UINT64 },
{ "layoutreturn", KSTAT_DATA_UINT64 },
{ "secinfo_no_name", KSTAT_DATA_UINT64 },
{ "sequence", KSTAT_DATA_UINT64 },
{ "set_ssv", KSTAT_DATA_UINT64 },
{ "test_stateid", KSTAT_DATA_UINT64 },
{ "want_delegation", KSTAT_DATA_UINT64 },
{ "destroy_clientid", KSTAT_DATA_UINT64 },
{ "reclaim_complete", KSTAT_DATA_UINT64 },
{ "illegal", KSTAT_DATA_UINT64 },
};
static const kstat_named_t aclreqcnt_v4_tmpl[] = {
{ "null", KSTAT_DATA_UINT64 },
{ "getacl", KSTAT_DATA_UINT64 },
{ "setacl", KSTAT_DATA_UINT64 },
};
static void
nfsstat_zone_init_aclreq_v4(zoneid_t zoneid, struct nfs_version_stats *statsp)
{
statsp->aclreqcnt_ptr = nfsstat_zone_init_common(zoneid, "nfs_acl", 0,
"aclreqcnt_v4", aclreqcnt_v4_tmpl, sizeof (aclreqcnt_v4_tmpl));
}
static void
nfsstat_zone_fini_aclreq_v4(zoneid_t zoneid, struct nfs_version_stats *statsp)
{
nfsstat_zone_fini_common(zoneid, "nfs_acl", 0, "aclreqcnt_v4");
kmem_free(statsp->aclreqcnt_ptr, sizeof (aclreqcnt_v4_tmpl));
}
void *
nfsstat_zone_init(zoneid_t zoneid)
{
struct nfs_stats *nfs_stats_ptr;
nfs_stats_ptr = kmem_zalloc(sizeof (*nfs_stats_ptr), KM_SLEEP);
nfsstat_zone_init_rfsreq_v2(zoneid, &nfs_stats_ptr->nfs_stats_v2);
nfsstat_zone_init_aclreq_v2(zoneid, &nfs_stats_ptr->nfs_stats_v2);
nfsstat_zone_init_rfsreq_v3(zoneid, &nfs_stats_ptr->nfs_stats_v3);
nfsstat_zone_init_aclreq_v3(zoneid, &nfs_stats_ptr->nfs_stats_v3);
nfsstat_zone_init_rfsreq_v4(zoneid, &nfs_stats_ptr->nfs_stats_v4);
nfsstat_zone_init_aclreq_v4(zoneid, &nfs_stats_ptr->nfs_stats_v4);
return (nfs_stats_ptr);
}
void
nfsstat_zone_fini(zoneid_t zoneid, void *data)
{
struct nfs_stats *nfs_stats_ptr = data;
nfsstat_zone_fini_rfsreq_v2(zoneid, &nfs_stats_ptr->nfs_stats_v2);
nfsstat_zone_fini_aclreq_v2(zoneid, &nfs_stats_ptr->nfs_stats_v2);
nfsstat_zone_fini_rfsreq_v3(zoneid, &nfs_stats_ptr->nfs_stats_v3);
nfsstat_zone_fini_aclreq_v3(zoneid, &nfs_stats_ptr->nfs_stats_v3);
nfsstat_zone_fini_rfsreq_v4(zoneid, &nfs_stats_ptr->nfs_stats_v4);
nfsstat_zone_fini_aclreq_v4(zoneid, &nfs_stats_ptr->nfs_stats_v4);
kmem_free(nfs_stats_ptr, sizeof (*nfs_stats_ptr));
}
void
rfs_stat_zone_init(nfs_globals_t *ng)
{
zoneid_t zoneid = ng->nfs_zoneid;
nfsstat_zone_init_server(zoneid, ng->svstat);
ng->rfsproccnt[NFS_V2] = nfsstat_zone_init_common(zoneid, "nfs", 0,
"rfsproccnt_v2", rfsproccnt_v2_tmpl, sizeof (rfsproccnt_v2_tmpl));
ng->rfsproccnt[NFS_V3] = nfsstat_zone_init_common(zoneid, "nfs", 0,
"rfsproccnt_v3", rfsproccnt_v3_tmpl, sizeof (rfsproccnt_v3_tmpl));
ng->rfsproccnt[NFS_V4] = nfsstat_zone_init_common(zoneid, "nfs", 0,
"rfsproccnt_v4", rfsproccnt_v4_tmpl, sizeof (rfsproccnt_v4_tmpl));
ng->aclproccnt[NFS_V2] = nfsstat_zone_init_common(zoneid, "nfs_acl", 0,
"aclproccnt_v2", aclproccnt_v2_tmpl, sizeof (aclproccnt_v2_tmpl));
ng->aclproccnt[NFS_V3] = nfsstat_zone_init_common(zoneid, "nfs_acl", 0,
"aclproccnt_v3", aclproccnt_v3_tmpl, sizeof (aclproccnt_v3_tmpl));
}
void
rfs_stat_zone_fini(nfs_globals_t *ng)
{
zoneid_t zoneid = ng->nfs_zoneid;
nfsstat_zone_fini_server(zoneid, ng->svstat);
nfsstat_zone_fini_common(zoneid, "nfs", 0, "rfsproccnt_v2");
kmem_free(ng->rfsproccnt[NFS_V2], sizeof (rfsproccnt_v2_tmpl));
nfsstat_zone_fini_common(zoneid, "nfs", 0, "rfsproccnt_v3");
kmem_free(ng->rfsproccnt[NFS_V3], sizeof (rfsproccnt_v3_tmpl));
nfsstat_zone_fini_common(zoneid, "nfs", 0, "rfsproccnt_v4");
kmem_free(ng->rfsproccnt[NFS_V4], sizeof (rfsproccnt_v4_tmpl));
nfsstat_zone_fini_common(zoneid, "nfs_acl", 0, "aclproccnt_v2");
kmem_free(ng->aclproccnt[NFS_V2], sizeof (aclproccnt_v2_tmpl));
nfsstat_zone_fini_common(zoneid, "nfs_acl", 0, "aclproccnt_v3");
kmem_free(ng->aclproccnt[NFS_V3], sizeof (aclproccnt_v3_tmpl));
}