Whamcloud - gitweb
Add some basic data integrity checking to obdecho.
authoradilger <adilger>
Mon, 19 Aug 2002 21:51:33 +0000 (21:51 +0000)
committeradilger <adilger>
Mon, 19 Aug 2002 21:51:33 +0000 (21:51 +0000)
This puts the offset and objid into the first 16 bytes and last 16 bytes
of the bulk transfer.  These are in HTON__u64() format.

The lctl command for test_brw now takes an objid instead of an obdo count,
so that you can (potentially) use lctl with test_brw on a real OBD instead
of just obdecho.  That has not been tested yet.

lustre/include/linux/lustre_debug.h
lustre/include/linux/obd.h
lustre/lib/debug.c
lustre/obdclass/Makefile.am
lustre/obdclass/class_obd.c
lustre/obdecho/echo.c
lustre/utils/lctl.c
lustre/utils/obd.c
lustre/utils/obdctl.c

index a31430d..756d32e 100644 (file)
@@ -48,4 +48,6 @@ int dump_rniobuf(struct niobuf_remote *rnb);
 int dump_ioo(struct obd_ioobj *nb);
 int dump_req(struct ptlrpc_request *req);
 int dump_obdo(struct obdo *oa);
+int page_debug_setup(void *addr, int len, __u64 off, __u64 id);
+int page_debug_check(char *who, void *addr, int len, __u64 off, __u64 id);
 #endif
index 0b17ad4..8474b78 100644 (file)
@@ -278,4 +278,9 @@ struct obd_ops {
         int (*o_cancel)(struct lustre_handle *, struct lov_stripe_md *md, __u32 mode, struct lustre_handle *);
 };
 
+/* FIXME: for 64-bit arch */
+#define LPU64 "%Lu"
+#define LPD64 "%Ld"
+#define LPX64 "%Lx"
+
 #endif
index c3a2721..cd0d5e2 100644 (file)
 
 #define DEBUG_SUBSYSTEM D_OTHER
 
+#define EXPORT_SYMTAB
 #include <linux/obd_ost.h>
 #include <linux/lustre_debug.h>
+#include <linux/lustre_net.h>
 
 int dump_ioo(struct obd_ioobj *ioo)
 {
@@ -73,17 +75,78 @@ int dump_obdo(struct obdo *oa)
 }
 
 /* XXX assumes only a single page in request */
+/*
 int dump_req(struct ptlrpc_request *req)
 {
         struct ost_body *body = lustre_msg_buf(req->rq_reqmsg, 0);
         struct obd_ioobj *ioo = lustre_msg_buf(req->rq_reqmsg, 1);
         //struct niobuf *nb = lustre_msg_buf(req->rq_reqmsg, 2);
 
-        CERROR("ost_body: connid = %d, data = %d\n", body->connid, body->data);
         dump_obdo(&body->oa);
         //dump_niobuf(nb);
         dump_ioo(ioo);
 
         return -EINVAL;
 }
+*/
 
+#define LPDS sizeof(__u64)
+int page_debug_setup(void *addr, int len, __u64 off, __u64 id)
+{
+        LASSERT(addr);
+
+        off = HTON__u64(off);
+        id = HTON__u64(id);
+        memcpy(addr, (char *)&off, LPDS);
+        memcpy(addr + LPDS, (char *)&id, LPDS);
+
+        addr += len - LPDS - LPDS;
+        memcpy(addr, (char *)&off, LPDS);
+        memcpy(addr + LPDS, (char *)&id, LPDS);
+
+        return 0;
+}
+
+int page_debug_check(char *who, void *addr, int end, __u64 off, __u64 id)
+{
+        __u64 ne_off;
+        int err = 0;
+
+        LASSERT(addr);
+
+        ne_off = HTON__u64(off);
+        id = HTON__u64(id);
+        if (memcmp(addr, (char *)&ne_off, LPDS)) {
+                CERROR("%s: for offset "LPU64" off: "LPX64" != "LPX64"\n",
+                       who, off, *(__u64 *)addr, ne_off);
+                err = -EINVAL;
+        }
+        if (memcmp(addr + LPDS, (char *)&id, LPDS)) {
+                CERROR("%s: for offset "LPU64" id: "LPX64" != "LPX64"\n",
+                       who, off, *(__u64 *)(addr + LPDS), id);
+                err = -EINVAL;
+        }
+
+        addr += end - LPDS - LPDS;
+        if (memcmp(addr, (char *)&ne_off, LPDS)) {
+                CERROR("%s: for offset "LPU64" end off: "LPX64" != "LPX64"\n",
+                       who, off, *(__u64 *)addr, ne_off);
+                err = -EINVAL;
+        }
+        if (memcmp(addr + LPDS, (char *)&id, LPDS)) {
+                CERROR("%s: for offset "LPU64" end id: "LPX64" != "LPX64"\n",
+                       who, off, *(__u64 *)(addr + LPDS), id);
+                err = -EINVAL;
+        }
+
+        return err;
+}
+#undef LPDS
+
+EXPORT_SYMBOL(dump_lniobuf);
+EXPORT_SYMBOL(dump_rniobuf);
+EXPORT_SYMBOL(dump_ioo);
+//EXPORT_SYMBOL(dump_req);
+EXPORT_SYMBOL(dump_obdo);
+EXPORT_SYMBOL(page_debug_setup);
+EXPORT_SYMBOL(page_debug_check);
index bfb8e15..40f997f 100644 (file)
@@ -2,7 +2,11 @@ DEFS=
 MODULE = obdclass
 modulefs_DATA = obdclass.o
 EXTRA_PROGRAMS = obdclass
