Whamcloud - gitweb
b=9845
[fs/lustre-release.git] / lustre / mgs / mgs_handler.c
index 8b1d4e4..f84f60b 100644 (file)
@@ -43,9 +43,9 @@
 #include <linux/lprocfs_status.h>
 #include <linux/lustre_fsfilt.h>
 #include <linux/lustre_commit_confd.h>
+#include <linux/lustre_disk.h>
 #include "mgs_internal.h"
 
-static int mgs_postsetup(struct obd_device *obd);
 static int mgs_cleanup(struct obd_device *obd);
 
 /* Establish a connection to the MGS.*/
@@ -53,52 +53,24 @@ static int mgs_connect(struct lustre_handle *conn, struct obd_device *obd,
                        struct obd_uuid *cluuid, struct obd_connect_data *data)
 {
         struct obd_export *exp;
-        struct mgs_export_data *med;
-        struct mgs_client_data *mcd;
-        int rc, abort_recovery;
+        int rc;
         ENTRY;
 
         if (!conn || !obd || !cluuid)
                 RETURN(-EINVAL);
 
-        /* Check for aborted recovery. */
-        spin_lock_bh(&obd->obd_processing_task_lock);
-        abort_recovery = obd->obd_abort_recovery;
-        spin_unlock_bh(&obd->obd_processing_task_lock);
-        if (abort_recovery)
-                target_abort_recovery(obd);
-
         rc = class_connect(conn, obd, cluuid);
         if (rc)
                 RETURN(rc);
         exp = class_conn2export(conn);
         LASSERT(exp);
-        med = &exp->exp_mgs_data;
 
         if (data != NULL) {
-                data->ocd_connect_flags &= MGS_CONNECT_SUPPORTED;
+                data->ocd_connect_flags &= MGMT_CONNECT_SUPPORTED;
                 exp->exp_connect_flags = data->ocd_connect_flags;
         }
 
-        OBD_ALLOC(mcd, sizeof(*mcd));
-        if (!mcd) {
-                CERROR("mgs: out of memory for client data\n");
-                GOTO(out, rc = -ENOMEM);
-        }
-
-        memcpy(mcd->mcd_uuid, cluuid, sizeof(mcd->mcd_uuid));
-        med->med_mcd = mcd;
-#if 0
-        /* FIXME: recovery of connection*/
-        rc = mgs_client_add(obd, &obd->u.mgs, med, -1);
-        GOTO(out, rc);
-#endif 
-out:
         if (rc) {
-                if (mcd) {
-                        OBD_FREE(mcd, sizeof(*mcd));
-                        med->med_mcd = NULL;
-                }
                 class_disconnect(exp);
         } else {
                 class_export_put(exp);
@@ -107,15 +79,6 @@ out:
         RETURN(rc);
 }
 
-static int mgs_init_export(struct obd_export *exp)
-{
-        struct mgs_export_data *med = &exp->exp_mgs_data;
-
-        INIT_LIST_HEAD(&med->med_open_head);
-        spin_lock_init(&med->med_open_lock);
-        RETURN(0);
-}
-
 static int mgs_disconnect(struct obd_export *exp)
 {
         unsigned long irqflags;
@@ -148,59 +111,35 @@ static int mgs_disconnect(struct obd_export *exp)
         RETURN(rc);
 }
 
-/* mount the file system (secretly) */
+/* Start the MGS obd */
 static int mgs_setup(struct obd_device *obd, obd_count len, void *buf)
 {
         struct lprocfs_static_vars lvars;
-        struct lustre_cfg* lcfg = buf;
-        char *options = NULL;
+        char *ns_name = "MGS";
         struct mgs_obd *mgs = &obd->u.mgs;
+        struct lustre_mount_info *lmi;
+        struct lustre_sb_info *lsi;
         struct vfsmount *mnt;
-        unsigned long page;
         int rc = 0;
         ENTRY;
 
-        /* setup 1:/dev/loop/0 2:ext3 3:mgs 4:errors=remount-ro,iopen_nopriv*/
-
-        if (lcfg->lcfg_bufcount < 3)
-                RETURN(rc = -EINVAL);
+        CDEBUG(D_CONFIG, "Starting MGS\n");
 
-        if (LUSTRE_CFG_BUFLEN(lcfg, 1) == 0 || LUSTRE_CFG_BUFLEN(lcfg, 2) == 0)
+        lmi = server_get_mount(obd->obd_name);
+        if (!lmi) 
                 RETURN(rc = -EINVAL);
 
-        obd->obd_fsops = fsfilt_get_ops(lustre_cfg_string(lcfg, 2));
+        mnt = lmi->lmi_mnt;
+        lsi = s2lsi(lmi->lmi_sb);
+        obd->obd_fsops = fsfilt_get_ops(MT_STR(lsi->lsi_ldd));
         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);
-
-        if (LUSTRE_CFG_BUFLEN(lcfg, 4) > 0 && lustre_cfg_buf(lcfg, 4))
-                sprintf(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);
-        }
-
-        CDEBUG(D_SUPER, "%s: mnt = %p\n", lustre_cfg_string(lcfg, 1), mnt);
+                GOTO(err_put, rc = PTR_ERR(obd->obd_fsops));
 
