Whamcloud - gitweb
LU-1818 quota: en/disable quota enforcement via conf_param
authorNiu Yawei <niu@whamcloud.com>
Tue, 4 Sep 2012 03:45:55 +0000 (11:45 +0800)
committerOleg Drokin <green@whamcloud.com>
Mon, 10 Sep 2012 02:37:28 +0000 (22:37 -0400)
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 <niu@whamcloud.com>
Change-Id: I89ef9fc1a067981cf7caac29c8311b75054c91fe
Reviewed-on: http://review.whamcloud.com/3850
Reviewed-by: Johann Lombardi <johann@whamcloud.com>
Tested-by: Hudson
Reviewed-by: Fan Yong <yong.fan@whamcloud.com>
Tested-by: Maloo <whamcloud.maloo@gmail.com>
lustre/include/lquota.h
lustre/include/lustre_param.h
lustre/mgs/mgs_llog.c
lustre/obdclass/obd_config.c

index 8d54c8f..13d1021 100644 (file)
@@ -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
  */
index b9d6052..26d2935 100644 (file)
@@ -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 */
 
index 10016d9..f41532a 100644 (file)
@@ -60,6 +60,7 @@
 #include <lustre_disk.h>
 #include <lustre_param.h>
 #include <lustre_sec.h>
+#include <lquota.h>
 #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;
index 1ac5b87..9220ac7 100644 (file)
@@ -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;
         }