Whamcloud - gitweb
Branch b1_4_newconfig2
authornathan <nathan>
Sat, 6 Aug 2005 00:11:47 +0000 (00:11 +0000)
committernathan <nathan>
Sat, 6 Aug 2005 00:11:47 +0000 (00:11 +0000)
b=6663
add mount reference code

lustre/autoMakefile.am
lustre/include/linux/lustre_disk.h
lustre/include/linux/obd_class.h
lustre/ldlm/ldlm_lib.c
lustre/ldlm/ldlm_lockd.c
lustre/mds/handler.c
lustre/mgc/mgc_request.c
lustre/obdclass/obd_mount.c
lustre/utils/mkfs_lustre.c

index 045297c..a9c0c86 100644 (file)
@@ -8,7 +8,8 @@ AUTOMAKE_OPTIONS = foreign
 ALWAYS_SUBDIRS := include lvfs obdclass ldlm ptlrpc osc lov obdecho \
        mgc doc utils tests conf scripts autoconf
 
-SERVER_SUBDIRS := ldiskfs obdfilter ost mds mgs
+SERVER_SUBDIRS := ldiskfs obdfilter ost mds
+# mgs
 
 CLIENT_SUBDIRS := mdc llite
 
index a455691..8aee9f3 100644 (file)
 
 #define LDD_MAGIC 0xbabb0001
 