-obdclass_SOURCES = genops.c proc_lustre.c class_obd.c sysctl.c page.c uuid.c
+LINX=page.c debug.c
+obdclass_SOURCES = genops.c proc_lustre.c class_obd.c sysctl.c uuid.c $(LINX)
+
+debug.c: 
+       test -e debug.c || ln -sf $(top_srcdir)/lib/debug.c
 
 page.c: 
        test -e page.c || ln -sf $(top_srcdir)/lib/page.c
index d140511..69a99eb 100644 (file)
@@ -40,6 +40,7 @@
 
 #include <linux/obd_support.h>
 #include <linux/obd_class.h>
+#include <linux/lustre_debug.h>
 #include <linux/smp_lock.h>
 
 struct semaphore obd_conf_sem;   /* serialize configuration commands */
@@ -99,6 +100,7 @@ static int obd_class_ioctl (struct inode * inode, struct file * filp,
         int len = 0;
         struct obd_ioctl_data *data;
         struct obd_device *obd = filp->private_data;
+        
         struct lustre_handle conn;
         int rw = OBD_BRW_READ;
         int err = 0;
@@ -480,17 +482,17 @@ static int obd_class_ioctl (struct inode * inode, struct file * filp,
                 struct lov_stripe_md smd;
                 struct io_cb_data *cbd = ll_init_cb();
                 obd_count       pages = 0;
-                struct brw_page *pga;
+                struct brw_page *pga, *pgp;
                 int             j;
                 unsigned long off;
-                void *from;
-                
+                __u64 id;
+
                 if (!cbd)
-                        GOTO(out, -ENOMEM); 
+                        GOTO(out, err = -ENOMEM);
 
                 obd_data2conn(&conn, data);
 
-                pages = data->ioc_plen1 / PAGE_SIZE;
+                pages = data->ioc_count / PAGE_SIZE;
 
                 CDEBUG(D_INODE, "BRW %s with %d pages\n",
                        rw == OBD_BRW_READ ? "read" : "write", pages);
@@ -501,37 +503,47 @@ static int obd_class_ioctl (struct inode * inode, struct file * filp,
                 }
 
                 memset(&smd, 0, sizeof(smd));
-                smd.lmd_object_id = data->ioc_obdo1.o_id;
+                id = smd.lmd_object_id = data->ioc_obdo1.o_id;
 
-                from = (&data->ioc_pbuf1)[0];
                 off = data->ioc_offset;
 
-                for (j = 0; j < pages;
-                     j++, off += PAGE_SIZE, from += PAGE_SIZE) {
+                for (j = 0, pgp = pga; j < pages; j++, off += PAGE_SIZE, pgp++){
                         unsigned long to;
 
                         to = __get_free_pages(GFP_KERNEL, 0);
                         if (!to) {
-                                /*      ||
-                                        copy_from_user((void
-                                        *)to,from,PAGE_SIZE))
-                                        free_pages(to, 0);
-                                */
                                 CERROR("no memory for brw pages\n");
                                 GOTO(brw_cleanup, err = -ENOMEM);
                         }
-                        pga[j].pg = virt_to_page(to);
-                        pga[j].count = PAGE_SIZE;
-                        pga[j].off = off;
-                        pga[j].flag = 0;
+                        pgp->pg = virt_to_page(to);
+                        pgp->count = PAGE_SIZE;
+                        pgp->off = off;
+                        pgp->flag = 0;
+
+                        if (rw == OBD_BRW_WRITE) {
+                                void *addr = kmap(pgp->pg);
+
+                                LASSERT(addr == (void *)to);
+
+                                page_debug_setup(addr, PAGE_SIZE, off, id);
+                                kunmap(pgp->pg);
+                        }
                 }
 
                 err = obd_brw(rw, &conn, &smd, j, pga, ll_sync_io_cb, cbd);
                 EXIT;
         brw_cleanup:
-                for (j = 0; j < pages; j++)
-                        if (pga[j].pg != NULL)
-                                __free_pages(pga[j].pg, 0);
+                for (j = 0, pgp = pga; j < pages; j++) {
+                        if (pgp->pg != NULL) {
+                                void *addr = kmap(pgp->pg);
+
+                                page_debug_check("test_brw", addr, PAGE_SIZE,
+                                                 pgp->off, id);
+                                kunmap(pgp->pg);
+
+                                __free_pages(pgp->pg, 0);
+                        }
+                }
         brw_free:
                 OBD_FREE(pga, pages * sizeof(*pga));
                 GOTO(out, err);
index dc4b3e7..be305f3 100644 (file)
@@ -11,8 +11,8 @@
  * by Peter Braam <braam@clusterfs.com>
  */
 
-static char rcsid[] __attribute ((unused)) = "$Id: echo.c,v 1.22 2002/08/12 22:25:53 pschwan Exp $";
-#define OBDECHO_VERSION "$Revision: 1.22 $"
+static char rcsid[] __attribute ((unused)) = "$Id: echo.c,v 1.23 2002/08/19 21:51:33 adilger Exp $";
+#define OBDECHO_VERSION "$Revision: 1.23 $"
 
 #define EXPORT_SYMTAB
 
@@ -32,6 +32,7 @@ static char rcsid[] __attribute ((unused)) = "$Id: echo.c,v 1.22 2002/08/12 22:2
 #include <linux/obd_support.h>
 #include <linux/obd_class.h>
 #include <linux/obd_echo.h>
+#include <linux/lustre_debug.h>
 #include <linux/lustre_dlm.h>
 
 extern struct obd_device obd_dev[MAX_OBD_DEVICES];
@@ -50,13 +51,13 @@ echo_proc_read (char *page, char **start, off_t off, int count, int *eof, void *
        int                len;
         int                attrs = atomic_read (&echo_getattrs);
         int                pages = atomic_read (&echo_page_rws);
-       
+
        *eof = 1;
        if (off != 0)
                return (0);
-       
+
        len = sprintf (page, "%d %d\n", pages, attrs);
-       
+
        *start = page;
        return (len);
 }
@@ -67,17 +68,18 @@ echo_proc_write (struct file *file, const char *ubuffer, unsigned long count, vo
        /* Ignore what we've been asked to write, and just zero the stats counters */
         atomic_set (&echo_page_rws, 0);
         atomic_set (&echo_getattrs, 0);
-        
+
        return (count);
 }
 
 void
 echo_proc_init(void)
 {
-        struct proc_dir_entry *entry = create_proc_entry (ECHO_PROC_STAT, S_IFREG | S_IRUGO | S_IWUSR, NULL);
+        struct proc_dir_entry *entry;
+
+        entry = create_proc_entry(ECHO_PROC_STAT, S_IFREG|S_IRUGO|S_IWUSR,NULL);
 
-        if (entry == NULL) 
-       {
+        if (entry == NULL) {
                 CERROR("couldn't create proc entry %s\n", ECHO_PROC_STAT);
                 return;
         }
@@ -87,8 +89,7 @@ echo_proc_init(void)
        entry->write_proc = echo_proc_write;
 }
 
-void 
-echo_proc_fini(void)
+void echo_proc_fini(void)
 {
         remove_proc_entry(ECHO_PROC_STAT, 0);
 }
@@ -118,7 +119,7 @@ static int echo_disconnect(struct lustre_handle *conn)
         return rc;
 }
 
-static int echo_getattr(struct lustre_handle *conn, struct obdo *oa, 
+static int echo_getattr(struct lustre_handle *conn, struct obdo *oa,
                         struct lov_stripe_md *md)
 {
         memcpy(oa, &OA, sizeof(*oa));
@@ -150,11 +151,10 @@ int echo_preprw(int cmd, struct lustre_handle *conn, int objcount,
                 for (j = 0 ; j < obj->ioo_bufcnt ; j++, nb++, r++) {
                         unsigned long address;
 
-                        address = get_zeroed_page(GFP_KERNEL);
+                        address = __get_free_pages(GFP_KERNEL, 0);
                         if (!address) {
-                                CERROR("can't get new page %d/%d for id %Ld\n",
-                                       j, obj->ioo_bufcnt,
-                                       (unsigned long long)obj->ioo_id);
+                                CERROR("can't get page %d/%d for id "LPU64"\n",
+                                       j, obj->ioo_bufcnt, obj->ioo_id);
                                 GOTO(preprw_cleanup, rc = -ENOMEM);
                         }
                         echo_pages++;
@@ -163,6 +163,10 @@ int echo_preprw(int cmd, struct lustre_handle *conn, int objcount,
                         r->page = virt_to_page(address);
                         r->addr = kmap(r->page);
                         r->len = nb->len;
+
+                        if (cmd & OBD_BRW_READ)
+                                page_debug_setup(r->addr, r->len, r->offset,
+                                                 obj->ioo_id);
                 }
         }
         CDEBUG(D_PAGE, "%ld pages allocated after prep\n", echo_pages);
@@ -214,14 +218,17 @@ int echo_commitrw(int cmd, struct lustre_handle *conn, int objcount,
                             !(addr = (unsigned long)page_address(page)) ||
                             !kern_addr_valid(addr)) {
 
-                                CERROR("bad page %p, id %Ld (%d), buf %d/%d\n",
-                                       page, (unsigned long long)obj->ioo_id, i,
-                                       j, obj->ioo_bufcnt);
+                                CERROR("bad page "LPU64":%p, buf %d/%d\n",
+                                       obj->ioo_id, page, j,obj->ioo_bufcnt);
                                 GOTO(commitrw_cleanup, rc = -EFAULT);
                         }
 
                         atomic_inc (&echo_page_rws);
-                        
+
+                        if (cmd & OBD_BRW_WRITE)
+                                page_debug_check("echo", (void *)addr,PAGE_SIZE,
+                                                 r->offset, obj->ioo_id);
+
                         kunmap(page);
                         __free_pages(page, 0);
                         echo_pages--;
@@ -281,21 +288,21 @@ static int __init obdecho_init(void)
         printk(KERN_INFO "Echo OBD driver " OBDECHO_VERSION " info@clusterfs.com\n");
 
         echo_proc_init();
-        
+
         return class_register_type(&echo_obd_ops, OBD_ECHO_DEVICENAME);
 }
 
 static void __exit obdecho_exit(void)
 {
         echo_proc_fini ();
-        
+
         CERROR("%ld prep/commitrw pages leaked\n", echo_pages);
         class_unregister_type(OBD_ECHO_DEVICENAME);
 }
 
 MODULE_AUTHOR("Cluster Filesystems Inc. <info@clusterfs.com>");
 MODULE_DESCRIPTION("Lustre Testing Echo OBD driver " OBDECHO_VERSION);
-MODULE_LICENSE("GPL"); 
+MODULE_LICENSE("GPL");
 
 module_init(obdecho_init);
 module_exit(obdecho_exit);
index bcd723a..8197dc8 100644 (file)
@@ -130,7 +130,7 @@ command_t cmdlist[] = {
          "usage: test_getattr <count> [verbose]"},
         {"test_brw", jt_obd_test_brw, 0,
          "perform count number of bulk read/writes\n"
-         "usage: test_brw <count> [write [verbose [pages [obdos]]]]"},
+         "usage: test_brw <count> [write [verbose [pages [objid]]]]"},
         {"test_ldlm", jt_obd_test_ldlm, 0, "perform lock manager test\n"
          "usage: test_ldlm"},
         {"ldlm_regress_start", jt_obd_ldlm_regress_start, 0,
index 7c628d3..e114989 100644 (file)
@@ -957,10 +957,10 @@ int jt_obd_test_brw(int argc, char **argv)
 {
         struct obd_ioctl_data data;
         struct timeval start, next_time;
-        char *bulk, *b;
-        int pages = 1, obdos = 1, count, next_count;
+        int pages = 1, objid = 3, count, next_count;
         int verbose = 1, write = 0, rw;
-        int i, o, p;
+        long long offset;
+        int i;
         int len;
         int rc = 0;
 
@@ -981,65 +981,26 @@ int jt_obd_test_brw(int argc, char **argv)
         if (argc >= 5)
                 pages = strtoul(argv[4], NULL, 0);
         if (argc >= 6)
-                obdos = strtoul(argv[5], NULL, 0);
-
-        if (obdos != 1 && obdos != 2) {
-                fprintf(stderr, "error: %s: only 1 or 2 obdos supported\n",
-                        cmdname(argv[0]));
-                return -2;
-        }
+                objid = strtoul(argv[5], NULL, 0);
 
         len = pages * PAGE_SIZE;
 
-        bulk = calloc(obdos, len);
-        if (!bulk) {
-                fprintf(stderr, "error: %s: no memory allocating %dx%d pages\n",
-                        cmdname(argv[0]), obdos, pages);
-                return -2;
-        }
         IOCINIT(data);
-        data.ioc_obdo1.o_id = 2;
+        data.ioc_obdo1.o_id = objid;
         data.ioc_count = len;
         data.ioc_offset = 0;
-        data.ioc_plen1 = len;
-        data.ioc_pbuf1 = bulk;
-        if (obdos > 1) {
-                data.ioc_obdo2.o_id = 3;
-                data.ioc_plen2 = len;
-                data.ioc_pbuf2 = bulk + len;
-        }
 
         gettimeofday(&start, NULL);
         next_time.tv_sec = start.tv_sec - verbose;
         next_time.tv_usec = start.tv_usec;
 
         if (verbose != 0)
-                printf("%s: %s %d (%dx%d pages) (testing only): %s",
+                printf("%s: %s %dx%d pages (testing only): %s",
                        cmdname(argv[0]), write ? "writing" : "reading",
-                       count, obdos, pages, ctime(&start.tv_sec));
-
-        /*
-         * We will put in the start time (and loop count inside the loop)
-         * at the beginning of each page so that we will be able to validate
-         * (at some later time) whether the data actually made it or not.
-         *
-         * XXX we do not currently use any of this memory in OBD_IOC_BRW_*
-         *     just to avoid the overhead of the copy_{to,from}_user.  It
-         *     can be fixed if we ever need to send real data around.
-         */
-        for (o = 0, b = bulk; o < obdos; o++)
-                for (p = 0; p < pages; p++, b += PAGE_SIZE)
-                        memcpy(b, &start, sizeof(start));
+                       count, pages, ctime(&start.tv_sec));
 
         rw = write ? OBD_IOC_BRW_WRITE : OBD_IOC_BRW_READ;
-        for (i = 1, next_count = verbose; i <= count; i++) {
-                if (write) {
-                        b = bulk + sizeof(struct timeval);
-                        for (o = 0; o < obdos; o++)
-                                for (p = 0; p < pages; p++, b += PAGE_SIZE)
-                                        memcpy(b, &count, sizeof(count));
-                }
-
+        for (i = 1, next_count = verbose, offset = 0; i <= count; i++) {
                 rc = ioctl(fd, rw, &data);
                 SHMEM_BUMP();
                 if (rc) {
@@ -1051,9 +1012,9 @@ int jt_obd_test_brw(int argc, char **argv)
                            (verbose, &next_time, i, &next_count, count))
                         printf("%s: %s number %d\n", cmdname(argv[0]),
                                write ? "write" : "read", i);
-        }
 
-        free(bulk);
+                data.ioc_offset += len;
+        }
 
         if (!rc) {
                 struct timeval end;
@@ -1065,10 +1026,9 @@ int jt_obd_test_brw(int argc, char **argv)
 
                 --i;
                 if (verbose != 0)
-                        printf("%s: %s %dx%dx%d pages in %.4gs (%.4g pg/s): %s",
+                        printf("%s: %s %dx%d pages in %.4gs (%.4g pg/s): %s",
                                cmdname(argv[0]), write ? "wrote" : "read",
-                               obdos, pages, i, diff,
-                               (double)obdos * i * pages / diff,
+                               i, pages, diff, (double)i * pages / diff,
                                ctime(&end.tv_sec));
         }
         return rc;
index 6714200..241bc30 100644 (file)
@@ -70,7 +70,7 @@ command_t cmdlist[] = {
         {"setattr", jt_obd_setattr, 0, "setattr <id> <mode>"},
         {"newconn", jt_obd_newconn, 0, "newconn [newuuid]"},
         {"test_getattr", jt_obd_test_getattr, 0, "test_getattr <count> [verbose]"},
-        {"test_brw", jt_obd_test_brw, 0, "test_brw <count> [write [verbose]]"},
+        {"test_brw", jt_obd_test_brw, 0, "test_brw <count> [write [verbose [pages [objid]]]]"},
         {"test_ldlm", jt_obd_test_ldlm, 0, "test lock manager (no args)"},
         {"dump_ldlm", jt_obd_dump_ldlm, 0, "dump all lock manager state (no args)"},