-        /*namespace for mgs llog */
-        sprintf(ns_name, "mgs-%s", obd->obd_uuid.uuid);
+        /* namespace for mgs llog */
         obd->obd_namespace = ldlm_namespace_new(ns_name, LDLM_NAMESPACE_SERVER);
         if (obd->obd_namespace == NULL) {
                 mgs_cleanup(obd);
-                GOTO(err_put, rc = -ENOMEM);
+                GOTO(err_ops, rc = -ENOMEM);
         }
 
         LASSERT(!lvfs_check_rdonly(lvfs_sbdev(mnt->mnt_sb)));
@@ -212,41 +151,21 @@ static int mgs_setup(struct obd_device *obd, obd_count len, void *buf)
                 GOTO(err_ns, rc);
         }
 
-        INIT_LIST_HEAD(&mgs->mgs_open_llogs);
-        INIT_LIST_HEAD(&mgs->mgs_update_llhs);
-
         rc = llog_start_commit_thread();
         if (rc < 0)
                 GOTO(err_fs, rc);
 
-        rc = mgs_postsetup(obd);
+        rc = llog_setup(obd, LLOG_CONFIG_ORIG_CTXT, obd, 0, NULL,
+                        &llog_lvfs_ops);
         if (rc)
                 GOTO(err_fs, rc);
 
+        mgs_init_db_list(obd);
+
         lprocfs_init_vars(mgs, &lvars);
         lprocfs_obd_setup(obd, lvars.obd_vars);
 
-        if (obd->obd_recovering) {
-                LCONSOLE_WARN("MGT %s now serving %s, but will be in recovery "
-                              "until %d %s reconnect, or if no clients "
-                              "reconnect for %d:%.02d; during that time new "
-                              "clients will not be allowed to connect. "
-                              "Recovery progress can be monitored by watching "
-                              "/proc/fs/lustre/mgs/%s/recovery_status.\n",
-                              obd->obd_name,
-                              lustre_cfg_string(lcfg, 1),
-                              obd->obd_recoverable_clients,
-                              (obd->obd_recoverable_clients == 1) 
-                              ? "client" : "clients",
-                              (int)(OBD_RECOVERY_TIMEOUT / HZ) / 60,
-                              (int)(OBD_RECOVERY_TIMEOUT / HZ) % 60,
-                              obd->obd_name);
-        } else {
-                LCONSOLE_INFO("MGT %s now serving %s with recovery %s.\n",
-                              obd->obd_name,
-                              lustre_cfg_string(lcfg, 1),
-                              obd->obd_replayable ? "enabled" : "disabled");
-        }
+        LCONSOLE_INFO("MGS %s started\n", obd->obd_name);
 
         ldlm_timeout = 6;
         ping_evictor_start();
@@ -259,33 +178,25 @@ err_fs:
 err_ns:
         ldlm_namespace_free(obd->obd_namespace, 0);
         obd->obd_namespace = NULL;
-err_put:
-        unlock_kernel();
-        mntput(mgs->mgs_vfsmnt);
-        mgs->mgs_sb = 0;
-        lock_kernel();
 err_ops:
         fsfilt_put_ops(obd->obd_fsops);
+err_put:
+        server_put_mount(obd->obd_name, mgs->mgs_vfsmnt);
+        mgs->mgs_sb = 0;
         return rc;
 }
 
