Whamcloud - gitweb
client capa list is sorted.
[fs/lustre-release.git] / lustre / obdclass / lprocfs_status.c
index 8fd0175..a597cd4 100644 (file)
@@ -35,6 +35,7 @@
 #  include <asm/statfs.h>
 # endif
 # include <linux/seq_file.h>
+# include <asm/div64.h>
 #else /* __KERNEL__ */
 # include <liblustre.h>
 #endif
@@ -44,7 +45,6 @@
 #include <linux/lustre_fsfilt.h>
 
 #if defined(LPROCFS) && defined(__KERNEL__)
-
 struct proc_dir_entry *lprocfs_srch(struct proc_dir_entry *head,
                                     const char *name)
 {
@@ -64,7 +64,6 @@ struct proc_dir_entry *lprocfs_srch(struct proc_dir_entry *head,
 }
 
 /* lprocfs API calls */
-
 int lprocfs_add_vars(struct proc_dir_entry *root, struct lprocfs_vars *list,
                      void *data)
 {
@@ -138,13 +137,20 @@ void lprocfs_remove(struct proc_dir_entry *root)
         LASSERT(root != NULL);
         parent = root->parent;
         LASSERT(parent != NULL);
-
         while (1) {
                 while (temp->subdir != NULL)
                         temp = temp->subdir;
 
                 rm_entry = temp;
                 temp = temp->parent;
+
+                /* Memory corruption once caused this to fail, and
+                   without this LASSERT we would loop here forever. */
+                LASSERTF(strlen(rm_entry->name) == rm_entry->namelen,
+                         "0x%p  %s/%s len %d\n", rm_entry, temp->name,
+                         rm_entry->name, (int)strlen(rm_entry->name));
+
                 remove_proc_entry(rm_entry->name, rm_entry->parent);
                 if (temp == parent)
                         break;
@@ -265,6 +271,24 @@ int lprocfs_rd_kbytesfree(char *page, char **start, off_t off, int count,
         return rc;
 }
 
+int lprocfs_rd_kbytesavail(char *page, char **start, off_t off, int count,
+                           int *eof, void *data)
+{
+        struct obd_statfs osfs;
+        int rc = obd_statfs(data, &osfs, jiffies - HZ);
+        if (!rc) {
+                __u32 blk_size = osfs.os_bsize >> 10;
+                __u64 result = osfs.os_bavail;
+
+                while (blk_size >>= 1)
+                        result <<= 1;
+
+                *eof = 1;
+                rc = snprintf(page, count, LPU64"\n", result);
+        }
+        return rc;
+}
+
 int lprocfs_rd_filestotal(char *page, char **start, off_t off, int count,
                           int *eof, void *data)
 {
@@ -290,20 +314,13 @@ int lprocfs_rd_filesfree(char *page, char **start, off_t off, int count,
         return rc;
 }
 
-int lprocfs_rd_filegroups(char *page, char **start, off_t off, int count,
-                          int *eof, void *data)
-{
-        *eof = 1;
-        return snprintf(page, count, "unimplemented\n");
-}
-
 int lprocfs_rd_server_uuid(char *page, char **start, off_t off, int count,
                            int *eof, void *data)
 {
         struct obd_device *obd = (struct obd_device *)data;
         struct obd_import *imp;
         char *imp_state_name = NULL;
-        
+
         LASSERT(obd != NULL);
         imp = obd->u.cli.cl_import;
         imp_state_name = ptlrpc_import_state_name(imp->imp_state);
@@ -325,6 +342,16 @@ int lprocfs_rd_conn_uuid(char *page, char **start, off_t off, int count,
         return snprintf(page, count, "%s\n", conn->c_remote_uuid.uuid);
 }
 
+int lprocfs_rd_num_exports(char *page, char **start, off_t off, int count,
+                           int *eof,  void *data)
+{
+        struct obd_device *obd = (struct obd_device*)data;
+
+        LASSERT(obd != NULL);
+        *eof = 1;
+        return snprintf(page, count, "%u\n", obd->obd_num_exports);
+}
+
 int lprocfs_rd_numrefs(char *page, char **start, off_t off, int count,
                        int *eof, void *data)
 {
@@ -513,13 +540,15 @@ static int lprocfs_stats_seq_open(struct inode *inode, struct file *file)
 }
 
 struct file_operations lprocfs_stats_seq_fops = {
-        open:    lprocfs_stats_seq_open,
-        read:    seq_read,
-        llseek:  seq_lseek,
-        release: seq_release,
+        .owner   = THIS_MODULE,
+        .open    = lprocfs_stats_seq_open,
+        .read    = seq_read,
+        .llseek  = seq_lseek,
+        .release = seq_release,
 };
 
-int lprocfs_register_stats(struct proc_dir_entry *root, const char *name,
+int lprocfs_register_stats(struct proc_dir_entry *root,
+                           const char *name,
                            struct lprocfs_stats *stats)
 {
         struct proc_dir_entry *entry;
@@ -535,7 +564,8 @@ int lprocfs_register_stats(struct proc_dir_entry *root, const char *name,
 }
 
 void lprocfs_counter_init(struct lprocfs_stats *stats, int index,
-                          unsigned conf, const char *name, const char *units)
+                          unsigned conf, const char *name,
+                          const char *units)
 {
         struct lprocfs_counter *c;
         int i;
@@ -558,7 +588,8 @@ do {                                                                       \
         lprocfs_counter_init(stats, coffset, 0, #op, "reqs");              \
 } while (0)
 
-int lprocfs_alloc_obd_stats(struct obd_device *obd, unsigned num_private_stats)
+int lprocfs_alloc_obd_stats(struct obd_device *obd,
+                            unsigned num_private_stats)
 {
         struct lprocfs_stats *stats;
         unsigned int num_stats;
@@ -568,7 +599,7 @@ int lprocfs_alloc_obd_stats(struct obd_device *obd, unsigned num_private_stats)
         LASSERT(obd->obd_proc_entry != NULL);
         LASSERT(obd->obd_cntr_base == 0);
 
-        num_stats = 1 + OBD_COUNTER_OFFSET(notify) +
+        num_stats = 1 + OBD_COUNTER_OFFSET(init_ea_size) +
                 num_private_stats;
         stats = lprocfs_alloc_stats(num_stats);
         if (stats == NULL)
@@ -582,12 +613,17 @@ int lprocfs_alloc_obd_stats(struct obd_device *obd, unsigned num_private_stats)
         LPROCFS_OBD_OP_INIT(num_private_stats, stats, setup);
         LPROCFS_OBD_OP_INIT(num_private_stats, stats, precleanup);
         LPROCFS_OBD_OP_INIT(num_private_stats, stats, cleanup);
+        LPROCFS_OBD_OP_INIT(num_private_stats, stats, process_config);
         LPROCFS_OBD_OP_INIT(num_private_stats, stats, postrecov);
+        LPROCFS_OBD_OP_INIT(num_private_stats, stats, add_conn);
+        LPROCFS_OBD_OP_INIT(num_private_stats, stats, del_conn);
         LPROCFS_OBD_OP_INIT(num_private_stats, stats, connect);
+        LPROCFS_OBD_OP_INIT(num_private_stats, stats, connect_post);
         LPROCFS_OBD_OP_INIT(num_private_stats, stats, disconnect);
         LPROCFS_OBD_OP_INIT(num_private_stats, stats, statfs);
         LPROCFS_OBD_OP_INIT(num_private_stats, stats, packmd);
         LPROCFS_OBD_OP_INIT(num_private_stats, stats, unpackmd);
+        LPROCFS_OBD_OP_INIT(num_private_stats, stats, revalidate_md);
         LPROCFS_OBD_OP_INIT(num_private_stats, stats, preallocate);
         LPROCFS_OBD_OP_INIT(num_private_stats, stats, create);
         LPROCFS_OBD_OP_INIT(num_private_stats, stats, destroy);
@@ -599,9 +635,10 @@ int lprocfs_alloc_obd_stats(struct obd_device *obd, unsigned num_private_stats)
         LPROCFS_OBD_OP_INIT(num_private_stats, stats, prep_async_page);
         LPROCFS_OBD_OP_INIT(num_private_stats, stats, queue_async_io);
         LPROCFS_OBD_OP_INIT(num_private_stats, stats, set_async_flags);
-        LPROCFS_OBD_OP_INIT(num_private_stats, stats, queue_sync_io);
-        LPROCFS_OBD_OP_INIT(num_private_stats, stats, trigger_sync_io);
+        LPROCFS_OBD_OP_INIT(num_private_stats, stats, queue_group_io);
+        LPROCFS_OBD_OP_INIT(num_private_stats, stats, trigger_group_io);
         LPROCFS_OBD_OP_INIT(num_private_stats, stats, teardown_async_page);
+        LPROCFS_OBD_OP_INIT(num_private_stats, stats, adjust_kms);
         LPROCFS_OBD_OP_INIT(num_private_stats, stats, punch);
         LPROCFS_OBD_OP_INIT(num_private_stats, stats, sync);
         LPROCFS_OBD_OP_INIT(num_private_stats, stats, migrate);
@@ -609,6 +646,8 @@ int lprocfs_alloc_obd_stats(struct obd_device *obd, unsigned num_private_stats)
         LPROCFS_OBD_OP_INIT(num_private_stats, stats, iterate);
         LPROCFS_OBD_OP_INIT(num_private_stats, stats, preprw);
         LPROCFS_OBD_OP_INIT(num_private_stats, stats, commitrw);
+        LPROCFS_OBD_OP_INIT(num_private_stats, stats, do_cow);
+        LPROCFS_OBD_OP_INIT(num_private_stats, stats, write_extents);
         LPROCFS_OBD_OP_INIT(num_private_stats, stats, enqueue);
         LPROCFS_OBD_OP_INIT(num_private_stats, stats, match);
         LPROCFS_OBD_OP_INIT(num_private_stats, stats, change_cbdata);
@@ -617,19 +656,19 @@ int lprocfs_alloc_obd_stats(struct obd_device *obd, unsigned num_private_stats)
         LPROCFS_OBD_OP_INIT(num_private_stats, stats, san_preprw);
         LPROCFS_OBD_OP_INIT(num_private_stats, stats, init_export);
         LPROCFS_OBD_OP_INIT(num_private_stats, stats, destroy_export);
-        LPROCFS_OBD_OP_INIT(num_private_stats, stats, lock_contains);
         LPROCFS_OBD_OP_INIT(num_private_stats, stats, llog_init); 
         LPROCFS_OBD_OP_INIT(num_private_stats, stats, llog_finish); 
+        LPROCFS_OBD_OP_INIT(num_private_stats, stats, llog_connect); 
         LPROCFS_OBD_OP_INIT(num_private_stats, stats, pin); 
         LPROCFS_OBD_OP_INIT(num_private_stats, stats, unpin);
-        LPROCFS_OBD_OP_INIT(num_private_stats, stats, invalidate_import);
+        LPROCFS_OBD_OP_INIT(num_private_stats, stats, import_event);
         LPROCFS_OBD_OP_INIT(num_private_stats, stats, notify);
-        
+        LPROCFS_OBD_OP_INIT(num_private_stats, stats, init_ea_size);
+
         for (i = num_private_stats; i < num_stats; i++) {
-                /* If this LBUGs, it is likely that an obd
-                 * operation was added to struct obd_ops in
-                 * <linux/obd.h>, and that the corresponding line item
-                 * LPROCFS_OBD_OP_INIT(.., .., opname)
+                /* if this LBUGs, it is likely that an obd operation was added
+                 * to struct obd_ops in <linux/obd.h>, and that the
+                 * corresponding line item LPROCFS_OBD_OP_INIT(.., .., opname)
                  * is missing from the list above. */
                 if (stats->ls_percpu[0]->lp_cntr[i].lc_name == NULL) {
                         CERROR("Missing obd_stat initializer obd_op "
@@ -658,11 +697,89 @@ void lprocfs_free_obd_stats(struct obd_device *obd)
         }
 }
 
+#define LPROCFS_MD_OP_INIT(base, stats, op)                             \
+do {                                                                    \
+        unsigned int coffset = base + MD_COUNTER_OFFSET(op);            \
+        LASSERT(coffset < stats->ls_num);                               \
+        lprocfs_counter_init(stats, coffset, 0, #op, "reqs");           \
+} while (0)
+
+int lprocfs_alloc_md_stats(struct obd_device *obd,
+                           unsigned num_private_stats)
+{
+        struct lprocfs_stats *stats;
+        unsigned int num_stats;
+        int rc, i;
+
+        LASSERT(obd->md_stats == NULL);
+        LASSERT(obd->obd_proc_entry != NULL);
+        LASSERT(obd->md_cntr_base == 0);
+
+        num_stats = 1 + MD_COUNTER_OFFSET(delete_inode) +
+                num_private_stats;
+        stats = lprocfs_alloc_stats(num_stats);
+        if (stats == NULL)
+                return -ENOMEM;
+
+        LPROCFS_MD_OP_INIT(num_private_stats, stats, getstatus);
+        LPROCFS_MD_OP_INIT(num_private_stats, stats, change_cbdata);
+        LPROCFS_MD_OP_INIT(num_private_stats, stats, change_cbdata_name);
+        LPROCFS_MD_OP_INIT(num_private_stats, stats, close);
+        LPROCFS_MD_OP_INIT(num_private_stats, stats, create);
+        LPROCFS_MD_OP_INIT(num_private_stats, stats, done_writing);
+        LPROCFS_MD_OP_INIT(num_private_stats, stats, enqueue);
+        LPROCFS_MD_OP_INIT(num_private_stats, stats, getattr);
+        LPROCFS_MD_OP_INIT(num_private_stats, stats, access_check);
+        LPROCFS_MD_OP_INIT(num_private_stats, stats, getattr_lock);
+        LPROCFS_MD_OP_INIT(num_private_stats, stats, intent_lock);
+        LPROCFS_MD_OP_INIT(num_private_stats, stats, link);
+        LPROCFS_MD_OP_INIT(num_private_stats, stats, rename);
+        LPROCFS_MD_OP_INIT(num_private_stats, stats, setattr);
+        LPROCFS_MD_OP_INIT(num_private_stats, stats, sync);
+        LPROCFS_MD_OP_INIT(num_private_stats, stats, readpage);
+        LPROCFS_MD_OP_INIT(num_private_stats, stats, unlink);
+        LPROCFS_MD_OP_INIT(num_private_stats, stats, valid_attrs);
+        LPROCFS_MD_OP_INIT(num_private_stats, stats, get_real_obd);
+        LPROCFS_MD_OP_INIT(num_private_stats, stats, req2lustre_md);
+        LPROCFS_MD_OP_INIT(num_private_stats, stats, set_open_replay_data);
+        LPROCFS_MD_OP_INIT(num_private_stats, stats, clear_open_replay_data);
+        LPROCFS_MD_OP_INIT(num_private_stats, stats, store_inode_generation);
+        LPROCFS_MD_OP_INIT(num_private_stats, stats, set_lock_data);
+        LPROCFS_MD_OP_INIT(num_private_stats, stats, delete_inode);
+
+        for (i = num_private_stats; i < num_stats; i++) {
+                if (stats->ls_percpu[0]->lp_cntr[i].lc_name == NULL) {
+                        CERROR("Missing md_stat initializer md_op "
+                               "operation at offset %d. Aborting.\n",
+                               i - num_private_stats);
+                        LBUG();
+                }
+        }
+        rc = lprocfs_register_stats(obd->obd_proc_entry, "stats", stats);
+        if (rc < 0) {
+                lprocfs_free_stats(stats);
+        } else {
+                obd->md_stats  = stats;
+                obd->md_cntr_base = num_private_stats;
+        }
+        return rc;
+}
+
+void lprocfs_free_md_stats(struct obd_device *obd)
+{
+        struct lprocfs_stats *stats = obd->md_stats;
+
+        if (stats != NULL) {
+                obd->md_stats = NULL;
+                lprocfs_free_stats(stats);
+        }
+}
+
 int lprocfs_write_helper(const char *buffer, unsigned long count,
                          int *val)
 {
         char kernbuf[20], *end;
-        
+
         if (count > (sizeof(kernbuf) - 1))
                 return -EINVAL;
 
@@ -691,7 +808,10 @@ int lprocfs_write_u64_helper(const char *buffer, unsigned long count,
 
         kernbuf[count] = '\0';
 
-        *val = simple_strtoull(kernbuf, &end, 0);
+        if (kernbuf[0] == '-')
+                *val = -simple_strtoull(kernbuf + 1, &end, 0);
+        else
+                *val = simple_strtoull(kernbuf, &end, 0);
         if (kernbuf == end)
                 return -EINVAL;
 
@@ -758,6 +878,120 @@ void lprocfs_oh_clear(struct obd_histogram *oh)
 }
 EXPORT_SYMBOL(lprocfs_oh_clear);
 
+/* XXX copied from ldlm/ldlm_lockd.c, copied from ptlrpc/service.c */
+static long timeval_sub(struct timeval *large, struct timeval *small)
+{
+        return ((large->tv_sec - small->tv_sec) * 1000000) +
+                (large->tv_usec - small->tv_usec);
+}
+
+void lprocfs_stime_record(struct obd_service_time *stime, struct timeval *large,
+                          struct timeval *small)
+{
+        long diff = timeval_sub(large, small);
+
+        if (diff < 0)
+                return;
+
+        stime->st_num++;
+        stime->st_total_us += diff;
+}
+EXPORT_SYMBOL(lprocfs_stime_record);
+
+unsigned long lprocfs_stime_avg_ms(struct obd_service_time *stime)
+{
+        struct obd_service_time copy;
+
+        memcpy(&copy, stime, sizeof(copy));
+        if (copy.st_num > 0) {
+                do_div(copy.st_total_us, copy.st_num * 1000);
+                return (unsigned long)copy.st_total_us;
+        }
+        return 0;
+}
+EXPORT_SYMBOL(lprocfs_stime_avg_ms);
+
+unsigned long lprocfs_stime_avg_us(struct obd_service_time *stime)
+{
+        struct obd_service_time copy;
+        __u32 remainder;
+
+        memcpy(&copy, stime, sizeof(copy));
+        if (copy.st_num > 0) {
+                do_div(copy.st_total_us, copy.st_num);
+                remainder = do_div(copy.st_total_us, 1000);
+                return (unsigned long)remainder;
+        }
+        return 0;
+}
+EXPORT_SYMBOL(lprocfs_stime_avg_us);
+
+int lprocfs_obd_rd_recovery_status(char *page, char **start, off_t off,
+                                          int count, int *eof, void *data)
+{
+        struct obd_device *obd = data;
+        int len = 0, n,
+                connected = obd->obd_connected_clients,
+                max_recoverable = obd->obd_max_recoverable_clients,
+                recoverable = obd->obd_recoverable_clients,
+                completed = max_recoverable - recoverable,
+                queue_len = obd->obd_requests_queued_for_recovery,
+                replayed = obd->obd_replayed_requests;
+        __u64 next_transno = obd->obd_next_recovery_transno;
+
+        LASSERT(obd != NULL);
+        *eof = 1;
+
+        n = snprintf(page, count, "status: ");
+        page += n; len += n; count -= n;
+        if (obd->obd_max_recoverable_clients == 0) {
+                n = snprintf(page, count, "INACTIVE\n");
+                return len + n;
+        }
+
+        /* sampled unlocked, but really... */
+        if (obd->obd_recovering == 0) {
+                n = snprintf(page, count, "COMPLETE\n");
+                page += n; len += n; count -= n;
+
+                n = snprintf(page, count, "recovery_start: %lu\n",
+                             obd->obd_recovery_start);
+                page += n; len += n; count -= n;
+                n = snprintf(page, count, "recovery_end: %lu\n",
+                             obd->obd_recovery_end);
+                page += n; len += n; count -= n;
+                n = snprintf(page, count, "recovered_clients: %d\n",
+                             completed);
+                page += n; len += n; count -= n;
+                n = snprintf(page, count, "unrecovered_clients: %d\n",
+                             obd->obd_recoverable_clients);
+                page += n; len += n; count -= n;
+                n = snprintf(page, count, "last_transno: "LPD64"\n",
+                             next_transno - 1);
+                page += n; len += n; count -= n;
+                n = snprintf(page, count, "replayed_requests: %d\n", replayed);
+                return len + n;
+        }
+
+        n = snprintf(page, count, "RECOVERING\n");
+        page += n; len += n; count -= n;
+        n = snprintf(page, count, "recovery_start: %lu\n",
+                     obd->obd_recovery_start);
+        page += n; len += n; count -= n;
+        n = snprintf(page, count, "connected_clients: %d/%d\n",
+                     connected, max_recoverable);
+        page += n; len += n; count -= n;
+        n = snprintf(page, count, "completed_clients: %d/%d\n",
+                     completed, max_recoverable);
+        page += n; len += n; count -= n;
+        n = snprintf(page, count, "replayed_requests: %d/??\n", replayed);
+        page += n; len += n; count -= n;
+        n = snprintf(page, count, "queued_requests: %d\n", queue_len);
+        page += n; len += n; count -= n;
+        n = snprintf(page, count, "next_transno: "LPD64"\n", next_transno);
+        return len + n;
+}
+EXPORT_SYMBOL(lprocfs_obd_rd_recovery_status);
 #endif /* LPROCFS*/
 
 EXPORT_SYMBOL(lprocfs_register);
@@ -771,6 +1005,8 @@ EXPORT_SYMBOL(lprocfs_free_stats);
 EXPORT_SYMBOL(lprocfs_register_stats);
 EXPORT_SYMBOL(lprocfs_alloc_obd_stats);
 EXPORT_SYMBOL(lprocfs_free_obd_stats);
+EXPORT_SYMBOL(lprocfs_alloc_md_stats);
+EXPORT_SYMBOL(lprocfs_free_md_stats);
 
 EXPORT_SYMBOL(lprocfs_rd_u64);
 EXPORT_SYMBOL(lprocfs_rd_uuid);
@@ -778,14 +1014,15 @@ EXPORT_SYMBOL(lprocfs_rd_name);
 EXPORT_SYMBOL(lprocfs_rd_fstype);
 EXPORT_SYMBOL(lprocfs_rd_server_uuid);
 EXPORT_SYMBOL(lprocfs_rd_conn_uuid);
+EXPORT_SYMBOL(lprocfs_rd_num_exports);
 EXPORT_SYMBOL(lprocfs_rd_numrefs);
 
 EXPORT_SYMBOL(lprocfs_rd_blksize);
 EXPORT_SYMBOL(lprocfs_rd_kbytestotal);
 EXPORT_SYMBOL(lprocfs_rd_kbytesfree);
+EXPORT_SYMBOL(lprocfs_rd_kbytesavail);
 EXPORT_SYMBOL(lprocfs_rd_filestotal);
 EXPORT_SYMBOL(lprocfs_rd_filesfree);
-EXPORT_SYMBOL(lprocfs_rd_filegroups);
 
 EXPORT_SYMBOL(lprocfs_write_helper);
 EXPORT_SYMBOL(lprocfs_write_u64_helper);