* Author: Nathan Rutman <nathan@clusterfs.com>
*/
-#ifndef EXPORT_SYMTAB
-#define EXPORT_SYMTAB
-#endif
#define DEBUG_SUBSYSTEM S_MGS
#define D_MGS D_CONFIG
#include <lustre_disk.h>
#include <lustre_param.h>
#include <lustre_sec.h>
+#include <lquota.h>
#include "mgs_internal.h"
/********************** Class functions ********************/
*/
/* 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);
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:
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);
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) -
/* 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++;
}
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);
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:
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);
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);
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);
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);
/* 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;
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,
dirent->lld_name);
}
}
+next:
OBD_FREE(dirent, sizeof(*dirent));
}
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;
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:
*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;
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;
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);
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:
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;
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);