Whamcloud - gitweb
- much of the striping configuration managment and setup builds up
authorbraam <braam>
Mon, 1 Jul 2002 07:30:40 +0000 (07:30 +0000)
committerbraam <braam>
Mon, 1 Jul 2002 07:30:40 +0000 (07:30 +0000)
  this patch
- the mds has a new lovconfig command to tell it the UUID's and
  default striping pattern of the targets it needs to use (these are
  the UUID's of the OSC's typically).
- To make this scalable I changed some of the memory management in the
  class ioctl handling
- The LOV device has a trivial attach method and setup only tells it
  what MDC to use to get its information, by giving it the MDC-UUID.
- As discussed before, the MDS really provides the persistent storage
  for the LOV, what little it needs.  So during the obd_connect call
  for the object storage target (which is made from read_super) the
  storage target learns how it is striped and then connects to all the
  targets.
- We are in need of better configuration scripts for this stuff and
  tomorrow we will push the XML configurations a little further.
- Updated the documentation
- Began to cleanup the /proc/lustre/ stuff -- have some neat ideas
  about that and SNMP now.

23 files changed:
lustre/Makefile.am
lustre/configure.in
lustre/include/linux/lustre_idl.h
lustre/include/linux/obd.h
lustre/include/linux/obd_class.h
lustre/include/linux/obd_lov.h
lustre/ldlm/Makefile.am
lustre/lib/lov_pack.c [new file with mode: 0644]
lustre/llite/super.c
lustre/lov/Makefile.am
lustre/lov/lov_obd.c
lustre/mds/Makefile.am
lustre/mds/handler.c
lustre/mds/mds_lov.c [new file with mode: 0644]
lustre/obdclass/class_obd.c
lustre/obdclass/genops.c
lustre/obdclass/proc_lustre.c
lustre/tests/common.sh
lustre/tests/llmountcleanup.sh
lustre/tests/mds.cfg
lustre/utils/obdctl.c
lustre/utils/parser.c
lustre/utils/parser.h

index d9a6945..a43ae23 100644 (file)
@@ -6,8 +6,8 @@
 AUTOMAKE_OPTIONS = foreign
 
 # NOTE: keep extN before mds
-SUBDIRS = utils obdclass ldlm ptlrpc llite lib obdecho mdc osc extN mds ost 
-SUBDIRS+=  tests obdfilter obdfs demos doc scripts 
+SUBDIRS = lov utils obdclass ldlm ptlrpc llite lib obdecho mdc osc extN 
+SUBDIRS+=  mds ost tests obdfilter obdfs demos doc scripts 
 EXTRA_DIST = BUGS FDL Rules include patches
 
 # We get the version from the spec file.
index 2afd890..41c5502 100644 (file)
@@ -14,7 +14,6 @@ AC_PROG_RANLIB
 
 # 
 # Check for required packages
-*
 
 AC_PATH_PROG([XML2_CONFIG], [xml2-config], [],)
 if test -z "$XML2_CONFIG"; then
@@ -89,7 +88,8 @@ AC_SUBST(docdir)
 demodir='$(docdir)/demo'
 AC_SUBST(demodir)
 
