From 6d9df3b2c0d54b16d00b6e419c7bb958e6b54844 Mon Sep 17 00:00:00 2001 From: James Simmons Date: Tue, 6 Feb 2018 10:39:30 -0500 Subject: [PATCH] LU-7004 quota: make lctl set_param -P functional for quota Currently setting up quota permanently can only be done with a command like lctl conf_param $FSNAME.quota.ost=ug. To see if those settings take hold we examine the 'enabled' proc file located in the quota_slave directory in the proc tree. To make this workable with lctl set_param -P we can make the 'enabled' proc file writable and lustre can treat the config log change from set_param -P for quota like any other tunable to be set permanetly. Change-Id: I6a4c1fdc9d16658930f48d21e4f79e6f36047511 Signed-off-by: James Simmons Reviewed-on: https://review.whamcloud.com/31081 Reviewed-by: Fan Yong Tested-by: Jenkins Tested-by: Maloo Reviewed-by: Wang Shilong Reviewed-by: Oleg Drokin --- lustre/quota/qsd_config.c | 62 +++++++++++++++++++++++++-------------------- lustre/quota/qsd_internal.h | 1 + lustre/quota/qsd_lib.c | 44 +++++++++++++++++++++++++++++++- 3 files changed, 79 insertions(+), 28 deletions(-) diff --git a/lustre/quota/qsd_config.c b/lustre/quota/qsd_config.c index 2701a08..3eb49c9 100644 --- a/lustre/quota/qsd_config.c +++ b/lustre/quota/qsd_config.c @@ -119,35 +119,13 @@ out: RETURN(qfs); } -/* - * Quota configuration handlers in charge of processing all per-filesystem quota - * parameters set via conf_param. - * - * \param lcfg - quota configuration log to be processed - */ -int qsd_process_config(struct lustre_cfg *lcfg) +int qsd_config(char *valstr, char *fsname, int pool) { - struct qsd_fsinfo *qfs; - char *fsname = lustre_cfg_string(lcfg, 0); - char *cfgstr = lustre_cfg_string(lcfg, 1); - char *keystr, *valstr; - int rc, pool, enabled = 0; - bool reint = false; - ENTRY; - - CDEBUG(D_QUOTA, "processing quota parameter: fs:%s cfgstr:%s\n", fsname, - cfgstr); - - if (class_match_param(cfgstr, PARAM_QUOTA, &keystr) != 0) - RETURN(-EINVAL); - - if (!class_match_param(keystr, QUOTA_METAPOOL_NAME, &valstr)) - pool = LQUOTA_RES_MD; - else if (!class_match_param(keystr, QUOTA_DATAPOOL_NAME, &valstr)) - pool = LQUOTA_RES_DT; - else - RETURN(-EINVAL); + struct qsd_fsinfo *qfs; + int rc, enabled = 0; + bool reint = false; + ENTRY; qfs = qsd_get_fsinfo(fsname, 0); if (qfs == NULL) { CERROR("failed to find quota filesystem information for %s\n", @@ -211,3 +189,33 @@ out: qsd_put_fsinfo(qfs); RETURN(0); } + +/* + * Quota configuration handlers in charge of processing all per-filesystem quota + * parameters set via conf_param. + * + * \param lcfg - quota configuration log to be processed + */ +int qsd_process_config(struct lustre_cfg *lcfg) +{ + char *fsname = lustre_cfg_string(lcfg, 0); + char *cfgstr = lustre_cfg_string(lcfg, 1); + char *keystr, *valstr; + int pool; + + ENTRY; + CDEBUG(D_QUOTA, "processing quota parameter: fs:%s cfgstr:%s\n", fsname, + cfgstr); + + if (class_match_param(cfgstr, PARAM_QUOTA, &keystr) != 0) + RETURN(-EINVAL); + + if (!class_match_param(keystr, QUOTA_METAPOOL_NAME, &valstr)) + pool = LQUOTA_RES_MD; + else if (!class_match_param(keystr, QUOTA_DATAPOOL_NAME, &valstr)) + pool = LQUOTA_RES_DT; + else + RETURN(-EINVAL); + + return qsd_config(valstr, fsname, pool); +} diff --git a/lustre/quota/qsd_internal.h b/lustre/quota/qsd_internal.h index e6271c7..1ffed37 100644 --- a/lustre/quota/qsd_internal.h +++ b/lustre/quota/qsd_internal.h @@ -379,6 +379,7 @@ void qsd_upd_schedule(struct qsd_qtype_info *, struct lquota_entry *, /* qsd_config.c */ struct qsd_fsinfo *qsd_get_fsinfo(char *, bool); void qsd_put_fsinfo(struct qsd_fsinfo *); +int qsd_config(char *valstr, char *fsname, int pool); int qsd_process_config(struct lustre_cfg *); /* qsd_handler.c */ diff --git a/lustre/quota/qsd_lib.c b/lustre/quota/qsd_lib.c index f68eb0c..1042d3b 100644 --- a/lustre/quota/qsd_lib.c +++ b/lustre/quota/qsd_lib.c @@ -148,7 +148,49 @@ static int qsd_enabled_seq_show(struct seq_file *m, void *data) seq_printf(m, "%s\n", enabled); return 0; } -LPROC_SEQ_FOPS_RO(qsd_enabled); + +static ssize_t qsd_enabled_seq_write(struct file *file, + const char __user *buffer, + size_t count, loff_t *off) +{ + struct seq_file *m = file->private_data; + struct qsd_instance *qsd = m->private; + char fsname[LUSTRE_MAXFSNAME]; + int enabled = 0; + char valstr[5]; + int pool, rc; + + if (count > 4) + return -E2BIG; + + if (copy_from_user(valstr, buffer, count)) + GOTO(out, count = -EFAULT); + + if (strchr(valstr, 'u')) + enabled |= BIT(USRQUOTA); + if (strchr(valstr, 'g')) + enabled |= BIT(GRPQUOTA); + if (strchr(valstr, 'p')) + enabled |= BIT(PRJQUOTA); + + if (enabled == 0 && strcmp(valstr, "none")) + GOTO(out, count = -EINVAL); + + if (qsd->qsd_is_md) + pool = LQUOTA_RES_MD; + else + pool = LQUOTA_RES_DT; + + if (server_name2fsname(qsd->qsd_svname, fsname, NULL)) + GOTO(out, count = -EINVAL); + + rc = qsd_config(valstr, fsname, pool); + if (rc) + count = rc; +out: + return count; +} +LPROC_SEQ_FOPS(qsd_enabled); /* force reintegration procedure to be executed. * Used for test/debugging purpose */ -- 1.8.3.1