1/* 2 * GPL HEADER START 3 * 4 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 5 * 6 * This program is free software; you can redistribute it and/or modify 7 * it under the terms of the GNU General Public License version 2 only, 8 * as published by the Free Software Foundation. 9 * 10 * This program is distributed in the hope that it will be useful, but 11 * WITHOUT ANY WARRANTY; without even the implied warranty of 12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13 * General Public License version 2 for more details (a copy is included 14 * in the LICENSE file that accompanied this code). 15 * 16 * You should have received a copy of the GNU General Public License 17 * version 2 along with this program; If not, see 18 * http://www.sun.com/software/products/lustre/docs/GPLv2.pdf 19 * 20 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, 21 * CA 95054 USA or visit www.sun.com if you need additional information or 22 * have any questions. 23 * 24 * GPL HEADER END 25 */ 26/* 27 * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved. 28 * Use is subject to license terms. 29 * 30 * Copyright (c) 2011, 2012, Intel Corporation. 31 */ 32/* 33 * This file is part of Lustre, http://www.lustre.org/ 34 * Lustre is a trademark of Sun Microsystems, Inc. 35 * 36 * lustre/include/lprocfs_status.h 37 * 38 * Top level header file for LProc SNMP 39 * 40 * Author: Hariharan Thantry thantry@users.sourceforge.net 41 */ 42#ifndef _LPROCFS_SNMP_H 43#define _LPROCFS_SNMP_H 44 45#include <linux/proc_fs.h> 46#include <linux/seq_file.h> 47#include <linux/spinlock.h> 48#include <linux/types.h> 49 50#include "lustre/lustre_idl.h" 51 52struct lprocfs_vars { 53 const char *name; 54 struct file_operations *fops; 55 void *data; 56 /** 57 * /proc file mode. 58 */ 59 umode_t proc_mode; 60}; 61 62struct lprocfs_static_vars { 63 struct lprocfs_vars *module_vars; 64 struct lprocfs_vars *obd_vars; 65}; 66 67/* if we find more consumers this could be generalized */ 68#define OBD_HIST_MAX 32 69struct obd_histogram { 70 spinlock_t oh_lock; 71 unsigned long oh_buckets[OBD_HIST_MAX]; 72}; 73 74enum { 75 BRW_R_PAGES = 0, 76 BRW_W_PAGES, 77 BRW_R_RPC_HIST, 78 BRW_W_RPC_HIST, 79 BRW_R_IO_TIME, 80 BRW_W_IO_TIME, 81 BRW_R_DISCONT_PAGES, 82 BRW_W_DISCONT_PAGES, 83 BRW_R_DISCONT_BLOCKS, 84 BRW_W_DISCONT_BLOCKS, 85 BRW_R_DISK_IOSIZE, 86 BRW_W_DISK_IOSIZE, 87 BRW_R_DIO_FRAGS, 88 BRW_W_DIO_FRAGS, 89 BRW_LAST, 90}; 91 92struct brw_stats { 93 struct obd_histogram hist[BRW_LAST]; 94}; 95 96enum { 97 RENAME_SAMEDIR_SIZE = 0, 98 RENAME_CROSSDIR_SRC_SIZE, 99 RENAME_CROSSDIR_TGT_SIZE, 100 RENAME_LAST, 101}; 102 103struct rename_stats { 104 struct obd_histogram hist[RENAME_LAST]; 105}; 106 107/* An lprocfs counter can be configured using the enum bit masks below. 108 * 109 * LPROCFS_CNTR_EXTERNALLOCK indicates that an external lock already 110 * protects this counter from concurrent updates. If not specified, 111 * lprocfs an internal per-counter lock variable. External locks are 112 * not used to protect counter increments, but are used to protect 113 * counter readout and resets. 114 * 115 * LPROCFS_CNTR_AVGMINMAX indicates a multi-valued counter samples, 116 * (i.e. counter can be incremented by more than "1"). When specified, 117 * the counter maintains min, max and sum in addition to a simple 118 * invocation count. This allows averages to be be computed. 119 * If not specified, the counter is an increment-by-1 counter. 120 * min, max, sum, etc. are not maintained. 121 * 122 * LPROCFS_CNTR_STDDEV indicates that the counter should track sum of 123 * squares (for multi-valued counter samples only). This allows 124 * external computation of standard deviation, but involves a 64-bit 125 * multiply per counter increment. 126 */ 127 128enum { 129 LPROCFS_CNTR_EXTERNALLOCK = 0x0001, 130 LPROCFS_CNTR_AVGMINMAX = 0x0002, 131 LPROCFS_CNTR_STDDEV = 0x0004, 132 133 /* counter data type */ 134 LPROCFS_TYPE_REGS = 0x0100, 135 LPROCFS_TYPE_BYTES = 0x0200, 136 LPROCFS_TYPE_PAGES = 0x0400, 137 LPROCFS_TYPE_CYCLE = 0x0800, 138}; 139 140#define LC_MIN_INIT ((~(__u64)0) >> 1) 141 142struct lprocfs_counter_header { 143 unsigned int lc_config; 144 const char *lc_name; /* must be static */ 145 const char *lc_units; /* must be static */ 146}; 147 148struct lprocfs_counter { 149 __s64 lc_count; 150 __s64 lc_min; 151 __s64 lc_max; 152 __s64 lc_sumsquare; 153 /* 154 * Every counter has lc_array_sum[0], while lc_array_sum[1] is only 155 * for irq context counter, i.e. stats with 156 * LPROCFS_STATS_FLAG_IRQ_SAFE flag, its counter need 157 * lc_array_sum[1] 158 */ 159 __s64 lc_array_sum[1]; 160}; 161#define lc_sum lc_array_sum[0] 162#define lc_sum_irq lc_array_sum[1] 163 164struct lprocfs_percpu { 165#ifndef __GNUC__ 166 __s64 pad; 167#endif 168 struct lprocfs_counter lp_cntr[0]; 169}; 170 171#define LPROCFS_GET_NUM_CPU 0x0001 172#define LPROCFS_GET_SMP_ID 0x0002 173 174enum lprocfs_stats_flags { 175 LPROCFS_STATS_FLAG_NONE = 0x0000, /* per cpu counter */ 176 LPROCFS_STATS_FLAG_NOPERCPU = 0x0001, /* stats have no percpu 177 * area and need locking */ 178 LPROCFS_STATS_FLAG_IRQ_SAFE = 0x0002, /* alloc need irq safe */ 179}; 180 181enum lprocfs_fields_flags { 182 LPROCFS_FIELDS_FLAGS_CONFIG = 0x0001, 183 LPROCFS_FIELDS_FLAGS_SUM = 0x0002, 184 LPROCFS_FIELDS_FLAGS_MIN = 0x0003, 185 LPROCFS_FIELDS_FLAGS_MAX = 0x0004, 186 LPROCFS_FIELDS_FLAGS_AVG = 0x0005, 187 LPROCFS_FIELDS_FLAGS_SUMSQUARE = 0x0006, 188 LPROCFS_FIELDS_FLAGS_COUNT = 0x0007, 189}; 190 191struct lprocfs_stats { 192 /* # of counters */ 193 unsigned short ls_num; 194 /* 1 + the biggest cpu # whose ls_percpu slot has been allocated */ 195 unsigned short ls_biggest_alloc_num; 196 enum lprocfs_stats_flags ls_flags; 197 /* Lock used when there are no percpu stats areas; For percpu stats, 198 * it is used to protect ls_biggest_alloc_num change */ 199 spinlock_t ls_lock; 200 201 /* has ls_num of counter headers */ 202 struct lprocfs_counter_header *ls_cnt_header; 203 struct lprocfs_percpu *ls_percpu[0]; 204}; 205 206#define OPC_RANGE(seg) (seg ## _LAST_OPC - seg ## _FIRST_OPC) 207 208/* Pack all opcodes down into a single monotonically increasing index */ 209static inline int opcode_offset(__u32 opc) { 210 if (opc < OST_LAST_OPC) { 211 /* OST opcode */ 212 return (opc - OST_FIRST_OPC); 213 } else if (opc < MDS_LAST_OPC) { 214 /* MDS opcode */ 215 return (opc - MDS_FIRST_OPC + 216 OPC_RANGE(OST)); 217 } else if (opc < LDLM_LAST_OPC) { 218 /* LDLM Opcode */ 219 return (opc - LDLM_FIRST_OPC + 220 OPC_RANGE(MDS) + 221 OPC_RANGE(OST)); 222 } else if (opc < MGS_LAST_OPC) { 223 /* MGS Opcode */ 224 return (opc - MGS_FIRST_OPC + 225 OPC_RANGE(LDLM) + 226 OPC_RANGE(MDS) + 227 OPC_RANGE(OST)); 228 } else if (opc < OBD_LAST_OPC) { 229 /* OBD Ping */ 230 return (opc - OBD_FIRST_OPC + 231 OPC_RANGE(MGS) + 232 OPC_RANGE(LDLM) + 233 OPC_RANGE(MDS) + 234 OPC_RANGE(OST)); 235 } else if (opc < LLOG_LAST_OPC) { 236 /* LLOG Opcode */ 237 return (opc - LLOG_FIRST_OPC + 238 OPC_RANGE(OBD) + 239 OPC_RANGE(MGS) + 240 OPC_RANGE(LDLM) + 241 OPC_RANGE(MDS) + 242 OPC_RANGE(OST)); 243 } else if (opc < QUOTA_LAST_OPC) { 244 /* LQUOTA Opcode */ 245 return (opc - QUOTA_FIRST_OPC + 246 OPC_RANGE(LLOG) + 247 OPC_RANGE(OBD) + 248 OPC_RANGE(MGS) + 249 OPC_RANGE(LDLM) + 250 OPC_RANGE(MDS) + 251 OPC_RANGE(OST)); 252 } else if (opc < SEQ_LAST_OPC) { 253 /* SEQ opcode */ 254 return (opc - SEQ_FIRST_OPC + 255 OPC_RANGE(QUOTA) + 256 OPC_RANGE(LLOG) + 257 OPC_RANGE(OBD) + 258 OPC_RANGE(MGS) + 259 OPC_RANGE(LDLM) + 260 OPC_RANGE(MDS) + 261 OPC_RANGE(OST)); 262 } else if (opc < SEC_LAST_OPC) { 263 /* SEC opcode */ 264 return (opc - SEC_FIRST_OPC + 265 OPC_RANGE(SEQ) + 266 OPC_RANGE(QUOTA) + 267 OPC_RANGE(LLOG) + 268 OPC_RANGE(OBD) + 269 OPC_RANGE(MGS) + 270 OPC_RANGE(LDLM) + 271 OPC_RANGE(MDS) + 272 OPC_RANGE(OST)); 273 } else if (opc < FLD_LAST_OPC) { 274 /* FLD opcode */ 275 return (opc - FLD_FIRST_OPC + 276 OPC_RANGE(SEC) + 277 OPC_RANGE(SEQ) + 278 OPC_RANGE(QUOTA) + 279 OPC_RANGE(LLOG) + 280 OPC_RANGE(OBD) + 281 OPC_RANGE(MGS) + 282 OPC_RANGE(LDLM) + 283 OPC_RANGE(MDS) + 284 OPC_RANGE(OST)); 285 } else if (opc < UPDATE_LAST_OPC) { 286 /* update opcode */ 287 return (opc - UPDATE_FIRST_OPC + 288 OPC_RANGE(FLD) + 289 OPC_RANGE(SEC) + 290 OPC_RANGE(SEQ) + 291 OPC_RANGE(QUOTA) + 292 OPC_RANGE(LLOG) + 293 OPC_RANGE(OBD) + 294 OPC_RANGE(MGS) + 295 OPC_RANGE(LDLM) + 296 OPC_RANGE(MDS) + 297 OPC_RANGE(OST)); 298 } else { 299 /* Unknown Opcode */ 300 return -1; 301 } 302} 303 304 305#define LUSTRE_MAX_OPCODES (OPC_RANGE(OST) + \ 306 OPC_RANGE(MDS) + \ 307 OPC_RANGE(LDLM) + \ 308 OPC_RANGE(MGS) + \ 309 OPC_RANGE(OBD) + \ 310 OPC_RANGE(LLOG) + \ 311 OPC_RANGE(SEC) + \ 312 OPC_RANGE(SEQ) + \ 313 OPC_RANGE(SEC) + \ 314 OPC_RANGE(FLD) + \ 315 OPC_RANGE(UPDATE)) 316 317#define EXTRA_MAX_OPCODES ((PTLRPC_LAST_CNTR - PTLRPC_FIRST_CNTR) + \ 318 OPC_RANGE(EXTRA)) 319 320enum { 321 PTLRPC_REQWAIT_CNTR = 0, 322 PTLRPC_REQQDEPTH_CNTR, 323 PTLRPC_REQACTIVE_CNTR, 324 PTLRPC_TIMEOUT, 325 PTLRPC_REQBUF_AVAIL_CNTR, 326 PTLRPC_LAST_CNTR 327}; 328 329#define PTLRPC_FIRST_CNTR PTLRPC_REQWAIT_CNTR 330 331enum { 332 LDLM_GLIMPSE_ENQUEUE = 0, 333 LDLM_PLAIN_ENQUEUE, 334 LDLM_EXTENT_ENQUEUE, 335 LDLM_FLOCK_ENQUEUE, 336 LDLM_IBITS_ENQUEUE, 337 MDS_REINT_SETATTR, 338 MDS_REINT_CREATE, 339 MDS_REINT_LINK, 340 MDS_REINT_UNLINK, 341 MDS_REINT_RENAME, 342 MDS_REINT_OPEN, 343 MDS_REINT_SETXATTR, 344 BRW_READ_BYTES, 345 BRW_WRITE_BYTES, 346 EXTRA_LAST_OPC 347}; 348 349#define EXTRA_FIRST_OPC LDLM_GLIMPSE_ENQUEUE 350/* class_obd.c */ 351extern struct proc_dir_entry *proc_lustre_root; 352 353struct obd_device; 354struct obd_histogram; 355 356/* Days / hours / mins / seconds format */ 357struct dhms { 358 int d, h, m, s; 359}; 360static inline void s2dhms(struct dhms *ts, time_t secs) 361{ 362 ts->d = secs / 86400; 363 secs = secs % 86400; 364 ts->h = secs / 3600; 365 secs = secs % 3600; 366 ts->m = secs / 60; 367 ts->s = secs % 60; 368} 369#define DHMS_FMT "%dd%dh%02dm%02ds" 370#define DHMS_VARS(x) (x)->d, (x)->h, (x)->m, (x)->s 371 372#define JOBSTATS_JOBID_VAR_MAX_LEN 20 373#define JOBSTATS_DISABLE "disable" 374#define JOBSTATS_PROCNAME_UID "procname_uid" 375#define JOBSTATS_NODELOCAL "nodelocal" 376 377extern int lprocfs_write_frac_helper(const char *buffer, unsigned long count, 378 int *val, int mult); 379extern int lprocfs_read_frac_helper(char *buffer, unsigned long count, 380 long val, int mult); 381#if defined (CONFIG_PROC_FS) 382 383extern int lprocfs_stats_alloc_one(struct lprocfs_stats *stats, 384 unsigned int cpuid); 385/* 386 * \return value 387 * < 0 : on error (only possible for opc as LPROCFS_GET_SMP_ID) 388 */ 389static inline int lprocfs_stats_lock(struct lprocfs_stats *stats, int opc, 390 unsigned long *flags) 391{ 392 int rc = 0; 393 394 switch (opc) { 395 default: 396 LBUG(); 397 398 case LPROCFS_GET_SMP_ID: 399 if (stats->ls_flags & LPROCFS_STATS_FLAG_NOPERCPU) { 400 if (stats->ls_flags & LPROCFS_STATS_FLAG_IRQ_SAFE) 401 spin_lock_irqsave(&stats->ls_lock, *flags); 402 else 403 spin_lock(&stats->ls_lock); 404 return 0; 405 } else { 406 unsigned int cpuid = get_cpu(); 407 408 if (unlikely(stats->ls_percpu[cpuid] == NULL)) { 409 rc = lprocfs_stats_alloc_one(stats, cpuid); 410 if (rc < 0) { 411 put_cpu(); 412 return rc; 413 } 414 } 415 return cpuid; 416 } 417 418 case LPROCFS_GET_NUM_CPU: 419 if (stats->ls_flags & LPROCFS_STATS_FLAG_NOPERCPU) { 420 if (stats->ls_flags & LPROCFS_STATS_FLAG_IRQ_SAFE) 421 spin_lock_irqsave(&stats->ls_lock, *flags); 422 else 423 spin_lock(&stats->ls_lock); 424 return 1; 425 } else { 426 return stats->ls_biggest_alloc_num; 427 } 428 } 429} 430 431static inline void lprocfs_stats_unlock(struct lprocfs_stats *stats, int opc, 432 unsigned long *flags) 433{ 434 switch (opc) { 435 default: 436 LBUG(); 437 438 case LPROCFS_GET_SMP_ID: 439 if (stats->ls_flags & LPROCFS_STATS_FLAG_NOPERCPU) { 440 if (stats->ls_flags & LPROCFS_STATS_FLAG_IRQ_SAFE) { 441 spin_unlock_irqrestore(&stats->ls_lock, 442 *flags); 443 } else { 444 spin_unlock(&stats->ls_lock); 445 } 446 } else { 447 put_cpu(); 448 } 449 return; 450 451 case LPROCFS_GET_NUM_CPU: 452 if (stats->ls_flags & LPROCFS_STATS_FLAG_NOPERCPU) { 453 if (stats->ls_flags & LPROCFS_STATS_FLAG_IRQ_SAFE) { 454 spin_unlock_irqrestore(&stats->ls_lock, 455 *flags); 456 } else { 457 spin_unlock(&stats->ls_lock); 458 } 459 } 460 return; 461 } 462} 463 464static inline unsigned int 465lprocfs_stats_counter_size(struct lprocfs_stats *stats) 466{ 467 unsigned int percpusize; 468 469 percpusize = offsetof(struct lprocfs_percpu, lp_cntr[stats->ls_num]); 470 471 /* irq safe stats need lc_array_sum[1] */ 472 if ((stats->ls_flags & LPROCFS_STATS_FLAG_IRQ_SAFE) != 0) 473 percpusize += stats->ls_num * sizeof(__s64); 474 475 if ((stats->ls_flags & LPROCFS_STATS_FLAG_NOPERCPU) == 0) 476 percpusize = L1_CACHE_ALIGN(percpusize); 477 478 return percpusize; 479} 480 481static inline struct lprocfs_counter * 482lprocfs_stats_counter_get(struct lprocfs_stats *stats, unsigned int cpuid, 483 int index) 484{ 485 struct lprocfs_counter *cntr; 486 487 cntr = &stats->ls_percpu[cpuid]->lp_cntr[index]; 488 489 if ((stats->ls_flags & LPROCFS_STATS_FLAG_IRQ_SAFE) != 0) 490 cntr = (void *)cntr + index * sizeof(__s64); 491 492 return cntr; 493} 494 495/* Two optimized LPROCFS counter increment functions are provided: 496 * lprocfs_counter_incr(cntr, value) - optimized for by-one counters 497 * lprocfs_counter_add(cntr) - use for multi-valued counters 498 * Counter data layout allows config flag, counter lock and the 499 * count itself to reside within a single cache line. 500 */ 501 502extern void lprocfs_counter_add(struct lprocfs_stats *stats, int idx, 503 long amount); 504extern void lprocfs_counter_sub(struct lprocfs_stats *stats, int idx, 505 long amount); 506 507#define lprocfs_counter_incr(stats, idx) \ 508 lprocfs_counter_add(stats, idx, 1) 509#define lprocfs_counter_decr(stats, idx) \ 510 lprocfs_counter_sub(stats, idx, 1) 511 512extern __s64 lprocfs_read_helper(struct lprocfs_counter *lc, 513 struct lprocfs_counter_header *header, 514 enum lprocfs_stats_flags flags, 515 enum lprocfs_fields_flags field); 516static inline __u64 lprocfs_stats_collector(struct lprocfs_stats *stats, 517 int idx, 518 enum lprocfs_fields_flags field) 519{ 520 int i; 521 unsigned int num_cpu; 522 unsigned long flags = 0; 523 __u64 ret = 0; 524 525 LASSERT(stats != NULL); 526 527 num_cpu = lprocfs_stats_lock(stats, LPROCFS_GET_NUM_CPU, &flags); 528 for (i = 0; i < num_cpu; i++) { 529 if (stats->ls_percpu[i] == NULL) 530 continue; 531 ret += lprocfs_read_helper( 532 lprocfs_stats_counter_get(stats, i, idx), 533 &stats->ls_cnt_header[idx], stats->ls_flags, 534 field); 535 } 536 lprocfs_stats_unlock(stats, LPROCFS_GET_NUM_CPU, &flags); 537 return ret; 538} 539 540extern struct lprocfs_stats * 541lprocfs_alloc_stats(unsigned int num, enum lprocfs_stats_flags flags); 542extern void lprocfs_clear_stats(struct lprocfs_stats *stats); 543extern void lprocfs_free_stats(struct lprocfs_stats **stats); 544extern void lprocfs_init_ops_stats(int num_private_stats, 545 struct lprocfs_stats *stats); 546extern void lprocfs_init_mps_stats(int num_private_stats, 547 struct lprocfs_stats *stats); 548extern void lprocfs_init_ldlm_stats(struct lprocfs_stats *ldlm_stats); 549extern int lprocfs_alloc_obd_stats(struct obd_device *obddev, 550 unsigned int num_private_stats); 551extern int lprocfs_alloc_md_stats(struct obd_device *obddev, 552 unsigned int num_private_stats); 553extern void lprocfs_counter_init(struct lprocfs_stats *stats, int index, 554 unsigned conf, const char *name, 555 const char *units); 556extern void lprocfs_free_obd_stats(struct obd_device *obddev); 557extern void lprocfs_free_md_stats(struct obd_device *obddev); 558struct obd_export; 559struct nid_stat; 560extern int lprocfs_add_clear_entry(struct obd_device * obd, 561 struct proc_dir_entry *entry); 562extern int lprocfs_exp_setup(struct obd_export *exp, 563 lnet_nid_t *peer_nid, int *newnid); 564extern int lprocfs_exp_cleanup(struct obd_export *exp); 565extern struct proc_dir_entry *lprocfs_add_simple(struct proc_dir_entry *root, 566 char *name, 567 void *data, 568 struct file_operations *fops); 569extern struct proc_dir_entry * 570lprocfs_add_symlink(const char *name, struct proc_dir_entry *parent, 571 const char *format, ...); 572extern void lprocfs_free_per_client_stats(struct obd_device *obd); 573extern int 574lprocfs_nid_stats_clear_write(struct file *file, const char *buffer, 575 unsigned long count, void *data); 576extern int lprocfs_nid_stats_clear_read(struct seq_file *m, void *data); 577 578extern int lprocfs_register_stats(struct proc_dir_entry *root, const char *name, 579 struct lprocfs_stats *stats); 580 581/* lprocfs_status.c */ 582extern int lprocfs_add_vars(struct proc_dir_entry *root, 583 struct lprocfs_vars *var, 584 void *data); 585 586extern struct proc_dir_entry *lprocfs_register(const char *name, 587 struct proc_dir_entry *parent, 588 struct lprocfs_vars *list, 589 void *data); 590 591extern void lprocfs_remove(struct proc_dir_entry **root); 592extern void lprocfs_remove_proc_entry(const char *name, 593 struct proc_dir_entry *parent); 594 595extern int lprocfs_obd_setup(struct obd_device *obd, struct lprocfs_vars *list); 596extern int lprocfs_obd_cleanup(struct obd_device *obd); 597 598extern int lprocfs_seq_create(struct proc_dir_entry *parent, const char *name, 599 umode_t mode, 600 const struct file_operations *seq_fops, 601 void *data); 602extern int lprocfs_obd_seq_create(struct obd_device *dev, const char *name, 603 umode_t mode, 604 const struct file_operations *seq_fops, 605 void *data); 606 607/* Generic callbacks */ 608 609extern int lprocfs_rd_u64(struct seq_file *m, void *data); 610extern int lprocfs_rd_atomic(struct seq_file *m, void *data); 611extern int lprocfs_wr_atomic(struct file *file, const char __user *buffer, 612 unsigned long count, void *data); 613extern int lprocfs_rd_uint(struct seq_file *m, void *data); 614extern int lprocfs_wr_uint(struct file *file, const char __user *buffer, 615 unsigned long count, void *data); 616extern int lprocfs_rd_uuid(struct seq_file *m, void *data); 617extern int lprocfs_rd_name(struct seq_file *m, void *data); 618extern int lprocfs_rd_server_uuid(struct seq_file *m, void *data); 619extern int lprocfs_rd_conn_uuid(struct seq_file *m, void *data); 620extern int lprocfs_rd_import(struct seq_file *m, void *data); 621extern int lprocfs_rd_state(struct seq_file *m, void *data); 622extern int lprocfs_rd_connect_flags(struct seq_file *m, void *data); 623extern int lprocfs_rd_num_exports(struct seq_file *m, void *data); 624extern int lprocfs_rd_numrefs(struct seq_file *m, void *data); 625 626struct adaptive_timeout; 627extern int lprocfs_at_hist_helper(struct seq_file *m, 628 struct adaptive_timeout *at); 629extern int lprocfs_rd_timeouts(struct seq_file *m, void *data); 630extern int lprocfs_wr_timeouts(struct file *file, const char *buffer, 631 unsigned long count, void *data); 632extern int lprocfs_wr_evict_client(struct file *file, const char *buffer, 633 size_t count, loff_t *off); 634extern int lprocfs_wr_ping(struct file *file, const char *buffer, 635 size_t count, loff_t *off); 636extern int lprocfs_wr_import(struct file *file, const char *buffer, 637 size_t count, loff_t *off); 638extern int lprocfs_rd_pinger_recov(struct seq_file *m, void *n); 639extern int lprocfs_wr_pinger_recov(struct file *file, const char *buffer, 640 size_t count, loff_t *off); 641 642/* Statfs helpers */ 643extern int lprocfs_rd_blksize(struct seq_file *m, void *data); 644extern int lprocfs_rd_kbytestotal(struct seq_file *m, void *data); 645extern int lprocfs_rd_kbytesfree(struct seq_file *m, void *data); 646extern int lprocfs_rd_kbytesavail(struct seq_file *m, void *data); 647extern int lprocfs_rd_filestotal(struct seq_file *m, void *data); 648extern int lprocfs_rd_filesfree(struct seq_file *m, void *data); 649 650extern int lprocfs_write_helper(const char *buffer, unsigned long count, 651 int *val); 652extern int lprocfs_seq_read_frac_helper(struct seq_file *m, long val, int mult); 653extern int lprocfs_write_u64_helper(const char *buffer, unsigned long count, 654 __u64 *val); 655extern int lprocfs_write_frac_u64_helper(const char *buffer, 656 unsigned long count, 657 __u64 *val, int mult); 658extern char *lprocfs_find_named_value(const char *buffer, const char *name, 659 size_t *count); 660void lprocfs_oh_tally(struct obd_histogram *oh, unsigned int value); 661void lprocfs_oh_tally_log2(struct obd_histogram *oh, unsigned int value); 662void lprocfs_oh_clear(struct obd_histogram *oh); 663unsigned long lprocfs_oh_sum(struct obd_histogram *oh); 664 665void lprocfs_stats_collect(struct lprocfs_stats *stats, int idx, 666 struct lprocfs_counter *cnt); 667 668extern int lprocfs_single_release(struct inode *, struct file *); 669extern int lprocfs_seq_release(struct inode *, struct file *); 670 671/* You must use these macros when you want to refer to 672 * the import in a client obd_device for a lprocfs entry */ 673#define LPROCFS_CLIMP_CHECK(obd) do { \ 674 typecheck(struct obd_device *, obd); \ 675 down_read(&(obd)->u.cli.cl_sem); \ 676 if ((obd)->u.cli.cl_import == NULL) { \ 677 up_read(&(obd)->u.cli.cl_sem); \ 678 return -ENODEV; \ 679 } \ 680} while (0) 681#define LPROCFS_CLIMP_EXIT(obd) \ 682 up_read(&(obd)->u.cli.cl_sem); 683 684 685/* write the name##_seq_show function, call LPROC_SEQ_FOPS_RO for read-only 686 proc entries; otherwise, you will define name##_seq_write function also for 687 a read-write proc entry, and then call LPROC_SEQ_SEQ instead. Finally, 688 call lprocfs_obd_seq_create(obd, filename, 0444, &name#_fops, data); */ 689#define __LPROC_SEQ_FOPS(name, custom_seq_write) \ 690static int name##_single_open(struct inode *inode, struct file *file) \ 691{ \ 692 return single_open(file, name##_seq_show, PDE_DATA(inode)); \ 693} \ 694static struct file_operations name##_fops = { \ 695 .owner = THIS_MODULE, \ 696 .open = name##_single_open, \ 697 .read = seq_read, \ 698 .write = custom_seq_write, \ 699 .llseek = seq_lseek, \ 700 .release = lprocfs_single_release, \ 701} 702 703#define LPROC_SEQ_FOPS_RO(name) __LPROC_SEQ_FOPS(name, NULL) 704#define LPROC_SEQ_FOPS(name) __LPROC_SEQ_FOPS(name, name##_seq_write) 705 706#define LPROC_SEQ_FOPS_RO_TYPE(name, type) \ 707 static int name##_##type##_seq_show(struct seq_file *m, void *v)\ 708 { \ 709 return lprocfs_rd_##type(m, m->private); \ 710 } \ 711 LPROC_SEQ_FOPS_RO(name##_##type) 712 713#define LPROC_SEQ_FOPS_RW_TYPE(name, type) \ 714 static int name##_##type##_seq_show(struct seq_file *m, void *v)\ 715 { \ 716 return lprocfs_rd_##type(m, m->private); \ 717 } \ 718 static ssize_t name##_##type##_seq_write(struct file *file, \ 719 const char *buffer, size_t count, loff_t *off) \ 720 { \ 721 struct seq_file *seq = file->private_data; \ 722 return lprocfs_wr_##type(file, buffer, \ 723 count, seq->private); \ 724 } \ 725 LPROC_SEQ_FOPS(name##_##type); 726 727#define LPROC_SEQ_FOPS_WR_ONLY(name, type) \ 728 static ssize_t name##_##type##_write(struct file *file, \ 729 const char *buffer, size_t count, loff_t *off) \ 730 { \ 731 return lprocfs_wr_##type(file, buffer, count, off); \ 732 } \ 733 static int name##_##type##_open(struct inode *inode, struct file *file) \ 734 { \ 735 return single_open(file, NULL, PDE_DATA(inode)); \ 736 } \ 737 static struct file_operations name##_##type##_fops = { \ 738 .open = name##_##type##_open, \ 739 .write = name##_##type##_write, \ 740 .release = lprocfs_single_release, \ 741 }; 742 743/* lproc_ptlrpc.c */ 744struct ptlrpc_request; 745extern void target_print_req(void *seq_file, struct ptlrpc_request *req); 746 747/* lproc_status.c */ 748int lprocfs_obd_rd_max_pages_per_rpc(struct seq_file *m, void *data); 749int lprocfs_obd_wr_max_pages_per_rpc(struct file *file, const char *buffer, 750 size_t count, loff_t *off); 751 752/* all quota proc functions */ 753extern int lprocfs_quota_rd_bunit(char *page, char **start, 754 loff_t off, int count, 755 int *eof, void *data); 756extern int lprocfs_quota_wr_bunit(struct file *file, const char *buffer, 757 unsigned long count, void *data); 758extern int lprocfs_quota_rd_btune(char *page, char **start, 759 loff_t off, int count, 760 int *eof, void *data); 761extern int lprocfs_quota_wr_btune(struct file *file, const char *buffer, 762 unsigned long count, void *data); 763extern int lprocfs_quota_rd_iunit(char *page, char **start, 764 loff_t off, int count, 765 int *eof, void *data); 766extern int lprocfs_quota_wr_iunit(struct file *file, const char *buffer, 767 unsigned long count, void *data); 768extern int lprocfs_quota_rd_itune(char *page, char **start, 769 loff_t off, int count, 770 int *eof, void *data); 771extern int lprocfs_quota_wr_itune(struct file *file, const char *buffer, 772 unsigned long count, void *data); 773extern int lprocfs_quota_rd_type(char *page, char **start, loff_t off, int count, 774 int *eof, void *data); 775extern int lprocfs_quota_wr_type(struct file *file, const char *buffer, 776 unsigned long count, void *data); 777extern int lprocfs_quota_rd_switch_seconds(char *page, char **start, loff_t off, 778 int count, int *eof, void *data); 779extern int lprocfs_quota_wr_switch_seconds(struct file *file, 780 const char *buffer, 781 unsigned long count, void *data); 782extern int lprocfs_quota_rd_sync_blk(char *page, char **start, loff_t off, 783 int count, int *eof, void *data); 784extern int lprocfs_quota_wr_sync_blk(struct file *file, const char *buffer, 785 unsigned long count, void *data); 786extern int lprocfs_quota_rd_switch_qs(char *page, char **start, loff_t off, 787 int count, int *eof, void *data); 788extern int lprocfs_quota_wr_switch_qs(struct file *file, 789 const char *buffer, 790 unsigned long count, void *data); 791extern int lprocfs_quota_rd_boundary_factor(char *page, char **start, loff_t off, 792 int count, int *eof, void *data); 793extern int lprocfs_quota_wr_boundary_factor(struct file *file, 794 const char *buffer, 795 unsigned long count, void *data); 796extern int lprocfs_quota_rd_least_bunit(char *page, char **start, loff_t off, 797 int count, int *eof, void *data); 798extern int lprocfs_quota_wr_least_bunit(struct file *file, 799 const char *buffer, 800 unsigned long count, void *data); 801extern int lprocfs_quota_rd_least_iunit(char *page, char **start, loff_t off, 802 int count, int *eof, void *data); 803extern int lprocfs_quota_wr_least_iunit(struct file *file, 804 const char *buffer, 805 unsigned long count, void *data); 806extern int lprocfs_quota_rd_qs_factor(char *page, char **start, loff_t off, 807 int count, int *eof, void *data); 808extern int lprocfs_quota_wr_qs_factor(struct file *file, 809 const char *buffer, 810 unsigned long count, void *data); 811#else 812/* CONFIG_PROC_FS is not defined */ 813 814#define proc_lustre_root NULL 815 816static inline void lprocfs_counter_add(struct lprocfs_stats *stats, 817 int index, long amount) 818{ return; } 819static inline void lprocfs_counter_incr(struct lprocfs_stats *stats, 820 int index) 821{ return; } 822static inline void lprocfs_counter_sub(struct lprocfs_stats *stats, 823 int index, long amount) 824{ return; } 825static inline void lprocfs_counter_decr(struct lprocfs_stats *stats, 826 int index) 827{ return; } 828static inline void lprocfs_counter_init(struct lprocfs_stats *stats, 829 int index, unsigned conf, 830 const char *name, const char *units) 831{ return; } 832 833static inline __u64 lc_read_helper(struct lprocfs_counter *lc, 834 enum lprocfs_fields_flags field) 835{ return 0; } 836 837/* NB: we return !NULL to satisfy error checker */ 838static inline struct lprocfs_stats * 839lprocfs_alloc_stats(unsigned int num, enum lprocfs_stats_flags flags) 840{ return (struct lprocfs_stats *)1; } 841static inline void lprocfs_clear_stats(struct lprocfs_stats *stats) 842{ return; } 843static inline void lprocfs_free_stats(struct lprocfs_stats **stats) 844{ return; } 845static inline int lprocfs_register_stats(struct proc_dir_entry *root, 846 const char *name, 847 struct lprocfs_stats *stats) 848{ return 0; } 849static inline void lprocfs_init_ops_stats(int num_private_stats, 850 struct lprocfs_stats *stats) 851{ return; } 852static inline void lprocfs_init_mps_stats(int num_private_stats, 853 struct lprocfs_stats *stats) 854{ return; } 855static inline void lprocfs_init_ldlm_stats(struct lprocfs_stats *ldlm_stats) 856{ return; } 857static inline int lprocfs_alloc_obd_stats(struct obd_device *obddev, 858 unsigned int num_private_stats) 859{ return 0; } 860static inline int lprocfs_alloc_md_stats(struct obd_device *obddev, 861 unsigned int num_private_stats) 862{ return 0; } 863static inline void lprocfs_free_obd_stats(struct obd_device *obddev) 864{ return; } 865static inline void lprocfs_free_md_stats(struct obd_device *obddev) 866{ return; } 867 868struct obd_export; 869static inline int lprocfs_add_clear_entry(struct obd_export *exp) 870{ return 0; } 871static inline int lprocfs_exp_setup(struct obd_export *exp, 872 lnet_nid_t *peer_nid, 873 int *newnid) 874{ return 0; } 875static inline int lprocfs_exp_cleanup(struct obd_export *exp) 876{ return 0; } 877static inline struct proc_dir_entry * 878lprocfs_add_simple(struct proc_dir_entry *root, char *name, 879 void *data, struct file_operations *fops) 880{return 0; } 881static inline struct proc_dir_entry * 882lprocfs_add_symlink(const char *name, struct proc_dir_entry *parent, 883 const char *format, ...) 884{return NULL; } 885static inline void lprocfs_free_per_client_stats(struct obd_device *obd) 886{ return; } 887static inline 888int lprocfs_nid_stats_clear_write(struct file *file, const char *buffer, 889 unsigned long count, void *data) 890{return count;} 891static inline 892int lprocfs_nid_stats_clear_read(struct seq_file *m, void *data) 893{ return 0; } 894 895static inline struct proc_dir_entry * 896lprocfs_register(const char *name, struct proc_dir_entry *parent, 897 struct lprocfs_vars *list, void *data) 898{ return NULL; } 899static inline int lprocfs_add_vars(struct proc_dir_entry *root, 900 struct lprocfs_vars *var, 901 void *data) 902{ return 0; } 903static inline void lprocfs_remove(struct proc_dir_entry **root) 904{ return; } 905static inline void lprocfs_remove_proc_entry(const char *name, 906 struct proc_dir_entry *parent) 907{ return; } 908static inline int lprocfs_obd_setup(struct obd_device *dev, 909 struct lprocfs_vars *list) 910{ return 0; } 911static inline int lprocfs_obd_cleanup(struct obd_device *dev) 912{ return 0; } 913static inline int lprocfs_rd_u64(struct seq_file *m, void *data) 914{ return 0; } 915static inline int lprocfs_rd_uuid(struct seq_file *m, void *data) 916{ return 0; } 917static inline int lprocfs_rd_name(struct seq_file *m, void *data) 918{ return 0; } 919static inline int lprocfs_rd_server_uuid(struct seq_file *m, void *data) 920{ return 0; } 921static inline int lprocfs_rd_conn_uuid(struct seq_file *m, void *data) 922{ return 0; } 923static inline int lprocfs_rd_import(struct seq_file *m, void *data) 924{ return 0; } 925static inline int lprocfs_rd_pinger_recov(struct seq_file *m, void *n) 926{ return 0; } 927static inline int lprocfs_rd_state(struct seq_file *m, void *data) 928{ return 0; } 929static inline int lprocfs_rd_connect_flags(struct seq_file *m, void *data) 930{ return 0; } 931static inline int lprocfs_rd_num_exports(struct seq_file *m, void *data) 932{ return 0; } 933extern inline int lprocfs_rd_numrefs(struct seq_file *m, void *data) 934{ return 0; } 935struct adaptive_timeout; 936static inline int lprocfs_at_hist_helper(struct seq_file *m, 937 struct adaptive_timeout *at) 938{ return 0; } 939static inline int lprocfs_rd_timeouts(struct seq_file *m, void *data) 940{ return 0; } 941static inline int lprocfs_wr_timeouts(struct file *file, 942 const char *buffer, 943 unsigned long count, void *data) 944{ return 0; } 945static inline int lprocfs_wr_evict_client(struct file *file, const char *buffer, 946 size_t count, loff_t *off) 947{ return 0; } 948static inline int lprocfs_wr_ping(struct file *file, const char *buffer, 949 size_t count, loff_t *off) 950{ return 0; } 951static inline int lprocfs_wr_import(struct file *file, const char *buffer, 952 size_t count, loff_t *off) 953{ return 0; } 954static inline int lprocfs_wr_pinger_recov(struct file *file, const char *buffer, 955 size_t count, loff_t *off) 956{ return 0; } 957 958/* Statfs helpers */ 959static inline 960int lprocfs_rd_blksize(struct seq_file *m, void *data) 961{ return 0; } 962static inline 963int lprocfs_rd_kbytestotal(struct seq_file *m, void *data) 964{ return 0; } 965static inline 966int lprocfs_rd_kbytesfree(struct seq_file *m, void *data) 967{ return 0; } 968static inline 969int lprocfs_rd_kbytesavail(struct seq_file *m, void *data) 970{ return 0; } 971static inline 972int lprocfs_rd_filestotal(struct seq_file *m, void *data) 973{ return 0; } 974static inline 975int lprocfs_rd_filesfree(struct seq_file *m, void *data) 976{ return 0; } 977static inline 978void lprocfs_oh_tally(struct obd_histogram *oh, unsigned int value) 979{ return; } 980static inline 981void lprocfs_oh_tally_log2(struct obd_histogram *oh, unsigned int value) 982{ return; } 983static inline 984void lprocfs_oh_clear(struct obd_histogram *oh) 985{ return; } 986static inline 987unsigned long lprocfs_oh_sum(struct obd_histogram *oh) 988{ return 0; } 989static inline 990void lprocfs_stats_collect(struct lprocfs_stats *stats, int idx, 991 struct lprocfs_counter *cnt) 992{ return; } 993static inline 994__u64 lprocfs_stats_collector(struct lprocfs_stats *stats, int idx, 995 enum lprocfs_fields_flags field) 996{ return (__u64)0; } 997 998#define LPROC_SEQ_FOPS_RO(name) 999#define LPROC_SEQ_FOPS(name) 1000#define LPROC_SEQ_FOPS_RO_TYPE(name, type) 1001#define LPROC_SEQ_FOPS_RW_TYPE(name, type) 1002#define LPROC_SEQ_FOPS_WR_ONLY(name, type) 1003 1004/* lproc_ptlrpc.c */ 1005#define target_print_req NULL 1006 1007#endif /* CONFIG_PROC_FS */ 1008 1009#endif /* LPROCFS_SNMP_H */ 1010