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
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
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,
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]) ==
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);
}
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);
/* 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;
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,
}
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);
}
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;
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");
{ 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" },
(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",
(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 */
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);
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();
(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",
(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 */