nfs.c revision 1.1
1/* $OpenBSD: nfs.c,v 1.1 2009/06/19 07:48:45 jasper Exp $ */ 2 3/* 4 * Copyright (c) 2009 Jasper Lievisse Adriaanse <jasper@openbsd.org> 5 * 6 * Permission to use, copy, modify, and distribute this software for any 7 * purpose with or without fee is hereby granted, provided that the above 8 * copyright notice and this permission notice appear in all copies. 9 * 10 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 11 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 12 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 13 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 14 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 15 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 16 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 17 * 18 */ 19 20#include <sys/param.h> 21#include <sys/mount.h> 22#include <sys/sysctl.h> 23#include <sys/types.h> 24#include <nfs/rpcv2.h> 25#include <nfs/nfsproto.h> 26#include <nfs/nfs.h> 27 28#include <err.h> 29#include <errno.h> 30#include <stdio.h> 31#include <stdlib.h> 32#include <string.h> 33 34#include "systat.h" 35 36int check_nfs(void); 37int select_client(void); 38int select_server(void); 39int read_nfs(void); 40void print_client(void); 41void print_server(void); 42 43struct nfsstats nfsstats; 44int num_client = 0; 45int num_server = 0; 46 47field_def fields_nfs[] = { 48 /* Client */ 49 {"Rpc Counts", 10, 12, 1, FLD_ALIGN_RIGHT, -1, 0, 0, 0}, 50 {"", 12, 14, 1, FLD_ALIGN_LEFT, -1, 0, 0, 0}, 51 {"Rpc Info", 14, 12, 1, FLD_ALIGN_RIGHT, -1, 0, 0, 0}, 52 {"", 12, 14, 1, FLD_ALIGN_LEFT, -1, 0, 0, 0}, 53 {"Cache Info", 10, 12, 1, FLD_ALIGN_LEFT, -1, 0, 0, 0}, 54 {"", 12, 14, 1, FLD_ALIGN_LEFT, -1, 0, 0, 0}, 55 56 /* Server */ 57 {"Rpc Counts", 10, 12, 1, FLD_ALIGN_RIGHT, -1, 0, 0, 0}, 58 {"", 12, 14, 1, FLD_ALIGN_LEFT, -1, 0, 0, 0}, 59 {"Cache Stats", 14, 12, 1, FLD_ALIGN_RIGHT, -1, 0, 0, 0}, 60 {"", 12, 14, 1, FLD_ALIGN_LEFT, -1, 0, 0, 0}, 61 {"Writes", 10, 12, 1, FLD_ALIGN_LEFT, -1, 0, 0, 0}, 62 {"", 12, 14, 1, FLD_ALIGN_LEFT, -1, 0, 0, 0}, 63}; 64 65/* _V suffixed fields indicate a value column. */ 66#define FIELD_ADDR(x) (&fields_nfs[x]) 67 68/* Client */ 69#define FLD_NFS_C_RPC_COUNTS FIELD_ADDR(0) 70#define FLD_NFS_C_RPC_COUNTS_V FIELD_ADDR(1) 71#define FLD_NFS_C_RPC_INFO FIELD_ADDR(2) 72#define FLD_NFS_C_RPC_INFO_V FIELD_ADDR(3) 73#define FLD_NFS_C_CACHE_INFO FIELD_ADDR(4) 74#define FLD_NFS_C_CACHE_V FIELD_ADDR(5) 75 76/* Server */ 77#define FLD_NFS_S_RPC_COUNTS FIELD_ADDR(6) 78#define FLD_NFS_S_RPC_COUNTS_V FIELD_ADDR(7) 79#define FLD_NFS_S_CACHE_STATS FIELD_ADDR(8) 80#define FLD_NFS_S_CACHE_STATS_V FIELD_ADDR(9) 81#define FLD_NFS_S_WRITES FIELD_ADDR(10) 82#define FLD_NFS_S_WRITES_V FIELD_ADDR(11) 83 84/* Define views */ 85field_def *view_nfs_0[] = { 86 FLD_NFS_C_RPC_COUNTS, FLD_NFS_C_RPC_COUNTS_V, FLD_NFS_C_RPC_INFO, 87 FLD_NFS_C_RPC_INFO_V, FLD_NFS_C_CACHE_INFO, FLD_NFS_C_CACHE_V ,NULL 88}; 89 90field_def *view_nfs_1[] = { 91 FLD_NFS_S_RPC_COUNTS, FLD_NFS_S_RPC_COUNTS_V, FLD_NFS_S_CACHE_STATS, 92 FLD_NFS_S_CACHE_STATS_V, FLD_NFS_S_WRITES, FLD_NFS_S_WRITES_V, NULL 93}; 94 95/* Define view managers */ 96struct view_manager nfs_client_mgr = { 97 "Client", select_client, read_nfs, NULL, print_header, 98 print_client, keyboard_callback, NULL, NULL 99}; 100 101struct view_manager nfs_server_mgr = { 102 "Server", select_server, read_nfs, NULL, print_header, 103 print_server, keyboard_callback, NULL, NULL 104}; 105 106field_view views_nfs[] = { 107 {view_nfs_0, "nfsclient", '8', &nfs_client_mgr}, 108 {view_nfs_1, "nfsserver", '9', &nfs_server_mgr}, 109 {NULL, NULL, 0, NULL} 110}; 111 112int 113select_client(void) 114{ 115 num_disp = num_client; 116 return(0); 117} 118 119int 120select_server(void) 121{ 122 num_disp = num_server; 123 return(0); 124} 125 126int 127initnfs(void) 128{ 129 field_view *v; 130 131 for (v = views_nfs; v->name != NULL; v++) 132 add_view(v); 133 134 read_nfs(); 135 136 return(0); 137} 138 139/* 140 * We get all the information in one go and don't care about 141 * server or client fields (those will be '0' if not applicable. 142 */ 143int 144read_nfs(void) 145{ 146 struct nfsstats *p = &nfsstats; 147 int mib[3]; 148 size_t len = sizeof(*p); 149 150 mib[0] = CTL_VFS; 151 mib[1] = 2; /* NETDEV */ 152 mib[2] = NFS_NFSSTATS; 153 154 if (sysctl(mib, 3, p, &len, NULL, 0) < 0) 155 return(-1); 156 else 157 return(0); 158} 159 160 161/* 162 * As we want a view with multiple columns, mixed with labels and values, 163 * we can't use the regular dance and have to use our own (looong) dance 164 * to build the layout. 165 */ 166void 167print_client(void) 168{ 169 print_fld_str(FLD_NFS_C_RPC_COUNTS, "Getattr"); 170 print_fld_ssize(FLD_NFS_C_RPC_COUNTS_V, 171 nfsstats.rpccnt[NFSPROC_GETATTR]); 172 print_fld_str(FLD_NFS_C_RPC_INFO, "TimedOut"); 173 print_fld_ssize(FLD_NFS_C_RPC_INFO_V, nfsstats.rpctimeouts); 174 print_fld_str(FLD_NFS_C_CACHE_INFO, "Attr Hits "); 175 print_fld_ssize(FLD_NFS_C_CACHE_V, nfsstats.attrcache_hits); 176 end_line(); 177 178 print_fld_str(FLD_NFS_C_RPC_COUNTS, "Setattr"); 179 print_fld_ssize(FLD_NFS_C_RPC_COUNTS_V, 180 nfsstats.rpccnt[NFSPROC_SETATTR]); 181 print_fld_str(FLD_NFS_C_RPC_INFO, "Invalid"); 182 print_fld_ssize(FLD_NFS_C_RPC_INFO_V, nfsstats.rpcinvalid); 183 print_fld_str(FLD_NFS_C_CACHE_INFO, "Attr Misses"); 184 print_fld_ssize(FLD_NFS_C_CACHE_V, nfsstats.attrcache_misses); 185 end_line(); 186 187 print_fld_str(FLD_NFS_C_RPC_COUNTS, "Lookup"); 188 print_fld_ssize(FLD_NFS_C_RPC_COUNTS_V, 189 nfsstats.rpccnt[NFSPROC_LOOKUP]); 190 print_fld_str(FLD_NFS_C_RPC_INFO, "X Replies"); 191 print_fld_ssize(FLD_NFS_C_RPC_INFO_V, nfsstats.rpcunexpected); 192 print_fld_str(FLD_NFS_C_CACHE_INFO, "Lkup Hits "); 193 print_fld_ssize(FLD_NFS_C_CACHE_V, nfsstats.lookupcache_hits); 194 end_line(); 195 196 print_fld_str(FLD_NFS_C_RPC_COUNTS, "Readlink"); 197 print_fld_ssize(FLD_NFS_C_RPC_COUNTS_V, 198 nfsstats.rpccnt[NFSPROC_READLINK]); 199 print_fld_str(FLD_NFS_C_RPC_INFO, "Retries"); 200 print_fld_ssize(FLD_NFS_C_RPC_INFO_V, nfsstats.rpcretries); 201 print_fld_str(FLD_NFS_C_CACHE_INFO, "Lkup Misses "); 202 print_fld_ssize(FLD_NFS_C_CACHE_V, nfsstats.lookupcache_misses); 203 end_line(); 204 205 print_fld_str(FLD_NFS_C_RPC_COUNTS, "Read"); 206 print_fld_ssize(FLD_NFS_C_RPC_COUNTS_V, 207 nfsstats.rpccnt[NFSPROC_READ]); 208 print_fld_str(FLD_NFS_C_RPC_INFO, "Requests"); 209 print_fld_ssize(FLD_NFS_C_RPC_INFO_V, nfsstats.rpcrequests); 210 print_fld_str(FLD_NFS_C_CACHE_INFO, "BioR Hits "); 211 print_fld_ssize(FLD_NFS_C_CACHE_V, 212 nfsstats.biocache_reads-nfsstats.read_bios); 213 end_line(); 214 215 print_fld_str(FLD_NFS_C_RPC_COUNTS, "Write"); 216 print_fld_ssize(FLD_NFS_C_RPC_COUNTS_V, nfsstats.rpccnt[NFSPROC_WRITE]); 217 print_fld_str(FLD_NFS_C_RPC_INFO, "FrcSync"); 218 print_fld_ssize(FLD_NFS_C_RPC_INFO_V, nfsstats.forcedsync); 219 print_fld_str(FLD_NFS_C_CACHE_INFO, "BioR Misses"); 220 print_fld_ssize(FLD_NFS_C_CACHE_V, nfsstats.read_bios); 221 end_line(); 222 223 print_fld_str(FLD_NFS_C_RPC_COUNTS, "Create"); 224 print_fld_ssize(FLD_NFS_C_RPC_COUNTS_V, 225 nfsstats.rpccnt[NFSPROC_CREATE]); 226 print_fld_str(FLD_NFS_C_CACHE_INFO, "BioW Hits "); 227 print_fld_ssize(FLD_NFS_C_CACHE_V, 228 nfsstats.biocache_writes-nfsstats.write_bios); 229 end_line(); 230 231 print_fld_str(FLD_NFS_C_RPC_COUNTS, "Remove"); 232 print_fld_ssize(FLD_NFS_C_RPC_COUNTS_V, 233 nfsstats.rpccnt[NFSPROC_REMOVE]); 234 print_fld_str(FLD_NFS_C_CACHE_INFO, "BioW Misses"); 235 print_fld_ssize(FLD_NFS_C_CACHE_V, nfsstats.write_bios); 236 end_line(); 237 238 print_fld_str(FLD_NFS_C_RPC_COUNTS, "Rename"); 239 print_fld_ssize(FLD_NFS_C_RPC_COUNTS_V, 240 nfsstats.rpccnt[NFSPROC_RENAME]); 241 print_fld_str(FLD_NFS_C_CACHE_INFO, "BioRL Hits "); 242 print_fld_ssize(FLD_NFS_C_CACHE_V, 243 nfsstats.biocache_readlinks-nfsstats.readlink_bios); 244 end_line(); 245 246 print_fld_str(FLD_NFS_C_RPC_COUNTS, "Link"); 247 print_fld_ssize(FLD_NFS_C_RPC_COUNTS_V, nfsstats.rpccnt[NFSPROC_LINK]); 248 print_fld_str(FLD_NFS_C_CACHE_INFO, "BioRL Misses"); 249 print_fld_ssize(FLD_NFS_C_CACHE_V, nfsstats.readlink_bios); 250 end_line(); 251 252 print_fld_str(FLD_NFS_C_RPC_COUNTS, "Symlink"); 253 print_fld_ssize(FLD_NFS_C_RPC_COUNTS_V, 254 nfsstats.rpccnt[NFSPROC_SYMLINK]); 255 print_fld_str(FLD_NFS_C_CACHE_INFO, "BioD Hits "); 256 print_fld_ssize(FLD_NFS_C_CACHE_V, 257 nfsstats.biocache_readdirs-nfsstats.readdir_bios); 258 end_line(); 259 260 print_fld_str(FLD_NFS_C_RPC_COUNTS, "Mkdir"); 261 print_fld_ssize(FLD_NFS_C_RPC_COUNTS_V, nfsstats.rpccnt[NFSPROC_MKDIR]); 262 print_fld_str(FLD_NFS_C_CACHE_INFO, "BioD Misses"); 263 print_fld_ssize(FLD_NFS_C_CACHE_V, nfsstats.readdir_bios); 264 end_line(); 265 266 print_fld_str(FLD_NFS_C_RPC_COUNTS, "Rmdir"); 267 print_fld_ssize(FLD_NFS_C_RPC_COUNTS_V, nfsstats.rpccnt[NFSPROC_RMDIR]); 268 print_fld_str(FLD_NFS_C_CACHE_INFO, "DirE Hits "); 269 print_fld_ssize(FLD_NFS_C_CACHE_V, nfsstats.direofcache_hits); 270 end_line(); 271 272 print_fld_str(FLD_NFS_C_RPC_COUNTS, "Readdir"); 273 print_fld_ssize(FLD_NFS_C_RPC_COUNTS_V, 274 nfsstats.rpccnt[NFSPROC_READDIR]); 275 print_fld_str(FLD_NFS_C_CACHE_INFO, "DirE Misses"); 276 print_fld_ssize(FLD_NFS_C_CACHE_V, nfsstats.direofcache_misses); 277 end_line(); 278 279 print_fld_str(FLD_NFS_C_RPC_COUNTS, "RdirPlus"); 280 print_fld_ssize(FLD_NFS_C_RPC_COUNTS_V, 281 nfsstats.rpccnt[NFSPROC_READDIRPLUS]); 282 end_line(); 283 284 print_fld_str(FLD_NFS_C_RPC_COUNTS, "Access"); 285 print_fld_ssize(FLD_NFS_C_RPC_COUNTS_V, 286 nfsstats.rpccnt[NFSPROC_ACCESS]); 287 end_line(); 288 289 print_fld_str(FLD_NFS_C_RPC_COUNTS, "Mknod"); 290 print_fld_ssize(FLD_NFS_C_RPC_COUNTS_V, nfsstats.rpccnt[NFSPROC_MKNOD]); 291 end_line(); 292 293 print_fld_str(FLD_NFS_C_RPC_COUNTS, "Fsstat"); 294 print_fld_ssize(FLD_NFS_C_RPC_COUNTS_V, 295 nfsstats.rpccnt[NFSPROC_FSSTAT]); 296 end_line(); 297 298 print_fld_str(FLD_NFS_C_RPC_COUNTS, "Fsinfo"); 299 print_fld_ssize(FLD_NFS_C_RPC_COUNTS_V, 300 nfsstats.rpccnt[NFSPROC_FSINFO]); 301 end_line(); 302 303 print_fld_str(FLD_NFS_C_RPC_COUNTS, "PathConf"); 304 print_fld_ssize(FLD_NFS_C_RPC_COUNTS_V, 305 nfsstats.rpccnt[NFSPROC_PATHCONF]); 306 end_line(); 307 308 print_fld_str(FLD_NFS_C_RPC_COUNTS, "Commit"); 309 print_fld_ssize(FLD_NFS_C_RPC_COUNTS_V, 310 nfsstats.rpccnt[NFSPROC_COMMIT]); 311 end_line(); 312} 313 314void 315print_server(void) 316{ 317 print_fld_str(FLD_NFS_S_RPC_COUNTS, "Getattr"); 318 print_fld_ssize(FLD_NFS_S_RPC_COUNTS_V, 319 nfsstats.srvrpccnt[NFSPROC_GETATTR]); 320 print_fld_str(FLD_NFS_S_CACHE_STATS, "Inprog"); 321 print_fld_ssize(FLD_NFS_S_CACHE_STATS_V, nfsstats.srvcache_inproghits); 322 print_fld_str(FLD_NFS_S_WRITES, "WriteOps"); 323 print_fld_ssize(FLD_NFS_S_WRITES_V, nfsstats.srvvop_writes); 324 end_line(); 325 326 print_fld_str(FLD_NFS_S_RPC_COUNTS, "Setattr"); 327 print_fld_ssize(FLD_NFS_S_RPC_COUNTS_V, 328 nfsstats.srvrpccnt[NFSPROC_SETATTR]); 329 print_fld_str(FLD_NFS_S_CACHE_STATS, "Idem"); 330 print_fld_ssize(FLD_NFS_S_CACHE_STATS_V, 331 nfsstats.srvcache_idemdonehits); 332 print_fld_str(FLD_NFS_S_WRITES, "WriteRPC"); 333 print_fld_ssize(FLD_NFS_S_WRITES_V, nfsstats.srvrpccnt[NFSPROC_WRITE]); 334 end_line(); 335 336 print_fld_str(FLD_NFS_S_RPC_COUNTS, "Lookup"); 337 print_fld_ssize(FLD_NFS_S_RPC_COUNTS_V, 338 nfsstats.srvrpccnt[NFSPROC_LOOKUP]); 339 print_fld_str(FLD_NFS_S_CACHE_STATS, "Non-idem"); 340 print_fld_ssize(FLD_NFS_S_CACHE_STATS_V, 341 nfsstats.srvcache_nonidemdonehits); 342 print_fld_str(FLD_NFS_S_WRITES, "Opsaved"); 343 print_fld_ssize(FLD_NFS_S_WRITES_V, 344 nfsstats.srvrpccnt[NFSPROC_WRITE] - nfsstats.srvvop_writes); 345 end_line(); 346 347 print_fld_str(FLD_NFS_S_RPC_COUNTS, "Readlink"); 348 print_fld_ssize(FLD_NFS_S_RPC_COUNTS_V, 349 nfsstats.srvrpccnt[NFSPROC_READLINK]); 350 print_fld_str(FLD_NFS_S_CACHE_STATS, "Misses"); 351 print_fld_ssize(FLD_NFS_S_CACHE_STATS_V, nfsstats.srvcache_misses); 352 end_line(); 353 354 print_fld_str(FLD_NFS_S_RPC_COUNTS, "Read"); 355 print_fld_ssize(FLD_NFS_S_RPC_COUNTS_V, 356 nfsstats.srvrpccnt[NFSPROC_READ]); 357 end_line(); 358 359 print_fld_str(FLD_NFS_S_RPC_COUNTS, "Write"); 360 print_fld_ssize(FLD_NFS_S_RPC_COUNTS_V, 361 nfsstats.srvrpccnt[NFSPROC_WRITE]); 362 end_line(); 363 364 print_fld_str(FLD_NFS_S_RPC_COUNTS, "Create"); 365 print_fld_ssize(FLD_NFS_S_RPC_COUNTS_V, 366 nfsstats.srvrpccnt[NFSPROC_CREATE]); 367 end_line(); 368 369 print_fld_str(FLD_NFS_S_RPC_COUNTS, "Remove"); 370 print_fld_ssize(FLD_NFS_S_RPC_COUNTS_V, 371 nfsstats.srvrpccnt[NFSPROC_REMOVE]); 372 end_line(); 373 374 print_fld_str(FLD_NFS_S_RPC_COUNTS, "Rename"); 375 print_fld_ssize(FLD_NFS_S_RPC_COUNTS_V, 376 nfsstats.srvrpccnt[NFSPROC_RENAME]); 377 end_line(); 378 379 print_fld_str(FLD_NFS_S_RPC_COUNTS, "Link"); 380 print_fld_ssize(FLD_NFS_S_RPC_COUNTS_V, 381 nfsstats.srvrpccnt[NFSPROC_LINK]); 382 end_line(); 383 384 print_fld_str(FLD_NFS_S_RPC_COUNTS, "Symlink"); 385 print_fld_ssize(FLD_NFS_S_RPC_COUNTS_V, 386 nfsstats.srvrpccnt[NFSPROC_SYMLINK]); 387 end_line(); 388 389 print_fld_str(FLD_NFS_S_RPC_COUNTS, "Mkdir"); 390 print_fld_ssize(FLD_NFS_S_RPC_COUNTS_V, 391 nfsstats.srvrpccnt[NFSPROC_MKDIR]); 392 end_line(); 393 394 print_fld_str(FLD_NFS_S_RPC_COUNTS, "Rmdir"); 395 print_fld_ssize(FLD_NFS_S_RPC_COUNTS_V, 396 nfsstats.srvrpccnt[NFSPROC_RMDIR]); 397 end_line(); 398 399 print_fld_str(FLD_NFS_S_RPC_COUNTS, "Readdir"); 400 print_fld_ssize(FLD_NFS_S_RPC_COUNTS_V, 401 nfsstats.srvrpccnt[NFSPROC_READDIR]); 402 end_line(); 403 404 print_fld_str(FLD_NFS_S_RPC_COUNTS, "RdirPlus"); 405 print_fld_ssize(FLD_NFS_S_RPC_COUNTS_V, 406 nfsstats.srvrpccnt[NFSPROC_READDIRPLUS]); 407 end_line(); 408 409 print_fld_str(FLD_NFS_S_RPC_COUNTS, "Access"); 410 print_fld_ssize(FLD_NFS_S_RPC_COUNTS_V, 411 nfsstats.srvrpccnt[NFSPROC_ACCESS]); 412 end_line(); 413 414 print_fld_str(FLD_NFS_S_RPC_COUNTS, "Mknod"); 415 print_fld_ssize(FLD_NFS_S_RPC_COUNTS_V, 416 nfsstats.srvrpccnt[NFSPROC_MKNOD]); 417 end_line(); 418 419 print_fld_str(FLD_NFS_S_RPC_COUNTS, "Fsstat"); 420 print_fld_ssize(FLD_NFS_S_RPC_COUNTS_V, 421 nfsstats.srvrpccnt[NFSPROC_FSSTAT]); 422 end_line(); 423 424 print_fld_str(FLD_NFS_S_RPC_COUNTS, "Fsinfo"); 425 print_fld_ssize(FLD_NFS_S_RPC_COUNTS_V, 426 nfsstats.srvrpccnt[NFSPROC_FSINFO]); 427 end_line(); 428 429 print_fld_str(FLD_NFS_S_RPC_COUNTS, "PathConf"); 430 print_fld_ssize(FLD_NFS_S_RPC_COUNTS_V, 431 nfsstats.srvrpccnt[NFSPROC_PATHCONF]); 432 end_line(); 433 434 print_fld_str(FLD_NFS_S_RPC_COUNTS, "Commit"); 435 print_fld_ssize(FLD_NFS_S_RPC_COUNTS_V, 436 nfsstats.srvrpccnt[NFSPROC_COMMIT]); 437 end_line(); 438 439 /* The following end_line() creates two seperate blocks on the screen */ 440 end_line(); 441 442 print_fld_str(FLD_NFS_S_RPC_COUNTS, "Ret-Failed"); 443 print_fld_ssize(FLD_NFS_S_RPC_COUNTS_V, nfsstats.srvrpc_errs); 444 print_fld_str(FLD_NFS_S_CACHE_STATS, "Faults"); 445 print_fld_ssize(FLD_NFS_S_CACHE_STATS_V, nfsstats.srv_errs); 446 end_line(); 447} 448