-#define LDD_SV_TYPE_MDT  0x0001
-#define LDD_SV_TYPE_OST  0x0002
-#define LDD_SV_TYPE_MGMT 0x0004
+#define LDD_F_SV_TYPE_MDT  0x0001
+#define LDD_F_SV_TYPE_OST  0x0002
+#define LDD_F_SV_TYPE_MGMT 0x0004
+#define LDD_F_NEED_INDEX   0x0010
 
 enum ldd_mount_type {
         LDD_MT_EXT3 = 0, 
@@ -79,9 +80,9 @@ struct lustre_disk_data {
         char      ldd_mount_opts[128]; /* target fs mount opts */
 };
         
-#define IS_MDT(data)   ((data)->ldd_flags & LDD_SV_TYPE_MDT)
-#define IS_OST(data)   ((data)->ldd_flags & LDD_SV_TYPE_OST)
-#define IS_MGMT(data)  ((data)->ldd_flags & LDD_SV_TYPE_MGMT)
+#define IS_MDT(data)   ((data)->ldd_flags & LDD_F_SV_TYPE_MDT)
+#define IS_OST(data)   ((data)->ldd_flags & LDD_F_SV_TYPE_OST)
+#define IS_MGMT(data)  ((data)->ldd_flags & LDD_F_SV_TYPE_MGMT)
 #define MT_STR(data)   mt_str((data)->ldd_mount_type)
 
 /****************** mount command *********************/
@@ -179,6 +180,7 @@ struct lustre_sb_info {
         struct lustre_disk_data  *lsi_ldd;     /* mount info on-disk */
         //struct fsfilt_operations *lsi_fsops;
         struct ll_sb_info        *lsi_llsbi;   /* add'l client sbi info */
+        atomic_t                  lsi_mounts;  /* mount references to this sb */
 };
 
 #define LSI_SERVER                       0x00000001
@@ -197,4 +199,31 @@ struct lustre_sb_info {
 
 #endif /* __KERNEL__ */
 
+/****************** mount lookup info *********************/
+
+struct lustre_mount_info {
+        char               *lmi_name;
+        struct super_block *lmi_sb;
+        struct vfsmount    *lmi_mnt;
+        struct list_head    lmi_list_chain;
+};
+
+/****************** misc *********************/
+#define LUSTRE_MGC_NAME "mgc"
+
+/****************** prototypes *********************/
+
+#ifdef __KERNEL__
+
+/* obd_mount.c */
+int lustre_fill_super(struct super_block *sb, void *data, int silent);
+void lustre_register_client_fill_super(int (*cfs)(struct super_block *sb));
+void lustre_common_put_super(struct super_block *sb);
+int class_manual_cleanup(struct obd_device *obd, char *flags);
+struct lustre_mount_info *lustre_get_mount(char *name);
+struct lustre_mount_info *lustre_put_mount(char *name);
+
+#endif
+
+
 #endif // _LUSTRE_DISK_H
index 74415a5..bdf2d27 100644 (file)
@@ -91,12 +91,6 @@ void ping_evictor_stop(void);
 
 char *obd_export_nid2str(struct obd_export *exp);
 
-/* obd_mount.c */
-int lustre_fill_super(struct super_block *sb, void *data, int silent);
-void lustre_register_client_fill_super(int (*cfs)(struct super_block *sb));
-void lustre_common_put_super(struct super_block *sb);
-int class_manual_cleanup(struct obd_device *obd, char *flags);
-
 /* config.c */
 int class_process_config(struct lustre_cfg *lcfg);
 int class_attach(struct lustre_cfg *lcfg);
index 803fdb4..7338654 100644 (file)
@@ -177,207 +177,6 @@ out:
         RETURN(rc);
 }
 
-/*mgc_obd_setup for mount-conf*/
-int mgc_obd_setup(struct obd_device *obddev, obd_count len, void *buf)
-{
-        struct lustre_cfg* lcfg = buf;
-        struct mgc_obd *mgc = &obddev->u.mgc;
-        struct obd_import *imp;
-        struct obd_uuid server_uuid;
-        int rq_portal, rp_portal, connect_op;
-        char *name = obddev->obd_type->typ_name;
-        int rc;
-        ENTRY;
-
-        if (strcmp(name, LUSTRE_MGC_NAME) == 0) {
-                rq_portal = MGS_REQUEST_PORTAL;
-                rp_portal = MGC_REPLY_PORTAL;
-                connect_op = MGS_CONNECT;
-        } else {
-                CERROR("wrong client OBD type \"%s\", can't setup\n",
-                       name);
-                RETURN(-EINVAL);
-        }
-
-        if (LUSTRE_CFG_BUFLEN(lcfg, 1) < 1) {
-                CERROR("requires a TARGET UUID\n");
-                RETURN(-EINVAL);
-        }
-
-        if (LUSTRE_CFG_BUFLEN(lcfg, 1) > 37) {
-                CERROR("client UUID must be less than 38 characters\n");
-                RETURN(-EINVAL);
-        }
-
-        if (LUSTRE_CFG_BUFLEN(lcfg, 2) < 1) {
-                CERROR("setup requires a SERVER UUID\n");
-                RETURN(-EINVAL);
-        }
-
-        if (LUSTRE_CFG_BUFLEN(lcfg, 2) > 37) {
-                CERROR("target UUID must be less than 38 characters\n");
-                RETURN(-EINVAL);
-        }
-
-        sema_init(&mgc->cl_sem, 1);
-        mgc->cl_conn_count = 0;
-        memcpy(server_uuid.uuid, lustre_cfg_buf(lcfg, 2),
-               min_t(unsigned int, LUSTRE_CFG_BUFLEN(lcfg, 2),
-                     sizeof(server_uuid)));
-
-        rc = ldlm_get_ref();
-        if (rc) {
-                CERROR("ldlm_get_ref failed: %d\n", rc);
-                GOTO(err, rc);
-        }
-
-        ptlrpc_init_client(rq_portal, rp_portal, name,
-                           &obddev->obd_ldlm_client);
-
-        imp = class_new_import();
-        if (imp == NULL)
-                GOTO(err_ldlm, rc = -ENOENT);
-        imp->imp_client = &obddev->obd_ldlm_client;
-        imp->imp_obd = obddev;
-        imp->imp_connect_op = connect_op;
-        imp->imp_generation = 0;
-        imp->imp_initial_recov = 1;
-        INIT_LIST_HEAD(&imp->imp_pinger_chain);
-        memcpy(imp->imp_target_uuid.uuid, lustre_cfg_buf(lcfg, 1),
-               LUSTRE_CFG_BUFLEN(lcfg, 1));
-        class_import_put(imp);
-
-        rc = client_import_add_conn(imp, &server_uuid, 1);
-        if (rc) {
-                CERROR("can't add initial connection\n");
-                GOTO(err_import, rc);
-        }
-
-        mgc->cl_import = imp;
-
-        RETURN(rc);
-
-err_import:
-        class_destroy_import(imp);
-err_ldlm:
-        ldlm_put_ref(0);
-err:
-        RETURN(rc);
-}
-
-/*mgc_obd_cleaup for mount-conf*/
-int mgc_obd_cleanup(struct obd_device *obddev)
-{
-        struct mgc_obd *mgc = &obddev->u.mgc;
-
-        if (!mgc->cl_import)
-                RETURN(-EINVAL);
-
-        class_destroy_import(mgc->cl_import);
-        mgc->cl_import = NULL;
-
-        ldlm_put_ref(obddev->obd_force);
-
-        RETURN(0);
-}
-
-/* mgc_connect_import for mount-conf*/
-int mgc_connect_import(struct lustre_handle *dlm_handle,
-                       struct obd_device *obd, struct obd_uuid *cluuid,
-                       struct obd_connect_data *data)
-{
-        struct mgc_obd *cli = &obd->u.mgc;
-        struct obd_import *imp = mgc->cl_import;
-        struct obd_export *exp;
-        int rc;
-        ENTRY;
-
-        down(&mgc->cl_sem);
-        rc = class_connect(dlm_handle, obd, cluuid);
-        if (rc)
-                GOTO(out_sem, rc);
-
-        mgc->cl_conn_count++;
-        if (mgc->cl_conn_count > 1)
-                GOTO(out_sem, rc);
-        exp = class_conn2export(dlm_handle);
-
-        imp->imp_dlm_handle = *dlm_handle;
-        rc = ptlrpc_init_import(imp);
-        if (rc != 0) 
-                GOTO(out_disco, rc);
-
-        if (data)
-                memcpy(&imp->imp_connect_data, data, sizeof(*data));
-        rc = ptlrpc_connect_import(imp, NULL);
-        if (rc != 0) {
-                LASSERT (imp->imp_state == LUSTRE_IMP_DISCON);
-                GOTO(out_disco, rc);
-        }
-        LASSERT(exp->exp_connection);
-
-        ptlrpc_pinger_add_import(imp);
-        EXIT;
-
-        if (rc) {
-out_disco:
-                mgc->cl_conn_count--;
-                class_disconnect(exp);
-        } else {
-                class_export_put(exp);
-        }
-out_sem:
-        up(&mgc->cl_sem);
-        return rc;
-}
-
-/* mgc_disconnect_export for mount-conf*/
-int mgc_disconnect_export(struct obd_export *exp)
-{
-        struct obd_device *obd = class_exp2obd(exp);
-        struct mgc_obd *mgc = &obd->u.mgc;
-        struct obd_import *imp = mgc->cl_import;
-        int rc = 0, err;
-        ENTRY;
-
-        if (!obd) {
-                CERROR("invalid export for disconnect: exp %p cookie "LPX64"\n",
-                       exp, exp ? exp->exp_handle.h_cookie : -1);
-                RETURN(-EINVAL);
-        }
-
-        down(&mgc->cl_sem);
-        if (!mgc->cl_conn_count) {
-                CERROR("disconnecting disconnected device (%s)\n",
-                       obd->obd_name);
-                GOTO(out_sem, rc = -EINVAL);
-        }
-
-        mgc->cl_conn_count--;
-        if (mgc->cl_conn_count)
-                GOTO(out_no_disconnect, rc = 0);
-
-        /* Some non-replayable imports (MDS's OSCs) are pinged, so just
-         * delete it regardless.  (It's safe to delete an import that was
-         * never added.) */
-        (void)ptlrpc_pinger_del_import(imp);
-
-        /* Yeah, obd_no_recov also (mainly) means "forced shutdown". */
-        if (obd->obd_no_recov)
-                ptlrpc_invalidate_import(imp);
-        else
-                rc = ptlrpc_disconnect_import(imp);
-
-        EXIT;
- out_no_disconnect:
-        err = class_disconnect(exp);
-        if (!rc && err)
-                rc = err;
- out_sem:
-        up(&mgc->cl_sem);
-        RETURN(rc);
-}
-
 int client_obd_setup(struct obd_device *obddev, obd_count len, void *buf)
 {
         struct lustre_cfg* lcfg = buf;
index 90f43af..875fcd6 100644 (file)
@@ -1668,10 +1668,6 @@ EXPORT_SYMBOL(client_obd_setup);
 EXPORT_SYMBOL(client_obd_cleanup);
 EXPORT_SYMBOL(client_connect_import);
 EXPORT_SYMBOL(client_disconnect_export);
-EXPORT_SYMBOL(mgc_obd_setup);
-EXPORT_SYMBOL(mgc_obd_cleanup);
-EXPORT_SYMBOL(mgc_connect_import);
-EXPORT_SYMBOL(mgc_disconnect_export);
 EXPORT_SYMBOL(target_abort_recovery);
 EXPORT_SYMBOL(target_cleanup_recovery);
 EXPORT_SYMBOL(target_handle_connect);
index 81c0ccd..91ac52a 100644 (file)
@@ -1451,6 +1451,7 @@ static int mds_setup(struct obd_device *obd, obd_count len, void *buf)
         struct lustre_cfg* lcfg = buf;
         char *options = NULL;
         struct mds_obd *mds = &obd->u.mds;
+        struct lustre_mount_info *lmi;
         struct vfsmount *mnt;
         char ns_name[48];
         unsigned long page;
@@ -1469,31 +1470,36 @@ static int mds_setup(struct obd_device *obd, obd_count len, void *buf)
         if (IS_ERR(obd->obd_fsops))
                 RETURN(rc = PTR_ERR(obd->obd_fsops));
 
-        page = __get_free_page(GFP_KERNEL);
-        if (!page)
-                RETURN(-ENOMEM);
-
-        options = (char *)page;
-        memset(options, 0, PAGE_SIZE);
-
-        /* here we use "iopen_nopriv" hardcoded, because it affects MDS utility
-         * and the rest of options are passed by mount options. Probably this
-         * should be moved to somewhere else like startup scripts or lconf. */
-        sprintf(options, "iopen_nopriv");
-
-        if (LUSTRE_CFG_BUFLEN(lcfg, 4) > 0 && lustre_cfg_buf(lcfg, 4))
-                sprintf(options + strlen(options), ",%s",
-                        lustre_cfg_string(lcfg, 4));
-
-        //FIXME mount was already done in lustre_fill_super,
-        //we just need to access it
-        mnt = do_kern_mount(lustre_cfg_string(lcfg, 2), 0,
-                            lustre_cfg_string(lcfg, 1), (void *)options);
-        free_page(page);
-        if (IS_ERR(mnt)) {
-                rc = PTR_ERR(mnt);
-                CERROR("do_kern_mount failed: rc = %d\n", rc);
-                GOTO(err_ops, rc);
+        lmi = lustre_get_mount(obd->obd_name);
+        if (lmi) {
+                /* We already mounted in lustre_fill_super */
+                mnt = lmi->lmi_mnt;
+        } else {
+                /* old path */
+                page = __get_free_page(GFP_KERNEL);
+                if (!page)
+                        RETURN(-ENOMEM);
+
+                options = (char *)page;
+                memset(options, 0, PAGE_SIZE);
+
+                /* here we use "iopen_nopriv" hardcoded, because it affects MDS utility
+                 * and the rest of options are passed by mount options. Probably this
+                 * should be moved to somewhere else like startup scripts or lconf. */
+                sprintf(options, "iopen_nopriv");
+
+                if (LUSTRE_CFG_BUFLEN(lcfg, 4) > 0 && lustre_cfg_buf(lcfg, 4))
+                        sprintf(options + strlen(options), ",%s",
+                                lustre_cfg_string(lcfg, 4));
+                
+                mnt = do_kern_mount(lustre_cfg_string(lcfg, 2), 0,
+                                    lustre_cfg_string(lcfg, 1), (void *)options);
+                free_page(page);
+                if (IS_ERR(mnt)) {
+                        rc = PTR_ERR(mnt);
+                        CERROR("do_kern_mount failed: rc = %d\n", rc);
+                        GOTO(err_ops, rc);
+                }
         }
 
         CDEBUG(D_SUPER, "%s: mnt = %p\n", lustre_cfg_string(lcfg, 1), mnt);
@@ -1587,10 +1593,14 @@ err_ns:
         ldlm_namespace_free(obd->obd_namespace, 0);
         obd->obd_namespace = NULL;
 err_put:
-        unlock_kernel();
-        mntput(mds->mds_vfsmnt);
+        if (lmi) {
+                lustre_put_mount(obd->obd_name);
+        } else {
+                unlock_kernel();
+                mntput(mds->mds_vfsmnt);
+                lock_kernel();
+        }               
         mds->mds_sb = 0;
-        lock_kernel();
 err_ops:
         fsfilt_put_ops(obd->obd_fsops);
         return rc;
index 6451681..9eadaa6 100644 (file)
 //#include <linux/lustre_mds.h>
 #include <linux/lustre_dlm.h>
 #include <linux/lustre_log.h>
+#include <linux/lustre_fsfilt.h>
+#include <linux/lustre_disk.h>
 //#include <linux/lprocfs_status.h>
 #include "mgc_internal.h"
 
+          
+static int mgc_fs_setup(struct super_block *sb, struct vfsmount *mnt)
+{
+        struct lvfs_run_ctxt saved;
+        struct lustre_sb_info *sbi = s2sbi(sb);
+        struct obd_device *obd = sbi->lsi_mgc;
+        struct mgc_obd *mgcobd = &obd->u.mgc;
+        struct dentry *dentry;
+        int err = 0;
+
+        LASSERT(obd);
+
+        obd->obd_fsops = fsfilt_get_ops(MT_STR(sbi->lsi_ldd));
+        if (IS_ERR(obd->obd_fsops)) {
+               CERROR("No fstype %s rc=%ld\n", MT_STR(sbi->lsi_ldd), 
+                      PTR_ERR(obd->obd_fsops));
+               return(PTR_ERR(obd->obd_fsops));
+        }
+
+        mgcobd->mgc_vfsmnt = mnt;
+        mgcobd->mgc_sb = mnt->mnt_root->d_inode->i_sb; // is this different than sb? */
+        fsfilt_setup(obd, mgcobd->mgc_sb);
+
+        OBD_SET_CTXT_MAGIC(&obd->obd_lvfs_ctxt);
+        obd->obd_lvfs_ctxt.pwdmnt = mnt;
+        obd->obd_lvfs_ctxt.pwd = mnt->mnt_root;
+        obd->obd_lvfs_ctxt.fs = get_ds();
+        //obd->obd_lvfs_ctxt.cb_ops = mds_lvfs_ops;
+
+        push_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
+        dentry = lookup_one_len(MOUNT_CONFIGS_DIR, current->fs->pwd,
+                                strlen(MOUNT_CONFIGS_DIR));
+        pop_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
+        if (IS_ERR(dentry)) {
+                err = PTR_ERR(dentry);
+                CERROR("cannot lookup %s directory: rc = %d\n", 
+                       MOUNT_CONFIGS_DIR, err);
+                goto err_ops;
+        }
+        mgcobd->mgc_configs_dir = dentry;
+        return (0);
+
+err_ops:        
+        fsfilt_put_ops(obd->obd_fsops);
+        obd->obd_fsops = NULL;
+        mgcobd->mgc_sb = NULL;
+        return(err);
+}
+
+static int mgc_fs_cleanup(struct obd_device *obd)
+{
+        struct mgc_obd *mgc = &obd->u.mgc;
+
+       // in mgc_cleanup: llog_cleanup(llog_get_context(obd, LLOG_CONFIG_ORIG_CTXT));
+        
+        if (mgc->mgc_configs_dir != NULL) {
+                struct lvfs_run_ctxt saved;
+                push_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
+                l_dput(mgc->mgc_configs_dir);
+                mgc->mgc_configs_dir = NULL; 
+                pop_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
+        }
+
+        if (mgc->mgc_vfsmnt)
+                // FIXME mntput should not be done by real server, only us 
+                // FIXME or mntcount on sbi?
+                mntput(mgc->mgc_vfsmnt);
+        mgc->mgc_sb = NULL;
+        
+        if (obd->obd_fsops) 
+                fsfilt_put_ops(obd->obd_fsops);
+        return(0);
+}
+
+static int mgc_cleanup(struct obd_device *obd)
+{
+        struct mgc_obd *mgc = &obd->u.mgc;
+        int rc;
+
+        rc = llog_cleanup(llog_get_context(obd, LLOG_CONFIG_ORIG_CTXT));
+
+        // FIXME REPL rc = obd_llog_finish(obd, 0);
+        if (rc != 0)
+                CERROR("failed to cleanup llogging subsystems\n");
+
+
+        if (mgc->mgc_sb)
+                /* if we're a server, eg. something's mounted */
+                mgc_fs_cleanup(obd);
+
+        //lprocfs_obd_cleanup(obd);
+        
+        //rc = mgc_obd_cleanup(obd);
+        
+        if (!lustre_put_mount(obd->obd_name))
+             CERROR("mount_put failed\n");
+
+        ptlrpcd_decref();
+        
+        OBD_FREE(mgc->mgc_rpc_lock, sizeof (*mgc->mgc_rpc_lock));
+
+        return(rc);
+}
+
 static int mgc_setup(struct obd_device *obd, obd_count len, void *buf)
 {
+        struct lustre_mount_info *lmi;
         struct mgc_obd *mgc = &obd->u.mgc;
         //struct lprocfs_static_vars lvars;
         int rc;
@@ -61,51 +168,49 @@ static int mgc_setup(struct obd_device *obd, obd_count len, void *buf)
 
         ptlrpcd_addref();
 
-        rc = mgc_obd_setup(obd, len, buf);
-        if (rc)
-                GOTO(err_rpc_lock, rc);
+        //mgc_obd_setup(obd, len, buf);
         //lprocfs_init_vars(mgc, &lvars);
         //lprocfs_obd_setup(obd, lvars.obd_vars);
         
         rc = llog_setup(obd, LLOG_CONFIG_ORIG_CTXT, obd, 0, NULL,
                         &llog_lvfs_ops);
+        //need ORIG and REPL rc = llog_setup(obd, LLOG_CONFIG_REPL_CTXT, tgt, 0, NULL,
+       //                 &llog_client_ops);
         //rc = obd_llog_init(obd, obd, 0, NULL);
         if (rc) {
-                mgc_cleanup(obd);
                 CERROR("failed to setup llogging subsystems\n");
+                GOTO(err_rpc_lock, rc);
         }
+
+        lmi = lustre_get_mount(obd->obd_name);
+        if (!lmi) {
+                CERROR("No mount registered!");
+                mgc_cleanup(obd);
+                RETURN(-ENOENT);
+        }
+
+        rc = mgc_fs_setup(lmi->lmi_sb, lmi->lmi_mnt);
+        if (rc) {
+                CERROR("fs setup failed %d\n", rc);
+                mgc_cleanup(obd);
+                RETURN(-ENOENT);
+                GOTO(err_rpc_lock, rc);
+        }
+
         RETURN(rc);
 
 err_rpc_lock:
-        OBD_FREE(mgc->mgc_rpc_lock, sizeof (*mgc->mgc_rpc_lock));
         ptlrpcd_decref();
+        OBD_FREE(mgc->mgc_rpc_lock, sizeof (*mgc->mgc_rpc_lock));
         RETURN(rc);
 }
 
-static int mgc_cleanup(struct obd_device *obd)
-{
-        struct mgc_obd *mgc = &obd->u.mgc;
-        int rc;
-
-        rc = obd_llog_finish(obd, 0);
-        if (rc != 0)
-                CERROR("failed to cleanup llogging subsystems\n");
-
-        OBD_FREE(mgc->mgc_rpc_lock, sizeof (*mgc->mgc_rpc_lock));
-
-        //lprocfs_obd_cleanup(obd);
-        ptlrpcd_decref();
-
-        rc = mgc_obd_cleanup(obd);
-        return(rc);
-}
 
 static int mgc_iocontrol(unsigned int cmd, struct obd_export *exp, int len,
                          void *karg, void *uarg)
 {
         struct obd_device *obd = exp->exp_obd;
         struct obd_ioctl_data *data = karg;
-        struct obd_import *imp = obd->u.mgc.mgc_import;
         struct llog_ctxt *ctxt;
         int rc;
         ENTRY;
@@ -119,14 +224,7 @@ static int mgc_iocontrol(unsigned int cmd, struct obd_export *exp, int len,
         }
 #endif
         switch (cmd) {
-        case OBD_IOC_CLIENT_RECOVER:
-                rc = ptlrpc_recover_import(imp, data->ioc_inlbuf1);
-                if (rc < 0)
-                        GOTO(out, rc);
-                GOTO(out, rc = 0);
-        case IOC_OSC_SET_ACTIVE:
-                rc = ptlrpc_set_import_active(imp, data->ioc_offset);
-                GOTO(out, rc);
+        /* REPLicator context */
         case OBD_IOC_PARSE: {
                 CERROR("MGC parsing llog %s\n", data->ioc_inlbuf1);
                 ctxt = llog_get_context(exp->exp_obd, LLOG_CONFIG_REPL_CTXT);
@@ -142,6 +240,38 @@ static int mgc_iocontrol(unsigned int cmd, struct obd_export *exp, int len,
                 GOTO(out, rc);
         }
 #endif
+        /* ORIGinator context */
+        case OBD_IOC_DUMP_LOG: {
+                struct lvfs_run_ctxt saved;
+                ctxt = llog_get_context(obd, LLOG_CONFIG_ORIG_CTXT);
+                push_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
+                rc = class_config_dump_llog(ctxt, data->ioc_inlbuf1, NULL);
+                pop_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
+                if (rc)
+                        RETURN(rc);
+
+                RETURN(rc);
+        }
+        case OBD_IOC_START: {
+                char *conf_prof;
+                char *name = data->ioc_inlbuf1;
+                int len = strlen(name) + sizeof("-conf");
+
+                OBD_ALLOC(conf_prof, len);
+                if (!conf_prof) {
+                        CERROR("no memory\n");
+                        RETURN(-ENOMEM);
+                }
+                sprintf(conf_prof, "%s-conf", name);
+
+                ctxt = llog_get_context(obd, LLOG_CONFIG_ORIG_CTXT);
+                rc = class_config_parse_llog(ctxt, conf_prof, NULL);
+                if (rc < 0)
+                        CERROR("Unable to process log: %s\n", conf_prof);
+                OBD_FREE(conf_prof, len);
+
+                RETURN(rc);
+        }
         default:
                 CERROR("mgc_ioctl(): unrecognised ioctl %#x\n", cmd);
                 GOTO(out, rc = -ENOTTY);
@@ -211,6 +341,207 @@ static int mgc_llog_finish(struct obd_device *obd, int count)
         RETURN(rc);
 }
 
+/*mgc_obd_setup for mount-conf*/
+int mgc_obd_setup(struct obd_device *obddev, obd_count len, void *buf)
+{
+        struct lustre_cfg* lcfg = buf;
+        struct mgc_obd *mgc = &obddev->u.mgc;
+        struct obd_import *imp;
+        struct obd_uuid server_uuid;
+        int rq_portal, rp_portal, connect_op;
+        char *name = obddev->obd_type->typ_name;
+        int rc;
+        ENTRY;
+
+        if (strcmp(name, LUSTRE_MGC_NAME) == 0) {
+                rq_portal = MGS_REQUEST_PORTAL;
+                rp_portal = MGC_REPLY_PORTAL;
+                connect_op = MGS_CONNECT;
+        } else {
+                CERROR("wrong client OBD type \"%s\", can't setup\n",
+                       name);
+                RETURN(-EINVAL);
+        }
+
+        if (LUSTRE_CFG_BUFLEN(lcfg, 1) < 1) {
+                CERROR("requires a TARGET UUID\n");
+                RETURN(-EINVAL);
+        }
+
+        if (LUSTRE_CFG_BUFLEN(lcfg, 1) > 37) {
+                CERROR("client UUID must be less than 38 characters\n");
+                RETURN(-EINVAL);
+        }
+
+        if (LUSTRE_CFG_BUFLEN(lcfg, 2) < 1) {
+                CERROR("setup requires a SERVER UUID\n");
+                RETURN(-EINVAL);
+        }
+
+        if (LUSTRE_CFG_BUFLEN(lcfg, 2) > 37) {
+                CERROR("target UUID must be less than 38 characters\n");
+                RETURN(-EINVAL);
+        }
+
+        sema_init(&mgc->mgc_sem, 1);
+        mgc->mgc_conn_count = 0;
+        memcpy(server_uuid.uuid, lustre_cfg_buf(lcfg, 2),
+               min_t(unsigned int, LUSTRE_CFG_BUFLEN(lcfg, 2),
+                     sizeof(server_uuid)));
+
+        rc = ldlm_get_ref();
+        if (rc) {
+                CERROR("ldlm_get_ref failed: %d\n", rc);
+                GOTO(err, rc);
+        }
+
+        ptlrpc_init_client(rq_portal, rp_portal, name,
+                           &obddev->obd_ldlm_client);
+
+        imp = class_new_import();
+        if (imp == NULL)
+                GOTO(err_ldlm, rc = -ENOENT);
+        imp->imp_client = &obddev->obd_ldlm_client;
+        imp->imp_obd = obddev;
+        imp->imp_connect_op = connect_op;
+        imp->imp_generation = 0;
+        imp->imp_initial_recov = 1;
+        INIT_LIST_HEAD(&imp->imp_pinger_chain);
+        memcpy(imp->imp_target_uuid.uuid, lustre_cfg_buf(lcfg, 1),
+               LUSTRE_CFG_BUFLEN(lcfg, 1));
+        class_import_put(imp);
+
+        rc = client_import_add_conn(imp, &server_uuid, 1);
+        if (rc) {
+                CERROR("can't add initial connection\n");
+                GOTO(err_import, rc);
+        }
+
+        mgc->mgc_import = imp;
+
+        RETURN(rc);
+
+err_import:
+        class_destroy_import(imp);
+err_ldlm:
+        ldlm_put_ref(0);
+err:
+        RETURN(rc);
+}
+
+/*mgc_obd_cleaup for mount-conf*/
+int mgc_obd_cleanup(struct obd_device *obddev)
+{
+        struct mgc_obd *mgc = &obddev->u.mgc;
+
+        if (!mgc->mgc_import)
+                RETURN(-EINVAL);
+
+        class_destroy_import(mgc->mgc_import);
+        mgc->mgc_import = NULL;
+
+        ldlm_put_ref(obddev->obd_force);
+
+        RETURN(0);
+}
+
+/* mgc_connect_import for mount-conf*/
+int mgc_connect_import(struct lustre_handle *dlm_handle,
+                       struct obd_device *obd, struct obd_uuid *cluuid,
+                       struct obd_connect_data *data)
+{
+        struct mgc_obd *mgc = &obd->u.mgc;
+        struct obd_import *imp = mgc->mgc_import;
+        struct obd_export *exp;
+        int rc;
+        ENTRY;
+
+        down(&mgc->mgc_sem);
+        rc = class_connect(dlm_handle, obd, cluuid);
+        if (rc)
+                GOTO(out_sem, rc);
+
+        mgc->mgc_conn_count++;
+        if (mgc->mgc_conn_count > 1)
+                GOTO(out_sem, rc);
+        exp = class_conn2export(dlm_handle);
+
+        imp->imp_dlm_handle = *dlm_handle;
+        rc = ptlrpc_init_import(imp);
+        if (rc != 0) 
+                GOTO(out_disco, rc);
+
+        if (data)
+                memcpy(&imp->imp_connect_data, data, sizeof(*data));
+        rc = ptlrpc_connect_import(imp, NULL);
+        if (rc != 0) {
+                LASSERT (imp->imp_state == LUSTRE_IMP_DISCON);
+                GOTO(out_disco, rc);
+        }
+        LASSERT(exp->exp_connection);
+
+        ptlrpc_pinger_add_import(imp);
+        EXIT;
+
+        if (rc) {
+out_disco:
+                mgc->mgc_conn_count--;
+                class_disconnect(exp);
+        } else {
+                class_export_put(exp);
+        }
+out_sem:
+        up(&mgc->mgc_sem);
+        return rc;
+}
+
+/* mgc_disconnect_export for mount-conf*/
+int mgc_disconnect_export(struct obd_export *exp)
+{
+        struct obd_device *obd = class_exp2obd(exp);
+        struct mgc_obd *mgc = &obd->u.mgc;
+        struct obd_import *imp = mgc->mgc_import;
+        int rc = 0, err;
+        ENTRY;
+
+        if (!obd) {
+                CERROR("invalid export for disconnect: exp %p cookie "LPX64"\n",
+                       exp, exp ? exp->exp_handle.h_cookie : -1);
+                RETURN(-EINVAL);
+        }
+
+        down(&mgc->mgc_sem);
+        if (!mgc->mgc_conn_count) {
+                CERROR("disconnecting disconnected device (%s)\n",
+                       obd->obd_name);
+                GOTO(out_sem, rc = -EINVAL);
+        }
+
+        mgc->mgc_conn_count--;
+        if (mgc->mgc_conn_count)
+                GOTO(out_no_disconnect, rc = 0);
+
+        /* Some non-replayable imports (MDS's OSCs) are pinged, so just
+         * delete it regardless.  (It's safe to delete an import that was
+         * never added.) */
+        (void)ptlrpc_pinger_del_import(imp);
+
+        /* Yeah, obd_no_recov also (mainly) means "forced shutdown". */
+        if (obd->obd_no_recov)
+                ptlrpc_invalidate_import(imp);
+        else
+                rc = ptlrpc_disconnect_import(imp);
+
+        EXIT;
+ out_no_disconnect:
+        err = class_disconnect(exp);
+        if (!rc && err)
+                rc = err;
+ out_sem:
+        up(&mgc->mgc_sem);
+        RETURN(rc);
+}
+
 /* reuse the client_import_[add/del]_conn*/
 struct obd_ops mgc_obd_ops = {
         .o_owner        = THIS_MODULE,
index 1abaeb0..d9945ea 100644 (file)
 
 static int (*client_fill_super)(struct super_block *sb) = NULL;
 
+/******* mount lookup *****/
+DECLARE_MUTEX(lustre_mount_info_lock);
+struct list_head lustre_mount_info_list = LIST_HEAD_INIT(lustre_mount_info_list);
+
+static struct lustre_mount_info *lustre_find_mount(char *name)
+{
+        struct list_head *tmp;
+        struct lustre_mount_info *lmi;
+        int found = 0;
+        list_for_each(tmp, &lustre_mount_info_list) {
+                lmi = list_entry(tmp, struct lustre_mount_info, lmi_list_chain);
+                if (strcmp(name, lmi->lmi_name) == 0) {
+                        CERROR("Match %s with mnt=%p\n", name, lmi->lmi_mnt);
+                        found++;
+                        break;
+                }
+        }
+        if (found)
+                return(lmi);
+        return(NULL);
+}
+
+/* obd's using a mount must be preregistered so they can find it. */
+int lustre_register_mount(char *name, struct super_block *sb,
+                          struct vfsmount *mnt)
+{
+        struct lustre_mount_info *lmi;
+        char *name_cp;
+
+        OBD_ALLOC(lmi, sizeof(*lmi));
+        if (!lmi) 
+                return -ENOMEM;
+        OBD_ALLOC(name_cp, strlen(name) + 1);
+        if (!name_cp) { 
+                OBD_FREE(lmi, sizeof(*lmi));
+                return -ENOMEM;
+        }
+
+        down(&lustre_mount_info_lock);
+        if (lustre_find_mount(name)) {
+                up(&lustre_mount_info_lock);
+                OBD_FREE(lmi, sizeof(*lmi));
+                OBD_FREE(name_cp, strlen(name) + 1);
+                CERROR("Already registered %s?\n", name);
+                return -EEXIST;
+        }
+        lmi->lmi_name = name_cp;
+        lmi->lmi_sb = sb;
+        lmi->lmi_mnt = mnt;
+        list_add(&lmi->lmi_list_chain, &lustre_mount_info_list);
+        up(&lustre_mount_info_lock);
+        return 0;
+}
+
+/* when an obd no longer needs a mount */
+static int lustre_deregister_mount(char *name)
+{
+        struct lustre_mount_info *lmi;
+        
+        down(&lustre_mount_info_lock);
+        lmi = lustre_find_mount(name);
+        if (!lmi) {
+                up(&lustre_mount_info_lock);
+                CERROR("%s not registered\n", name);
+                return -ENOENT;
+        }
+        OBD_FREE(lmi->lmi_name, strlen(lmi->lmi_name) + 1);
+        list_del(&lmi->lmi_list_chain);
+        OBD_FREE(lmi, sizeof(*lmi));
+        up(&lustre_mount_info_lock);
+        return 0;
+}
+
+/* obd's look up a registered mount using their name */
+struct lustre_mount_info *lustre_get_mount(char *name)
+{
+        struct lustre_mount_info *lmi;
+        struct lustre_sb_info *sbi;
+
+        down(&lustre_mount_info_lock);
+        lmi = lustre_find_mount(name);
+        if (!lmi) {
+                up(&lustre_mount_info_lock);
+                CERROR("Can't find mount for %s\n", name);
+                return NULL;
+        }
+        sbi = s2sbi(lmi->lmi_sb);
+        atomic_inc(&sbi->lsi_mounts);
+        up(&lustre_mount_info_lock);
+        CERROR("got mount for %s\n", name);
+        return lmi;
+}
+
+struct lustre_mount_info *lustre_put_mount(char *name)
+{
+        struct lustre_mount_info *lmi;
+        struct lustre_sb_info *sbi;
+
+        down(&lustre_mount_info_lock);
+        lmi = lustre_find_mount(name);
+        if (!lmi) {
+                up(&lustre_mount_info_lock);
+                CERROR("Can't find mount for %s\n", name);
+                return NULL;
+        }
+        sbi = s2sbi(lmi->lmi_sb);
+        if (atomic_dec_and_test(&sbi->lsi_mounts)) {
+                CERROR("Last put of mnt %p from %s\n", lmi->lmi_mnt, name);
+                if (kernel_locked()) {
+                        unlock_kernel();
+                        mntput(lmi->lmi_mnt);
+                        lock_kernel();
+                } else {
+                        mntput(lmi->lmi_mnt);
+                }
+        }
+        up(&lustre_mount_info_lock);
+
+        /* any reason why a server might need the mount again? */
+        lustre_deregister_mount(name);
+        
+        return lmi;
+}
+
+
+/******* utilities *********/
+
 static int dentry_readdir(struct obd_device *obd, struct dentry *dir, 
                           struct vfsmount *inmnt, struct list_head *dentry_list)
 {
@@ -208,6 +335,7 @@ struct lustre_sb_info *lustre_init_sbi(struct super_block *sb)
                 RETURN(NULL);
 
         s2sbi_nocast(sb) = sbi;
+        atomic_set(&sbi->lsi_mounts, 0);
         return(sbi);
 }
 
@@ -506,48 +634,19 @@ do client and confobd do servers. MGC should do both. */
 int lustre_process_logs(struct super_block *sb,
                         struct config_llog_instance *cfg, int allow_recov)
 {
-        char lr_uuid[40];
         struct obd_ioctl_data ioc_data = { 0 };
         struct list_head dentry_list;
         struct l_linux_dirent *dirent, *n;
         struct obd_device *obd;
         struct mgc_obd *mgcobd;
         struct lustre_sb_info *sbi = s2sbi(sb);
-        int is_first_mount = 0;
         int err;
                                                                                        
         obd = sbi->lsi_mgc;
         LASSERT(obd);
         mgcobd = &obd->u.mgc;
-                                                                                       
-        err = parse_last_rcvd(obd, lr_uuid, &is_first_mount);
-        if (err) {
-                CERROR("Can't read %s\n", LAST_RCVD);
-                return(err);
-        }
-                                                                                       
-        if ((strncmp(lr_uuid, "OST", 3) == 0) && is_first_mount) {
-                /* Always register with MGS.  If this is the first mount
-                   for an OST, we might have to change our name */
-                err = 1;//ost_register(lmd, lr_uuid);
-                if (err) {
-                        CERROR("OST register Failed\n");
-                        return(err);
-                }
-        } else if (strncmp(lr_uuid, "MDS", 3) == 0) {
-   #if 0 
-                //FIXME stripe count is set in the mds llog
-                uint32_t stripe_size;
-                err = get_stripe_size(obd, &stripe_size);
-                if (err) {
-                        CERROR("Can't read %s\n", STRIPE_FILE);
-                        return(err);
-                }
-                mgcobd_start_accept(obd, lmd, lr_uuid, stripe_size);
-   #endif                                                                       
-        }
-                                                                                       
-        /* Find all the logs in the CONFIGS directory */
+                                                                                                                                                                              
+        /* Find all the logs in the local CONFIGS directory */
         err = dentry_readdir(obd, mgcobd->mgc_configs_dir,
                        mgcobd->mgc_vfsmnt, &dentry_list);
         if (err) {
@@ -563,7 +662,8 @@ int lustre_process_logs(struct super_block *sb,
                 list_del(&dirent->lld_list);
                 logname = dirent->lld_name;
                                                                                        
-                /* Confobd start adds "-conf" */
+                CERROR("file: %s\n", logname);
+                /* mgcobd start adds "-conf" */
                 len = strlen(logname) - 5;
                 if ((len < 1) || (strcmp(logname + len, "-conf") != 0)) {
                         CDEBUG(D_CONFIG, "ignoring %s\n", logname);
@@ -585,86 +685,6 @@ int lustre_process_logs(struct super_block *sb,
                                                                                        
         return(err);
 }
-                                                 
-int mgc_fs_setup(struct super_block *sb, struct vfsmount *mnt)
-{
-        struct lvfs_run_ctxt saved;
-        struct lustre_sb_info *sbi = s2sbi(sb);
-        struct obd_device *obd = sbi->lsi_mgc;
-        struct mgc_obd *mgcobd = &obd->u.mgc;
-        struct dentry *dentry;
-        int err;
-
-        LASSERT(obd);
-
-        obd->obd_fsops = fsfilt_get_ops(MT_STR(sbi->lsi_ldd))
-        if (IS_ERR(obd->obd_fsops)) {
-               CERROR("No fstype %s rc=%ld\n", MT_STR(sbi->lsi_ldd), 
-                      PTR_ERR(obd->obd_fsops));
-               return(PTR_ERR(obd->obd_fsops));
-        }
-
-        mgcobd->mgc_vfsmnt = mnt;
-        mgcobd->mgc_sb = mnt->mnt_root->d_inode->i_sb; // is this different than sb? */
-        fsfilt_setup(obd, mgcobd->mgc_sb);
-
-        OBD_SET_CTXT_MAGIC(&obd->obd_lvfs_ctxt);
-        obd->obd_lvfs_ctxt.pwdmnt = mnt;
-        obd->obd_lvfs_ctxt.pwd = mnt->mnt_root;
-        obd->obd_lvfs_ctxt.fs = get_ds();
-        //obd->obd_lvfs_ctxt.cb_ops = mds_lvfs_ops;
-
-        push_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
-
-        dentry = lookup_one_len(MOUNT_CONFIGS_DIR, current->fs->pwd,
-                                strlen(MOUNT_CONFIGS_DIR));
-        if (IS_ERR(dentry)) {
-                err = PTR_ERR(dentry);
-                CERROR("cannot lookup %s directory: rc = %d\n", 
-                       MOUNT_CONFIGS_DIR, err);
-                goto err_ops;
-        }
-        mgcobd->mgc_configs_dir = dentry;
-     #if 0   
-        err = llog_setup(obd, LLOG_CONFIG_ORIG_CTXT, obd, 0,
-                            NULL, &llog_lvfs_ops);
-        if (err)
-                goto err_dput;
-     #endif
-         
-err_pop:
-        pop_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
-        return(err);
-err_dput:
-        dput(mgcobd->mgc_configs_dir);
-err_ops:        
-        fsfilt_put_ops(obd->obd_fsops);
-        obd->obd_fsops = NULL;
-        goto err_pop;
-}
-
-int mgc_fs_cleanup(struct obdclass *obd)
-{
-        llog_cleanup(llog_get_context(obd, LLOG_CONFIG_ORIG_CTXT));
-        
-        if (mgcobd->mgc_configs_dir != NULL) {
-                struct lvfs_run_ctxt saved;
-                push_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
-                l_dput(mgcobd->mgc_configs_dir);
-                mgcobd->mgc_configs_dir = NULL; 
-                pop_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
-        }
-
-        if (mgcobd->mgc_vfsmnt)
-                // FIXME mntput should not be done by real server, only us */
-                mntput(mgcobd->mgc_vfsmnt);
-        mgc->mgc_sb = NULL;
-        
-        if (obd->obd_fsops) 
-                fsfilt_put_ops(obd->obd_fsops);
-        return(0);
-}
-
 
 /* Kernel mount using mount options in MOUNT_DATA_FILE */
 static struct vfsmount *lustre_kern_mount(struct super_block *sb)
@@ -673,7 +693,6 @@ static struct vfsmount *lustre_kern_mount(struct super_block *sb)
         struct lustre_sb_info *sbi = s2sbi(sb);
         struct lustre_disk_data *ldd;
         struct lustre_mount_data *lmd = sbi->lsi_lmd;
-        struct obd_device *obd;
         struct vfsmount *mnt;
         char *options = NULL;
         unsigned long page;
@@ -681,7 +700,7 @@ static struct vfsmount *lustre_kern_mount(struct super_block *sb)
 
         OBD_ALLOC(ldd, sizeof(*ldd));
         if (!ldd)
-                return(-ENOMEM);
+                return(ERR_PTR(-ENOMEM));
 
         /* Pre-mount ext3 with no options to read the MOUNT_DATA_FILE */
         CERROR("Pre-mount ext3 %s\n", lmd->lmd_dev);
@@ -745,72 +764,18 @@ out_free:
         return(ERR_PTR(err));
 }
 
-static int server_fill_super(struct super_block *sb)
-{
-        struct config_llog_instance cfg;
-        struct lustre_sb_info *sbi = s2sbi(sb);
-        struct vfsmount *mnt;
-        int err;
-
-        cfg.cfg_instance = sbi->lsi_mgc->obd_name;
-        snprintf(cfg.cfg_uuid.uuid, sizeof(cfg.cfg_uuid.uuid), 
-                 sbi->lsi_mgc->obd_name);
-
-        /* mount to read server info */
-        mnt = lustre_kern_mount(sb);
-        if (IS_ERR(mnt)) {
-                CERROR("Unable to mount device %s: %d\n", 
-                      sbi->lsi_lmd->lmd_dev, err);
-                GOTO(out_free, err = PTR_ERR(mnt));
-        }
-        CERROR("Found service %s for fs %s on device %s\n",
-               sbi->lsi_ldd->ldd_svname, sbi->lsi_ldd->ldd_fsname, 
-               sbi->lsi_lmd->lmd_dev);
-        
-        err = mgc_fs_setup(sb, mnt);
-        if (err) 
-                goto out_free;
-        
-        /* Set up all obd devices for service */
-        err = lustre_process_logs(sb, &cfg, 0);
-        if (err < 0) {
-                CERROR("Unable to process log: %d\n", err);
-                GOTO(out_free, err);
-        }
-        
-        /* Finally, put something at the mount point. */
-        CERROR("Mounting server\n");
-        err = server_fill_super_common(sb);
-       
-        /* FIXME overmount client here,
-           or can we just start a client log and client_fill_super on this sb? 
-           have to fix up the s_ops after! */
-out_free:
-        //FIXME mntput
-        //FIXME manual_cleanup (server_put_super)
-        if (sbi->lsi_ldd)
-                class_del_profile(sbi->lsi_ldd->ldd_svname);
-        return (err);
-}
-
 /* Set up a mgcobd to process startup logs */
-static int lustre_start_mgc(struct super_block *sb)
+static int lustre_start_mgc(char *mcname, struct super_block *sb)
 {
         struct config_llog_instance cfg;
         struct lustre_sb_info *sbi = s2sbi(sb);
         struct obd_device *obd;
-        char *mcname;
-        int mcname_sz = sizeof(sb) * 2 + 5;
         int err = 0;
 
-        /* Generate a string unique to this super, let's try
-           the address of the super itself.*/
-        OBD_ALLOC(mcname, mcname_sz);
-        sprintf(mcname, "MGC_%p", sb);
         cfg.cfg_instance = mcname;
         snprintf(cfg.cfg_uuid.uuid, sizeof(cfg.cfg_uuid.uuid), mcname);
  
-        err = do_lcfg(mcname, 0, LCFG_ATTACH, "mgc", cfg.cfg_uuid.uuid, 0, 0);
+        err = do_lcfg(mcname, 0, LCFG_ATTACH, LUSTRE_MGC_NAME, cfg.cfg_uuid.uuid, 0, 0);
         if (err)
                 goto out_free;
                                                                                        
@@ -830,7 +795,6 @@ static int lustre_start_mgc(struct super_block *sb)
         sbi->lsi_mgc = obd;
         
 out_free:
-        OBD_FREE(mcname, mcname_sz);
         return err;
 }
 
@@ -841,13 +805,86 @@ static void lustre_stop_mgc(struct super_block *sb)
 
         obd = sbi->lsi_mgc;
 
-        /* FIXME this should be called from mgc_cleanup from manual_cleanup */
-        if (mgcobd->mgc_sb)
-                /* if we're a server, eg. something's mounted */
-                mgc_fs_cleanup(obd);
-
         class_manual_cleanup(obd, NULL);
 }
+                                                
+static int server_fill_super(struct super_block *sb)
+{
+        struct config_llog_instance cfg;
+        struct lustre_sb_info *sbi = s2sbi(sb);
+        struct vfsmount *mnt;
+        char *mgcname;
+        int mgcname_sz = sizeof(sb) * 2 + 5;
+        int err;
+        ENTRY;
+
+        /* Generate a string unique to this super, let's try
+           the address of the super itself.*/
+        OBD_ALLOC(mgcname, mgcname_sz);
+        if (!mgcname)
+                GOTO(out_free, err = -ENOMEM);
+        sprintf(mgcname, "MGC_%p", sb);
+
+        /* mount to read server info */
+        mnt = lustre_kern_mount(sb);
+        if (IS_ERR(mnt)) {
+                CERROR("Unable to mount device %s: %d\n", 
+                      sbi->lsi_lmd->lmd_dev, err);
+                GOTO(out_free, err = PTR_ERR(mnt));
+        }
+        LASSERT(sbi->lsi_ldd);
+        CERROR("Found service %s for fs %s on device %s\n",
+               sbi->lsi_ldd->ldd_svname, sbi->lsi_ldd->ldd_fsname, 
+               sbi->lsi_lmd->lmd_dev);
+        
+        /* register a mount for the mgc so it can call mgc_fs_setup() */
+        err = lustre_register_mount(mgcname, sb, mnt);
+        if (err) 
+                GOTO(out_free, err);
+
+        err = lustre_start_mgc(mgcname, sb);
+        //part of mgc_startup err = mgc_fs_setup(sb, mnt);
+        if (err) 
+                GOTO(out_free, err);
+        
+        /* we also need to register a mount for the real server */
+        err = lustre_register_mount(sbi->lsi_ldd->ldd_svname, sb, mnt);
+        if (err) 
+                GOTO(out_free, err);
+
+
+        if (sbi->lsi_ldd->ldd_flags & LDD_F_NEED_INDEX) {
+                // FIXME implement
+                CERROR("Need new server index from MGS!\n");
+                // rewrite last_rcvd, ldd (for new svname)
+        }
+        // FIXME register with MGS
+        /* Set up all obd devices for service */
+        cfg.cfg_instance = mgcname;
+        snprintf(cfg.cfg_uuid.uuid, sizeof(cfg.cfg_uuid.uuid), mgcname);
+        err = lustre_process_logs(sb, &cfg, 0);
+        if (err < 0) {
+                CERROR("Unable to process log: %d\n", err);
+                GOTO(out_free, err);
+        }
+        
+        /* Finally, put something at the mount point. */
+        CERROR("Mounting server\n");
+        err = server_fill_super_common(sb);
+       
+        /* FIXME overmount client here,
+           or can we just start a client log and client_fill_super on this sb? 
+           have to fix up the s_ops after! */
+out_free:
+        //FIXME mntput
+        //FIXME manual_cleanup (server_put_super)
+        OBD_FREE(mgcname, mgcname_sz);
+out:
+        if (sbi->lsi_ldd)
+                class_del_profile(sbi->lsi_ldd->ldd_svname);
+        RETURN(err);
+}
 
 /* Common umount */
 void lustre_common_put_super(struct super_block *sb)
@@ -882,7 +919,6 @@ int lustre_fill_super(struct super_block *sb, void *data, int silent)
         }
         memcpy(sbi->lsi_lmd, lmd, sizeof(*lmd));
         
-        lustre_start_mgc(sb);
 
         if (lmd_is_client(lmd)) {
                 if (!client_fill_super) {
@@ -890,7 +926,11 @@ int lustre_fill_super(struct super_block *sb, void *data, int silent)
                                "Is llite module loaded?\n");
                         err = -ENOSYS;
                 } else {
+                        char mgcname[64];
+                        snprintf(mgcname, sizeof(mgcname), "mgc-client-%s", 
+                                 lmd->lmd_dev);
                         CERROR("Mounting client\n");
+                        lustre_start_mgc(mgcname, sb);
                         /* Connect and start */
                         /* (should always be ll_fill_super) */
                         err = (*client_fill_super)(sb);
@@ -921,5 +961,7 @@ EXPORT_SYMBOL(lustre_register_client_fill_super);
 EXPORT_SYMBOL(lustre_common_put_super);
 EXPORT_SYMBOL(lustre_get_process_log);
 EXPORT_SYMBOL(class_manual_cleanup);
+EXPORT_SYMBOL(lustre_get_mount);
+EXPORT_SYMBOL(lustre_put_mount);
 
 
index b33eb7d..95e118c 100644 (file)
@@ -884,6 +884,7 @@ void set_defaults(struct mkfs_opts *mop)
 {
         char hostname[128];
         mop->mo_ldd.ldd_magic = LDD_MAGIC;
+        mop->mo_ldd.ldd_flags = LDD_F_NEED_INDEX;
 
         if (get_os_version() == 24) 
                 mop->mo_ldd.ldd_mount_type = LDD_MT_EXT3;
@@ -980,16 +981,18 @@ int main(int argc , char *const argv[])
                         mop.mo_hostnid.backup = libcfs_str2nid(optarg);
                         break;
                 case 'G':
-                        mop.mo_ldd.ldd_flags |= LDD_SV_TYPE_MGMT;
+                        mop.mo_ldd.ldd_flags |= LDD_F_SV_TYPE_MGMT;
                         break;
                 case 'h':
                         usage(stdout);
                         break;
                 case 'i':
-                        if (IS_MDT(&mop.mo_ldd) || IS_OST(&mop.mo_ldd))
+                        if (IS_MDT(&mop.mo_ldd) || IS_OST(&mop.mo_ldd)) {
                                 mop.mo_index = atol(optarg);
-                        else
+                                mop.mo_ldd.ldd_flags &= ~LDD_F_NEED_INDEX;
+                        } else {
                                 badopt(opt, "MDT,OST");
+                        }
                         break;
                 case 'm':
                         if (IS_MGMT(&mop.mo_ldd))
@@ -997,7 +1000,7 @@ int main(int argc , char *const argv[])
                         set_nid_pair(&mop.mo_ldd.ldd_mgmtnid, optarg);
                         break;
                 case 'M':
-                        mop.mo_ldd.ldd_flags |= LDD_SV_TYPE_MDT;
+                        mop.mo_ldd.ldd_flags |= LDD_F_SV_TYPE_MDT;
                         break;
                 case 'n':
                         if (!(IS_MDT(&mop.mo_ldd) || IS_OST(&mop.mo_ldd)))
@@ -1015,7 +1018,7 @@ int main(int argc , char *const argv[])
                         mountopts = optarg;
                         break;
                 case 'O':
-                        mop.mo_ldd.ldd_flags |= LDD_SV_TYPE_OST;
+                        mop.mo_ldd.ldd_flags |= LDD_F_SV_TYPE_OST;
                         break;
                 case 'r':
                         mop.mo_flags |= MO_FORCEFORMAT;
@@ -1057,7 +1060,7 @@ int main(int argc , char *const argv[])
         if (IS_MDT(&mop.mo_ldd) && !IS_MGMT(&mop.mo_ldd) && 
             mop.mo_ldd.ldd_mgmtnid.primary == PTL_NID_ANY) {
                 vprint("No MGMT specified, adding to this MDT\n");
-                mop.mo_ldd.ldd_flags |= LDD_SV_TYPE_MGMT;
+                mop.mo_ldd.ldd_flags |= LDD_F_SV_TYPE_MGMT;
                 //FIXME mop.mo_ldd.ldd_mgmt.primary == libcfs_str2nid(localhost);
         }