Whamcloud - gitweb
b=11694
authorkomaln <komaln>
Wed, 10 Oct 2007 09:58:43 +0000 (09:58 +0000)
committerkomaln <komaln>
Wed, 10 Oct 2007 09:58:43 +0000 (09:58 +0000)
r=Nathan, Adilger

When striping policy is set on root of file system using "lfs setstripe", it changes the default stripe policy.

lustre/include/lustre/lustre_idl.h
lustre/llite/dir.c
lustre/llite/llite_internal.h
lustre/llite/xattr.c
lustre/mgc/mgc_request.c
lustre/mgs/mgs_handler.c
lustre/ptlrpc/lproc_ptlrpc.c
lustre/ptlrpc/wiretest.c
lustre/utils/wirecheck.c
lustre/utils/wiretest.c

index f9ed7af..b99ad84 100644 (file)
@@ -1614,10 +1614,18 @@ typedef enum {
         MGS_EXCEPTION,         /* node died, etc. */
         MGS_TARGET_REG,        /* whenever target starts up */
         MGS_TARGET_DEL,
+        MGS_SET_INFO,
         MGS_LAST_OPC
 } mgs_cmd_t;
 #define MGS_FIRST_OPC MGS_CONNECT
 
+#define MGS_PARAM_MAXLEN 1024
+#define KEY_SET_INFO "set_info"
+
+struct mgs_send_param {
+        char             mgs_param[MGS_PARAM_MAXLEN];
+};
+
 /* We pass this info to the MGS so it can write config logs */
 #define MTI_NAME_MAXLEN 64
 #define MTI_PARAM_MAXLEN 4096
index 7a2cc4b..743a42e 100644 (file)
@@ -528,12 +528,52 @@ do {                                    \
         Q_COPY(out, in, qc_dqblk);      \
 } while (0)
 
