diff --git a/lustre/include/lustre/lustre_idl.h b/lustre/include/lustre/lustre_idl.h index ec3890408c6d4ace0392a8fff3a85eab995fc1c0..83e441184f04cf69bf087245a8a2e83bddff0ccb 100644 --- a/lustre/include/lustre/lustre_idl.h +++ b/lustre/include/lustre/lustre_idl.h @@ -1110,10 +1110,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 diff --git a/lustre/llite/dir.c b/lustre/llite/dir.c index 8b17f466a436081d51af8fd816a9327cb42a980e..49caf89fe1a0bf07e88196062a5081876b183cd9 100644 --- a/lustre/llite/dir.c +++ b/lustre/llite/dir.c @@ -453,11 +453,51 @@ 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 mdc_op_data data; struct ptlrpc_request *req = NULL; + struct lustre_sb_info *lsi = s2lsi(inode->i_sb); + struct obd_device *mgc = lsi->lsi_mgc; + char *fsname = NULL, *param = NULL; struct iattr attr = { 0 }; int rc = 0; @@ -486,8 +526,38 @@ int ll_dir_setstripe(struct inode *inode, struct lov_user_md *lump) } ptlrpc_req_finished(req); - 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, @@ -614,6 +684,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]) == @@ -622,7 +693,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; } diff --git a/lustre/llite/llite_internal.h b/lustre/llite/llite_internal.h index 75cc6abe5f801e0a93f8865116fbb493fe7fb102..9f9c436a4eaa22c7a7fbb9b299eb9578db4f76dd 100644 --- a/lustre/llite/llite_internal.h +++ b/lustre/llite/llite_internal.h @@ -575,7 +575,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); diff --git a/lustre/llite/xattr.c b/lustre/llite/xattr.c index b27b1b45cda437c2d01e8985a6b9fe38d9813b14..235a9eda58da90f41ac37feee97fec4ef489dba1 100644 --- a/lustre/llite/xattr.c +++ b/lustre/llite/xattr.c @@ -175,7 +175,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; diff --git a/lustre/mgc/mgc_request.c b/lustre/mgc/mgc_request.c index 6020017b689f76adc90542aff7430ea2b9b9cbeb..ee88068a5fb29c6f80d856669c5a2d1d406267cf 100644 --- a/lustre/mgc/mgc_request.c +++ b/lustre/mgc/mgc_request.c @@ -733,6 +733,39 @@ static int mgc_target_register(struct obd_export *exp, 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); +} int mgc_reconnect_import(struct obd_import *imp) { @@ -834,6 +867,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); } diff --git a/lustre/mgs/mgs_handler.c b/lustre/mgs/mgs_handler.c index 7fa1198c61543934214c79e6df8e9543bc9d0078..14b7ac35af4b8bf1c44c4f62a1b190133ffc3eec 100644 --- a/lustre/mgs/mgs_handler.c +++ b/lustre/mgs/mgs_handler.c @@ -450,6 +450,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; @@ -493,6 +541,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"); diff --git a/lustre/ptlrpc/lproc_ptlrpc.c b/lustre/ptlrpc/lproc_ptlrpc.c index 79d68444208c49db1c09d4515270c925dcaa8e20..8fdacd8e969296dcf35ec6b10ecbb31737ecc7c8 100644 --- a/lustre/ptlrpc/lproc_ptlrpc.c +++ b/lustre/ptlrpc/lproc_ptlrpc.c @@ -90,6 +90,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_quota_callback" }, diff --git a/lustre/ptlrpc/wiretest.c b/lustre/ptlrpc/wiretest.c index bec68405a6774a780e1ade77b981e6708b1d26b3..34ec67fb061008105786bf0e7baca58ef558afbe 100644 --- a/lustre/ptlrpc/wiretest.c +++ b/lustre/ptlrpc/wiretest.c @@ -139,6 +139,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", @@ -211,6 +213,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 */ diff --git a/lustre/utils/wirecheck.c b/lustre/utils/wirecheck.c index 7c63dea53a24aff2cb0c897037dc06cb46df3ed9..126d58af05d21da7a3a2c310d32665b2388bb047 100644 --- a/lustre/utils/wirecheck.c +++ b/lustre/utils/wirecheck.c @@ -1129,6 +1129,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); @@ -1175,6 +1176,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(); diff --git a/lustre/utils/wiretest.c b/lustre/utils/wiretest.c index 536c45d73a96cf439cbef52b72c1996f585da861..2fa893317990f7144e38e82ba7913c200fe8d7b6 100644 --- a/lustre/utils/wiretest.c +++ b/lustre/utils/wiretest.c @@ -155,6 +155,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", @@ -227,6 +229,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 */