Whamcloud - gitweb
Branch HEAD
authorwangdi <wangdi>
Sat, 20 Aug 2005 19:37:38 +0000 (19:37 +0000)
committerwangdi <wangdi>
Sat, 20 Aug 2005 19:37:38 +0000 (19:37 +0000)
land add mds code to HEAD

lustre/include/linux/lustre_cfg.h
lustre/lmv/lmv_internal.h
lustre/lmv/lmv_obd.c
lustre/lov/lov_obd.c
lustre/obdclass/obd_config.c
lustre/utils/lconf
lustre/utils/lctl.c
lustre/utils/lmc
lustre/utils/lustre_cfg.c
lustre/utils/obdctl.h

index 4ccc7b7..649dbd5 100644 (file)
@@ -46,6 +46,7 @@ enum lcfg_command_type {
         LCFG_DEL_CONN       = 0x00cf00e,
         LCFG_SET_SECURITY   = 0x00cf00f,
         LCFG_SET_AUDIT      = 0x00cf010,
+        LCFG_LMV_ADD_MDC    = 0x00cf011,
 };
 
 struct lustre_cfg_bufs {
index 3ac6c5c..76055cb 100644 (file)
 #ifndef _LMV_INTERNAL_H_
 #define _LMV_INTERNAL_H_
 
+#define LMV_MAX_TGT_COUNT 128
+
+#define lmv_init_lock(lmv)   down(&lmv->init_sem);
+#define lmv_init_unlock(lmv) up(&lmv->init_sem);
+
 #define LL_IT2STR(it)                                  \
        ((it) ? ldlm_it2str((it)->it_op) : "0")
 
index 2fd67cb..eda7df2 100644 (file)
@@ -225,7 +225,6 @@ static int lmv_connect(struct lustre_handle *conn, struct obd_device *obd,
         lmv->connected = 0;
         lmv->cluuid = *cluuid;
         lmv->connect_flags = flags;
-        sema_init(&lmv->init_sem, 1);
         if (data)
                 memcpy(&lmv->conn_data, data, sizeof(*data));
 
@@ -240,7 +239,7 @@ static int lmv_connect(struct lustre_handle *conn, struct obd_device *obd,
 #endif
 
         /* 
-         * all real clients shouls perform actual connection rightaway, because
+         * all real clients should perform actual connection rightaway, because
          * it is possible, that LMV will not have opportunity to connect
          * targets, as MDC stuff will bit called directly, for instance while
          * reading ../mdc/../kbytesfree procfs file, etc.
@@ -280,145 +279,270 @@ static void lmv_set_timeouts(struct obd_device *obd)
         }
 }
 
+static int lmv_init_ea_size(struct obd_export *exp, int easize,
+                            int cookiesize)
+{
+        struct obd_device *obd = exp->exp_obd;
+        struct lmv_obd *lmv = &obd->u.lmv;
+        int i, rc = 0, change = 0;
+        ENTRY;
+
+        if (lmv->max_easize < easize) {
+                lmv->max_easize = easize;
+                change = 1;
+        }
+        if (lmv->max_cookiesize < cookiesize) {
+                lmv->max_cookiesize = cookiesize;
+                change = 1;
+        }
+        if (change == 0)
+                RETURN(0);
+        
+        if (lmv->connected == 0)
+                RETURN(0);
+
+        for (i = 0; i < lmv->desc.ld_tgt_count; i++) {
+                if (lmv->tgts[i].ltd_exp == NULL) {
+                        CWARN("%s: NULL export for %d\n", obd->obd_name, i);
+                        continue;
+                }
+
+                rc = obd_init_ea_size(lmv->tgts[i].ltd_exp, easize, cookiesize);
+                if (rc) {
+                        CERROR("obd_init_ea_size() failed on MDT target %d, "
+                               "error %d.\n", i, rc);
+                        break;
+                }
+        }
+        RETURN(rc);
+}
+
 #define MAX_STRING_SIZE 128
 
-/* performs a check if passed obd is connected. If no - connect it. */
-int lmv_check_connect(struct obd_device *obd)
+int lmv_connect_mdc(struct obd_device *obd, struct lmv_tgt_desc *tgt)
 {
+        struct lmv_obd *lmv = &obd->u.lmv;
+        struct obd_uuid *cluuid = &lmv->cluuid;
+        struct obd_uuid lmv_mdc_uuid = { "LMV_MDC_UUID" };
+        struct lustre_handle conn = {0, };
+        struct obd_device *mdc_obd;
+        struct obd_export *mdc_exp;
+        int rc;
 #ifdef __KERNEL__
         struct proc_dir_entry *lmv_proc_dir;
 #endif
-        struct lmv_obd *lmv = &obd->u.lmv;
-        struct lmv_tgt_desc *tgts;
-        struct obd_uuid *cluuid;
-        struct obd_export *exp;
-        int rc, rc2, i;
         ENTRY;
 
-        if (lmv->connected)
-                RETURN(0);
-        
-        down(&lmv->init_sem);
-        if (lmv->connected) {
-                up(&lmv->init_sem);
+        /* for MDS: don't connect to yourself */
+        if (obd_uuid_equals(&tgt->uuid, cluuid)) {
+                CDEBUG(D_CONFIG, "don't connect back to %s\n", cluuid->uuid);
+                /* XXX - the old code didn't increment active tgt count.
+                 *       should we ? */
                 RETURN(0);
         }
 
-        cluuid = &lmv->cluuid;
-        exp = lmv->exp;
+        mdc_obd = class_find_client_obd(&tgt->uuid, OBD_MDC_DEVICENAME,
+                                        &obd->obd_uuid);
+        if (!mdc_obd) {
+                CERROR("target %s not attached\n", tgt->uuid.uuid);
+                RETURN(-EINVAL);
+        }
+
+        CDEBUG(D_CONFIG, "connect to %s(%s) - %s, %s FOR %s\n",
+                mdc_obd->obd_name, mdc_obd->obd_uuid.uuid,
+                tgt->uuid.uuid, obd->obd_uuid.uuid,
+                cluuid->uuid);
+
+        if (!mdc_obd->obd_set_up) {
+                CERROR("target %s not set up\n", tgt->uuid.uuid);
+                RETURN(-EINVAL);
+        }
         
-        CDEBUG(D_OTHER, "time to connect %s to %s\n",
-               cluuid->uuid, obd->obd_name);
+        rc = obd_connect(&conn, mdc_obd, &lmv_mdc_uuid, &lmv->conn_data,
+                         lmv->connect_flags);
+        if (rc) {
+                CERROR("target %s connect error %d\n", tgt->uuid.uuid, rc);
+                RETURN(rc);
+        }
 
-        for (i = 0, tgts = lmv->tgts; i < lmv->desc.ld_tgt_count; i++, tgts++) {
-                struct obd_uuid lmv_mdc_uuid = { "LMV_MDC_UUID" };
-                struct lustre_handle conn = {0, };
-                struct obd_device *tgt_obd;
+        mdc_exp = class_conn2export(&conn);
 
-                LASSERT(tgts != NULL);
+        rc = obd_register_observer(mdc_obd, obd);
+        if (rc) {
+                obd_disconnect(mdc_exp, 0);
+                CERROR("target %s register_observer error %d\n",
+                       tgt->uuid.uuid, rc);
+                RETURN(rc);
+        }
 
-                tgt_obd = class_find_client_obd(&tgts->uuid, OBD_MDC_DEVICENAME, 
-                                                &obd->obd_uuid);
-                if (!tgt_obd) {
-                        CERROR("target %s not attached\n", tgts->uuid.uuid);
-                        GOTO(out_disc, rc = -EINVAL);
+        if (obd->obd_observer) {
+                /* tell the mds_lmv about the new target */
+                rc = obd_notify(obd->obd_observer, mdc_exp->exp_obd, 1,
+                                (void *)(tgt - lmv->tgts));
+                if (rc) {
+                        obd_disconnect(mdc_exp, 0);
+                        RETURN(rc);
                 }
+        }
 
-                /* for MDS: don't connect to yourself */
-                if (obd_uuid_equals(&tgts->uuid, cluuid)) {
-                        CDEBUG(D_OTHER, "don't connect back to %s\n",
-                               cluuid->uuid);
-                        tgts->ltd_exp = NULL;
-                        continue;
+        tgt->ltd_exp = mdc_exp;
+        tgt->active = 1; 
+        lmv->desc.ld_active_tgt_count++;
+
+        obd_init_ea_size(tgt->ltd_exp, lmv->max_easize,
+                         lmv->max_cookiesize);
+        CDEBUG(D_CONFIG, "connected to %s(%s) successfully (%d)\n",
+                mdc_obd->obd_name, mdc_obd->obd_uuid.uuid,
+                atomic_read(&obd->obd_refcount));
+
+#ifdef __KERNEL__
+        lmv_proc_dir = lprocfs_srch(obd->obd_proc_entry, "target_obds");
+        if (lmv_proc_dir) {
+                struct proc_dir_entry *mdc_symlink;
+                char name[MAX_STRING_SIZE + 1];
+
+                LASSERT(mdc_obd->obd_type != NULL);
+                LASSERT(mdc_obd->obd_type->typ_name != NULL);
+                name[MAX_STRING_SIZE] = '\0';
+                snprintf(name, MAX_STRING_SIZE, "../../../%s/%s",
+                         mdc_obd->obd_type->typ_name,
+                         mdc_obd->obd_name);
+                mdc_symlink = proc_symlink(mdc_obd->obd_name,
+                                           lmv_proc_dir, name);
+                if (mdc_symlink == NULL) {
+                        CERROR("could not register LMV target "
+                               "/proc/fs/lustre/%s/%s/target_obds/%s.",
+                               obd->obd_type->typ_name, obd->obd_name,
+                               mdc_obd->obd_name);
+                        lprocfs_remove(lmv_proc_dir);
+                        lmv_proc_dir = NULL;
                 }
+        }
+#endif
+        RETURN(0);
+}
 
-                CDEBUG(D_OTHER, "connect to %s(%s) - %s, %s FOR %s\n",
-                        tgt_obd->obd_name, tgt_obd->obd_uuid.uuid,
-                        tgts->uuid.uuid, obd->obd_uuid.uuid,
-                        cluuid->uuid);
+int lmv_add_mdc(struct obd_device *obd, struct obd_uuid *mdc_uuid)
+{
+        struct lmv_obd *lmv = &obd->u.lmv;
+        struct lmv_tgt_desc *tgt;
+        int rc = 0;
+        ENTRY;
+
+        CDEBUG(D_CONFIG, "mdc_uuid: %s.\n", mdc_uuid->uuid);
 
-                if (!tgt_obd->obd_set_up) {
-                        CERROR("target %s not set up\n", tgts->uuid.uuid);
-                        GOTO(out_disc, rc = -EINVAL);
+        lmv_init_lock(lmv);
+
+        if (lmv->desc.ld_active_tgt_count >= LMV_MAX_TGT_COUNT) {
+                lmv_init_unlock(lmv);
+                CERROR("can't add %s, LMV module compiled for %d MDCs. "
+                       "That many MDCs already configured.\n",
+                       mdc_uuid->uuid, LMV_MAX_TGT_COUNT);
+                RETURN(-EINVAL);
+        }
+
+        if (lmv->desc.ld_tgt_count == 0) {
+                struct obd_device *mdc_obd;
+
+                mdc_obd = class_find_client_obd(mdc_uuid, OBD_MDC_DEVICENAME,
+                                                &obd->obd_uuid);
+                if (!mdc_obd) {
+                        lmv_init_unlock(lmv);
+                        CERROR("Target %s not attached\n", mdc_uuid->uuid);
+                        RETURN(-EINVAL);
                 }
-                
-                rc = obd_connect(&conn, tgt_obd, &lmv_mdc_uuid, &lmv->conn_data,
-                                 lmv->connect_flags);
+
+                rc = obd_llog_init(obd, &obd->obd_llogs, mdc_obd, 0, NULL);
                 if (rc) {
-                        CERROR("target %s connect error %d\n",
-                                tgts->uuid.uuid, rc);
-                        GOTO(out_disc, rc);
+                        lmv_init_unlock(lmv);
+                        CERROR("lmv failed to setup llogging subsystems\n");
                 }
-                tgts->ltd_exp = class_conn2export(&conn);
+        }
 
-                obd_init_ea_size(tgts->ltd_exp, lmv->max_easize,
-                                 lmv->max_cookiesize);
+        spin_lock(&lmv->lmv_lock);
+        tgt = lmv->tgts + lmv->desc.ld_tgt_count++;
+        tgt->uuid = *mdc_uuid;
+        spin_unlock(&lmv->lmv_lock);
 
-                rc = obd_register_observer(tgt_obd, obd);
+        if (lmv->connected) {
+                rc = lmv_connect_mdc(obd, tgt);
                 if (rc) {
-                        CERROR("target %s register_observer error %d\n",
-                               tgts->uuid.uuid, rc);
-                        obd_disconnect(tgts->ltd_exp, 0);
-                        GOTO(out_disc, rc);
+                        spin_lock(&lmv->lmv_lock);
+                        lmv->desc.ld_tgt_count--;
+                        memset(tgt, 0, sizeof(*tgt));
+                        spin_unlock(&lmv->lmv_lock);
+                } else {
+                        int easize = sizeof(struct mea) +
+                                     lmv->desc.ld_tgt_count *
+                                     sizeof(struct lustre_id);
+                        lmv_init_ea_size(obd->obd_self_export, easize, 0);
                 }
+        }
+
+        lmv_init_unlock(lmv);
+        RETURN(rc);
+}
+
+/* performs a check if passed obd is connected. If no - connect it. */
+int lmv_check_connect(struct obd_device *obd)
+{
+        struct lmv_obd *lmv = &obd->u.lmv;
+        struct lmv_tgt_desc *tgt;
+        int i, rc, easize;
+        ENTRY;
 
-                lmv->desc.ld_active_tgt_count++;
-                tgts->active = 1;
+        if (lmv->connected)
+                RETURN(0);
+        
+        lmv_init_lock(lmv);
+        if (lmv->connected) {
+                lmv_init_unlock(lmv);
+                RETURN(0);
+        }
 
-                CDEBUG(D_OTHER, "connected to %s(%s) successfully (%d)\n",
-                        tgt_obd->obd_name, tgt_obd->obd_uuid.uuid,
-                        atomic_read(&obd->obd_refcount));
+        if (lmv->desc.ld_tgt_count == 0) {
+                CERROR("%s: no targets configured.\n", obd->obd_name);
+                RETURN(-EINVAL);
+        }
 
-#ifdef __KERNEL__
-                lmv_proc_dir = lprocfs_srch(obd->obd_proc_entry, "target_obds");
-                if (lmv_proc_dir) {
-                        struct obd_device *mdc_obd = class_conn2obd(&conn);
-                        struct proc_dir_entry *mdc_symlink;
-                        char name[MAX_STRING_SIZE + 1];
-
-                        LASSERT(mdc_obd != NULL);
-                        LASSERT(mdc_obd->obd_type != NULL);
-                        LASSERT(mdc_obd->obd_type->typ_name != NULL);
-                        name[MAX_STRING_SIZE] = '\0';
-                        snprintf(name, MAX_STRING_SIZE, "../../../%s/%s",
-                                 mdc_obd->obd_type->typ_name,
-                                 mdc_obd->obd_name);
-                        mdc_symlink = proc_symlink(mdc_obd->obd_name,
-                                                   lmv_proc_dir, name);
-                        if (mdc_symlink == NULL) {
-                                CERROR("could not register LMV target "
-                                       "/proc/fs/lustre/%s/%s/target_obds/%s.",
-                                       obd->obd_type->typ_name, obd->obd_name,
-                                       mdc_obd->obd_name);
-                                lprocfs_remove(lmv_proc_dir);
-                                lmv_proc_dir = NULL;
-                        }
-                }
-#endif
+        CDEBUG(D_CONFIG, "time to connect %s to %s\n",
+               lmv->cluuid.uuid, obd->obd_name);
+
+        LASSERT(lmv->tgts != NULL);
+
+        for (i = 0, tgt = lmv->tgts; i < lmv->desc.ld_tgt_count; i++, tgt++) {
+                rc = lmv_connect_mdc(obd, tgt);
+                if (rc)
+                        GOTO(out_disc, rc);
         }
 
         lmv_set_timeouts(obd);
-        class_export_put(exp);
+        class_export_put(lmv->exp);
         lmv->connected = 1;
-        up(&lmv->init_sem);
+        easize = lmv->desc.ld_tgt_count * sizeof(struct lustre_id) +
+                 sizeof(struct mea);
+        lmv_init_ea_size(obd->obd_self_export, easize, 0);
+        lmv_init_unlock(lmv);
         RETURN(0);
 
  out_disc:
         while (i-- > 0) {
-                struct obd_uuid uuid;
-                --tgts;
-                --lmv->desc.ld_active_tgt_count;
-                tgts->active = 0;
-                /* save for CERROR below; (we know it's terminated) */
-                uuid = tgts->uuid;
-                rc2 = obd_disconnect(tgts->ltd_exp, 0);
-                if (rc2)
-                        CERROR("error: LMV target %s disconnect on MDC idx %d: "
-                               "error %d\n", uuid.uuid, i, rc2);
-        }
-        class_disconnect(exp, 0);
-        up(&lmv->init_sem);
-        return rc;
+                int rc2;
+                --tgt;
+                tgt->active = 0;
+                if (tgt->ltd_exp) {
+                        --lmv->desc.ld_active_tgt_count;
+                        rc2 = obd_disconnect(tgt->ltd_exp, 0);
+                        if (rc2) {
+                                CERROR("error: LMV target %s disconnect on "
+                                       "MDC idx %d: error %d\n",
+                                       tgt->uuid.uuid, i, rc2);
+                        }
+                }
+        }
+        class_disconnect(lmv->exp, 0);
+        lmv_init_unlock(lmv);
+        RETURN(rc);
 }
 
 static int lmv_disconnect(struct obd_export *exp, unsigned long flags)
@@ -544,13 +668,10 @@ static int lmv_iocontrol(unsigned int cmd, struct obd_export *exp,
 
 static int lmv_setup(struct obd_device *obd, obd_count len, void *buf)
 {
-        int i, rc = 0;
-        struct lmv_desc *desc;
-        struct obd_uuid *uuids;
-        struct lmv_tgt_desc *tgts;
-        struct obd_device *tgt_obd;
-        struct lustre_cfg *lcfg = buf;
         struct lmv_obd *lmv = &obd->u.lmv;
+        struct lustre_cfg *lcfg = buf;
+        struct lmv_desc *desc;
+        int rc = 0;
         ENTRY;
 
         if (LUSTRE_CFG_BUFLEN(lcfg, 1) < 1) {
@@ -558,11 +679,6 @@ static int lmv_setup(struct obd_device *obd, obd_count len, void *buf)
                 RETURN(-EINVAL);
         }
 
-        if (LUSTRE_CFG_BUFLEN(lcfg, 2) < 1) {
-                CERROR("LMV setup requires an MDT UUID list\n");
-                RETURN(-EINVAL);
-        }
-
         desc = (struct lmv_desc *)lustre_cfg_buf(lcfg, 1);
         if (sizeof(*desc) > LUSTRE_CFG_BUFLEN(lcfg, 1)) {
                 CERROR("descriptor size wrong: %d > %d\n",
@@ -570,31 +686,23 @@ static int lmv_setup(struct obd_device *obd, obd_count len, void *buf)
                 RETURN(-EINVAL);
         }
 
-        uuids = (struct obd_uuid *)lustre_cfg_buf(lcfg, 2);
-        if (sizeof(*uuids) * desc->ld_tgt_count != LUSTRE_CFG_BUFLEN(lcfg, 2)) {
-                CERROR("UUID array size wrong: %u * %u != %u\n",
-                       sizeof(*uuids), desc->ld_tgt_count, LUSTRE_CFG_BUFLEN(lcfg, 2));
-                RETURN(-EINVAL);
-        }
+        lmv->tgts_size = LMV_MAX_TGT_COUNT * sizeof(struct lmv_tgt_desc);
 
-        lmv->tgts_size = sizeof(struct lmv_tgt_desc) * desc->ld_tgt_count;
         OBD_ALLOC(lmv->tgts, lmv->tgts_size);
         if (lmv->tgts == NULL) {
                 CERROR("Out of memory\n");
                 RETURN(-ENOMEM);
         }
 
-        lmv->desc = *desc;
-        spin_lock_init(&lmv->lmv_lock);
-        
-        for (i = 0, tgts = lmv->tgts; i < desc->ld_tgt_count; i++, tgts++)
-                tgts->uuid = uuids[i];
-        
+        obd_str2uuid(&lmv->desc.ld_uuid, desc->ld_uuid.uuid);
+        lmv->desc.ld_tgt_count = 0;
+        lmv->desc.ld_active_tgt_count = 0;
         lmv->max_cookiesize = 0;
+        lmv->max_easize = 0;
+
+        spin_lock_init(&lmv->lmv_lock);
+        sema_init(&lmv->init_sem, 1);
 
-        lmv->max_easize = sizeof(struct lustre_id) *
-                desc->ld_tgt_count + sizeof(struct mea);
-        
         rc = lmv_setup_mgr(obd);
         if (rc) {
                 CERROR("Can't setup LMV object manager, "
@@ -603,18 +711,6 @@ static int lmv_setup(struct obd_device *obd, obd_count len, void *buf)
                 RETURN(rc);
         }
 
-        tgt_obd = class_find_client_obd(&lmv->tgts->uuid, OBD_MDC_DEVICENAME,
-                                        &obd->obd_uuid);
-        if (!tgt_obd) {
-                CERROR("Target %s not attached\n", lmv->tgts->uuid.uuid);
-                RETURN(-EINVAL);
-        }
-
-        rc = obd_llog_init(obd, &obd->obd_llogs, tgt_obd, 0, NULL);
-        if (rc) {
-                CERROR("lmv_setup failed to setup llogging subsystems\n");
-        }
-
         RETURN(rc);
 }
 
@@ -629,6 +725,30 @@ static int lmv_cleanup(struct obd_device *obd, int flags)
         RETURN(0);
 }
 
+static int lmv_process_config(struct obd_device *obd, obd_count len, void *buf)
+{
+        struct lustre_cfg *lcfg = buf;
+        struct obd_uuid mdc_uuid;
+        int rc;
+        ENTRY;
+
+        switch(lcfg->lcfg_command) {
+        case LCFG_LMV_ADD_MDC:
+                if (LUSTRE_CFG_BUFLEN(lcfg, 1) > sizeof(mdc_uuid.uuid))
+                        GOTO(out, rc = -EINVAL);
+
+                obd_str2uuid(&mdc_uuid, lustre_cfg_string(lcfg, 1));
+               rc = lmv_add_mdc(obd, &mdc_uuid);
+                GOTO(out, rc);
+        default: {
+                CERROR("Unknown command: %d\n", lcfg->lcfg_command);
+                GOTO(out, rc = -EINVAL);
+        }
+        }
+out:
+        RETURN(rc);
+}
+
 static int lmv_statfs(struct obd_device *obd, struct obd_statfs *osfs,
                       unsigned long max_age)
 {
@@ -644,7 +764,7 @@ static int lmv_statfs(struct obd_device *obd, struct obd_statfs *osfs,
         OBD_ALLOC(temp, sizeof(*temp));
         if (temp == NULL)
                 RETURN(-ENOMEM);
-                
+               
         for (i = 0; i < lmv->desc.ld_tgt_count; i++) {
                 if (lmv->tgts[i].ltd_exp == NULL)
                         continue;
@@ -1653,44 +1773,6 @@ static struct obd_device *lmv_get_real_obd(struct obd_export *exp,
         return obd;
 }
 
-static int lmv_init_ea_size(struct obd_export *exp, int easize,
-                            int cookiesize)
-{
-        struct obd_device *obd = exp->exp_obd;
-        struct lmv_obd *lmv = &obd->u.lmv;
-        int i, rc = 0, change = 0;
-        ENTRY;
-
-        if (lmv->max_easize < easize) {
-                lmv->max_easize = easize;
-                change = 1;
-        }
-        if (lmv->max_cookiesize < cookiesize) {
-                lmv->max_cookiesize = cookiesize;
-                change = 1;
-        }
-        if (change == 0)
-                RETURN(0);
-        
-        if (lmv->connected == 0)
-                RETURN(0);
-
-        for (i = 0; i < lmv->desc.ld_tgt_count; i++) {
-                if (lmv->tgts[i].ltd_exp == NULL) {
-                        CWARN("%s: NULL export for %d\n", obd->obd_name, i);
-                        continue;
-                }
-
-                rc = obd_init_ea_size(lmv->tgts[i].ltd_exp, easize, cookiesize);
-                if (rc) {
-                        CERROR("obd_init_ea_size() failed on MDT target %d, "
-                               "error %d.\n", i, rc);
-                        break;
-                }
-        }
-        RETURN(rc);
-}
-
 static int lmv_obd_create_single(struct obd_export *exp, struct obdo *oa,
                                  void *acl, int acl_size,
                                  struct lov_stripe_md **ea,
@@ -1879,7 +1961,7 @@ static int lmv_get_info(struct obd_export *exp, __u32 keylen,
                 __u32 *mdsize = val;
                 *vallen = sizeof(__u32);
                 *mdsize = sizeof(struct lustre_id) * lmv->desc.ld_tgt_count
-                        + sizeof(struct mea);
+                       + sizeof(struct mea);
                 RETURN(0);
         } else if (keylen == strlen("mdsnum") && !strcmp(key, "mdsnum")) {
                 struct obd_uuid *cluuid = &lmv->cluuid;
@@ -1887,7 +1969,8 @@ static int lmv_get_info(struct obd_export *exp, __u32 keylen,
                 __u32 *mdsnum = val;
                 int i;
 
-                for (i = 0, tgts = lmv->tgts; i < lmv->desc.ld_tgt_count; i++, tgts++) {
+                tgts = lmv->tgts;
+                for (i = 0; i < lmv->desc.ld_tgt_count; i++, tgts++) {
                         if (obd_uuid_equals(&tgts->uuid, cluuid)) {
                                 *vallen = sizeof(__u32);
                                 *mdsnum = i;
@@ -2282,6 +2365,7 @@ struct obd_ops lmv_obd_ops = {
         .o_detach               = lmv_detach,
         .o_setup                = lmv_setup,
         .o_cleanup              = lmv_cleanup,
+        .o_process_config       = lmv_process_config,
         .o_connect              = lmv_connect,
         .o_disconnect           = lmv_disconnect,
         .o_statfs               = lmv_statfs,
index e41219d..2df455b 100644 (file)
@@ -466,11 +466,8 @@ static int lov_setup(struct obd_device *obd, obd_count len, void *buf)
                        desc->ld_default_stripe_size, count, ~0UL);
                 RETURN(-EINVAL);
         }
-        if (desc->ld_tgt_count > 0) {
-                lov->bufsize= sizeof(struct lov_tgt_desc) * desc->ld_tgt_count;
-        } else {
-                lov->bufsize = sizeof(struct lov_tgt_desc) * LOV_MAX_TGT_COUNT;  
-        }
+
+        lov->bufsize = sizeof(struct lov_tgt_desc) * LOV_MAX_TGT_COUNT;  
         OBD_ALLOC(lov->tgts, lov->bufsize);
         if (lov->tgts == NULL) {
                 lov->bufsize = 0;
index f562487..b659c1d 100644 (file)
@@ -68,7 +68,7 @@ static int class_attach(struct lustre_cfg *lcfg)
         }
         uuid = lustre_cfg_string(lcfg, 2);
 
-        CDEBUG(D_IOCTL, "attach type %s name: %s uuid: %s\n",
+        CDEBUG(D_CONFIG, "attach type %s name: %s uuid: %s\n",
                MKSTR(typename), MKSTR(name), MKSTR(uuid));
 
         /* find the type */
@@ -491,7 +491,7 @@ int class_process_config(struct lustre_cfg *lcfg)
 
         LASSERT(lcfg && !IS_ERR(lcfg));
 
-        CDEBUG(D_IOCTL, "processing cmd: %x\n", lcfg->lcfg_command);
+        CDEBUG(D_CONFIG, "processing cmd: %x\n", lcfg->lcfg_command);
 
         /* Commands that don't need a device */
         switch(lcfg->lcfg_command) {
@@ -500,8 +500,9 @@ int class_process_config(struct lustre_cfg *lcfg)
                 GOTO(out, err);
         }
         case LCFG_ADD_UUID: {
-                CDEBUG(D_IOCTL, "adding mapping from uuid %s to nid "LPX64
-                       " (%s), nal %x\n", lustre_cfg_string(lcfg, 1), lcfg->lcfg_nid,
+                CDEBUG(D_CONFIG, "adding mapping from uuid %s to nid "LPX64
+                       " (%s), nal %x\n", lustre_cfg_string(lcfg, 1),
+                       lcfg->lcfg_nid,
                        portals_nid2str(lcfg->lcfg_nal, lcfg->lcfg_nid, str),
                        lcfg->lcfg_nal);
 
@@ -510,7 +511,7 @@ int class_process_config(struct lustre_cfg *lcfg)
                GOTO(out, err);
         }
         case LCFG_DEL_UUID: {
-                CDEBUG(D_IOCTL, "removing mappings for uuid %s\n",
+                CDEBUG(D_CONFIG, "removing mappings for uuid %s\n",
                        (lcfg->lcfg_bufcount < 2 || LUSTRE_CFG_BUFLEN(lcfg, 1) == 0)
                        ? "<all uuids>" : lustre_cfg_string(lcfg, 1));
 
@@ -518,7 +519,7 @@ int class_process_config(struct lustre_cfg *lcfg)
                 GOTO(out, err);
         }
         case LCFG_MOUNTOPT: {
-                CDEBUG(D_IOCTL, "mountopt: profile %s osc %s mdc %s gkc %s \n",
+                CDEBUG(D_CONFIG, "mountopt: profile %s osc %s mdc %s gkc %s \n",
                        lustre_cfg_string(lcfg, 1),
                        lustre_cfg_string(lcfg, 2),
                        lustre_cfg_string(lcfg, 3),
@@ -536,7 +537,7 @@ int class_process_config(struct lustre_cfg *lcfg)
                 GOTO(out, err);
         }
         case LCFG_DEL_MOUNTOPT: {
-                CDEBUG(D_IOCTL, "mountopt: profile %s\n",
+                CDEBUG(D_CONFIG, "mountopt: profile %s\n",
                        lustre_cfg_string(lcfg, 1));
                 /* set these mount options somewhere, so ll_fill_super
                  * can find them. */
@@ -544,14 +545,14 @@ int class_process_config(struct lustre_cfg *lcfg)
                 GOTO(out, err = 0);
         }
         case LCFG_SET_TIMEOUT: {
-                CDEBUG(D_IOCTL, "changing lustre timeout from %d to %d\n",
+                CDEBUG(D_CONFIG, "changing lustre timeout from %d to %d\n",
                        obd_timeout,
                        lcfg->lcfg_num);
                 obd_timeout = lcfg->lcfg_num;
                 GOTO(out, err = 0);
         }
         case LCFG_SET_UPCALL: {
-                CDEBUG(D_IOCTL, "setting lustre ucpall to: %s\n",
+                CDEBUG(D_CONFIG, "setting lustre ucpall to: %s\n",
                        lustre_cfg_string(lcfg, 1));
                 if (LUSTRE_CFG_BUFLEN(lcfg, 1) > sizeof obd_lustre_upcall)
                         GOTO(out, err = -EINVAL);
@@ -617,10 +618,8 @@ static int class_config_parse_handler(struct llog_handle * handle,
         if (rec->lrh_type == OBD_CFG_REC) {
                 struct lustre_cfg *lcfg, *lcfg_new;
                 struct lustre_cfg_bufs bufs;
-
                 char *inst_name = NULL;
                 int inst_len = 0;
-                int inst = 0;
 
                 lcfg = (struct lustre_cfg *)cfg_buf;
                 if (lcfg->lcfg_version == __swab32(LUSTRE_CFG_VERSION))
@@ -631,29 +630,30 @@ static int class_config_parse_handler(struct llog_handle * handle,
                         GOTO(out, rc);
 
                 lustre_cfg_bufs_init(&bufs, lcfg);
-                if (cfg && cfg->cfg_instance && LUSTRE_CFG_BUFLEN(lcfg, 0) > 0) {
-                        inst = 1;
-                        inst_len = LUSTRE_CFG_BUFLEN(lcfg, 0) +
-                                strlen(cfg->cfg_instance) + 1;
-                        OBD_ALLOC(inst_name, inst_len);
-                        if (inst_name == NULL)
-                                GOTO(out, rc = -ENOMEM);
-                        sprintf(inst_name, "%s-%s",
-                                lustre_cfg_string(lcfg, 0),
-                                cfg->cfg_instance);
-                        lustre_cfg_bufs_set_string(&bufs, 0, inst_name);
-
-                }
-                if (cfg && lcfg->lcfg_command == LCFG_ATTACH)
-                        lustre_cfg_bufs_set_string(&bufs, 2,
-                                                   (char *)cfg->cfg_uuid.uuid);
-
-                if (cfg && cfg->cfg_instance && 
-                    lcfg->lcfg_command == LCFG_SETUP) {
-                        /*add cfg_instance to the end of lcfg buffers*/
-                        lustre_cfg_bufs_set_string(&bufs, bufs.lcfg_bufcount, 
-                                                   cfg->cfg_instance); 
+                if (cfg && cfg->cfg_instance) {
+                        if (LUSTRE_CFG_BUFLEN(lcfg, 0) > 0) {
+                                inst_len = LUSTRE_CFG_BUFLEN(lcfg, 0) +
+                                        strlen(cfg->cfg_instance) + 1;
+                                OBD_ALLOC(inst_name, inst_len);
+                                if (inst_name == NULL)
+                                        GOTO(out, rc = -ENOMEM);
+                                sprintf(inst_name, "%s-%s",
+                                        lustre_cfg_string(lcfg, 0),
+                                        cfg->cfg_instance);
+                                lustre_cfg_bufs_set_string(&bufs, 0, inst_name);
+                        }
+                        if (lcfg->lcfg_command == LCFG_ATTACH) {
+                                lustre_cfg_bufs_set_string(&bufs, 2,
+                                                    (char *)cfg->cfg_uuid.uuid);
+                        }
+                        if (lcfg->lcfg_command == LCFG_SETUP) {
+                                /*add cfg_instance to the end of lcfg buffers*/
+                                lustre_cfg_bufs_set_string(&bufs,
+                                                           bufs.lcfg_bufcount, 
+                                                           cfg->cfg_instance); 
+                        }
                 }
+
                 lcfg_new = lustre_cfg_new(lcfg->lcfg_command, &bufs);
 
                 lcfg_new->lcfg_num   = lcfg->lcfg_num;
@@ -664,7 +664,7 @@ static int class_config_parse_handler(struct llog_handle * handle,
                 rc = class_process_config(lcfg_new);
                 lustre_cfg_free(lcfg_new);
 
-                if (inst)
+                if (inst_name)
                         OBD_FREE(inst_name, inst_len);
         } else if (rec->lrh_type == PTL_CFG_REC) {
                 struct portals_cfg *pcfg = (struct portals_cfg *)cfg_buf;
index 9ea94a1..e69dbcb 100755 (executable)
@@ -101,7 +101,7 @@ subsystem_names = {
     "mds" :          (1 << 2),
     "osc" :          (1 << 3),
     "ost" :          (1 << 4),
-    "class" :        (1 << 5),
+    "obdclass" :     (1 << 5),
     "log" :          (1 << 6),
     "llite" :        (1 << 7),
     "rpc" :          (1 << 8),
@@ -664,14 +664,6 @@ class LCTLInterface:
   quit""" % (name, ost_uuid, index, gen)
         self.run(cmds)
 
-    # create an lmv
-    def lmv_setup(self, name, uuid, desc_uuid, devlist):
-        cmds = """
-  attach lmv %s %s
-  lmv_setup %s %s
-  quit""" % (name, uuid, desc_uuid, devlist)
-        self.run(cmds)
-
     # delete an OSC from a LOV
     def lov_del_osc(self, name, ost_uuid, index, gen):
         cmds = """
@@ -687,6 +679,21 @@ class LCTLInterface:
   quit""" % (name)
         self.run(cmds)
 
+    # create an lmv
+    def lmv_setup(self, name, uuid, desc_uuid):
+        cmds = """
+  attach lmv %s %s
+  lmv_setup %s
+  quit""" % (name, uuid, desc_uuid)
+        self.run(cmds)
+
+    # add an MDC to an LMV
+    def lmv_add_mdc(self, lmv_name, mdt_uuid):
+        cmds = """
+  lmv_modify_tgts add %s %s
+  quit""" % (lmv_name, mdt_uuid)
+        self.run(cmds)
+
     # dump the log file
     def dump(self, dump_file):
         cmds = """
@@ -1700,6 +1707,7 @@ class LMV(Module):
             return
            
        self.info();
+        lctl.lmv_setup(self.name, self.uuid, self.desc_uuid)
         for mdc in self.mdclist:
             try:
                 # Only ignore connect failures with --force, which
@@ -1708,10 +1716,8 @@ class LMV(Module):
             except CommandError, e:
                 print "Error preparing LMV %s\n" % mdc.uuid
                 raise e
+            lctl.lmv_add_mdc(self.name, mdc.target_uuid)
        
-        lctl.lmv_setup(self.name, self.uuid, self.desc_uuid,
-                       string.join(self.devlist))
-
     def cleanup(self):
         for mdc in self.mdclist:
             mdc.cleanup()
@@ -2026,6 +2032,12 @@ class CONFDEV(Module):
         if not self.client_uuids:
             return 0
 
+        if self.lmv:
+           client_uuid = self.conf_name + "_lmv_UUID"
+            lmv = VMDC(self.lmv, client_uuid, self.conf_name, self.conf_name);
+        else:
+            lmv = None
+
         for uuid in self.client_uuids:
             log("recording client:", uuid)
             client_uuid = generate_client_uuid(self.name)
@@ -2037,7 +2049,7 @@ class CONFDEV(Module):
             client.prepare()
             lctl.mount_option(self.target.getName(), client.get_name(), "", "")
             lctl.end_record()
-            process_updates(self.db, self.name, self.target.getName(), client) 
+            process_updates(self.db, self.name, self.target.getName(), lmv, client)
             config.cleanup = 1
             lctl.clear_log(self.name, self.target.getName() + '-clean')
             lctl.record(self.name, self.target.getName() + '-clean')
@@ -2655,7 +2667,7 @@ class CMOBD(Module):
            self.master = get_osc(master_obd, client_uuid, self.master_uuid) 
         elif master_class == 'mds':
            client_uuid = "%s_mds_master_UUID" % (self.name)
-           self.master = get_mdc(master_obd, client_uuid, self.master_uuid) 
+           self.master = get_mdc(master_obd,  self.master_uuid, client_uuid) 
         elif master_class == 'lmv':
            client_uuid = "%s_lmv_master_UUID" % (self.name)
             self.master = LMV(master_obd, client_uuid, self.name, 
@@ -2667,8 +2679,8 @@ class CMOBD(Module):
            self.cache = get_osc(cache_obd, cache_obd.getUUID(), 
                                 self.cache_uuid)
         elif cache_class == 'mds':
-           self.cache = get_mdc(cache_obd, cache_obd.getUUID(), 
-                                self.cache_uuid)
+           self.cache = get_mdc(cache_obd, self.cache_uuid,
+                                cache_obd.getUUID())
        else:
            panic("invalid cache obd class '%s'" %(cache_class))
 
@@ -2734,7 +2746,7 @@ class COBD(Module):
             self.master = LOV(master_obd, client_uuid, name,
                              "master_%s" % (self.name));
         elif master_class == 'mds':
-            self.master = get_mdc(db, name, self.master_uuid
+            self.master = get_mdc(db, self.master_uuid, name
         elif master_class == 'lmv':
            client_uuid = "%s_lmv_master_UUID" % (self.name)
             self.master = LMV(master_obd, client_uuid, self.name, 
@@ -2747,7 +2759,7 @@ class COBD(Module):
             self.cache = LOV(cache_obd, client_uuid, name,
                             "cache_%s" % (self.name));
         elif cache_class == 'mds':
-            self.cache = get_mdc(db, name, self.cache_uuid)
+            self.cache = get_mdc(db, self.cache_uuid, name)
         elif cache_class == 'lmv':
            client_uuid = "%s_lmv_cache_UUID" % (self.name)
             self.cache = LMV(cache_obd, client_uuid, self.name, 
@@ -3083,11 +3095,11 @@ def get_osc(db, ost_uuid, fs_name):
     osc = OSC(db, ost_uuid, fs_name)
     return osc
 
-def get_mdc(db, fs_name, mds_uuid):
-    mds_db = db.lookup(mds_uuid);
-    if not mds_db:
-        error("no mds:", mds_uuid)
-    mdc = MDC(mds_db, mds_uuid, fs_name)
+def get_mdc(db, mdt_uuid, fs_name):
+    mdt_db = db.lookup(mdt_uuid);
+    if not mdt_db:
+        error("no mdt:", mdt_uuid)
+    mdc = MDC(mdt_db, mdt_uuid, fs_name)
     return mdc
 
 def get_gkc(db, uuid, fs_name, gks_uuid):
@@ -3325,10 +3337,32 @@ def magic_get_osc(db, rec, lov):
         panic('osc not found:', obd_uuid)
     return lov_name, lov_uuid, osc
 
+def magic_get_mdc(db, rec, lmv):
+    if lmv:
+        lmv_uuid = lmv.mdc.uuid
+        fs_name = lmv.mdc.fs_name
+        lmv_name = lmv.mdc.name
+    else:
+        lmv_uuid = rec.getAttribute('lmv_uuidref')
+        fs_name = get_fs_name(db, rec, 'mds_ref', lmv_uuid)
+        lmv_name = "lmv_" + fs_name
+
+    mdt_uuid = rec.getAttribute('mdt_uuidref')
+
+    mds = db.lookup(mdt_uuid)
+    print mds
+    if not mds:
+        panic("MDS not found!")
+
+    mdc = MDC(mds, lmv_uuid, fs_name)
+    if not mdc:
+        panic('mdc not found:', mdt_uuid)
+    return lmv_name, lmv_uuid, mdc
+
 # write logs for update records.  sadly, logs of all types -- and updates in
 # particular -- are something of an afterthought.  lconf needs rewritten with
 # these as core concepts.  so this is a pretty big hack.
-def process_update_record(db, update, lov):
+def process_update_record(db, update, lmv, lov):
     for rec in update.childNodes:
         if rec.nodeType != rec.ELEMENT_NODE:
             continue
@@ -3339,6 +3373,26 @@ def process_update_record(db, update, lov):
         log("found " + rec.nodeName + " record in update version " +
             str(update.getAttribute('version')))
 
+        if rec.nodeName == 'lmv_add':
+            lmv_uuid = rec.getAttribute('lmv_uuidref')
+            mdt_uuid = rec.getAttribute('mdt_uuidref')
+            if not lmv_uuid or not mdt_uuid:
+                panic("malformed xml: '" + rec.nodeName + \
+                     "' record requires lmv_uuid and mdt_uuid.")
+
+            lmv_name, lmv_uuid, mdc = magic_get_mdc(db, rec, lmv)
+
+            try:
+                # Only ignore connect failures with --force, which
+                # isn't implemented here yet.
+                mdc.prepare(ignore_connect_failure=0)
+            except CommandError, e:
+                print "Error preparing MDC %s\n" % osc.uuid
+                raise e
+
+            lctl.lmv_add_mdc(lmv_name, mdt_uuid)
+            continue
+
         if rec.nodeName != 'lov_add' and rec.nodeName != 'lov_delete' and \
            rec.nodeName != 'lov_deactivate':
                 panic("unrecognized update record type '" + rec.nodeName + "'.")
@@ -3385,7 +3439,7 @@ def process_update_record(db, update, lov):
                 print "Error cleaning up OSC %s\n" % osc.uuid
                 raise e
 
-def process_updates(db, log_device, log_name, lov = None):
+def process_updates(db, log_device, log_name, lmv = None, lov = None):
     if not config.write_conf and not config.record:
         return
     if config.cleanup:
@@ -3403,7 +3457,7 @@ def process_updates(db, log_device, log_name, lov = None):
         lctl.clear_log(log_device, real_name)
         lctl.record(log_device, real_name)
 
-        process_update_record(db, u, lov)
+        process_update_record(db, u, lmv, lov)
 
         lctl.end_record()
 
@@ -3428,8 +3482,26 @@ def doSetup(services):
        nl = n[1].correct_level(n[0])
        nlist.append((nl, n[1]))
     nlist.sort()
+
+    if config.record:
+        lctl.clear_log(config.record_device, config.record_log)
+        lctl.record(config.record_device, config.record_log)
+
+    # ugly hack, only need to run lctl commands for --dump
+    if config.lctl_dump or config.record:
+        sys_set_timeout(timeout)
+        sys_set_lustre_upcall(lustre_upcall)
+
     for n in nlist:
         n[1].prepare()
+        if config.record and n[1].module_name == 'MTPT':
+           lmv = n[1].vmdc
+           lov = n[1].vosc
+
+    if config.record:
+        lctl.end_record()
+        process_updates(n[1].db, config.record_device, config.record_log,
+                        lmv, lov)
 
 def doLoadModules(services):
     if config.nomod:
@@ -3472,14 +3544,21 @@ def doCleanup(services):
     nlist.sort()
     nlist.reverse()
 
+    if config.record:
+        lctl.clear_log(config.record_device, config.record_log)
+        lctl.record(config.record_device, config.record_log)
+
     for n in nlist:
         if n[1].safe_to_clean():
             n[1].cleanup()
 
+    if config.record:
+        lctl.end_record()
+
 #
 # Load profile for 
 def doHost(lustreDB, hosts):
-    global is_router, local_node_name
+    global is_router, local_node_name, lustre_upcall, timeout
     node_db = None
     for h in hosts:
         node_db = lustreDB.lookup_name(h, 'node')
@@ -3539,8 +3618,6 @@ def doHost(lustreDB, hosts):
     else:
         # ugly hack, only need to run lctl commands for --dump
         if config.lctl_dump or config.record:
-            sys_set_timeout(timeout)
-            sys_set_lustre_upcall(lustre_upcall)
             for_each_profile(node_db, prof_list, doSetup)
             return
 
@@ -3959,18 +4036,12 @@ def main():
     if config.record:
         if not (config.record_device and config.record_log):
             panic("When recording, both --record_log and --record_device must be specified.")
-        lctl.clear_log(config.record_device, config.record_log)
-        lctl.record(config.record_device, config.record_log)
 
     # init module manager
     mod_manager = kmod_manager(config.lustre, config.portals)
 
     doHost(lustreDB, node_list)
 
-    if config.record:
-        lctl.end_record()
-        process_updates(lustreDB, config.record_device, config.record_log)
-
     return
 
 if __name__ == "__main__":
index 0b670d7..0c8c7c0 100644 (file)
@@ -385,6 +385,9 @@ command_t cmdlist[] = {
         {"lov_getconfig", jt_obd_lov_getconfig, 0,
          "read lov configuration from an mds device\n"
          "usage: lov_getconfig lov-uuid"},
+        {"lmv_modify_tgts", jt_lcfg_lmv_modify_tgts, 0,
+         "add an mdc to a LMV device\n"
+         "usage: lmv_modify_tgts add <lmv_name> <mdc_uuid>"},
         {"record", jt_cfg_record, 0, "record commands that follow in log\n"
          "usage: record cfg-uuid-name"},
         {"endrecord", jt_cfg_endrecord, 0, "stop recording\n"
index 220276d..ed41d95 100755 (executable)
@@ -666,6 +666,12 @@ class GenConfig:
         new = self.doc.createElement("info")
         return new
 
+    def lmv_add(self, lmv, mdt):
+       new = self.doc.createElement("lmv_add")
+        new.setAttribute("lmv_uuidref", lmv)
+        new.setAttribute("mdt_uuidref", mdt)
+        return new
+
     def lov_add(self, lov, ost, index, gen):
         new = self.doc.createElement("lov_add")
         new.setAttribute("lov_uuidref", lov)
@@ -852,9 +858,11 @@ def lov_del_osc(gen, lustre, lov, osc_uuid, options):
             tgt.setAttribute('active', '0')
             tgt.setAttribute('generation', gener)
 
-def lmv_add_obd(gen, lmv, mdc_uuid):
+def lmv_add_mdc(gen, lustre, lmv, mdc_uuid):
     lmv.appendChild(gen.lmv_tgt(mdc_uuid))
-
+    addrec = gen.lmv_add(getUUID(lmv), mdc_uuid)
+    addUpdate(gen, lustre, addrec)
+                            
 def ref_exists(profile, uuid):
     elist = profile.childNodes
     for e in elist:
@@ -1039,13 +1047,6 @@ def add_mds(gen, lustre, options):
     mdd_name = new_name("MDD_" + mds_name +"_" + node_name)
     mdd_uuid = new_uuid(mdd_name)
 
-    lmv_uuid = ""
-    if lmv_name:
-        lmv = findByName(lustre, lmv_name, "lmv")
-        if not lmv:
-            error('add_mds:', '"' + lmv_name + '"', "lmv element not found.")
-        lmv_uuid = name2uuid(lustre, lmv_name, fatal=0)
-
     mds_uuid = name2uuid(lustre, mds_name, 'mds', fatal=0)
     if not mds_uuid:
         mds_uuid = get_option(options, 'mdsuuid')
@@ -1056,11 +1057,19 @@ def add_mds(gen, lustre, options):
             mds_uuid = new_uuid(mds_name)
         mds = gen.mds(mds_name, mds_uuid, mdd_uuid, options.group)
         lustre.appendChild(mds)
-        if lmv_name:
-            lmv_add_obd(gen, lmv, mds_uuid)
     else:
         mds = lookup(lustre, mds_uuid)
 
+    lmv_uuid = ""
+    if lmv_name:
+        lmv = findByName(lustre, lmv_name, "lmv")
+        if not lmv:
+            error('add_mds:', '"' + lmv_name + '"', "lmv element not found.")
+        lmv_add_mdc(gen, lustre, lmv, mds_uuid)
+        lmv_uuid = name2uuid(lustre, lmv_name, fatal=0)
+        if lmv_uuid:
+            mds.appendChild(gen.ref("lmv", lmv_uuid))
+    
     if options.failover:
         mds.setAttribute('failover', "1")
 
@@ -1089,9 +1098,6 @@ def add_mds(gen, lustre, options):
     if not net_uuid:
         error("NODE: ", node_name, "not found")
 
-    if lmv_name:
-        mds.appendChild(gen.ref("lmv", lmv_uuid))
-
     if fs_name != "":
        fs_uuid = name2uuid(lustre, fs_name, 'filesystem', fatal=1)
     else:
index 7d1b9a8..a0fc2af 100644 (file)
@@ -410,68 +410,6 @@ int jt_lcfg_lov_setup(int argc, char **argv)
         return rc;
 }
 
-int jt_lcfg_lmv_setup(int argc, char **argv)
-{
-        struct lustre_cfg_bufs bufs;
-        struct lustre_cfg *lcfg;
-        struct lmv_desc desc;
-        struct obd_uuid *uuidarray, *ptr;
-        int rc, i;
-
-        lustre_cfg_bufs_reset(&bufs, lcfg_devname);
-        if (argc <= 2)
-                return CMD_HELP;
-
-        if (strlen(argv[1]) > sizeof(desc.ld_uuid) - 1) {
-                fprintf(stderr,
-                        "error: %s: LMV uuid '%s' longer than "LPSZ" chars\n",
-                        jt_cmdname(argv[0]), argv[1], sizeof(desc.ld_uuid) - 1);
-                return -EINVAL;
-        }
-
-        memset(&desc, 0, sizeof(desc));
-        obd_str2uuid(&desc.ld_uuid, argv[1]);
-        desc.ld_tgt_count = argc - 2;
-        printf("LMV: %d uuids:\n", desc.ld_tgt_count);
-
-        /* NOTE: it is possible to overwrite the default striping parameters,
-         *       but EXTREME care must be taken when saving the OST UUID list.
-         *       It must be EXACTLY the same, or have only additions at the
-         *       end of the list, or only overwrite individual OST entries
-         *       that are restored from backups of the previous OST.
-         */
-        uuidarray = calloc(desc.ld_tgt_count, sizeof(*uuidarray));
-        if (!uuidarray) {
-                fprintf(stderr, "error: %s: no memory for %d UUIDs\n",
-                        jt_cmdname(argv[0]), desc.ld_tgt_count);
-                rc = -ENOMEM;
-                goto out;
-        }
-        for (i = 2, ptr = uuidarray; i < argc; i++, ptr++) {
-                if (strlen(argv[i]) >= sizeof(*ptr)) {
-                        fprintf(stderr, "error: %s: arg %d (%s) too long\n",
-                                jt_cmdname(argv[0]), i, argv[i]);
-                        rc = -EINVAL;
-                        goto out;
-                }
-                printf("  %s\n", argv[i]);
-                strcpy((char *)ptr, argv[i]);
-        }
-
-        lustre_cfg_bufs_set(&bufs, 1, &desc, sizeof(desc));
-        lustre_cfg_bufs_set(&bufs, 2, (char*)uuidarray, 
-                            desc.ld_tgt_count * sizeof(*uuidarray));
-        lcfg = lustre_cfg_new(LCFG_SETUP, &bufs);
-        rc = lcfg_ioctl(argv[0], OBD_DEV_ID, lcfg);
-        lustre_cfg_free(lcfg);
-        
-        if (rc)
-                fprintf(stderr, "error: %s: ioctl error: %s\n",
-                        jt_cmdname(argv[0]), strerror(rc = errno));
-out:
-        free(uuidarray);
-        return rc;
-}
 int jt_lcfg_lov_modify_tgts(int argc, char **argv)
 {
         struct lustre_cfg_bufs bufs;
@@ -533,6 +471,82 @@ int jt_lcfg_lov_modify_tgts(int argc, char **argv)
         return rc;
 }
 
+int jt_lcfg_lmv_setup(int argc, char **argv)
+{
+        struct lustre_cfg_bufs bufs;
+        struct lustre_cfg *lcfg;
+        struct lmv_desc desc;
+        int rc;
+
+        /* argv: lmv_setup <lmv_uuid> */
+
+        if (argc != 2)
+                return CMD_HELP;
+
+        lustre_cfg_bufs_reset(&bufs, lcfg_devname);
+
+        if (strlen(argv[1]) > (sizeof(desc.ld_uuid) - 1)) {
+                fprintf(stderr,
+                        "error: %s: LMV uuid '%s' longer than "LPSZ" chars\n",
+                        jt_cmdname(argv[0]), argv[1], sizeof(desc.ld_uuid) - 1);
+                return -EINVAL;
+        }
+
+        memset(&desc, 0, sizeof(desc));
+        obd_str2uuid(&desc.ld_uuid, argv[1]);
+
+        lustre_cfg_bufs_set(&bufs, 1, &desc, sizeof(desc));
+        lcfg = lustre_cfg_new(LCFG_SETUP, &bufs);
+        rc = lcfg_ioctl(argv[0], OBD_DEV_ID, lcfg);
+        if (rc)
+                fprintf(stderr, "error: %s: ioctl error: %s\n",
+                        jt_cmdname(argv[0]), strerror(rc = errno));
+
+        lustre_cfg_free(lcfg);
+        return rc;
+}
+
+int jt_lcfg_lmv_modify_tgts(int argc, char **argv)
+{
+        struct lustre_cfg_bufs bufs;
+        struct lustre_cfg *lcfg;
+        int mdc_uuid_len, rc;
+
+        /* NOTE: EXTREME care must be taken to always add MDCs in the same
+         *       order, or have only additions at the end of the list.
+         */
+
+        /* argv: lmv_modify_tgts add <LMV name> <MDC uuid> */
+        if (argc != 4)
+                return CMD_HELP;
+
+        if (strncmp(argv[1], "add", 4) != 0) {
+                fprintf(stderr, "error: %s: bad operation '%s'\n",
+                        jt_cmdname(argv[0]), argv[1]);
+                return CMD_HELP;
+        }
+
+        lustre_cfg_bufs_reset(&bufs, argv[2]);
+
+        if (((mdc_uuid_len = strlen(argv[3]) + 1)) > sizeof(struct obd_uuid)) {
+                fprintf(stderr,
+                        "error: %s: MDC uuid '%s' longer than "LPSZ" chars\n",
+                        jt_cmdname(argv[0]), argv[3],
+                        sizeof(struct obd_uuid) - 1);
+                return -EINVAL;
+        }
+
+        lustre_cfg_bufs_set(&bufs, 1, argv[3], mdc_uuid_len);
+        
+        lcfg = lustre_cfg_new(LCFG_LMV_ADD_MDC, &bufs);
+        rc = lcfg_ioctl(argv[0], OBD_DEV_ID, lcfg);
+        lustre_cfg_free(lcfg);
+        if (rc)
+                fprintf(stderr, "error: %s: ioctl error: %s\n",
+                        jt_cmdname(argv[0]), strerror(rc = errno));
+        return rc;
+}
+
 int jt_lcfg_mount_option(int argc, char **argv)
 {
         int rc;
index e507a7e..8c65ea4 100644 (file)
@@ -111,8 +111,9 @@ int jt_lcfg_setup(int argc, char **argv);
 int jt_lcfg_add_uuid(int argc, char **argv);
 int jt_lcfg_del_uuid(int argc, char **argv);
 int jt_lcfg_lov_setup(int argc, char **argv);
-int jt_lcfg_lmv_setup(int argc, char **argv);
 int jt_lcfg_lov_modify_tgts(int argc, char **argv);
+int jt_lcfg_lmv_setup(int argc, char **argv);
+int jt_lcfg_lmv_modify_tgts(int argc, char **argv);
 int jt_lcfg_mount_option(int argc, char **argv);
 int jt_lcfg_del_mount_option(int argc, char **argv);
 int jt_lcfg_set_timeout(int argc, char **argv);