Whamcloud - gitweb
LU-1818 quota: en/disable quota enforcement via conf_param
[fs/lustre-release.git] / lustre / mgs / mgs_llog.c
index 04d1326..f41532a 100644 (file)
@@ -40,9 +40,6 @@
  * Author: Nathan Rutman <nathan@clusterfs.com>
  */
 
-#ifndef EXPORT_SYMTAB
-#define EXPORT_SYMTAB
-#endif
 #define DEBUG_SUBSYSTEM S_MGS
 #define D_MGS D_CONFIG
 
@@ -63,6 +60,7 @@
 #include <lustre_disk.h>
 #include <lustre_param.h>
 #include <lustre_sec.h>
+#include <lquota.h>
 #include "mgs_internal.h"
 
 /********************** Class functions ********************/
@@ -139,10 +137,10 @@ struct mgs_fsdb_handler_data
 */
 /* It might be better to have a separate db file, instead of parsing the info
    out of the client log.  This is slow and potentially error-prone. */
-static int mgs_fsdb_handler(struct llog_handle *llh, struct llog_rec_hdr *rec,
-                            void *data)
+static int mgs_fsdb_handler(const struct lu_env *env, struct llog_handle *llh,
+                           struct llog_rec_hdr *rec, void *data)
 {
-        struct mgs_fsdb_handler_data *d = (struct mgs_fsdb_handler_data *) data;
+       struct mgs_fsdb_handler_data *d = data;
         struct fs_db *fsdb = d->fsdb;
         int cfg_len = rec->lrh_len;
         char *cfg_buf = (char*) (rec + 1);
@@ -278,21 +276,22 @@ static int mgs_get_fsdb_from_llog(struct obd_device *obd, struct fs_db *fsdb)
         name_create(&logname, fsdb->fsdb_name, "-client");
         cfs_mutex_lock(&fsdb->fsdb_mutex);
         push_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
-        rc = llog_create(ctxt, &loghandle, NULL, logname);
-        if (rc)
-                GOTO(out_pop, rc);
+       rc = llog_create(NULL, ctxt, &loghandle, NULL, logname);
+       if (rc)
+               GOTO(out_pop, rc);
 
-        rc = llog_init_handle(loghandle, LLOG_F_IS_PLAIN, NULL);
+       rc = llog_init_handle(NULL, loghandle, LLOG_F_IS_PLAIN, NULL);
         if (rc)
                 GOTO(out_close, rc);
 
         if (llog_get_size(loghandle) <= 1)
                 cfs_set_bit(FSDB_LOG_EMPTY, &fsdb->fsdb_flags);
 
-        rc = llog_process(loghandle, mgs_fsdb_handler, (void *) &d, NULL);
-        CDEBUG(D_INFO, "get_db = %d\n", rc);
+       rc = llog_process(NULL, loghandle, mgs_fsdb_handler, (void *) &d,
+                         NULL);
+       CDEBUG(D_INFO, "get_db = %d\n", rc);
 out_close:
-        rc2 = llog_close(loghandle);
+       rc2 = llog_close(NULL, loghandle);
         if (!rc)
                 rc = rc2;
 out_pop:
@@ -602,8 +601,8 @@ static int mgs_set_index(struct obd_device *obd, struct mgs_target_info *mti)
 
         cfs_set_bit(mti->mti_stripe_index, imap);
         cfs_clear_bit(FSDB_LOG_EMPTY, &fsdb->fsdb_flags);
-        server_make_name(mti->mti_flags, mti->mti_stripe_index,
-                         mti->mti_fsname, mti->mti_svname);
+       server_make_name(mti->mti_flags & ~(LDD_F_VIRGIN | LDD_F_WRITECONF),
+                        mti->mti_stripe_index, mti->mti_fsname, mti->mti_svname);
 
         CDEBUG(D_MGS, "Set index for %s to %d\n", mti->mti_svname,
                mti->mti_stripe_index);
@@ -616,10 +615,11 @@ struct mgs_modify_lookup {
         int               mml_modified;
 };
 
-static int mgs_modify_handler(struct llog_handle *llh, struct llog_rec_hdr *rec,
-                              void *data)
+static int mgs_modify_handler(const struct lu_env *env,
+                             struct llog_handle *llh,
+                             struct llog_rec_hdr *rec, void *data)
 {
-        struct mgs_modify_lookup *mml = (struct mgs_modify_lookup *)data;
+       struct mgs_modify_lookup *mml = data;
         struct cfg_marker *marker;
         struct lustre_cfg *lcfg = (struct lustre_cfg *)(rec + 1);
         int cfg_len = rec->lrh_len - sizeof(struct llog_rec_hdr) -
@@ -658,8 +658,8 @@ static int mgs_modify_handler(struct llog_handle *llh, struct llog_rec_hdr *rec,
                 /* Header and tail are added back to lrh_len in
                    llog_lvfs_write_rec */
                 rec->lrh_len = cfg_len;
-                rc = llog_write_rec(llh, rec, NULL, 0, (void *)lcfg,
-                                    rec->lrh_index);
+               rc = llog_write_rec(NULL, llh, rec, NULL, 0, (void *)lcfg,
+                                   rec->lrh_index);
                 if (!rc)
                          mml->mml_modified++;
         }
@@ -686,11 +686,11 @@ static int mgs_modify(struct obd_device *obd, struct fs_db *fsdb,
 
         ctxt = llog_get_context(obd, LLOG_CONFIG_ORIG_CTXT);
         LASSERT(ctxt != NULL);
-        rc = llog_create(ctxt, &loghandle, NULL, logname);
+       rc = llog_create(NULL, ctxt, &loghandle, NULL, logname);
         if (rc)
                 GOTO(out_pop, rc);
 
-        rc = llog_init_handle(loghandle, LLOG_F_IS_PLAIN, NULL);
+       rc = llog_init_handle(NULL, loghandle, LLOG_F_IS_PLAIN, NULL);
         if (rc)
                 GOTO(out_close, rc);
 
@@ -706,13 +706,14 @@ static int mgs_modify(struct obd_device *obd, struct fs_db *fsdb,
         mml->mml_marker.cm_flags = flags;
         mml->mml_marker.cm_canceltime = flags ? cfs_time_current_sec() : 0;
         mml->mml_modified = 0;
-        rc = llog_process(loghandle, mgs_modify_handler, (void *)mml, NULL);
+       rc = llog_process(NULL, loghandle, mgs_modify_handler, (void *)mml,
+                         NULL);
         if (!rc && !mml->mml_modified)
                 rc = -ENODEV;
         OBD_FREE_PTR(mml);
 
 out_close:
-        rc2 = llog_close(loghandle);
+       rc2 = llog_close(NULL, loghandle);
         if (!rc)
                 rc = rc2;
 out_pop:
@@ -745,7 +746,7 @@ static int record_lcfg(struct obd_device *obd, struct llog_handle *llh,
 
         push_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
         /* idx = -1 means append */
-        rc = llog_write_rec(llh, &rec, NULL, 0, (void *)lcfg, -1);
+       rc = llog_write_rec(NULL, llh, &rec, NULL, 0, (void *)lcfg, -1);
         pop_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
         if (rc)
                 CERROR("failed %d\n", rc);
@@ -927,11 +928,11 @@ static int record_start_log(struct obd_device *obd,
                 GOTO(out, rc = -ENODEV);
 
         push_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
-        rc = llog_create(ctxt, llh, NULL, name);
-        if (rc == 0)
-                llog_init_handle(*llh, LLOG_F_IS_PLAIN, &cfg_uuid);
-        else
-                *llh = NULL;
+       rc = llog_create(NULL, ctxt, llh, NULL, name);
+       if (rc == 0)
+               llog_init_handle(NULL, *llh, LLOG_F_IS_PLAIN, &cfg_uuid);
+       else
+               *llh = NULL;
 
         pop_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
         llog_ctxt_put(ctxt);
@@ -950,7 +951,7 @@ static int record_end_log(struct obd_device *obd, struct llog_handle **llh)
 
         push_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
 
-        rc = llog_close(*llh);
+       rc = llog_close(NULL, *llh);
         *llh = NULL;
 
         pop_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
@@ -967,11 +968,11 @@ static int mgs_log_is_empty(struct obd_device *obd, char *name)
         ctxt = llog_get_context(obd, LLOG_CONFIG_ORIG_CTXT);
         LASSERT(ctxt != NULL);
         push_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
-        rc = llog_create(ctxt, &llh, NULL, name);
+        rc = llog_create(NULL, ctxt, &llh, NULL, name);
         if (rc == 0) {
-                llog_init_handle(llh, LLOG_F_IS_PLAIN, NULL);
-                rc = llog_get_size(llh);
-                llog_close(llh);
+               llog_init_handle(NULL, llh, LLOG_F_IS_PLAIN, NULL);
+               rc = llog_get_size(llh);
+               llog_close(NULL, llh);
         }
         pop_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
         llog_ctxt_put(ctxt);
@@ -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));
         }
 
@@ -1088,9 +1097,9 @@ static int mgs_write_log_osc_to_lov(struct obd_device *obd, struct fs_db *fsdb,
 static void name_create_mdt_and_lov(char **logname, char **lovname,
                                     struct fs_db *fsdb, int i);
 
-static int mgs_steal_llog_handler(struct llog_handle *llh,
-                                  struct llog_rec_hdr *rec,
-                                  void *data)
+static int mgs_steal_llog_handler(const struct lu_env *env,
+                                 struct llog_handle *llh,
+                                 struct llog_rec_hdr *rec, void *data)
 {
         struct obd_device * obd;
         struct mgs_target_info *mti, *tmti;
@@ -1262,18 +1271,19 @@ static int mgs_steal_llog_for_mdt_from_client(struct obd_device *obd,
 
         push_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
 
-        rc = llog_create(ctxt, &loghandle, NULL, client_name);
+       rc = llog_create(NULL, ctxt, &loghandle, NULL, client_name);
         if (rc)
                 GOTO(out_pop, rc);
 
-        rc = llog_init_handle(loghandle, LLOG_F_IS_PLAIN, NULL);
+       rc = llog_init_handle(NULL, loghandle, LLOG_F_IS_PLAIN, NULL);
         if (rc)
                 GOTO(out_close, rc);
 
-        rc = llog_process(loghandle, mgs_steal_llog_handler, (void *)comp, NULL);
+       rc = llog_process(NULL, loghandle, mgs_steal_llog_handler,
+                         (void *)comp, NULL);
         CDEBUG(D_MGS, "steal llog re = %d\n", rc);
 out_close:
-        rc2 = llog_close(loghandle);
+       rc2 = llog_close(NULL, loghandle);
         if (!rc)
                 rc = rc2;
 out_pop:
@@ -2046,8 +2056,74 @@ 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:
+                       if (!obd_timeout_set || lcfg->lcfg_num > obd_timeout)
+                               class_process_config(lcfg);
+                       break;
+               case LCFG_SET_LDLM_TIMEOUT:
+                       if (!ldlm_timeout_set || lcfg->lcfg_num > ldlm_timeout)
+                               class_process_config(lcfg);
+                       break;
+               default:
+                       break;
+               }
+       }
+       *ptr = sep;
+       lustre_cfg_free(lcfg);
+       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;
@@ -2281,11 +2357,11 @@ struct mgs_srpc_read_data {
         int             msrd_skip;
 };
 
-static int mgs_srpc_read_handler(struct llog_handle *llh,
-                                 struct llog_rec_hdr *rec,
-                                 void *data)
+static int mgs_srpc_read_handler(const struct lu_env *env,
+                                struct llog_handle *llh,
+                                struct llog_rec_hdr *rec, void *data)
 {
-        struct mgs_srpc_read_data *msrd = (struct mgs_srpc_read_data *) data;
+       struct mgs_srpc_read_data *msrd = data;
         struct cfg_marker         *marker;
         struct lustre_cfg         *lcfg = (struct lustre_cfg *)(rec + 1);
         char                      *svname, *param;
@@ -2369,11 +2445,11 @@ int mgs_get_fsdb_srpc_from_llog(struct obd_device *obd,
 
         push_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
 
-        rc = llog_create(ctxt, &llh, NULL, logname);
+       rc = llog_create(NULL, ctxt, &llh, NULL, logname);
         if (rc)
                 GOTO(out_pop, rc);
 
-        rc = llog_init_handle(llh, LLOG_F_IS_PLAIN, NULL);
+       rc = llog_init_handle(NULL, llh, LLOG_F_IS_PLAIN, NULL);
         if (rc)
                 GOTO(out_close, rc);
 
@@ -2383,10 +2459,11 @@ int mgs_get_fsdb_srpc_from_llog(struct obd_device *obd,
         msrd.msrd_fsdb = fsdb;
         msrd.msrd_skip = 0;
 
-        rc = llog_process(llh, mgs_srpc_read_handler, (void *) &msrd, NULL);
+       rc = llog_process(NULL, llh, mgs_srpc_read_handler, (void *) &msrd,
+                         NULL);
 
 out_close:
-        llog_close(llh);
+       llog_close(NULL, llh);
 out_pop:
         pop_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
 out:
@@ -2460,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;
@@ -2885,10 +2967,10 @@ int mgs_erase_log(struct obd_device *obd, char *name)
         LASSERT(ctxt != NULL);
 
         push_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
-        rc = llog_create(ctxt, &llh, NULL, name);
-        if (rc == 0) {
-                llog_init_handle(llh, LLOG_F_IS_PLAIN, NULL);
-                rc = llog_destroy(llh);
+       rc = llog_create(NULL, ctxt, &llh, NULL, name);
+       if (rc == 0) {
+               llog_init_handle(NULL, llh, LLOG_F_IS_PLAIN, NULL);
+               rc = llog_destroy(NULL, llh);
                 llog_free_handle(llh);
         }
         pop_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);