-int ll_dir_setstripe(struct inode *inode, struct lov_user_md *lump)
+int ll_send_mgc_param(struct obd_export *mgc, char *string)
+{
+        struct mgs_send_param *msp;
+        int rc = 0;
+
+        OBD_ALLOC_PTR(msp);
+        if (!msp)
+                return -ENOMEM;
+
+        strncpy(msp->mgs_param, string, MGS_PARAM_MAXLEN);
+        rc = obd_set_info_async(mgc, strlen(KEY_SET_INFO), KEY_SET_INFO,
+                                sizeof(struct mgs_send_param), msp, NULL);
+        if (rc)
+                CERROR("Failed to set parameter: %d\n", rc);
+        OBD_FREE_PTR(msp);
+
+        return rc;
+}
+
+char *ll_get_fsname(struct inode *inode)
+{
+        struct lustre_sb_info *lsi = s2lsi(inode->i_sb);
+        char *ptr, *fsname;
+        int len;
+
+        OBD_ALLOC(fsname, MGS_PARAM_MAXLEN);
+        len = strlen(lsi->lsi_lmd->lmd_profile);
+        ptr = strrchr(lsi->lsi_lmd->lmd_profile, '-');
+        if (ptr && (strcmp(ptr, "-client") == 0))
+                len -= 7;
+        strncpy(fsname, lsi->lsi_lmd->lmd_profile, len);
+        fsname[len] = '\0';
+
+        return fsname;
+}
+
+int ll_dir_setstripe(struct inode *inode, struct lov_user_md *lump,
+                     int set_default)
 {
         struct ll_sb_info *sbi = ll_i2sbi(inode);
         struct md_op_data *op_data;
         struct ptlrpc_request *req = NULL;
         int rc = 0;
+        struct lustre_sb_info *lsi = s2lsi(inode->i_sb);
+        struct obd_device *mgc = lsi->lsi_mgc;
+        char *fsname = NULL, *param = NULL;
 
         /*
          * This is coming from userspace, so should be in
@@ -560,8 +600,39 @@ int ll_dir_setstripe(struct inode *inode, struct lov_user_md *lump)
                 if (rc != -EPERM && rc != -EACCES)
                         CERROR("mdc_setattr fails: rc = %d\n", rc);
         }
-        return rc;
 
+        if (set_default && mgc->u.cli.cl_mgc_mgsexp) {
+                OBD_ALLOC(param, MGS_PARAM_MAXLEN);
+
+                /* Get fsname and assume devname to be -MDT0000. */
+                fsname = ll_get_fsname(inode);
+                /* Set root stripesize */
+                sprintf(param, "%s-MDT0000.lov.stripesize=%u", fsname,
+                        lump->lmm_stripe_size);
+                rc = ll_send_mgc_param(mgc->u.cli.cl_mgc_mgsexp, param);
+                if (rc)
+                        goto end;
+
+                /* Set root stripecount */
+                sprintf(param, "%s-MDT0000.lov.stripecount=%u", fsname,
+                        lump->lmm_stripe_count);
+                rc = ll_send_mgc_param(mgc->u.cli.cl_mgc_mgsexp, param);
+                if (rc)
+                        goto end;
+
+                /* Set root stripeoffset */
+                sprintf(param, "%s-MDT0000.lov.stripeoffset=%u", fsname,
+                        lump->lmm_stripe_offset);
+                rc = ll_send_mgc_param(mgc->u.cli.cl_mgc_mgsexp, param);
+                if (rc)
+                        goto end;
+end:
+                if (fsname)
+                        OBD_FREE(fsname, MGS_PARAM_MAXLEN);
+                if (param)
+                        OBD_FREE(param, MGS_PARAM_MAXLEN);
+        }
+        return rc;
 }
 
 int ll_dir_getstripe(struct inode *inode, struct lov_mds_md **lmmp, 
@@ -690,6 +761,7 @@ static int ll_dir_ioctl(struct inode *inode, struct file *file,
         case LL_IOC_LOV_SETSTRIPE: {
                 struct lov_user_md lum, *lump = (struct lov_user_md *)arg;
                 int rc = 0;
+                int set_default = 0;
 
                 LASSERT(sizeof(lum) == sizeof(*lump));
                 LASSERT(sizeof(lum.lmm_objects[0]) ==
@@ -698,7 +770,10 @@ static int ll_dir_ioctl(struct inode *inode, struct file *file,
                 if (rc)
                         RETURN(-EFAULT);
 
-                rc = ll_dir_setstripe(inode, &lum);
+                if (inode->i_sb->s_root == file->f_dentry)
+                        set_default = 1;
+
+                rc = ll_dir_setstripe(inode, &lum, set_default);
 
                 RETURN(rc);
         }
index b4c880d..c06cd36 100644 (file)
@@ -551,7 +551,8 @@ int ll_lov_setstripe_ea_info(struct inode *inode, struct file *file,
 int ll_lov_getstripe_ea_info(struct inode *inode, const char *filename,
                              struct lov_mds_md **lmm, int *lmm_size,
                              struct ptlrpc_request **request);
-int ll_dir_setstripe(struct inode *inode, struct lov_user_md *lump);
+int ll_dir_setstripe(struct inode *inode, struct lov_user_md *lump,
+                     int set_default);
 int ll_dir_getstripe(struct inode *inode, struct lov_mds_md **lmm, 
                      int *lmm_size, struct ptlrpc_request **request);
 
index 4ae9f62..db7deb7 100644 (file)
@@ -165,7 +165,7 @@ int ll_setxattr(struct dentry *dentry, const char *name,
                         /* b10667: rc always be 0 here for now */
                         rc = 0;
                 } else if (S_ISDIR(inode->i_mode)) {
-                        rc = ll_dir_setstripe(inode, lump);
+                        rc = ll_dir_setstripe(inode, lump, 0);
                 }
                 
                 return rc;
index e25539a..cfe7c8c 100644 (file)
@@ -588,6 +588,40 @@ static int mgc_blocking_ast(struct ldlm_lock *lock, struct ldlm_lock_desc *desc,
         RETURN(rc);
 }
 
+/* Send parameter to MGS*/
+static int mgc_set_mgs_param(struct obd_export *exp,
+                             struct mgs_send_param *msp)
+{
+        struct ptlrpc_request *req;
+        struct mgs_send_param *req_msp, *rep_msp;
+        int size[] = { sizeof(struct ptlrpc_body), sizeof(*req_msp) };
+        int rep_size[] = { sizeof(struct ptlrpc_body), sizeof(*msp) };
+        int rc;
+        ENTRY;
+
+        req = ptlrpc_prep_req(class_exp2cliimp(exp), LUSTRE_MGS_VERSION,
+                              MGS_SET_INFO, 2, size, NULL);
+        if (!req)
+                RETURN(-ENOMEM);
+
+        req_msp = lustre_msg_buf(req->rq_reqmsg, REQ_REC_OFF, sizeof(*req_msp));
+        if (!req_msp)
+                RETURN(-ENOMEM);
+
+        memcpy(req_msp, msp, sizeof(*req_msp));
+        ptlrpc_req_set_repsize(req, 2, rep_size);
+        rc = ptlrpc_queue_wait(req);
+        if (!rc) {
+                rep_msp = lustre_swab_repbuf(req, REPLY_REC_OFF,
+                                             sizeof(*rep_msp), NULL);
+                memcpy(msp, rep_msp, sizeof(*rep_msp));
+        }
+
+        ptlrpc_req_finished(req);
+
+        RETURN(rc);
+}
+
 /* Take a config lock so we can get cancel notifications */
 static int mgc_enqueue(struct obd_export *exp, struct lov_stripe_md *lsm,
                        __u32 type, ldlm_policy_data_t *policy, __u32 mode,
@@ -831,6 +865,13 @@ int mgc_set_info_async(struct obd_export *exp, obd_count keylen,
                 }
                 RETURN(rc);
         }
+        if (KEY_IS(KEY_SET_INFO)) {
+                struct mgs_send_param *msp;
+
+                msp = (struct mgs_send_param *)val;
+                rc =  mgc_set_mgs_param(exp, msp);
+                RETURN(rc);
+        }
 
         RETURN(rc);
 }
index def11e3..b7c670e 100644 (file)
@@ -458,6 +458,54 @@ out_nolock:
         RETURN(rc);
 }
 
+static int mgs_set_info_rpc(struct ptlrpc_request *req)
+{
+        struct obd_device *obd = req->rq_export->exp_obd;
+        struct mgs_send_param *msp, *rep_msp;
+        struct lustre_handle lockh;
+        int rep_size[] = { sizeof(struct ptlrpc_body), sizeof(*msp) };
+        int lockrc, rc;
+        struct lustre_cfg_bufs bufs;
+        struct lustre_cfg *lcfg;
+        char fsname[MTI_NAME_MAXLEN];
+        ENTRY;
+
+        msp = lustre_swab_reqbuf(req, REQ_REC_OFF, sizeof(*msp), NULL);
+
+        /* Construct lustre_cfg structure to pass to function mgs_setparam */
+        lustre_cfg_bufs_reset(&bufs, NULL);
+        lustre_cfg_bufs_set_string(&bufs, 1, msp->mgs_param);
+        lcfg = lustre_cfg_new(LCFG_PARAM, &bufs);
+        rc = mgs_setparam(obd, lcfg, fsname);
+        if (rc) {
+                CERROR("Error %d in setting the parameter %s for fs %s\n",
+                       rc, msp->mgs_param, fsname);
+                RETURN(rc);
+        }
+
+        /* Revoke lock so everyone updates.  Should be alright if
+         * someone was already reading while we were updating the logs,
+         * so we don't really need to hold the lock while we're
+         * writing.
+         */
+        if (fsname[0]) {
+                lockrc = mgs_get_cfg_lock(obd, fsname, &lockh);
+                if (lockrc != ELDLM_OK)
+                        CERROR("lock error %d for fs %s\n", lockrc,
+                               fsname);
+                else
+                        mgs_put_cfg_lock(&lockh);
+        }
+        lustre_cfg_free(lcfg);
+
+        lustre_pack_reply(req, 2, rep_size, NULL);
+        rep_msp = lustre_msg_buf(req->rq_repmsg, REPLY_REC_OFF,
+                                 sizeof(*rep_msp));
+        memcpy(rep_msp, msp, sizeof(*rep_msp));
+
+        RETURN(rc);
+}
+
 int mgs_handle(struct ptlrpc_request *req)
 {
         int fail = OBD_FAIL_MGS_ALL_REPLY_NET;
@@ -500,6 +548,9 @@ int mgs_handle(struct ptlrpc_request *req)
                 DEBUG_REQ(D_MGS, req, "target del");
                 //rc = mgs_handle_target_del(req);
                 break;
+        case MGS_SET_INFO:
+                rc = mgs_set_info_rpc(req);
+                break;
 
         case LDLM_ENQUEUE:
                 DEBUG_REQ(D_MGS, req, "enqueue");
index 0730b0f..10ee5fc 100644 (file)
@@ -92,6 +92,7 @@ struct ll_rpc_opcode {
         { MGS_EXCEPTION,    "mgs_exception" },
         { MGS_TARGET_REG,   "mgs_target_reg" },
         { MGS_TARGET_DEL,   "mgs_target_del" },
+        { MGS_SET_INFO,     "mgs_set_info" },
         { OBD_PING,         "obd_ping" },
         { OBD_LOG_CANCEL,   "llog_origin_handle_cancel" },
         { OBD_QC_CALLBACK,  "obd_qc_callback" },
index ea5c7b7..24c1a16 100644 (file)
@@ -137,6 +137,8 @@ void lustre_assert_wire_constants(void)
                  (long long)MGS_TARGET_REG);
         LASSERTF(MGS_TARGET_DEL == 254, " found %lld\n",
                  (long long)MGS_TARGET_DEL);
+        LASSERTF(MGS_SET_INFO == 255, " found %lld\n",
+                 (long long)MGS_SET_INFO);
         LASSERTF(DISP_IT_EXECD == 1, " found %lld\n",
                  (long long)DISP_IT_EXECD);
         LASSERTF(DISP_LOOKUP_EXECD == 2, " found %lld\n",
@@ -209,6 +211,8 @@ void lustre_assert_wire_constants(void)
                  (long long)MGS_TARGET_REG);
         LASSERTF(MGS_TARGET_DEL == 254, " found %lld\n",
                  (long long)MGS_TARGET_DEL);
+        LASSERTF(MGS_SET_INFO == 255, " found %lld\n",
+                 (long long)MGS_SET_INFO);
         /* Sizes and Offsets */
 
         /* Checks for struct obd_uuid */
index 6b971f1..a193fe9 100644 (file)
@@ -1126,6 +1126,7 @@ main(int argc, char **argv)
         CHECK_VALUE(MGS_EXCEPTION);
         CHECK_VALUE(MGS_TARGET_REG);
         CHECK_VALUE(MGS_TARGET_DEL);
+        CHECK_VALUE(MGS_SET_INFO);
 
         CHECK_VALUE(DISP_IT_EXECD);
         CHECK_VALUE(DISP_LOOKUP_EXECD);
@@ -1172,6 +1173,7 @@ main(int argc, char **argv)
         CHECK_VALUE(MGS_EXCEPTION);   
         CHECK_VALUE(MGS_TARGET_REG);
         CHECK_VALUE(MGS_TARGET_DEL);
+        CHECK_VALUE(MGS_SET_INFO);
 
         COMMENT("Sizes and Offsets");
         BLANK_LINE();
index 4eff64f..9153194 100644 (file)
@@ -153,6 +153,8 @@ void lustre_assert_wire_constants(void)
                  (long long)MGS_TARGET_REG);
         LASSERTF(MGS_TARGET_DEL == 254, " found %lld\n",
                  (long long)MGS_TARGET_DEL);
+        LASSERTF(MGS_SET_INFO == 255, " found %lld\n",
+                 (long long)MGS_SET_INFO);
         LASSERTF(DISP_IT_EXECD == 1, " found %lld\n",
                  (long long)DISP_IT_EXECD);
         LASSERTF(DISP_LOOKUP_EXECD == 2, " found %lld\n",
@@ -225,6 +227,8 @@ void lustre_assert_wire_constants(void)
                  (long long)MGS_TARGET_REG);
         LASSERTF(MGS_TARGET_DEL == 254, " found %lld\n",
                  (long long)MGS_TARGET_DEL);
+        LASSERTF(MGS_SET_INFO == 255, " found %lld\n",
+                 (long long)MGS_SET_INFO);
         /* Sizes and Offsets */
 
         /* Checks for struct obd_uuid */