Whamcloud - gitweb
another part of code patch of llog_producing
authorlincent <lincent>
Mon, 28 Nov 2005 19:30:52 +0000 (19:30 +0000)
committerlincent <lincent>
Mon, 28 Nov 2005 19:30:52 +0000 (19:30 +0000)
lustre/mds/handler.c
lustre/mgc/mgc_request.c
lustre/mgs/mgs_internal.h
lustre/mgs/mgs_llog.c

index cd25591..d2d0a6f 100644 (file)
@@ -827,7 +827,6 @@ out_ucred:
         return rc;
 }
 
-
 static int mds_obd_statfs(struct obd_device *obd, struct obd_statfs *osfs,
                           unsigned long max_age)
 {
index 57041ee..948a0cd 100644 (file)
 
 #include "mgc_internal.h"
 
-int mgc_mds_add(struct obd_export *exp, struct mgmt_mds_info *minfo)
+int mgc_first_connect(struct obd_export *exp, int disk_type,
+                      char *full_fsname, char *node_name,
+                      int *index)
 {
         struct ptlrpc_request *req;
-        struct mgmt_mds_info *req_minfo, *rep_minfo;
-        int size = sizeof(*req_minfo);
-        int rep_size = sizeof(rep_minfo);
+        int size[3] = {sizeof(disk_type), NAME_MAXLEN, NAME_MAXLEN};
+        int *type;
+        char *fsname, *nodename;
         int rc;
         ENTRY;
 
-        req = ptlrpc_prep_req(class_exp2cliimp(exp), MGMT_REGISTER,
+        req = ptlrpc_prep_req(class_exp2cliimp(exp), MGMT_FIRST_CONNECT,
+                              3, size, NULL);
+        if (!req)
+                RETURN(rc = -ENOMEM);
+
+        type = lustre_msg_buf(req->rq_reqmsg, 0, sizeof(*type));
+        *type = disk_type;
+
+        fsname = lustre_msg_buf(req->rq_reqmsg, 1, NAME_MAXLEN);
+        memcpy(fsname, full_fsname, strlen(full_fsname));
+
+        nodename = lustre_msg_buf(req->rq_reqmsg, 2, NAME_MAXLEN);
+        memcpy(nodename, node_name, strlen(node_name));
+        
+        rc = ptlrpc_queue_wait(req);
+        if (!rc) {
+               int *rep_index;
+               rep_index = lustre_swab_repbuf(req, 0, sizeof(int),
+                                              __swab32s);
+               if (*rep_index >= 0){
+                       CDEBUG(D_INODE, "Get index: %d from mgs.", *rep_index);
+                       *index = *rep_index;
+               }
+               else
+                       CERROR("Can not get index from mgs. rc:%d", *rep_index);
+        }
+
+        ptlrpc_req_finished(req);
+
+        RETURN(rc);
+}
+EXPORT_SYMBOL(mgc_first_connect);
+
+int mgc_mds_add(struct obd_export *exp, struct mgmt_mds_info *mmi)
+{
+        struct ptlrpc_request *req;
+        struct mgmt_mds_info *req_mmi, *rep_mmi;
+        int size = sizeof(*req_mmi);
+        int rep_size = sizeof(rep_mmi);
+        int rc;
+        ENTRY;
+
+        req = ptlrpc_prep_req(class_exp2cliimp(exp), MGMT_MDS_ADD,
                               1, &size, NULL);
         if (!req)
                 RETURN(rc = -ENOMEM);
 
-        req_minfo = lustre_msg_buf(req->rq_reqmsg, 0, sizeof(*req_minfo));
-        memcpy(req_minfo, minfo, sizeof(*req_minfo));
+        req_mmi = lustre_msg_buf(req->rq_reqmsg, 0, sizeof(*req_mmi));
+        memcpy(req_mmi, mmi, sizeof(*req_mmi));
 
         req->rq_replen = lustre_msg_size(1, &rep_size);
 
         rc = ptlrpc_queue_wait(req);
         if (!rc) {
                 int index;
-                rep_minfo = lustre_swab_repbuf(req, 0, sizeof(*rep_minfo),
-                                               lustre_swab_mgmt_mds_info);
-                index = rep_minfo->mmi_index;
-                if (index < 0) {
-                        CERROR("Register failed. rc = %d\n", index);
+                rep_mmi = lustre_swab_repbuf(req, 0, sizeof(*rep_mmi),
+                                             lustre_swab_mgmt_mds_info);
+                index = rep_mmi->mmi_index;
+                if (index != mmi->mmi_index) {
+                        CERROR("MDS ADD failed. rc = %d\n", index);
                         GOTO(out, rc = index);
                 } else 
-                        CERROR("Register OK. (index = %d)\n", index);
+                        CERROR("MDS ADD OK. (index = %d)\n", index);
         }
 out:
         ptlrpc_req_finished(req);
@@ -86,14 +130,12 @@ out:
 }
 EXPORT_SYMBOL(mgc_mds_add);
 
-int mgc_ost_add(struct obd_export *exp, struct mgmt_ost_info *oinfo,
-                struct mgmt_mds_info *minfo)
+int mgc_ost_add(struct obd_export *exp, struct mgmt_ost_info *moi)
 {
         struct ptlrpc_request *req;
-        struct mgmt_ost_info *req_oinfo;
-        int size = sizeof(*req_oinfo);
-        int rep_size[2] = { sizeof(*oinfo),
-                            sizeof(*minfo)};
+        struct mgmt_ost_info *req_moi, *rep_moi;
+        int size = sizeof(*req_moi);
+        int rep_size = sizeof(*moi);
         int rc;
         ENTRY;
 
@@ -102,29 +144,23 @@ int mgc_ost_add(struct obd_export *exp, struct mgmt_ost_info *oinfo,
         if (!req)
                 RETURN(rc = -ENOMEM);
 
-        req_oinfo = lustre_msg_buf(req->rq_reqmsg, 0, sizeof(*req_oinfo));
-        memcpy(req_oinfo, oinfo, sizeof(*req_oinfo));
+        req_moi = lustre_msg_buf(req->rq_reqmsg, 0, sizeof(*req_moi));
+        memcpy(req_moi, moi, sizeof(*req_moi));
 
-        req->rq_replen = lustre_msg_size(2, rep_size);
+        req->rq_replen = lustre_msg_size(1, &rep_size);
 
         rc = ptlrpc_queue_wait(req);
         if (!rc) {
-                struct mgmt_ost_info *rep_oinfo;
-                struct mgmt_mds_info *rep_minfo;
-                rep_oinfo = lustre_swab_repbuf(req, 0, sizeof(*rep_oinfo),
-                                               lustre_swab_mgmt_ost_info);
-                rep_minfo = lustre_swab_repbuf(req, 1, sizeof(*rep_minfo),
-                                               lustre_swab_mgmt_mds_info);
-                if (rep_oinfo->moi_stripe_index == -1) {
-                        CERROR ("Register failed\n");
+                int index;
+                rep_moi = lustre_swab_repbuf(req, 0, sizeof(*rep_moi),
+                                             lustre_swab_mgmt_ost_info);
+                index = rep_moi->moi_stripe_index;
+                if (index != moi->moi_stripe_index) {
+                        CERROR ("OST ADD failed. rc=%d\n", index);
                         GOTO (out, rc = -EINVAL);
                 }
-                CERROR("register OK.(index = %d)\n",
-                        rep_oinfo->moi_stripe_index);
-                memcpy(oinfo, rep_oinfo, sizeof(*oinfo));
-                memcpy(minfo, rep_minfo, sizeof(*minfo));
+                CERROR("OST ADD OK.(index = %d)\n", index);
         }
-
 out:
         ptlrpc_req_finished(req);
 
@@ -132,11 +168,11 @@ out:
 }
 EXPORT_SYMBOL(mgc_ost_add);
 
-int mgc_ost_del(struct obd_export *exp, struct mgmt_ost_info *oinfo)
+int mgc_ost_del(struct obd_export *exp, struct mgmt_ost_info *moi)
 {
         struct ptlrpc_request *req;
-        struct mgmt_ost_info *req_oinfo;
-        int size = sizeof(*req_oinfo);
+        struct mgmt_ost_info *req_moi, *rep_moi;
+        int size = sizeof(*req_moi);
         int rc;
         ENTRY;
 
@@ -145,16 +181,20 @@ int mgc_ost_del(struct obd_export *exp, struct mgmt_ost_info *oinfo)
         if (!req)
                 RETURN(rc = -ENOMEM);
 
-        req_oinfo = lustre_msg_buf(req->rq_reqmsg, 0, sizeof(*req_oinfo));
-        memcpy(req_oinfo, oinfo, sizeof(*req_oinfo));
+        req_moi = lustre_msg_buf(req->rq_reqmsg, 0, sizeof(*req_moi));
+        memcpy(req_moi, moi, sizeof(*req_moi));
 
         rc = ptlrpc_queue_wait(req);
-        if (!rc)
-                CERROR("unregister OK.(old index = %d)\n", 
-                        oinfo->moi_stripe_index);
-        else {
-                CERROR ("Unregister failed\n");
-                GOTO (out, rc = -EINVAL);
+        if (!rc) {
+                int index;
+                rep_moi = lustre_swab_repbuf(req, 0, sizeof(*rep_moi),
+                                             lustre_swab_mgmt_ost_info);
+                index = rep_moi->moi_stripe_index;
+                if (index != moi->moi_stripe_index) {
+                        CERROR ("OST DEL failed. rc=%d\n", index);
+                        GOTO (out, rc = -EINVAL);
+                }
+                CERROR("OST DEL OK.(old index = %d)\n", index);
         }
 out:
         ptlrpc_req_finished(req);
index fe69daf..1a73415 100644 (file)
@@ -16,4 +16,8 @@ static inline struct mgs_obd *mgs_req2mgs(struct ptlrpc_request *req)
         return &req->rq_export->exp_obd->u.mgs;
 }
 
+extern int mgmt_handle_first_connect(struct ptlrpc_request *req);
+extern int mgmt_handle_mds_add(struct ptlrpc_request *req);
+extern int mgmt_handle_ost_add(struct ptlrpc_request *req);
+extern int mgmt_handle_ost_del(struct ptlrpc_request *req);
 #endif
index 8fc2f44..80e4231 100644 (file)
 #include "mgs_internal.h"
 
 static struct lustre_cfg_bufs llog_bufs;
+static int get_index_map_handler(struct llog_handle *llh,
+                                 struct llog_rec_hdr *rec, 
+                                 void *data)
+{
+        void *index_map = data;
+        int cfg_len = rec->lrh_len;
+        char *cfg_buf = (char*) (rec + 1);
+        int rc = 0;
+        ENTRY;
+
+        if (rec->lrh_type == OBD_CFG_REC) {
+                struct lustre_cfg *lcfg;
+                char index_str[16];
+                int i, index;
+
+                rc = lustre_cfg_sanity_check(cfg_buf, cfg_len);
+                if (rc)
+                        GOTO(out, rc);
+
+                lcfg = (struct lustre_cfg *)cfg_buf;
+
+                if (lcfg->lcfg_command == LCFG_LOV_ADD_OBD) {
+                        memset(index_str, 0, 16);
+                        strncpy(index_str, (char *)lustre_cfg_buf(lcfg, 2),
+                                lcfg->lcfg_buflens[2]);
+                        index = simple_strtol(index_str, NULL, 0);
+                        set_bit(i, index_map);
+                }
+                if (lcfg->lcfg_command == LCFG_LOV_DEL_OBD) {
+                        memset(index_str, 0, 16);
+                        strncpy(index_str, (char *)lustre_cfg_buf(lcfg, 2),
+                                lcfg->lcfg_buflens[2]);
+                        index = simple_strtol(index_str, NULL, 0);
+                        clear_bit(i, index_map);
+                }
+        } else {
+                CERROR("unhandled lrh_type: %#x\n", rec->lrh_type);
+                rc = -EINVAL;
+        }
+out:
+        RETURN(rc);
+}
+
+static int get_index_map_from_llog(struct obd_device *obd, char *fsname,
+                                   void *index_map)
+{
+        struct llog_handle *loghandle;
+        struct lvfs_run_ctxt saved;
+        int rc, rc2;
+
+        OBD_ALLOC(index_map, 4096);
+        if (!index_map)
+                return -ENOMEM;
+
+        push_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
+
+        rc = llog_create(llog_get_context(obd, LLOG_CONFIG_REPL_CTXT),
+                         &loghandle, NULL, fsname);
+        if (rc)
+                GOTO(out_pop, rc);
+
+        llog_init_handle(loghandle, 0, NULL);
+        if (rc)
+                GOTO(out_close, rc);
 
+        rc = llog_process(loghandle, get_index_map_handler, 
+                          index_map, NULL);
+
+out_close:
+        rc2 = llog_close(loghandle);
+        if (!rc)
+                rc = rc2;
+out_pop:
+        pop_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
+
+        RETURN(rc);
+}
+
+static int next_ost_index(void *index_map, int map_len)
+{
+        int i;
+        for (i = 0; i < map_len * 8; i++)
+                 if (test_bit(i, index_map))
+                        return i;
+        CERROR("Index exceed upping.\n");
+        return -ERANGE;
+}
+
+static int get_ost_number(void *index_map, int map_len)
+{
+       int i,num;
+       for (i = 0, num = 0; i < map_len * 8; i++)
+               if (test_bit(i, index_map))
+                        num++;
+       return num;
+}
+static int mgs_get_index(struct obd_device *obd, char *full_fsname,
+                         int disk_type, int *new_index)
+{
+        struct mgs_obd *mgs = &obd->u.mgs;
+        struct system_db *db;
+        struct list_head *tmp;
+        int rc = 0;
+
+        list_for_each(tmp, &mgs->mgs_system_db_list) {
+                db = list_entry(tmp, struct system_db, db_list);
+                if (!strcmp(db->fsname, full_fsname)) {
+                        if (disk_type & LDD_F_SV_TYPE_OST)
+                                *new_index = next_ost_index(db->index_map, 4096);
+                        else
+                                *new_index = 1; /*FIXME*/
+                        return 0;
+                }
+        }
+        OBD_ALLOC(db, sizeof(*db));
+        if (!db)
+               return -ENOMEM;
+        strcpy(db->fsname, full_fsname);
+        INIT_LIST_HEAD(&db->db_list);
+        INIT_LIST_HEAD(&db->ost_infos);
+        rc = get_index_map_from_llog(obd, full_fsname, db->index_map);
+        if (rc)
+                GOTO(clean, rc);
+        spin_lock(&mgs->mgs_system_db_lock);
+        list_add(&db->db_list, &mgs->mgs_system_db_list);
+        spin_unlock(&mgs->mgs_system_db_lock);
+
+        *new_index = next_ost_index(db->index_map, 4096);
+
+out:
+        return rc;
+clean:
+        OBD_FREE(db, sizeof(*db));
+        goto out;
+}
+                          
 static int mgs_do_record(struct obd_device *obd, struct llog_handle *llh,
                          void *cfg_buf)
 {
@@ -543,6 +679,7 @@ int mgs_update_llog(struct obd_device *obd, char *name)
         return rc;
 }
 #endif
+
 int decompose_fullfsname(char *fullfsname, char *fsname, char *poolname)
 {
         char *p = NULL;
@@ -561,31 +698,19 @@ int decompose_fullfsname(char *fullfsname, char *fsname, char *poolname)
         return 0;       
 }
 
-int mgs_mds_register(struct ptlrpc_request *req)
+/* Build basic disk directory for llog */
+static int build_llog_dir(struct obd_device *obd, char *full_fsname)
 {
-        struct obd_export *exp = req->rq_export;
-        struct obd_device *obd = exp->exp_obd;
         struct mgs_obd *mgs = &obd->u.mgs;
-        struct mgmt_mds_info *mmi, *rep_mmi;
         struct lvfs_run_ctxt saved;
         struct dentry *fs_dentry, *pool_dentry;
         char *fsname = NULL, *poolname = NULL;
-        int rep_size = sizeof(*rep_mmi);
-        int index, rc;
-
-        mmi = lustre_swab_reqbuf(req, 0, sizeof(*mmi),
-                                 lustre_swab_mgmt_mds_info);
-        if (mmi == NULL) {
-                CERROR("Can't unpack mgmt_mds_info\n");
-                GOTO(out, rc=-EFAULT);
-        }
-
-        CDEBUG(D_INODE, "New mds belong to FS/POOL %s\n", mmi->mmi_fullfsname);
+        int rc;
 
-        rc = decompose_fullfsname(mmi->mmi_fullfsname, fsname, poolname);
+        rc = decompose_fullfsname(full_fsname, fsname, poolname);
         if (rc)
                 GOTO(out, rc);
-
+        
         push_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
 
         fs_dentry = simple_mkdir(mgs->mgs_configs_dir, fsname, 0777, 1);
@@ -602,29 +727,276 @@ int mgs_mds_register(struct ptlrpc_request *req)
                 GOTO(cleanup_dput, rc);
         }
         dput(pool_dentry);
-
-        /*FIXME : change when we can use several mds */
-        mmi->mmi_index = 1;
-
-        rc = mgs_write_basic_llog(obd, mmi);
 cleanup_dput:
         dput(fs_dentry);
 cleanup_pop:
         pop_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
-        OBD_FREE(fsname, sizeof(mmi->mmi_fullfsname));
+        OBD_FREE(fsname, sizeof(full_fsname));
 out:
-        if (rc) 
-                mmi->mmi_index = rc;
-        rc = lustre_pack_reply(req, 1, &rep_size, NULL);
-        if (!rc) {
-                rep_mmi = lustre_msg_buf(req->rq_repmsg, 0, sizeof(*rep_mmi));
-                memcpy(rep_mmi, mmi, sizeof(*mmi));
-        } else {
-                CERROR("lustre_pack_reply failed: rc %d\n", rc);
-                req->rq_status = rc;
+        return rc;
+}
+
+int mgmt_handle_first_connect(struct ptlrpc_request *req)
+{
+        struct obd_export *exp = req->rq_export;
+        struct obd_device *obd = exp->exp_obd;
+        struct mgs_obd *mgs = &obd->u.mgs;
+        __u32  *disk_type;
+        char *full_fsname, *node_name;
+        int rep_size = sizeof(int);
+        int new_index, *rep_index;
+        int rc;
+
+        disk_type = lustre_swab_reqbuf(req, 0, sizeof(*disk_type),
+                                       __swab32s);
+
+        full_fsname = lustre_swab_reqbuf(req, 1, NAME_MAXLEN, NULL);
+
+        node_name = lustre_swab_reqbuf(req, 2, NAME_MAXLEN, NULL);
+
+        if (*disk_type & LDD_F_SV_TYPE_MDT) {
+                CDEBUG(D_INODE,
+                       "New MDS Server belong to FILESYSTEM[/POOL]%s\n",
+                       full_fsname);
+        }
+        else if (*disk_type & LDD_F_SV_TYPE_OST) {
+                CDEBUG(D_INODE,
+                       "New OST Server belong to FILESYSTEM[/POOL]%s\n",
+                       full_fsname);
+
+        }
+        else {
+                CERROR("Wrong disk type register.\n");
+                GOTO(out, rc = -EFAULT);
+        }
+
+        rc = build_llog_dir(obd, full_fsname);
+        if (rc) {
+                CERROR("Can not build llog dir.\n");
+                GOTO(out, rc);
+        }
+
+        rc = mgs_get_index(obd, full_fsname, *disk_type, &new_index);
+        if (rc) {
+                CERROR("Can not get index for the new server.\n" );
+                new_index = rc;
+        }
+
+out:
+        lustre_pack_reply(req, 1, &rep_size, NULL);
+        rep_index = lustre_msg_buf(req->rq_repmsg, 0, sizeof(int));
+        *rep_index = new_index;
+
+        return rc;
+}
+
+static int llog_add_mds(struct obd_device *obd, struct mgmt_mds_info *mmi)
+{
+        struct mgs_obd *mgs = &obd->u.mgs;
+        struct llog_handle *llh;
+        struct system_db *db = NULL;
+        struct list_head *tmp;
+        char logname[64], lov_name[64];
+        char mds_node_uuid[64];
+        char uuid[64];
+        char mdc_name[80];
+        char mdc_uuid[64];
+        char *setup_argv[2];
+        struct lov_desc *ld;
+        int rc = 0;
+
+        list_for_each(tmp, &mgs->mgs_system_db_list) {
+                struct system_db *tmp_db;
+                tmp_db = list_entry(tmp, struct system_db, db_list);
+                if (!strcmp(tmp_db->fsname, mmi->mmi_fullfsname)) {
+                        db = tmp_db;
+                        break;
+                }
         }
+        if (!db)
+                RETURN(-EINVAL);
+
+        llh = llog_alloc_handle();
+        if (llh == NULL)
+                RETURN(-ENOMEM);
+
+        OBD_ALLOC(ld, sizeof(*ld));
+        if (!ld)
+             GOTO(out, rc = -ENOMEM);
+
+        ld->ld_tgt_count = get_ost_number(db->index_map, 4096);
+        ld->ld_default_stripe_count = mmi->mmi_stripe_size;
+        ld->ld_pattern = mmi->mmi_pattern;
+        ld->ld_default_stripe_offset = mmi->mmi_stripe_offset;
+        sprintf((char*)ld->ld_uuid.uuid,  "lov1_UUID");
+
+        /* Two phases: 1. writing mds log. 
+                       2. writing client log
+         */
+
+        /*First phase: writing mds log  */
+        sprintf(logname, "%s/mds1", mmi->mmi_fullfsname);
+
+        rc = mgs_start_record(obd, llh, logname);
+        if (rc) {
+                CERROR("failed to record log %s: %d\n", logname, rc);
+                GOTO(out, rc);;
+        }
+
+        /* the same uuid for lov and osc */
+        sprintf(uuid, "%s_lov_UUID", mmi->mmi_mds_name);
+        sprintf(lov_name, "lov_client");
+
+        rc = record_attach(obd, llh, lov_name, "lov", uuid);
+        if (rc) {
+                CERROR("failed to record log(attach lov) %s: %d\n", logname, rc);
+                GOTO(out, rc);;
+        }
+
+        rc = record_lov_setup(obd, llh, lov_name, ld);
+        if (rc) {
+                CERROR("failed to record log(setup) %s: %d\n", logname, rc);
+                GOTO(out, rc);;
+        }
+
+        rc = record_mount_point(obd, llh, mmi->mmi_mds_name, lov_name, NULL);
+        if (rc) {
+                CERROR("failed to record log(mount_point) %s: %d\n",
+                       logname, rc);
+                GOTO(cleanup, rc);
+        }
+
+        rc = mgs_end_record(obd, llh, logname);
+        if (rc) {
+                CERROR("failed to record log %s: %d\n", logname, rc);
+                GOTO(cleanup, rc);
+        }
+
+        /*Second phase: writing client log  */
+        sprintf(logname, "%s/client", logname);
+
+        rc = mgs_start_record(obd, llh, logname);
+        if (rc) {
+                CERROR("failed to record log %s: %d\n", logname, rc);
+                GOTO(out, rc);;
+        }
+
+        /* the same uuid for lov and osc */
+        sprintf(uuid, "%s_lov_UUID", mmi->mmi_mds_name);
+        sprintf(lov_name, "lov_client");
+
+        rc = record_attach(obd, llh, lov_name, "lov", uuid);
+        if (rc) {
+                CERROR("failed to record log(attach lov) %s: %d\n",
+                       logname, rc);
+                GOTO(out, rc);;
+        }
+
+        rc = record_lov_setup(obd, llh, lov_name, ld);
+        if (rc) {
+                CERROR("failed to record log(setup) %s: %d\n", logname, rc);
+                GOTO(out, rc);;
+        }
+
+        sprintf(mds_node_uuid, "%s_UUID", mmi->mmi_mds_nodename);
+        rc = record_add_uuid(obd, llh, mmi->mmi_nid, mds_node_uuid);
+        if (rc) {
+                CERROR("failed to record log(add uuid) %s: %d\n",
+                       logname, rc);
+                RETURN(rc);
+        }
+    
+        sprintf(mdc_name, "MDC_%s_%s_MNT_client",
+                mmi->mmi_mds_nodename, mmi->mmi_mds_name);
+        sprintf(mdc_uuid, "MDC_%s_UUID", mmi->mmi_fullfsname);
+
+        rc = record_attach(obd, llh, mdc_name, "mdc", mdc_uuid);
+        if (rc) {
+                CERROR("failed to record log(attach) %s: %d\n",
+                       logname, rc);
+                RETURN(rc);
+        }
+
+        sprintf(setup_argv[0],"%s_UUID", mmi->mmi_mds_name);
+        setup_argv[1] = mds_node_uuid;
+        rc = record_setup(obd, llh, mdc_name, 2, setup_argv);
+        if (rc) {
+                CERROR("failed to record log(setup) %s: %d\n",
+                       logname, rc);
+                RETURN(rc);
+        }
+
+        rc = record_mount_point(obd, llh, "client", lov_name, NULL);
+        if (rc) {
+                CERROR("failed to record log(mount_point) %s: %d\n",
+                       logname, rc);
+                RETURN(rc);
+        }
+
+        rc = mgs_end_record(obd, llh, logname);
+        if (rc) {
+                CERROR("failed to record log %s: %d\n", logname, rc);
+                RETURN(rc);
+        }
+
+cleanup:
+        OBD_FREE(ld, sizeof(*ld));
+out:
+        llog_free_handle(llh);
+        return rc;
+}
+
+int mgmt_handle_mds_add(struct ptlrpc_request *req)
+{    
+        struct obd_device *obd = &req->rq_export->exp_obd;
+        struct mgs_obd *mgs = &obd->u.mgs;
+        struct mgmt_mds_info *req_mmi, *mmi, *rep_mmi;
+        int rep_size = sizeof(*mmi);
+        int index, rc;
+
+        OBD_ALLOC(mmi, sizeof(*mmi));
+        if (!mmi)
+                GOTO(out, rc = -ENOMEM);
+        req_mmi = lustre_swab_reqbuf(req, 0, sizeof(*mmi),
+                                     lustre_swab_mgmt_mds_info);
+        memcpy(mmi, req_mmi, sizeof(*mmi));
+        
+        rc = llog_add_mds(obd, mmi);
+out:
+        lustre_pack_reply(req, 1, &rep_size, NULL); 
+        rep_mmi = lustre_msg_buf(req->rq_repmsg, 0, sizeof(*rep_mmi));
+        memcpy(rep_mmi, mmi, sizeof(*rep_mmi));
+        if (rc)
+                rep_mmi->mmi_index = rc;
+        return rc;
+}
+EXPORT_SYMBOL(mgmt_handle_mds_add);
+
+int mgmt_handle_ost_add(struct ptlrpc_request *req)
+{    
+        struct obd_device *obd = &req->rq_export->exp_obd;
+        struct mgs_obd *mgs = &obd->u.mgs;
+        struct mgmt_ost_info *req_moi, *moi, *rep_moi;
+        int rep_size = sizeof(*moi);
+        int index, rc;
+
+        OBD_ALLOC(moi, sizeof(*moi));
+        if (!moi)
+                GOTO(out, rc = -ENOMEM);
+        req_moi = lustre_swab_reqbuf(req, 0, sizeof(*moi),
+                                     lustre_swab_mgmt_ost_info);
+        memcpy(moi, req_moi, sizeof(*moi));
+        
+        rc = llog_add_ost(obd, moi);
+out:
+        lustre_pack_reply(req, 1, &rep_size, NULL); 
+        rep_moi = lustre_msg_buf(req->rq_repmsg, 0, sizeof(*rep_moi));
+        memcpy(rep_moi, moi, sizeof(*rep_moi));
+        if (rc)
+                rep_moi->moi_index = rc;
         return rc;
 }
+EXPORT_SYMBOL(mgmt_handle_ost_add);
 
 int mgs_iocontrol(unsigned int cmd, struct obd_export *exp, int len,
                   void *karg, void *uarg)