-AC_OUTPUT(Makefile lib/Makefile ldlm/Makefile obdecho/Makefile ptlrpc/Makefile \
+AC_OUTPUT(Makefile lov/Makefile lib/Makefile ldlm/Makefile \
+         obdecho/Makefile ptlrpc/Makefile \
        osc/Makefile mdc/Makefile mds/Makefile ost/Makefile utils/Makefile \
        tests/Makefile obdfilter/Makefile obdclass/Makefile \
        llite/Makefile obdfs/Makefile demos/Makefile \
index 50c8c5b..94c8f4f 100644 (file)
  * - ioctl's
  */
 
+/*
+ *  GENERAL STUFF
+ */
+typedef __u8 uuid_t[37];
+
+
+
 #define PTL_RPC_MSG_REQUEST 4711
 #define PTL_RPC_MSG_ERR 4712
 
@@ -217,6 +224,7 @@ struct ost_body {
 #define MDS_DISCONNECT 8
 #define MDS_GETSTATUS  9
 #define MDS_STATFS     10
+#define MDS_LOVINFO    11
 
 #define REINT_SETATTR  1
 #define REINT_CREATE   2
@@ -232,6 +240,23 @@ struct ll_fid {
         __u32 f_type;
 };
 
+
+#define MDS_STATUS_CONN 1
+#define MDS_STATUS_LOV 2
+
+struct mds_status_req { 
+        __u32  flags;
+        __u32  repbuf;
+};
+
+struct mds_conn_status { 
+        struct ll_fid rootfid;
+        __u64          xid;
+        __u64          last_committed;
+        __u64          last_rcvd;
+        /* XXX preallocated quota & obj fields here */
+};
+
 struct mds_body {
         struct ll_fid  fid1;
         struct ll_fid  fid2;
@@ -301,6 +326,19 @@ struct mds_rec_rename {
 };
 
 
+/* 
+ *  LOV data structures
+ */
+
+#define LOV_RAID0  0
+struct lov_desc { 
+        __u32 ld_tgt_count; /* how many OBD's */
+        __u32 ld_default_stripecount;
+        __u32 ld_default_stripesize;   /* in bytes */
+        __u32 ld_pattern; /* RAID 0,1 etc */
+         uuid_t ld_uuid;
+}; 
+
 /*
  *   LDLM requests:
  */
@@ -416,6 +454,7 @@ static inline int obd_ioctl_packlen(struct obd_ioctl_data *data)
         return len;
 }
 
+
 static inline int obd_ioctl_is_invalid(struct obd_ioctl_data *data)
 {
         if (data->ioc_len > (1<<30)) {
@@ -481,6 +520,7 @@ static inline int obd_ioctl_is_invalid(struct obd_ioctl_data *data)
                 printk("OBD ioctl: packlen exceeds ioc_len\n");
                 return 1;
         }
+#if 0 
         if (data->ioc_inllen1 &&
             data->ioc_bulk[data->ioc_inllen1 - 1] != '\0') {
                 printk("OBD ioctl: inlbuf1 not 0 terminated\n");
@@ -497,6 +537,7 @@ static inline int obd_ioctl_is_invalid(struct obd_ioctl_data *data)
                 printk("OBD ioctl: inlbuf3 not 0 terminated\n");
                 return 1;
         }
+#endif 
         return 0;
 }
 
@@ -535,39 +576,45 @@ static inline int obd_ioctl_pack(struct obd_ioctl_data *data, char **pbuf,
 
 
 /* buffer MUST be at least the size of obd_ioctl_hdr */
-static inline int obd_ioctl_getdata(char *buf, int *len, void *arg)
+static inline int obd_ioctl_getdata(char **buf, int *len, void *arg)
 {
-        struct obd_ioctl_hdr *hdr;
+        struct obd_ioctl_hdr hdr;
         struct obd_ioctl_data *data;
         int err;
         ENTRY;
 
-        hdr = (struct obd_ioctl_hdr *)buf;
-        data = (struct obd_ioctl_data *)buf;
 
-        err = copy_from_user(buf, (void *)arg, sizeof(*hdr));
+        err = copy_from_user(&hdr, (void *)arg, sizeof(hdr));
         if ( err ) {
                 EXIT;
                 return err;
         }
 
-        if (hdr->ioc_version != OBD_IOCTL_VERSION) {
+        if (hdr.ioc_version != OBD_IOCTL_VERSION) {
                 printk("OBD: version mismatch kernel vs application\n");
                 return -EINVAL;
         }
 
-        if (hdr->ioc_len > *len) {
+        if (hdr.ioc_len > *len) {
                 printk("OBD: user buffer exceeds kernel buffer\n");
                 return -EINVAL;
         }
 
-
-        if (hdr->ioc_len < sizeof(struct obd_ioctl_data)) {
+        if (hdr.ioc_len < sizeof(struct obd_ioctl_data)) {
                 printk("OBD: user buffer too small for ioctl\n");
                 return -EINVAL;
         }
 
-        err = copy_from_user(buf, (void *)arg, hdr->ioc_len);
+        OBD_ALLOC(*buf, hdr.ioc_len); 
+        if (!*buf) { 
+                CERROR("Cannot allocate control buffer of len %d\n",
+                       hdr.ioc_len); 
+                RETURN(-EINVAL);
+        }
+        *len = hdr.ioc_len;
+        data = (struct obd_ioctl_data *)*buf;
+
+        err = copy_from_user(*buf, (void *)arg, hdr.ioc_len);
         if ( err ) {
                 EXIT;
                 return err;
@@ -629,7 +676,8 @@ static inline int obd_ioctl_getdata(char *buf, int *len, void *arg)
 #define OBD_IOC_UUID2DEV               _IOWR('f', 130, long)
 
 #define OBD_IOC_RECOVD_NEWCONN         _IOWR('f', 131, long)
+#define OBD_IOC_LOV_CONFIG             _IOWR('f', 132, long)
 
-#define OBD_IOC_DEC_FS_USE_COUNT       _IO  ('f', 132      )
+#define OBD_IOC_DEC_FS_USE_COUNT       _IO  ('f', 133      )
 
 #endif
index aab618d..f45ef06 100644 (file)
@@ -152,19 +152,16 @@ struct ost_obd {
 };
 
 
-typedef __u8 uuid_t[37];
+struct lov_tgt_desc { 
+        uuid_t uuid;
+        struct lustre_handle conn; 
+};
 
-#define MAX_MULTI       16
 struct lov_obd {
-        __u32 lov_default_count;
-        __u32 lov_default_pattern;
-        __u32 lov_default_size;
-        uuid_t lov_service_uuids[MAX_MULTI];
-
-#if 0
-        int lov_count;
-        struct lustre_handle *lov_targets;
-#endif
+        struct obd_device *mdcobd;
+        struct lov_desc desc;
+        int bufsize; 
+        struct lov_tgt_desc *tgts;
 };
 
 /* corresponds to one of the obd's */
@@ -178,11 +175,6 @@ struct obd_device {
         int obd_minor;
         int obd_flags;
         struct proc_dir_entry *obd_proc_entry;
-        int obd_multi_count;
-        struct lustre_handle obd_multi_conn[MAX_MULTI];
-        unsigned int obd_gen_last_id;
-        unsigned long obd_gen_prealloc_quota;
-        //        struct obd_device *obd_target; /* for anything that simply layers */ 
         struct list_head obd_exports;
         struct list_head obd_imports;
         struct ldlm_namespace *obd_namespace;
index 3c93a8e..4893907 100644 (file)
@@ -76,8 +76,9 @@ struct obd_export {
         struct list_head export_chain;
         struct obd_device *export_obd;
         struct ptlrpc_connection *export_connection;
-        unsigned int export_id;
         void *export_data; /* device specific data */
+        int export_desclen;
+        char *export_desc;
 };
 
 struct obd_import {
@@ -687,6 +688,7 @@ int class_register_type(struct obd_ops *ops, char *nm);
 int class_unregister_type(char *nm);
 int class_name2dev(char *name);
 int class_uuid2dev(char *name);
+struct obd_device *class_uuid2obd(char *name);
 int class_connect (struct lustre_handle *conn, struct obd_device *obd);
 int class_disconnect(struct lustre_handle *conn);
 struct obd_export *class_conn2export(struct lustre_handle *);
index 9cfbd85..ea6dded 100644 (file)
@@ -9,6 +9,9 @@
 
 #define OBD_LOV_DEVICENAME "lov"
 
+void lov_unpackdesc(struct lov_desc *ld);
+void lov_packdesc(struct lov_desc *ld);
+
 struct lov_object_id { /* per-child structure */
         __u64 l_object_id;
         __u32 l_device_id;
index f9bfc2a..bfc45d2 100644 (file)
@@ -16,6 +16,5 @@ LINX=l_lock.c
 ldlm_SOURCES = l_lock.c ldlm_lock.c ldlm_resource.c ldlm_test.c ldlm_lockd.c \
 ldlm_extent.c ldlm_request.c
 
-
 include $(top_srcdir)/Rules
 
diff --git a/lustre/lib/lov_pack.c b/lustre/lib/lov_pack.c
new file mode 100644 (file)
index 0000000..ad51941
--- /dev/null
@@ -0,0 +1,44 @@
+/* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*-
+ * vim:expandtab:shiftwidth=8:tabstop=8:
+ *
+ *  Copyright (C) 2002 Cluster File Systems, Inc. <adilger@clusterfs.com>
+ *
+ *   This file is part of Lustre, http://www.lustre.org.
+ *
+ *   Lustre is free software; you can redistribute it and/or
+ *   modify it under the terms of version 2 of the GNU General Public
+ *   License as published by the Free Software Foundation.
+ *
+ *   Lustre is distributed in the hope that it will be useful,
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *   GNU General Public License for more details.
+ *
+ *   You should have received a copy of the GNU General Public License
+ *   along with Lustre; if not, write to the Free Software
+ *   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ * (Un)packing of OST/MDS requests
+ *
+ */
+
+#define DEBUG_SUBSYSTEM S_LLITE
+
+#include <linux/lustre_net.h>
+#include <linux/obd_support.h>
+
+void lov_packdesc(struct lov_desc *ld)
+{
+        ld->ld_tgt_count = HTON__u32(ld->ld_tgt_count); 
+        ld->ld_default_stripecount = HTON__u32(ld->ld_default_stripecount); 
+        ld->ld_default_stripesize = HTON__u32(ld->ld_default_stripesize); 
+        ld->ld_pattern = HTON__u32(ld->ld_pattern); 
+}
+
+void lov_unpackdesc(struct lov_desc *ld)
+{
+        ld->ld_tgt_count = NTOH__u32(ld->ld_tgt_count); 
+        ld->ld_default_stripecount = HTON__u32(ld->ld_default_stripecount); 
+        ld->ld_default_stripesize = HTON__u32(ld->ld_default_stripesize); 
+        ld->ld_pattern = HTON__u32(ld->ld_pattern); 
+}
index 8c82b9e..fd2aa8b 100644 (file)
@@ -113,30 +113,14 @@ static struct super_block * ll_read_super(struct super_block *sb,
                 GOTO(out_free, sb = NULL);
         }
 
-        devno = simple_strtoul(ost, NULL, 0);
-        if (devno >= MAX_OBD_DEVICES) {
-                CERROR("devno of %s too high\n", ost);
-                GOTO(out_free, sb = NULL);
-        }
-
-        err = obd_connect(&sbi->ll_osc_conn, &obd_dev[devno]);
-        if (err) {
-                CERROR("cannot connect to %s: rc = %d\n", ost, err);
-                GOTO(out_free, sb = NULL);
-        }
-
         devno = simple_strtoul(mds, NULL, 0);
         if (devno >= MAX_OBD_DEVICES) {
                 CERROR("devno of %s too high\n", mds);
                 GOTO(out_free, sb = NULL);
         }
 
-        err = obd_connect(&sbi->ll_mdc_conn, &obd_dev[devno]);
-        if (err) {
-                CERROR("cannot connect to %s: rc = %d\n", mds, err);
-                GOTO(out_free, sb = NULL);
-        }
-
+        /* First the MDS since an LOV requires an the MDC connection 
+           to find its descriptor */ 
 #if 0
         err = connmgr_connect(ptlrpc_connmgr, sbi->ll_mds_conn);
         if (err) {
@@ -145,8 +129,25 @@ static struct super_block * ll_read_super(struct super_block *sb,
         }
 #endif 
 
+        err = obd_connect(&sbi->ll_mdc_conn, &obd_dev[devno]);
+        if (err) {
+                CERROR("cannot connect to %s: rc = %d\n", mds, err);
+                GOTO(out_free, sb = NULL);
+        }
         sbi2mdc(sbi)->mdc_conn->c_level = LUSTRE_CONN_FULL;
 
+        /* now the OST, which could be an LOV */ 
+        devno = simple_strtoul(ost, NULL, 0);
+        if (devno >= MAX_OBD_DEVICES) {
+                CERROR("devno of %s too high\n", ost);
+                GOTO(out_free, sb = NULL);
+        }
+        err = obd_connect(&sbi->ll_osc_conn, &obd_dev[devno]);
+        if (err) {
+                CERROR("cannot connect to %s: rc = %d\n", ost, err);
+                GOTO(out_free, sb = NULL);
+        }
+
         /* XXX: need to store the last_* values somewhere */
         err = mdc_getstatus(&sbi->ll_mdc_conn,
                             &rootfid, &last_committed, 
index 90d38d4..5d24fc4 100644 (file)
@@ -8,7 +8,11 @@ DEFS :=
 MODULE = lov
 modulefs_DATA = lov.o
 EXTRA_PROGRAMS = lov
+LINX= lov_pack.c
 
-lov_SOURCES = lov_obd.c
+lov_SOURCES = lov_obd.c $(LINX)
+
+lov_pack.c: 
+       test -e lov_pack.c || ln -sf $(top_srcdir)/lib/lov_pack.c
 
 include $(top_srcdir)/Rules
index b5d1054..7f56413 100644 (file)
 #define EXPORT_SYMTAB
 #define DEBUG_SUBSYSTEM S_LOV
 
+#include <linux/slab.h>
 #include <linux/module.h>
+#include <linux/obd_support.h>
+#include <linux/lustre_lib.h>
+#include <linux/lustre_net.h>
+#include <linux/lustre_idl.h>
 #include <linux/obd_class.h>
 #include <linux/obd_lov.h>
 
 extern struct obd_device obd_dev[MAX_OBD_DEVICES];
 
 /* obd methods */
-static int lov_connect(struct lustre_handle *conn)
+
+static int lov_getinfo(struct obd_device *obd, 
+                       struct lov_desc *desc, 
+                       uuid_t **uuids, 
+                       struct ptlrpc_request **request)
+{
+        struct ptlrpc_request *req;
+        struct mds_status_req *streq;
+        struct lov_obd *lov = &obd->u.lov; 
+        struct mdc_obd *mdc = &lov->mdcobd->u.mdc;
+        int rc, size[2] = {sizeof(*streq)};
+        ENTRY;
+
+        req = ptlrpc_prep_req2(mdc->mdc_client, mdc->mdc_conn, &mdc->mdc_connh,
+                               MDS_LOVINFO, 1, size, NULL);
+        if (!req)
+                GOTO(out, rc = -ENOMEM);
+        
+        *request = req;
+        streq = lustre_msg_buf(req->rq_reqmsg, 0);
+        streq->flags = HTON__u32(MDS_STATUS_LOV);
+        streq->repbuf = HTON__u32(8000);
+        
+        /* prepare for reply */ 
+        req->rq_level = LUSTRE_CONN_CON;
+        size[0] = sizeof(*desc); 
+        size[1] = 8000; 
+        req->rq_replen = lustre_msg_size(2, size);
+        
+        rc = ptlrpc_queue_wait(req);
+        rc = ptlrpc_check_status(req, rc);
+
+        if (!rc) {
+                memcpy(desc, lustre_msg_buf(req->rq_repmsg, 0), sizeof(*desc));
+                *uuids = lustre_msg_buf(req->rq_repmsg, 1);
+                lov_unpackdesc(desc); 
+        }
+        EXIT;
+ out:
+        return rc;
+}
+
+static int lov_connect(struct lustre_handle *conn, struct obd_device *obd)
 {
         int rc;
+        int i;
+        struct ptlrpc_request *req;
+        struct lov_obd *lov = &obd->u.lov;
+        uuid_t *uuidarray; 
 
         MOD_INC_USE_COUNT;
-        rc = class_connect(conn);
-
-        if (rc)
+        rc = class_connect(conn, obd);
+        if (rc) { 
                 MOD_DEC_USE_COUNT;
+                RETURN(rc); 
+        }
+        
+        rc = lov_getinfo(obd, &lov->desc, &uuidarray, &req);
+        if (rc) { 
+                CERROR("cannot get lov info %d\n", rc);
+                GOTO(out, rc); 
+        }
+        
+        if (lov->desc.ld_tgt_count > 1000) { 
+                CERROR("configuration error: target count > 1000 (%d)\n",
+                       lov->desc.ld_tgt_count);
+                GOTO(out, rc = -EINVAL); 
+        }
+        
+        if (strcmp(obd->obd_uuid, lov->desc.ld_uuid)) { 
+                CERROR("lov uuid %s not on mds device (%s)\n", 
+                       obd->obd_uuid, lov->desc.ld_uuid);
+                GOTO(out, rc = -EINVAL); 
+        }                
+            
+        if (req->rq_repmsg->bufcount < 2 || req->rq_repmsg->buflens[1] < 
+            sizeof(uuid_t) * lov->desc.ld_tgt_count) { 
+                CERROR("invalid uuid array returned\n");
+                GOTO(out, rc = -EINVAL); 
+        }
+
+        lov->bufsize = sizeof(struct lov_tgt_desc) *  lov->desc.ld_tgt_count; 
+        OBD_ALLOC(lov->tgts, lov->bufsize); 
+        if (!lov->tgts) { 
+                CERROR("Out of memory\n"); 
+                GOTO(out, rc = -ENOMEM); 
+        }
+
+        uuidarray = lustre_msg_buf(req->rq_repmsg, 1); 
+        for (i = 0 ; i < lov->desc.ld_tgt_count; i++) { 
+                memcpy(lov->tgts[i].uuid, uuidarray[i], sizeof(uuid_t)); 
+        }
+
+        for (i = 0 ; i < lov->desc.ld_tgt_count; i++) { 
+                struct obd_device *tgt = class_uuid2obd(uuidarray[i]);
+                if (!tgt) { 
+                        CERROR("Target %s not configured\n", uuidarray[i]); 
+                        GOTO(out_mem, rc = -EINVAL); 
+                }
+                rc = obd_connect(&lov->tgts[i].conn, tgt); 
+                if (rc) { 
+                        CERROR("Target %s connect error %d\n", 
+                               uuidarray[i], rc); 
+                        GOTO(out_mem, rc);
+                }
+        }
 
+ out_mem:
+        if (rc) { 
+                for (i = 0 ; i < lov->desc.ld_tgt_count; i++) { 
+                        rc = obd_disconnect(&lov->tgts[i].conn);
+                        if (rc)
+                                CERROR("Target %s disconnect error %d\n", 
+                                       uuidarray[i], rc); 
+                }
+                OBD_FREE(lov->tgts, lov->bufsize);
+        }
+ out:
+        if (rc) { 
+                class_disconnect(conn);
+        }
+        if (req)
+                ptlrpc_free_req(req); 
         return rc;
+        
 }
 
 static int lov_disconnect(struct lustre_handle *conn)
 {
+        struct obd_device *obd = class_conn2obd(conn);
+        struct lov_obd *lov = &obd->u.lov;
         int rc;
+        int i; 
+
+        if (!lov->tgts)
+                goto out_local;
+
+        for (i = 0 ; i < lov->desc.ld_tgt_count; i++) { 
+                rc = obd_disconnect(&lov->tgts[i].conn);
+                if (rc)
+                        CERROR("Target %s disconnect error %d\n", 
+                               lov->tgts[i].uuid, rc); 
+        }
+        OBD_FREE(lov->tgts, lov->bufsize);
+        lov->bufsize = 0;
+        lov->tgts = NULL; 
+
+ out_local:
 
         rc = class_disconnect(conn);
         if (!rc)
                 MOD_DEC_USE_COUNT;
 
-        /* XXX cleanup preallocated inodes */
         return rc;
 }
 
+static int lov_setup(struct obd_device *obd, obd_count len, void *buf)
+{
+        struct obd_ioctl_data* data = buf;
+        struct lov_obd *lov = &obd->u.lov;
+        int rc = 0;
+        ENTRY;
+
+        if (data->ioc_inllen1 < 1) {
+                CERROR("osc setup requires an MDC UUID\n");
+                RETURN(-EINVAL);
+        }
+
+        if (data->ioc_inllen1 > 37) {
+                CERROR("mdc UUID must be less than 38 characters\n");
+                RETURN(-EINVAL);
+        }
+
+        /* FIXME: we should make a connection instead perhaps to avoid
+           the mdc from walking away? The fs guarantees this. */ 
+        lov->mdcobd = class_uuid2obd(data->ioc_inlbuf1); 
+        if (!lov->mdcobd) { 
+                CERROR("LOV %s cannot locate MDC %s\n", obd->obd_uuid, 
+                       data->ioc_inlbuf1); 
+                rc = -EINVAL;
+        }
+        RETURN(rc); 
+} 
+
+#if 0
 static int lov_getattr(struct lustre_handle *conn, struct obdo *oa)
 {
         int rc;
@@ -389,16 +554,15 @@ static int lov_cancel(struct lustre_handle *conn, __u32 mode,
 #endif
 
 struct obd_ops lov_obd_ops = {
-        o_setup:       class_multi_setup,
-        o_cleanup:     class_multi_cleanup,
-        o_create:      lov_create,
+        o_setup:       lov_setup,
         o_connect:     lov_connect,
         o_disconnect:  lov_disconnect,
+#if 0
+        o_create:      lov_create,
         o_getattr:     lov_getattr,
         o_setattr:     lov_setattr,
         o_open:        lov_open,
         o_close:       lov_close,
-#if 0
         o_destroy:     lov_destroy,
         o_brw:         lov_pgcache_brw,
         o_punch:       lov_punch,
index f5fb932..8d5a486 100644 (file)
@@ -9,20 +9,20 @@ MODULE = mds
 modulefs_DATA = mds.o mds_extN.o # mds_ext2.o mds_ext3.o
 EXTRA_PROGRAMS = mds mds_extN # mds_ext2 mds_ext3
 
-LINX=mds_updates.c simple.c ll_pack.c l_net.c
+LINX= mds_updates.c simple.c ll_pack.c l_net.c lov_pack.c
+
 ll_pack.c: 
        test -e ll_pack.c || ln -sf $(top_srcdir)/lib/ll_pack.c
-
 mds_updates.c: 
        test -e mds_updates.c || ln -sf $(top_srcdir)/lib/mds_updates.c
-
 simple.c: 
        test -e simple.c || ln -sf $(top_srcdir)/lib/simple.c
-
 l_net.c: 
        test -e l_net.c || ln -sf $(top_srcdir)/lib/l_net.c
+lov_pack.c: 
+       test -e lov_pack.c || ln -sf $(top_srcdir)/lib/lov_pack.c
 
-mds_SOURCES = handler.c mds_reint.c mds_fs.c $(LINX)
+mds_SOURCES = mds_lov.c handler.c mds_reint.c mds_fs.c $(LINX)
 
 
 include $(top_srcdir)/Rules
index 48ba352..81a3a31 100644 (file)
@@ -23,6 +23,8 @@
 #include <linux/module.h>
 #include <linux/lustre_mds.h>
 #include <linux/lustre_dlm.h>
+extern int mds_get_lovtgts(struct obd_device *obd, uuid_t *uuidarray);
+extern int mds_get_lovdesc(struct obd_device *obd, struct lov_desc *desc);
 extern int mds_update_last_rcvd(struct mds_obd *mds, void *handle,
                                 struct ptlrpc_request *req);
 static int mds_cleanup(struct obd_device * obddev);
@@ -194,8 +196,8 @@ static int mds_getstatus(struct ptlrpc_request *req)
 
         body = lustre_msg_buf(req->rq_reqmsg, 0);
         mds_unpack_body(body);
-        /* Anything we need to do here with the client's trans no or so? */
 
+        /* Anything we need to do here with the client's trans no or so? */
         body = lustre_msg_buf(req->rq_repmsg, 0);
         memcpy(&body->fid1, &mds->mds_rootfid, sizeof(body->fid1));
 
@@ -233,6 +235,48 @@ static int mds_getstatus(struct ptlrpc_request *req)
         RETURN(0);
 }
 
+static int mds_lovinfo(struct ptlrpc_request *req)
+{
+        struct mds_status_req *streq;
+        struct lov_desc *desc; 
+        int rc, size[2] = {sizeof(*desc)};
+        ENTRY;
+
+        streq = lustre_msg_buf(req->rq_reqmsg, 0); 
+        streq->flags = NTOH__u32(streq->flags); 
+        streq->repbuf = NTOH__u32(streq->repbuf); 
+        size[1] = streq->repbuf;
+
+        rc = lustre_pack_msg(2, size, NULL, &req->rq_replen, &req->rq_repmsg);
+        if (rc) { 
+                CERROR("mds: out of memory for message: size=%d\n", size[1]);
+                req->rq_status = -ENOMEM;
+                RETURN(0);
+        }
+
+        desc = lustre_msg_buf(req->rq_repmsg, 0); 
+        rc = mds_get_lovdesc(req->rq_obd, desc);
+        if (rc != 0 ) { 
+                CERROR("get_lovdesc error %d", rc);
+                req->rq_status = rc;
+                RETURN(0);
+        }
+
+        if (desc->ld_tgt_count * sizeof(uuid_t) > streq->repbuf) { 
+                CERROR("too many targets, enlarge client buffers\n");
+                req->rq_status = -ENOSPC;
+                RETURN(0);
+        }
+
+        rc = mds_get_lovtgts(req->rq_obd, lustre_msg_buf(req->rq_repmsg, 1));
+        if (rc) { 
+                CERROR("get_lovtgts error %d", rc);
+                req->rq_status = rc;
+                RETURN(0);
+        }
+        RETURN(0);
+}
+
 int mds_lock_callback(struct lustre_handle *lockh, struct ldlm_lock_desc *desc,
                       void *data, int data_len, struct ptlrpc_request **reqp)
 {
@@ -709,6 +753,11 @@ int mds_handle(struct ptlrpc_request *req)
                 rc = mds_getstatus(req);
                 break;
 
+        case MDS_LOVINFO:
+                CDEBUG(D_INODE, "lovinfo\n");
+                rc = mds_lovinfo(req);
+                break;
+
         case MDS_GETATTR:
                 CDEBUG(D_INODE, "getattr\n");
                 OBD_FAIL_RETURN(OBD_FAIL_MDS_GETATTR_NET, 0);
@@ -1012,12 +1061,16 @@ static int mds_cleanup(struct obd_device * obddev)
         RETURN(0);
 }
 
+extern int mds_iocontrol(long cmd, struct lustre_handle *conn, 
+                          int len, void *karg, void *uarg);
+
 /* use obd ops to offer management infrastructure */
 static struct obd_ops mds_obd_ops = {
         o_connect:     mds_connect,
         o_disconnect:  mds_disconnect,
         o_setup:       mds_setup,
         o_cleanup:     mds_cleanup,
+        o_iocontrol:   mds_iocontrol
 };
 
 static int __init mds_init(void)
diff --git a/lustre/mds/mds_lov.c b/lustre/mds/mds_lov.c
new file mode 100644 (file)
index 0000000..42fac10
--- /dev/null
@@ -0,0 +1,186 @@
+/* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*-
+ * vim:expandtab:shiftwidth=8:tabstop=8:
+ *
+ *  linux/mds/mds_lov.c
+ *
+ *  Lustre Metadata Server (mds) handling of striped file data
+ *
+ *  Copyright (C) 2001, 2002 Cluster File Systems, Inc.
+ *
+ *  This code is issued under the GNU General Public License.
+ *  See the file COPYING in this distribution
+ *
+ *  by Peter Braam <braam@clusterfs.com> &
+ *
+ */
+
+#define EXPORT_SYMTAB
+#define DEBUG_SUBSYSTEM S_MDS
+
+#include <linux/module.h>
+#include <linux/lustre_mds.h>
+#include <linux/lustre_idl.h>
+#include <linux/obd_lov.h>
+
+int mds_configure_lov(struct obd_device *obd, struct lov_desc *desc, 
+                      uuid_t *uuidarray)
+{
+        struct mds_obd *mds = &obd->u.mds;
+        struct obd_run_ctxt saved;
+        struct file *f;
+        loff_t off = 0;
+        int count;
+        int rc;
+        int i;
+
+        count = desc->ld_tgt_count;
+        lov_packdesc(desc); 
+
+        push_ctxt(&saved, &mds->mds_ctxt);
+        f = filp_open("LOVDESC", O_CREAT|O_RDWR, 0644);
+        if (!f || IS_ERR(f)) { 
+                pop_ctxt(&saved); 
+                CERROR("Cannot open/create LOVDESC file\n");
+                RETURN(-EIO);
+        }
+        
+        rc = lustre_fwrite(f, (char *)desc, sizeof(*desc), &off); 
+        filp_close(f, 0);
+        if (rc != sizeof(*desc)) { 
+                pop_ctxt(&saved); 
+                CERROR("Cannot open/create LOVDESC file\n");
+                RETURN(-EIO);
+        }
+
+        off = 0;
+        f = filp_open("LOVTGTS", O_CREAT|O_RDWR, 0644);
+        if (!f || IS_ERR(f)) { 
+                pop_ctxt(&saved); 
+                CERROR("Cannot open/create LOVDESC file\n");
+                RETURN(-EIO);
+        }
+
+        for (i=0 ; i < count ; i++) { 
+                rc = lustre_fwrite(f, uuidarray[i], 
+                                   sizeof(uuidarray[i]), &off); 
+                if (rc != sizeof(uuidarray[i])) { 
+                        CERROR("cannot write LOV UUID %s (%d)\n",
+                               uuidarray[i], i);
+                        break;
+                }
+                rc = 0; 
+        }
+        filp_close(f, 0);
+        pop_ctxt(&saved); 
+
+        RETURN(rc); 
+}
+
+int mds_get_lovdesc(struct obd_device *obd, struct lov_desc *desc)
+{
+        struct mds_obd *mds = &obd->u.mds;
+        struct obd_run_ctxt saved;
+        struct file *f;
+        loff_t off = 0;
+        int rc, rc2;
+
+        push_ctxt(&saved, &mds->mds_ctxt);
+        f = filp_open("LOVDESC", O_RDONLY, 0644);
+        if (!f || IS_ERR(f)) { 
+                CERROR("Cannot open LOVDESC file\n");
+                pop_ctxt(&saved); 
+                RETURN(-EIO);
+        }
+        
+        rc = lustre_fread(f, (char *)desc, sizeof(*desc), &off); 
+        rc2 = filp_close(f, 0);
+        if (rc2) { 
+                CERROR("Error closing LOVDESC file %d\n", rc); 
+        }
+        if (rc != sizeof(*desc)) { 
+                CERROR("Cannot read LOVDESC file\n");
+                pop_ctxt(&saved); 
+                RETURN(-EIO);
+        }
+        pop_ctxt(&saved); 
+
+        RETURN(0); 
+}
+
+int mds_get_lovtgts(struct obd_device *obd, uuid_t *uuidarray)
+{
+        struct mds_obd *mds = &obd->u.mds;
+        struct obd_run_ctxt saved;
+        struct lov_desc desc; 
+        struct file *f;
+        loff_t off = 0;
+        int rc;
+        int rc2;
+        int count;
+
+        rc = mds_get_lovdesc(obd, &desc); 
+        if (rc) { 
+                CERROR("cannot get descriptor\n"); 
+                RETURN(-EIO); 
+        }
+
+        push_ctxt(&saved, &mds->mds_ctxt);
+        f = filp_open("LOVTGTS", O_RDONLY, 0644);
+        if (!f || IS_ERR(f)) { 
+                CERROR("Cannot open LOVTGTS file\n");
+                pop_ctxt(&saved); 
+                RETURN(-EIO);
+        }
+
+        lov_unpackdesc(&desc); 
+        count = desc.ld_tgt_count;
+
+        off = 0;
+        rc = lustre_fread(f, (char *)uuidarray, count * sizeof(uuid_t), 
+                          &off); 
+        rc2 = filp_close(f, 0);
+        if (rc2) { 
+                CERROR("Error closing LOVTGTS file %d\n", rc); 
+        }
+        if (rc != count * sizeof(uuid_t)) { 
+                CERROR("Error reading LOVTGTS file\n");
+                pop_ctxt(&saved); 
+                RETURN(-EIO);
+        }
+        pop_ctxt(&saved); 
+
+        RETURN(0); 
+}
+
+int mds_iocontrol(long cmd, struct lustre_handle *conn, 
+                          int len, void *karg, void *uarg)
+{
+        struct obd_device *obd = class_conn2obd(conn);
+        struct obd_ioctl_data *data = karg;
+        struct lov_desc *desc; 
+        int count; 
+        int rc; 
+
+
+        switch (cmd) { 
+        case OBD_IOC_LOV_CONFIG:
+                desc = (struct lov_desc *)data->ioc_inlbuf1;
+                if (sizeof(*desc) > data->ioc_inllen1) { 
+                        CERROR("descriptor size wrong\n");
+                        RETURN(-EINVAL); 
+                }
+
+                count = desc->ld_tgt_count;
+                if (sizeof(uuid_t) * count != data->ioc_inllen2) { 
+                        CERROR("UUID array size wrong\n");
+                        RETURN(-EINVAL); 
+                }
+                rc = mds_configure_lov(obd, desc, (uuid_t *)data->ioc_inlbuf2);
+
+                RETURN(rc); 
+        default:
+                RETURN(-EINVAL); 
+        }
+
+        RETURN(0);
+}
index 5cbacde..66e830b 100644 (file)
 
 #include <linux/obd_support.h>
 #include <linux/obd_class.h>
+#include <linux/smp_lock.h>
 
+struct semaphore obd_conf_sem;   /* serialize configuration commands */ 
 struct obd_device obd_dev[MAX_OBD_DEVICES];
-extern struct obd_type *class_nm_to_type(char *nm);
 struct list_head obd_types;
-
 unsigned long obd_memory = 0;
 unsigned long obd_fail_loc = 0;
 
+extern struct obd_type *class_nm_to_type(char *nm);
 
 /*  opening /dev/obd */
 static int obd_class_open(struct inode * inode, struct file * file)
@@ -87,13 +88,13 @@ inline void obd_conn2data(struct obd_ioctl_data *data, struct lustre_handle *con
         data->ioc_cookie = conn->cookie;
 }
 
+
 /* to control /dev/obd */
 static int obd_class_ioctl (struct inode * inode, struct file * filp,
                             unsigned int cmd, unsigned long arg)
 {
-        /* NOTE this must be larger than any of the ioctl data structs */
-        char buf[1024];
-        int len = 1024;
+        char *buf;
+        int len;
         struct obd_ioctl_data *data;
         struct obd_device *obd = filp->private_data;
         struct lustre_handle conn;
@@ -101,43 +102,43 @@ static int obd_class_ioctl (struct inode * inode, struct file * filp,
         int err = 0;
         ENTRY;
 
-        memset(buf, 0, sizeof(buf));
+        down(&obd_conf_sem); 
 
         if (!obd && cmd != OBD_IOC_DEVICE && cmd != TCGETS &&
             cmd != OBD_IOC_LIST &&
             cmd != OBD_IOC_NAME2DEV && cmd != OBD_IOC_NEWDEV) {
                 CERROR("OBD ioctl: No device\n");
-                RETURN(-EINVAL);
+                GOTO(out, err=-EINVAL);
         }
-        if (obd_ioctl_getdata(buf, &len, (void *)arg)) {
+        if (obd_ioctl_getdata(&buf, &len, (void *)arg)) {
                 CERROR("OBD ioctl: data error\n");
-                RETURN(-EINVAL);
+                GOTO(out, err=-EINVAL);
         }
         data = (struct obd_ioctl_data *)buf;
 
         switch (cmd) {
         case TCGETS:
-                RETURN(-EINVAL);
+                GOTO(out, err=-EINVAL);
         case OBD_IOC_DEVICE: {
                 CDEBUG(D_IOCTL, "\n");
                 if (data->ioc_dev >= MAX_OBD_DEVICES || data->ioc_dev < 0) {
                         CERROR("OBD ioctl: DEVICE insufficient devices\n");
-                        RETURN(-EINVAL);
+                        GOTO(out, err=-EINVAL);
                 }
                 CDEBUG(D_IOCTL, "device %d\n", data->ioc_dev);
 
                 filp->private_data = &obd_dev[data->ioc_dev];
-                RETURN(0);
+                GOTO(out, err=0);
         }
 
         case OBD_IOC_LIST: {
                 int i;
-                char *buf = data->ioc_bulk;
+                char *buf2 = data->ioc_bulk;
                 int remains = data->ioc_inllen1;
 
                 if (!data->ioc_inlbuf1) {
                         CERROR("No buffer passed!\n");
-                        RETURN(-EINVAL);
+                        GOTO(out, err=-EINVAL);
                 }
 
 
@@ -146,10 +147,10 @@ static int obd_class_ioctl (struct inode * inode, struct file * filp,
                         struct obd_device *obd = &obd_dev[i];
                         if (!obd->obd_type) 
                                 continue;
-                        l = snprintf(buf, remains, "%2d %s %s %s\n",
+                        l = snprintf(buf2, remains, "%2d %s %s %s\n",
                                      i, obd->obd_type->typ_name, 
                                      obd->obd_name, obd->obd_uuid);
-                        buf +=l;
+                        buf2 +=l;
                         remains -=l;
                         if (remains <= 0) { 
                                 CERROR("not enough space for device listing\n");
@@ -158,7 +159,7 @@ static int obd_class_ioctl (struct inode * inode, struct file * filp,
                 }
 
                 err = copy_to_user((int *)arg, data, len);
-                RETURN(err);
+                GOTO(out, err);
         }
 
 
@@ -168,23 +169,28 @@ static int obd_class_ioctl (struct inode * inode, struct file * filp,
                  */
                 int dev;
 
-                if (!data->ioc_inlbuf1) {
-                        CERROR("No name passed!\n");
-                        RETURN(-EINVAL);
+                if (!data->ioc_inllen1 || !data->ioc_inlbuf1 ) {
+                        CERROR("No name passed,!\n");
+                        GOTO(out, err=-EINVAL);
                 }
+                if (data->ioc_inlbuf1[data->ioc_inllen1-1] !=0) {
+                        CERROR("Name not nul terminated!\n");
+                        GOTO(out, err=-EINVAL);
+                }
+
                 CDEBUG(D_IOCTL, "device name %s\n", data->ioc_inlbuf1);
                 dev = class_name2dev(data->ioc_inlbuf1);
                 data->ioc_dev = dev;
                 if (dev == -1) {
                         CDEBUG(D_IOCTL, "No device for name %s!\n",
                                data->ioc_inlbuf1);
-                        RETURN(-EINVAL);
+                        GOTO(out, err=-EINVAL);
                 }
 
                 CDEBUG(D_IOCTL, "device name %s, dev %d\n", data->ioc_inlbuf1,
                        dev);
                 err = copy_to_user((int *)arg, data, sizeof(*data));
-                RETURN(err);
+                GOTO(out, err);
         }
 
         case OBD_IOC_UUID2DEV: {
@@ -193,23 +199,28 @@ static int obd_class_ioctl (struct inode * inode, struct file * filp,
                  */
                 int dev;
 
-                if (!data->ioc_inlbuf1) {
+                if (!data->ioc_inllen1 || !data->ioc_inlbuf1) {
                         CERROR("No UUID passed!\n");
-                        RETURN(-EINVAL);
+                        GOTO(out, err=-EINVAL);
                 }
+                if (data->ioc_inlbuf1[data->ioc_inllen1-1] !=0) {
+                        CERROR("Name not nul terminated!\n");
+                        GOTO(out, err=-EINVAL);
+                }
+
                 CDEBUG(D_IOCTL, "device name %s\n", data->ioc_inlbuf1);
                 dev = class_uuid2dev(data->ioc_inlbuf1);
                 data->ioc_dev = dev;
                 if (dev == -1) {
                         CDEBUG(D_IOCTL, "No device for name %s!\n",
                                data->ioc_inlbuf1);
-                        RETURN(-EINVAL);
+                        GOTO(out, err=-EINVAL);
                 }
 
                 CDEBUG(D_IOCTL, "device name %s, dev %d\n", data->ioc_inlbuf1,
                        dev);
                 err = copy_to_user((int *)arg, data, sizeof(*data));
-                RETURN(err);
+                GOTO(out, err);
         }
 
         case OBD_IOC_NEWDEV: {
@@ -229,10 +240,10 @@ static int obd_class_ioctl (struct inode * inode, struct file * filp,
 
                 data->ioc_dev = dev;
                 if (dev == -1)
-                        RETURN(-EINVAL);
+                        GOTO(out, err=-EINVAL);
 
                 err = copy_to_user((int *)arg, data, sizeof(*data));
-                RETURN(err);
+                GOTO(out, err);
         }
 
         case OBD_IOC_ATTACH: {
@@ -242,7 +253,16 @@ static int obd_class_ioctl (struct inode * inode, struct file * filp,
                 if (obd->obd_flags & OBD_ATTACHED) {
                         CERROR("OBD: Device %d already typed as %s.\n",
                                obd->obd_minor, MKSTR(obd->obd_type->typ_name));
-                        RETURN(-EBUSY);
+                        GOTO(out, err=-EBUSY);
+                }
+
+                if (!data->ioc_inllen1 || !data->ioc_inlbuf1) {
+                        CERROR("No type passed!\n");
+                        GOTO(out, err=-EINVAL);
+                }
+                if (data->ioc_inlbuf1[data->ioc_inllen1-1] !=0) {
+                        CERROR("Type not nul terminated!\n");
+                        GOTO(out, err=-EINVAL);
                 }
 
                 CDEBUG(D_IOCTL, "attach type %s name: %s uuid: %s\n", 
@@ -250,14 +270,14 @@ static int obd_class_ioctl (struct inode * inode, struct file * filp,
                        MKSTR(data->ioc_inlbuf2), MKSTR(data->ioc_inlbuf3));
 
                 /* find the type */
+
                 type = class_nm_to_type(data->ioc_inlbuf1);
                 if (!type) {
                         CERROR("OBD: unknown type dev %d\n", obd->obd_minor);
-                        RETURN(-EINVAL);
+                        GOTO(out, err=-EINVAL);
                 }
 
                 obd->obd_type = type;
-                obd->obd_multi_count = 0;
                 INIT_LIST_HEAD(&obd->obd_exports);
 
                 /* do the attach */
@@ -270,8 +290,6 @@ static int obd_class_ioctl (struct inode * inode, struct file * filp,
                         type->typ_refcnt++;
                         CDEBUG(D_IOCTL, "OBD: dev %d attached type %s\n",
                                obd->obd_minor, data->ioc_inlbuf1);
-                        obd->obd_proc_entry =
-                                proc_lustre_register_obd_device(obd);
                         if (data->ioc_inlbuf2) {
                                 int len = strlen(data->ioc_inlbuf2) + 1;
                                 OBD_ALLOC(obd->obd_name, len + 1);
@@ -280,7 +298,13 @@ static int obd_class_ioctl (struct inode * inode, struct file * filp,
                                         LBUG();
                                 }
                                 memcpy(obd->obd_name, data->ioc_inlbuf2, len + 1);
+                                obd->obd_proc_entry =
+                                        proc_lustre_register_obd_device(obd);
+                        } else { 
+                                CERROR("WARNING: unnamed obd device\n");
+                                obd->obd_proc_entry = NULL;
                         }
+
                         if (data->ioc_inlbuf3) {
                                 int len = strlen(data->ioc_inlbuf3);
                                 if (len > 37) { 
@@ -288,7 +312,7 @@ static int obd_class_ioctl (struct inode * inode, struct file * filp,
                                         if (obd->obd_name)
                                                 OBD_FREE(obd->obd_name, 
                                                          strlen(obd->obd_name) + 1);
-                                        RETURN(-EINVAL);
+                                        GOTO(out, err=-EINVAL);
                                 }
                                 memcpy(obd->obd_uuid, data->ioc_inlbuf3, 
                                        sizeof(obd->obd_uuid));
@@ -297,23 +321,23 @@ static int obd_class_ioctl (struct inode * inode, struct file * filp,
                         MOD_INC_USE_COUNT;
                 }
 
-                RETURN(err);
+                GOTO(out, err);
         }
 
         case OBD_IOC_DETACH: {
                 ENTRY;
                 if (obd->obd_flags & OBD_SET_UP) {
                         CERROR("OBD device %d still set up\n", obd->obd_minor);
-                        RETURN(-EBUSY);
+                        GOTO(out, err=-EBUSY);
                 }
                 if (! (obd->obd_flags & OBD_ATTACHED) ) {
                         CERROR("OBD device %d not attached\n", obd->obd_minor);
-                        RETURN(-ENODEV);
+                        GOTO(out, err=-ENODEV);
                 }
                 if ( !list_empty(&obd->obd_exports) ) {
                         CERROR("OBD device %d has exports\n",
                                obd->obd_minor);
-                        RETURN(-EBUSY);
+                        GOTO(out, err=-EBUSY);
                 }
 
                 if (obd->obd_name) {
@@ -328,21 +352,21 @@ static int obd_class_ioctl (struct inode * inode, struct file * filp,
                 obd->obd_type->typ_refcnt--;
                 obd->obd_type = NULL;
                 MOD_DEC_USE_COUNT;
-                RETURN(0);
+                GOTO(out, err=0);
         }
 
         case OBD_IOC_SETUP: {
                 /* have we attached a type to this device? */
                 if (!(obd->obd_flags & OBD_ATTACHED)) {
                         CERROR("Device %d not attached\n", obd->obd_minor);
-                        RETURN(-ENODEV);
+                        GOTO(out, err=-ENODEV);
                 }
 
                 /* has this been done already? */
                 if ( obd->obd_flags & OBD_SET_UP ) {
                         CERROR("Device %d already setup (type %s)\n",
                                obd->obd_minor, obd->obd_type->typ_name);
-                        RETURN(-EBUSY);
+                        GOTO(out, err=-EBUSY);
                 }
 
                 if ( OBT(obd) && OBP(obd, setup) )
@@ -353,13 +377,13 @@ static int obd_class_ioctl (struct inode * inode, struct file * filp,
                         obd->obd_flags |= OBD_SET_UP;
                 }
 
-                RETURN(err);
+                GOTO(out, err);
         }
         case OBD_IOC_CLEANUP: {
                 /* have we attached a type to this device? */
                 if (!(obd->obd_flags & OBD_ATTACHED)) {
                         CERROR("Device %d not attached\n", obd->obd_minor);
-                        RETURN(-ENODEV);
+                        GOTO(out, err=-ENODEV);
                 }
 
                 if ( OBT(obd) && OBP(obd, cleanup) )
@@ -369,7 +393,7 @@ static int obd_class_ioctl (struct inode * inode, struct file * filp,
                         obd->obd_flags &= ~OBD_SET_UP;
                         obd->obd_type->typ_refcnt--;
                 }
-                RETURN(err);
+                GOTO(out, err);
         }
 
         case OBD_IOC_CONNECT: {
@@ -380,21 +404,21 @@ static int obd_class_ioctl (struct inode * inode, struct file * filp,
                 CDEBUG(D_IOCTL, "assigned export %Lx\n", conn.addr);
                 obd_conn2data(data, &conn);
                 if (err)
-                        RETURN(err);
+                        GOTO(out, err);
 
                 err = copy_to_user((int *)arg, data, sizeof(*data));
-                RETURN(err);
+                GOTO(out, err);
         }
 
         case OBD_IOC_DISCONNECT: {
                 obd_data2conn(&conn, data);
                 err = obd_disconnect(&conn);
-                RETURN(err);
+                GOTO(out, err);
         }
 
         case OBD_IOC_DEC_USE_COUNT: {
                 MOD_DEC_USE_COUNT;
-                RETURN(0);
+                GOTO(out, err=0);
         }
 
         case OBD_IOC_CREATE: {
@@ -402,10 +426,10 @@ static int obd_class_ioctl (struct inode * inode, struct file * filp,
 
                 err = obd_create(&conn, &data->ioc_obdo1);
                 if (err)
-                        RETURN(err);
+                        GOTO(out, err);
 
                 err = copy_to_user((int *)arg, data, sizeof(*data));
-                RETURN(err);
+                GOTO(out, err);
         }
 
         case OBD_IOC_GETATTR: {
@@ -413,20 +437,20 @@ static int obd_class_ioctl (struct inode * inode, struct file * filp,
                 obd_data2conn(&conn, data);
                 err = obd_getattr(&conn, &data->ioc_obdo1);
                 if (err)
-                        RETURN(err);
+                        GOTO(out, err);
 
                 err = copy_to_user((int *)arg, data, sizeof(*data));
-                RETURN(err);
+                GOTO(out, err);
         }
 
         case OBD_IOC_SETATTR: {
                 obd_data2conn(&conn, data);
                 err = obd_setattr(&conn, &data->ioc_obdo1);
                 if (err)
-                        RETURN(err);
+                        GOTO(out, err);
 
                 err = copy_to_user((int *)arg, data, sizeof(*data));
-                RETURN(err);
+                GOTO(out, err);
         }
 
         case OBD_IOC_DESTROY: {
@@ -434,10 +458,10 @@ static int obd_class_ioctl (struct inode * inode, struct file * filp,
 
                 err = obd_destroy(&conn, &data->ioc_obdo1);
                 if (err)
-                        RETURN(err);
+                        GOTO(out, err);
 
                 err = copy_to_user((int *)arg, data, sizeof(*data));
-                RETURN(err);
+                GOTO(out, err);
         }
 
         case OBD_IOC_BRW_WRITE:
@@ -524,19 +548,23 @@ static int obd_class_ioctl (struct inode * inode, struct file * filp,
                 OBD_FREE(counts, pages * sizeof(*counts));
                 OBD_FREE(offsets, pages * sizeof(*offsets));
                 OBD_FREE(flags, pages * sizeof(*flags));
-                return err;
+                GOTO(out, err);
         }
-        default: {
+        default:
                 obd_data2conn(&conn, data);
 
-                err = obd_iocontrol(cmd, &conn, sizeof(*data), data, NULL);
+                err = obd_iocontrol(cmd, &conn, len, data, NULL);
                 if (err)
-                        RETURN(err);
+                        GOTO(out, err);
 
-                err = copy_to_user((int *)arg, data, sizeof(*data));
-                RETURN(err);
-        }
+                err = copy_to_user((int *)arg, data, len);
+                GOTO(out, err);
         }
+
+ out: 
+        OBD_FREE(buf, len); 
+        up(&obd_conf_sem); 
+        RETURN(err); 
 } /* obd_class_ioctl */
 
 
@@ -566,12 +594,13 @@ EXPORT_SYMBOL(class_register_type);
 EXPORT_SYMBOL(class_unregister_type);
 EXPORT_SYMBOL(class_name2dev);
 EXPORT_SYMBOL(class_uuid2dev);
+EXPORT_SYMBOL(class_uuid2obd);
 EXPORT_SYMBOL(class_connect);
 EXPORT_SYMBOL(class_conn2export);
 EXPORT_SYMBOL(class_conn2obd);
 EXPORT_SYMBOL(class_disconnect);
-EXPORT_SYMBOL(class_multi_setup);
-EXPORT_SYMBOL(class_multi_cleanup);
+//EXPORT_SYMBOL(class_multi_setup);
+//EXPORT_SYMBOL(class_multi_cleanup);
 
 static int __init init_obdclass(void)
 {
@@ -580,6 +609,7 @@ static int __init init_obdclass(void)
 
         printk(KERN_INFO "OBD class driver  v0.9, info@clusterfs.com\n");
 
+        sema_init(&obd_conf_sem, 1); 
         INIT_LIST_HEAD(&obd_types);
 
         if ((err = misc_register(&obd_psdev))) {
index 34e63eb..3a27245 100644 (file)
@@ -139,6 +139,21 @@ int class_uuid2dev(char *name)
         return res;
 }
 
+
+struct obd_device *class_uuid2obd(char *name)
+{
+        int i;
+
+        for (i=0; i < MAX_OBD_DEVICES; i++) {
+                struct obd_device *obd = &obd_dev[i];
+                if (obd->obd_name && strncmp(name, obd->obd_uuid, 37) == 0) {
+                        return obd;
+                }
+        }
+
+        return NULL;
+}
+
 void obd_cleanup_caches(void)
 {
         int rc;
@@ -246,19 +261,15 @@ int class_connect (struct lustre_handle *conn, struct obd_device *obd)
 
         memset(export, 0, sizeof(*export));
         get_random_bytes(&export->export_cookie, sizeof(__u64));
-        /* XXX this should probably spinlocked? */
-        export->export_id = ++obd->obd_gen_last_id;
         export->export_obd = obd; 
         export->export_import.addr = conn->addr;
         export->export_import.cookie = conn->cookie;
         
         list_add(&(export->export_chain), export->export_obd->obd_exports.prev);
-
-        CDEBUG(D_INFO, "connect: new ID %u\n", export->export_id);
         conn->addr = (__u64) (unsigned long)export;
         conn->cookie = export->export_cookie;
         return 0;
-} /* class_connect */
+} 
 
 int class_disconnect(struct lustre_handle *conn)
 {
@@ -275,7 +286,9 @@ int class_disconnect(struct lustre_handle *conn)
         kmem_cache_free(export_cachep, export);
 
         RETURN(0);
-} /* gen_obd_disconnect */
+} 
+
+#if 0
 
 /* FIXME: Data is a space- or comma-separated list of device IDs.  This will
  * have to change. */
@@ -347,4 +360,4 @@ int class_multi_cleanup(struct obd_device *obddev)
         }
         return 0;
 }
-
+#endif
index 66ff902..5c351c2 100644 (file)
@@ -19,8 +19,8 @@
  * the obdtrace driver creates /proc/lustre/obd/<obdid>/stats entry.
  *
  * This file defines three functions 
- *               proc_lustre_register_obd_device()
- *               proc_lustre_release_obd_device()
+ *   proc_lustre_register_obd_device() - called at device attach time
+ *   proc_lustre_release_obd_device() - called at detach
  *               proc_lustre_remove_obd_entry() 
  * that dynamically create/delete /proc/lustre/obd entries:
  *
@@ -59,29 +59,14 @@ static int read_lustre_status(char *page, char **start, off_t offset,
        struct obd_device * obddev = (struct obd_device *) data;
        int p;
 
-       p = sprintf(&page[0], "device %d: ", obddev->obd_minor);
+       p = sprintf(&page[0], "device=%d\n", obddev->obd_minor);
+       p += sprintf(&page[0], "name=%s\n", MKSTR(obddev->obd_name));
+       p += sprintf(&page[0], "uuid=%s\n", obddev->obd_uuid); 
+        p += sprintf(&page[p], "attached=1\n");
+        p += sprintf(&page[0], "type=%s\n", MKSTR(obddev->obd_type->typ_name));
        
-        if  (obddev->obd_flags & OBD_ATTACHED) {
-                p += sprintf(&page[p], ", attached(%s)", 
-                             obddev->obd_type->typ_name);
-        }
-        
         if  (obddev->obd_flags & OBD_SET_UP) {
-                struct dentry   *my_dentry;
-                struct vfsmount *root_mnt;
-                char *path;
-                char *pathpage;
-                
-                if (!(pathpage = (char*) __get_free_page(GFP_KERNEL)))
-                        return -ENOMEM;
-               
-                my_dentry = NULL;
-                root_mnt = mntget(current->fs->rootmnt);
-                path = d_path(my_dentry,root_mnt,pathpage,PAGE_SIZE);
-                
-                p += sprintf(&page[p], ", setup(%s)", path);
-                
-                free_page((unsigned long) pathpage);
+                p += sprintf(&page[p], "setup=1\n");
         }
         
         /* print exports */
@@ -104,7 +89,6 @@ static int read_lustre_status(char *page, char **start, off_t offset,
         p += sprintf(&page[p], "\n");
 
        /* Compute eof and return value */
-
        if (offset + count >= p) {
                *eof=1;
                return (p - offset);
@@ -125,17 +109,16 @@ proc_lustre_register_obd_device(struct obd_device *obd)
                        return 0;
        
                proc_lustre_obd_dir_entry = 
-                       proc_mkdir("obd", proc_lustre_dir_entry);
+                       proc_mkdir("devices", proc_lustre_dir_entry);
                if (IS_ERR(proc_lustre_obd_dir_entry))
                        return 0;
        }
-
-       sprintf(obdname, "%d", obd->obd_minor);
-
-
+       sprintf(obdname, "%s", obd->obd_name);
        obd_dir =  proc_mkdir(obdname, proc_lustre_obd_dir_entry);
+
         if (obd_dir) 
-               obd_status = create_proc_entry("status", S_IRUSR | S_IFREG, obd_dir);
+               obd_status = create_proc_entry("status", S_IRUSR | S_IFREG, 
+                                               obd_dir);
 
        if (obd_status) {
                obd_status->read_proc = read_lustre_status;
index 2b53629..fe77905 100644 (file)
@@ -221,6 +221,7 @@ setup_lustre() {
        do_insmod $LUSTRE/ost/ost.o || exit -1
        do_insmod $LUSTRE/osc/osc.o || exit -1
        do_insmod $LUSTRE/mdc/mdc.o || exit -1
+       do_insmod $LUSTRE/lov/lov.o || exit -1
        do_insmod $LUSTRE/llite/llite.o || exit -1
 
         echo "$R/tmp/lustre-log" > /proc/sys/portals/debug_path
@@ -294,6 +295,25 @@ setup_mds() {
        EOF
 }
 
+setup_mds_lov() { 
+
+       [ "$SETUP_MDS" = "y" ] || return 0
+
+        if [ -z "$LOVUUID" ]; then
+            echo "No LOV configured"
+            return
+        fi
+
+       $OBDCTL <<- EOF || return $?
+        name2dev MDSDEV
+        connect 
+        lovconfig ${LOVUUID} 1 4096 0 OSCUUID
+        disconnect
+       quit
+       EOF
+}
+
+
 setup_ost() {
        [ "$SETUP_OST" = "y" ] || return 0
 
@@ -354,7 +374,7 @@ setup_ost() {
 }
 
 setup_server() {
-       setup_mds $1 && setup_ost $1
+       setup_mds $1 && setup_mds_lov $1 && setup_ost $1
 }
 
 setup_osc() {
@@ -371,7 +391,7 @@ setup_osc() {
 
        $OBDCTL <<- EOF || return $rc
        newdev
-       attach osc $THEOSC
+       attach osc $THEOSC ${THEOSC}-UUID
        setup OBDUUID $OSTNODE
        quit
        EOF
@@ -392,13 +412,29 @@ setup_mdc() {
 
        $OBDCTL <<- EOF || return $?
        newdev
-       attach mdc $THEMDC
+       attach mdc $THEMDC  ${THEMDC}-UUID
        setup MDSUUID $MDSNODE
        quit
        EOF
         done
 }
 
+setup_lov () { 
+       [ "$SETUP_MDC" != "y" ] && return 0
+
+        if [ -z "$LOVUUID" ]; then
+            echo "No LOV configured"
+            return
+        fi
+
+       $OBDCTL <<- EOF || return $?
+       newdev
+       attach lov LOVNAME  ${LOVUUID}
+       setup  MDCDEV-UUID
+       quit
+       EOF
+}        
+
 
 setup_mount() {
        set -vx
@@ -424,7 +460,7 @@ setup_mount() {
 }
 
 setup_client() {
-       setup_osc && setup_mdc && setup_mount
+       setup_osc && setup_mdc && setup_lov  && setup_mount
 }
 
 DEBUG_ON="echo 0xffffffff > /proc/sys/portals/debug"
@@ -476,6 +512,7 @@ cleanup_lustre() {
        losetup -d ${LOOP}2
 
        do_rmmod llite
+       do_rmmod lov
        do_rmmod mdc
 
        do_rmmod mds_extN
index 0448d31..298d01d 100755 (executable)
@@ -39,6 +39,7 @@ detach
 quit
 EOF
 
+rmmod lov
 rmmod obdecho
 rmmod mds_extN
 rmmod mds_ext3
index bfea75b..b9b9f78 100644 (file)
@@ -4,3 +4,4 @@ MDSFS=extN
 MDSDEV=/tmp/mds
 MDSSIZE=25000
 SETUP_MDS=y
+# LOVUUID=LovUUID
index dd2a24f..5552116 100644 (file)
@@ -1420,6 +1420,71 @@ static int jt_test_brw(int argc, char **argv)
         return rc;
 }
 
+static int jt_lov_config(int argc, char **argv)
+{
+        struct obd_ioctl_data data;
+        struct lov_desc desc; 
+        uuid_t *uuidarray;
+        int size, i;
+        IOCINIT(data);
+
+        if (argc <= 5 ){
+                Parser_printhelp("lovconfig"); 
+                return -1;
+        }
+
+        if (strlen(argv[1]) > sizeof(uuid_t) - 1) { 
+                fprintf(stderr, "lov_config: no %dB memory for uuid's\n", 
+                        size);
+                return -ENOMEM;
+        }
+            
+        memset(&desc, 0, sizeof(desc)); 
+        strcpy(desc.ld_uuid, argv[1]); 
+        desc.ld_default_stripecount = strtoul(argv[2], NULL, 0); 
+        desc.ld_default_stripesize = strtoul(argv[3], NULL, 0); 
+        desc.ld_pattern = strtoul(argv[4], NULL, 0); 
+        desc.ld_tgt_count = argc - 5;
+
+
+        size = sizeof(uuid_t) * desc.ld_tgt_count;
+        uuidarray = malloc(size);
+        if (!uuidarray) { 
+                fprintf(stderr, "lov_config: no %dB memory for uuid's\n", 
+                        size);
+                return -ENOMEM;
+        }
+        memset(uuidarray, 0, size); 
+        for (i=5 ; i < argc ; i++) { 
+                char *buf = (char *) (uuidarray + i -5 );
+                if (strlen(argv[i]) >= sizeof(uuid_t)) { 
+                        fprintf(stderr, "lov_config: arg %d (%s) too long\n",  
+                                i, argv[i]);
+                        free(uuidarray);
+                        return -EINVAL;
+                }
+                strcpy(buf, argv[i]); 
+        }
+
+        data.ioc_inllen1 = sizeof(desc); 
+        data.ioc_inlbuf1 = (char *)&desc;
+        data.ioc_inllen2 = size;
+        data.ioc_inlbuf2 = (char *)uuidarray;
+
+        if (obd_ioctl_pack(&data, &buf, max)) {
+                fprintf(stderr, "error: %s: invalid ioctl\n", cmdname(argv[0]));
+                return -EINVAL;
+        }
+
+        rc = ioctl(fd, OBD_IOC_LOV_CONFIG , buf);
+        if (rc < 0)
+                fprintf(stderr, "lov_config: error: %s: %s\n", 
+                        cmdname(argv[0]),strerror(rc = errno));
+        free(uuidarray);
+        return rc;
+}
+
+
 static int jt_test_ldlm(int argc, char **argv)
 {
         struct obd_ioctl_data data;
@@ -1470,6 +1535,8 @@ command_t cmdlist[] = {
                 "--threads <threads> <devno> <command [args ...]>"},
 
         /* Device configuration commands */
+        {"lovconfig", jt_lov_config, 0, "configure lov data on MDS "
+         "(usage: lov-uuid stripecount, stripesize, pattern, UUID1, [UUID2, ...])"}, 
         {"list", jt_list, 0, "list the devices (no args)"},
         {"newdev", jt_newdev, 0, "set device to a new unused obd (no args)"},
         {"device", jt_device, 0, "set current device (args device_no name)"},
index fc22ba7..b06f624 100644 (file)
@@ -389,6 +389,14 @@ int Parser_help(int argc, char **argv)
         return 0;
 }  
 
+
+void Parser_printhelp(char *cmd)
+{
+        char *argv[] = { "help", cmd }; 
+        Parser_help(2, argv);
+}
+
+
 /*************************************************************************
  * COMMANDS                                                                 *
  *************************************************************************/ 
index 65dedaa..8f22505 100644 (file)
@@ -28,6 +28,7 @@ void Parser_init(char *, command_t *);        /* Set prompt and load command list */
 int Parser_commands(void);                     /* Start the command parser */
 void Parser_qhelp(int, char **);       /* Quick help routine */
 int Parser_help(int, char **);         /* Detailed help routine */
+void Parser_printhelp(char *);         /* Detailed help routine */
 void Parser_exit(int, char **);                /* Shuts down command parser */
 int Parser_execarg(int argc, char **argv, command_t cmds[]);
 int execute_line(char * line);