-static int mgs_postsetup(struct obd_device *obd)
-{
-        int rc = 0;
-        ENTRY;
-
-        rc = llog_setup(obd, LLOG_CONFIG_ORIG_CTXT, obd, 0, NULL,
-                        &llog_lvfs_ops);
-        RETURN(rc);
-}
-
 static int mgs_precleanup(struct obd_device *obd, int stage)
 {
         int rc = 0;
         ENTRY;
 
-        llog_cleanup(llog_get_context(obd, LLOG_CONFIG_ORIG_CTXT));
-        rc = obd_llog_finish(obd, 0);
+        switch (stage) {
+        case OBD_CLEANUP_SELF_EXP:
+                mgs_cleanup_db_list(obd);
+                llog_cleanup(llog_get_context(obd, LLOG_CONFIG_ORIG_CTXT));
+                rc = obd_llog_finish(obd, 0);
+        }
         RETURN(rc);
 }
 
@@ -293,7 +204,6 @@ static int mgs_cleanup(struct obd_device *obd)
 {
         struct mgs_obd *mgs = &obd->u.mgs;
         lvfs_sbdev_type save_dev;
-        int must_relock = 0;
         ENTRY;
 
         ping_evictor_stop();
@@ -302,24 +212,13 @@ static int mgs_cleanup(struct obd_device *obd)
                 RETURN(0);
         save_dev = lvfs_sbdev(mgs->mgs_sb);
 
-        lprocfs_obd_cleanup(obd);
-
-        mgs_update_server_data(obd, 1);
+//       lprocfs_obd_cleanup(obd);
 
       mgs_fs_cleanup(obd);
//       mgs_update_server_data(obd, 1);
 
-        if (atomic_read(&obd->u.mgs.mgs_vfsmnt->mnt_count) > 2)
-                CERROR("%s: mount busy, mnt_count %d != 2\n", obd->obd_name,
-                       atomic_read(&obd->u.mgs.mgs_vfsmnt->mnt_count));
-
-        /* We can only unlock kernel if we are in the context of sys_ioctl,
-           otherwise we never called lock_kernel */
-        if (kernel_locked()) {
-                unlock_kernel();
-                must_relock++;
-        }
+        //mgs_fs_cleanup(obd);
 
-        mntput(mgs->mgs_vfsmnt);
+        server_put_mount(obd->obd_name, mgs->mgs_vfsmnt);
         mgs->mgs_sb = NULL;
 
         ldlm_namespace_free(obd->obd_namespace, obd->obd_force);
@@ -333,86 +232,97 @@ static int mgs_cleanup(struct obd_device *obd)
 
         lvfs_clear_rdonly(save_dev);
 
-        if (must_relock)
-                lock_kernel();
-
         fsfilt_put_ops(obd->obd_fsops);
 
-        LCONSOLE_INFO("MGT %s has stopped.\n", obd->obd_name);
+        LCONSOLE_INFO("MGS %s has stopped.\n", obd->obd_name);
 
         RETURN(0);
 }
 
