From f52ece3201af131a7bb8a7b2766d3f0a98c00fca Mon Sep 17 00:00:00 2001 From: Niu Yawei Date: Tue, 4 Sep 2012 11:45:55 +0800 Subject: [PATCH 1/1] LU-1818 quota: en/disable quota enforcement via conf_param In the new quota architecture, quota is enabled/disabled per-filesystem, by 'lctl conf_param': lctl conf_param $FSNAME.quota.$POOLNAME=$VAL $FSNAME : filesystem name; $POOLNAME: 'mdt' (for meta pool) or 'ost' (for data pool); $VAL : 'none' - disable both, 'u' - enable user quota, 'g' - enable group quota, 'ug' - enable both; Signed-off-by: Niu Yawei Change-Id: I89ef9fc1a067981cf7caac29c8311b75054c91fe Reviewed-on: http://review.whamcloud.com/3850 Reviewed-by: Johann Lombardi Tested-by: Hudson Reviewed-by: Fan Yong Tested-by: Maloo --- lustre/include/lquota.h | 6 ++++ lustre/include/lustre_param.h | 1 + lustre/mgs/mgs_llog.c | 80 +++++++++++++++++++++++++++++++++++++++---- lustre/obdclass/obd_config.c | 19 +++++++--- 4 files changed, 95 insertions(+), 11 deletions(-) diff --git a/lustre/include/lquota.h b/lustre/include/lquota.h index 8d54c8f..13d1021 100644 --- a/lustre/include/lquota.h +++ b/lustre/include/lquota.h @@ -42,6 +42,12 @@ struct acct_rec { /* 16 bytes */ __u64 ispace; /* current # inodes in use */ }; +/* Name used in the configuration logs to identify the default metadata pool + * (composed of all the MDTs, with pool ID 0) and the default data pool (all + * the OSTs, with pool ID 0 too). */ +#define QUOTA_METAPOOL_NAME "mdt=" +#define QUOTA_DATAPOOL_NAME "ost=" + /* * Quota enforcement support on slaves */ diff --git a/lustre/include/lustre_param.h b/lustre/include/lustre_param.h index b9d6052..26d2935 100644 --- a/lustre/include/lustre_param.h +++ b/lustre/include/lustre_param.h @@ -111,6 +111,7 @@ int do_lcfg(char *cfgname, lnet_nid_t nid, int cmd, #define PARAM_SRPC_FLVR "srpc.flavor." #define PARAM_SRPC_UDESC "srpc.udesc.cli2mdt" #define PARAM_SEC "security." +#define PARAM_QUOTA "quota." /* global */ /** @} param */ diff --git a/lustre/mgs/mgs_llog.c b/lustre/mgs/mgs_llog.c index 10016d9..f41532a 100644 --- a/lustre/mgs/mgs_llog.c +++ b/lustre/mgs/mgs_llog.c @@ -60,6 +60,7 @@ #include #include #include +#include #include "mgs_internal.h" /********************** Class functions ********************/ @@ -1010,9 +1011,10 @@ static int mgs_write_log_direct(struct obd_device *obd, struct fs_db *fsdb, /* write the lcfg in all logs for the given fs */ int mgs_write_log_direct_all(struct obd_device *obd, struct fs_db *fsdb, - struct mgs_target_info *mti, - struct lustre_cfg *lcfg, - char *devname, char *comment) + struct mgs_target_info *mti, + struct lustre_cfg *lcfg, + char *devname, char *comment, + int server_only) { struct mgs_obd *mgs = &obd->u.mgs; cfs_list_t dentry_list; @@ -1048,8 +1050,14 @@ int mgs_write_log_direct_all(struct obd_device *obd, struct fs_db *fsdb, cfs_list_for_each_entry_safe(dirent, n, &dentry_list, lld_list) { cfs_list_del(&dirent->lld_list); /* don't write to sptlrpc rule log */ - if (strncmp(fsname, dirent->lld_name, len) == 0 && - strstr(dirent->lld_name, "-sptlrpc") == NULL) { + if (strstr(dirent->lld_name, "-sptlrpc") != NULL) + goto next; + + /* caller wants write server logs only */ + if (server_only && strstr(dirent->lld_name, "-client") != NULL) + goto next; + + if (strncmp(fsname, dirent->lld_name, len) == 0) { CDEBUG(D_MGS, "Changing log %s\n", dirent->lld_name); /* Erase any old settings of this same parameter */ mgs_modify(obd, fsdb, mti, dirent->lld_name, devname, @@ -1065,6 +1073,7 @@ int mgs_write_log_direct_all(struct obd_device *obd, struct fs_db *fsdb, dirent->lld_name); } } +next: OBD_FREE(dirent, sizeof(*dirent)); } @@ -2047,8 +2056,8 @@ static int mgs_write_log_sys(struct obd_device *obd, struct fs_db *fsdb, *ptr = '\0'; /* modify all servers and clients */ rc = mgs_write_log_direct_all(obd, fsdb, mti, - *tmp == '\0' ? NULL : lcfg, - mti->mti_fsname, sys); + *tmp == '\0' ? NULL : lcfg, + mti->mti_fsname, sys, 0); if (rc == 0 && *tmp != '\0') { switch (cmd) { case LCFG_SET_TIMEOUT: @@ -2068,6 +2077,58 @@ static int mgs_write_log_sys(struct obd_device *obd, struct fs_db *fsdb, return rc; } +/* write quota settings into log */ +static int mgs_write_log_quota(struct obd_device *obd, struct fs_db *fsdb, + struct mgs_target_info *mti, char *quota, + char *ptr) +{ + struct lustre_cfg_bufs bufs; + struct lustre_cfg *lcfg; + char *tmp; + char sep; + int cmd = LCFG_PARAM; + int rc; + + /* support only 'meta' and 'data' pools so far */ + if (class_match_param(ptr, QUOTA_METAPOOL_NAME, &tmp) != 0 && + class_match_param(ptr, QUOTA_DATAPOOL_NAME, &tmp) != 0) { + CERROR("parameter quota.%s isn't supported (only quota.mdt " + "& quota.ost are)\n", ptr); + return -EINVAL; + } + + if (*tmp == '\0') { + CDEBUG(D_MGS, "global '%s' removed\n", quota); + } else { + CDEBUG(D_MGS, "global '%s'\n", quota); + + if (strchr(tmp, 'u') == NULL && strchr(tmp, 'g') == NULL && + strcmp(tmp, "none") != 0) { + CERROR("enable option(%s) isn't supported\n", tmp); + return -EINVAL; + } + } + + lustre_cfg_bufs_reset(&bufs, NULL); + lustre_cfg_bufs_set_string(&bufs, 1, quota); + lcfg = lustre_cfg_new(cmd, &bufs); + /* truncate the comment to the parameter name */ + ptr = tmp - 1; + sep = *ptr; + *ptr = '\0'; + + /* XXX we duplicated quota enable information in all server + * config logs, it should be moved to a separate config + * log once we cleanup the config log for global param. */ + /* modify all servers */ + rc = mgs_write_log_direct_all(obd, fsdb, mti, + *tmp == '\0' ? NULL : lcfg, + mti->mti_fsname, quota, 1); + *ptr = sep; + lustre_cfg_free(lcfg); + return rc; +} + static int mgs_srpc_set_param_disk(struct obd_device *obd, struct fs_db *fsdb, struct mgs_target_info *mti, @@ -2476,6 +2537,11 @@ static int mgs_write_log_param(struct obd_device *obd, struct fs_db *fsdb, GOTO(end, rc); } + if (class_match_param(ptr, PARAM_QUOTA, &tmp) == 0) { + rc = mgs_write_log_quota(obd, fsdb, mti, ptr, tmp); + GOTO(end, rc); + } + if (class_match_param(ptr, PARAM_OSC""PARAM_ACTIVE, &tmp) == 0) { /* active=0 means off, anything else means on */ int flag = (*tmp == '0') ? CM_EXCLUDE : 0; diff --git a/lustre/obdclass/obd_config.c b/lustre/obdclass/obd_config.c index 1ac5b87..9220ac7 100644 --- a/lustre/obdclass/obd_config.c +++ b/lustre/obdclass/obd_config.c @@ -952,9 +952,10 @@ static int class_set_global(char *ptr, int val, struct lustre_cfg *lcfg) } -/* We can't call ll_process_config directly because it lives in a module that - must be loaded after this one. */ +/* We can't call ll_process_config or lquota_process_config directly because + * it lives in a module that must be loaded after this one. */ static int (*client_process_config)(struct lustre_cfg *lcfg) = NULL; +static int (*quota_process_config)(struct lustre_cfg *lcfg) = NULL; void lustre_register_client_process_config(int (*cpc)(struct lustre_cfg *lcfg)) { @@ -1035,6 +1036,12 @@ struct lustre_cfg *lustre_cfg_rename(struct lustre_cfg *cfg, } EXPORT_SYMBOL(lustre_cfg_rename); +void lustre_register_quota_process_config(int (*qpc)(struct lustre_cfg *lcfg)) +{ + quota_process_config = qpc; +} +EXPORT_SYMBOL(lustre_register_quota_process_config); + /** Process configuration commands given in lustre_cfg form. * These may come from direct calls (e.g. class_manual_cleanup) * or processing the config llog, or ioctl from lctl. @@ -1135,8 +1142,12 @@ int class_process_config(struct lustre_cfg *lcfg) if (err) CWARN("Ignoring unknown param %s\n", tmp); GOTO(out, 0); - } - + } else if ((class_match_param(lustre_cfg_string(lcfg, 1), + PARAM_QUOTA, &tmp) == 0) && + quota_process_config) { + err = (*quota_process_config)(lcfg); + GOTO(out, err); + } /* Fall through */ break; } -- 1.8.3.1