+static int mgs_handle_target_add(struct ptlrpc_request *req)
+{    
+        struct obd_device *obd = req->rq_export->exp_obd;
+        struct mgmt_target_info *req_mti, *mti, *rep_mti;
+        int rep_size = sizeof(*mti);
+        int rc;
+        ENTRY;
+
+        OBD_ALLOC(mti, sizeof(*mti));
+        if (!mti)
+                GOTO(out, rc = -ENOMEM);
+        req_mti = lustre_swab_reqbuf(req, 0, sizeof(*mti),
+                                     lustre_swab_mgmt_target_info);
+        memcpy(mti, req_mti, sizeof(*mti));
+        
+        /* set the new target index if needed */
+        if (mti->mti_flags & LDD_F_NEED_INDEX) {
+                rc = mgs_set_next_index(obd, mti);
+                if (rc) {
+                        CERROR("Can't get index (%d)\n", rc);
+                        GOTO(out, rc);
+                }
+        }
+
+        /* create the log for the new target 
+           and update the client/mdt logs */
+        rc = mgs_write_log_target(obd, mti);
+        if (rc) {
+                CERROR("Failed to write %s log (%d)\n", 
+                       mti->mti_svname, rc);
+                GOTO(out, rc);
+        }
+
+out:
+        lustre_pack_reply(req, 1, &rep_size, NULL); 
+        /* send back the whole mti in the reply */
+        rep_mti = lustre_msg_buf(req->rq_repmsg, 0, sizeof(*rep_mti));
+        memcpy(rep_mti, mti, sizeof(*rep_mti));
+        rep_mti->mti_rc = rc;
+        RETURN(rc);
+}
+
 int mgs_handle(struct ptlrpc_request *req)
 {
-        int fail = OBD_FAIL_MGS_ALL_REPLY_NET;
+        int fail = OBD_FAIL_MGMT_ALL_REPLY_NET;
         int rc = 0;
-        struct mgs_obd *mgs = NULL; /* quell gcc overwarning */
-        struct obd_device *obd = NULL;
         ENTRY;
+        
+        CERROR("MGS handle\n");
 
-        OBD_FAIL_RETURN(OBD_FAIL_MGS_ALL_REQUEST_NET | OBD_FAIL_ONCE, 0);
+        OBD_FAIL_RETURN(OBD_FAIL_MGMT_ALL_REQUEST_NET | OBD_FAIL_ONCE, 0);
 
         LASSERT(current->journal_info == NULL);
-        /* XXX identical to MDS */
-        if (req->rq_reqmsg->opc != MGS_CONNECT) {
-                struct mgs_export_data *med;
-                int abort_recovery;
-
+        if (req->rq_reqmsg->opc != MGMT_CONNECT) {
                 if (req->rq_export == NULL) {
                         CERROR("lustre_mgs: operation %d on unconnected MGS\n",
                                req->rq_reqmsg->opc);
                         req->rq_status = -ENOTCONN;
                         GOTO(out, rc = -ENOTCONN);
                 }
-
-                med = &req->rq_export->exp_mgs_data;
-                obd = req->rq_export->exp_obd;
-                mgs = &obd->u.mgs;
-
-                /* sanity check: if the xid matches, the request must
-                 * be marked as a resent or replayed */
-                if (req->rq_xid == med->med_mcd->mcd_last_xid)
-                        LASSERTF(lustre_msg_get_flags(req->rq_reqmsg) &
-                                 (MSG_RESENT | MSG_REPLAY),
-                                 "rq_xid "LPU64" matches last_xid, "
-                                 "expected RESENT flag\n",
-                                 req->rq_xid);
-                /* else: note the opposite is not always true; a
-                 * RESENT req after a failover will usually not match
-                 * the last_xid, since it was likely never
-                 * committed. A REPLAYed request will almost never
-                 * match the last xid, however it could for a
-                 * committed, but still retained, open. */
-
-                /* Check for aborted recovery. */
-                spin_lock_bh(&obd->obd_processing_task_lock);
-                abort_recovery = obd->obd_abort_recovery;
-                spin_unlock_bh(&obd->obd_processing_task_lock);
-                if (abort_recovery) {
-                        target_abort_recovery(obd);
-                } 
         }
 
         switch (req->rq_reqmsg->opc) {
-        case MGS_CONNECT:
+        case MGMT_CONNECT:
                 DEBUG_REQ(D_INODE, req, "connect");
-                OBD_FAIL_RETURN(OBD_FAIL_MGS_CONNECT_NET, 0);
+                OBD_FAIL_RETURN(OBD_FAIL_MGMT_CONNECT_NET, 0);
                 rc = target_handle_connect(req, mgs_handle);
-                if (!rc) {
-                        /* Now that we have an export, set mgs. */
-                        obd = req->rq_export->exp_obd;
-                        mgs = mgs_req2mgs(req);
-                }
                 break;
-
-        case MGS_DISCONNECT:
+        case MGMT_DISCONNECT:
                 DEBUG_REQ(D_INODE, req, "disconnect");
-                OBD_FAIL_RETURN(OBD_FAIL_MGS_DISCONNECT_NET, 0);
+                OBD_FAIL_RETURN(OBD_FAIL_MGMT_DISCONNECT_NET, 0);
                 rc = target_handle_disconnect(req);
                 req->rq_status = rc;            /* superfluous? */
                 break;
 
+        case MGMT_TARGET_ADD:
+                CDEBUG(D_INODE, "target add\n");
+                rc = mgs_handle_target_add(req);
+                break;
+        case MGMT_TARGET_DEL:
+                CDEBUG(D_INODE, "target del\n");
+                //rc = mgs_handle_target_del(req);
+                break;
+
         case LDLM_ENQUEUE:
                 DEBUG_REQ(D_INODE, req, "enqueue");
                 OBD_FAIL_RETURN(OBD_FAIL_LDLM_ENQUEUE, 0);
@@ -472,29 +382,9 @@ int mgs_handle(struct ptlrpc_request *req)
 
         LASSERT(current->journal_info == NULL);
 
-        /* If we're DISCONNECTing, the mgs_export_data is already freed */
-        if (!rc && req->rq_reqmsg->opc != MGS_DISCONNECT) {
-                struct mgs_export_data *med = &req->rq_export->exp_mgs_data;
-                req->rq_repmsg->last_xid =
-                        le64_to_cpu(med->med_mcd->mcd_last_xid);
-
-                target_committed_to_req(req);
-        }
-
-        EXIT;
  out:
-
-        if (lustre_msg_get_flags(req->rq_reqmsg) & MSG_LAST_REPLAY) {
-                if (obd && obd->obd_recovering) {
-                        DEBUG_REQ(D_HA, req, "LAST_REPLAY, queuing reply");
-                        return target_queue_final_reply(req, rc);
-                }
-                /* Lost a race with recovery; let the error path DTRT. */
-                rc = req->rq_status = -ENOTCONN;
-        }
-
         target_send_reply(req, rc, fail);
-        return 0;
+        RETURN(0);
 }
 
 static int mgt_setup(struct obd_device *obd, obd_count len, void *buf)
@@ -504,22 +394,22 @@ static int mgt_setup(struct obd_device *obd, obd_count len, void *buf)
         int rc = 0;
         ENTRY;
 
-        lprocfs_init_vars(mgt, &lvars);
-        lprocfs_obd_setup(obd, lvars.obd_vars);
+       lprocfs_init_vars(mgt, &lvars);
+       lprocfs_obd_setup(obd, lvars.obd_vars);
 
         mgs->mgs_service =
                 ptlrpc_init_svc(MGS_NBUFS, MGS_BUFSIZE, MGS_MAXREQSIZE,
-                                MGS_REQUEST_PORTAL, MGC_REPLY_PORTAL,
-                                MGS_SERVICE_WATCHDOG_TIMEOUT,
-                                mgs_handle, "mgs", obd->obd_proc_entry, NULL);
+                                MGS_MAXREPSIZE, MGS_REQUEST_PORTAL, 
+                                MGC_REPLY_PORTAL, MGS_SERVICE_WATCHDOG_TIMEOUT,
+                                mgs_handle, "mgs", obd->obd_proc_entry, NULL,
+                                MGT_NUM_THREADS);
 
         if (!mgs->mgs_service) {
                 CERROR("failed to start service\n");
                 GOTO(err_lprocfs, rc = -ENOMEM);
         }
 
-        rc = ptlrpc_start_n_threads(obd, mgs->mgs_service, MGT_NUM_THREADS,
-                                    "ll_mgt");
+        rc = ptlrpc_start_threads(obd, mgs->mgs_service, "ll_mgt");
         if (rc)
                 GOTO(err_thread, rc);
 
@@ -532,6 +422,7 @@ err_lprocfs:
         return rc;
 }
 
+
 static int mgt_cleanup(struct obd_device *obd)
 {
         struct mgs_obd *mgs = &obd->u.mgs;
@@ -545,15 +436,14 @@ static int mgt_cleanup(struct obd_device *obd)
 }
 
 struct lvfs_callback_ops mgs_lvfs_ops = {
-        l_fid2dentry:     mgs_lvfs_fid2dentry,
-        l_open_llog:      mgs_lvfs_open_llog,
+     //     l_fid2dentry:     mgs_lvfs_fid2dentry,
+    //    l_open_llog:      mgs_lvfs_open_llog,
 };
 
 /* use obd ops to offer management infrastructure */
 static struct obd_ops mgs_obd_ops = {
         .o_owner           = THIS_MODULE,
         .o_connect         = mgs_connect,
-        .o_init_export     = mgs_init_export,
         .o_disconnect      = mgs_disconnect,
         .o_setup           = mgs_setup,
         .o_precleanup      = mgs_precleanup,