* Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved.
* Use is subject to license terms.
*
- * Copyright (c) 2011, 2015, Intel Corporation.
+ * Copyright (c) 2011, 2016, Intel Corporation.
*/
/*
* This file is part of Lustre, http://www.lustre.org/
/********************** Class functions ********************/
-/* Find all logs in CONFIG directory and link then into list */
-int class_dentry_readdir(const struct lu_env *env,
- struct mgs_device *mgs, struct list_head *log_list)
+/**
+ * Find all logs in CONFIG directory and link then into list.
+ *
+ * \param[in] env pointer to the thread context
+ * \param[in] mgs pointer to the mgs device
+ * \param[out] log_list the list to hold the found llog name entry
+ *
+ * \retval 0 for success
+ * \retval negative error number on failure
+ **/
+int class_dentry_readdir(const struct lu_env *env, struct mgs_device *mgs,
+ struct list_head *log_list)
{
- struct dt_object *dir = mgs->mgs_configs_dir;
+ struct dt_object *dir = mgs->mgs_configs_dir;
const struct dt_it_ops *iops;
- struct dt_it *it;
+ struct dt_it *it;
struct mgs_direntry *de;
- char *key;
- int rc, key_sz;
+ char *key;
+ int rc, key_sz;
INIT_LIST_HEAD(log_list);
fini:
iops->fini(env, it);
- if (rc)
+ if (rc) {
+ struct mgs_direntry *n;
+
CERROR("%s: key failed when listing %s: rc = %d\n",
mgs->mgs_obd->obd_name, MOUNT_CONFIGS_DIR, rc);
+
+ list_for_each_entry_safe(de, n, log_list, mde_list) {
+ list_del_init(&de->mde_list);
+ mgs_direntry_free(de);
+ }
+ }
+
RETURN(rc);
}
}
rc = 0;
CDEBUG(D_MGS, "MDT index is %u\n", index);
- set_bit(index, fsdb->fsdb_mdt_index_map);
- fsdb->fsdb_mdt_count ++;
- }
+ if (!test_bit(index, fsdb->fsdb_mdt_index_map)) {
+ set_bit(index, fsdb->fsdb_mdt_index_map);
+ fsdb->fsdb_mdt_count++;
+ }
+ }
/**
* figure out the old config. fsdb_gen = 0 means old log
struct mgs_device *mgs,
struct fs_db *fsdb)
{
- char *logname;
- struct llog_handle *loghandle;
- struct llog_ctxt *ctxt;
- struct mgs_fsdb_handler_data d = { fsdb, 0 };
+ char *logname;
+ struct llog_handle *loghandle;
+ struct llog_ctxt *ctxt;
+ struct mgs_fsdb_handler_data d = {
+ .fsdb = fsdb,
+ };
int rc;
ENTRY;
sptlrpc_rule_set_free(&fsdb->fsdb_srpc_gen);
}
-struct fs_db *mgs_find_fsdb(struct mgs_device *mgs, char *fsname)
+static void mgs_unlink_fsdb(struct mgs_device *mgs, struct fs_db *fsdb)
{
- struct fs_db *fsdb;
+ mutex_lock(&mgs->mgs_mutex);
+ if (likely(!list_empty(&fsdb->fsdb_list))) {
+ LASSERTF(atomic_read(&fsdb->fsdb_ref) >= 2,
+ "Invalid ref %d on %s\n",
+ atomic_read(&fsdb->fsdb_ref),
+ fsdb->fsdb_name);
+
+ list_del_init(&fsdb->fsdb_list);
+ /* Drop the reference on the list.*/
+ mgs_put_fsdb(mgs, fsdb);
+ }
+ mutex_unlock(&mgs->mgs_mutex);
+}
+
+/* The caller must hold mgs->mgs_mutex. */
+static inline struct fs_db *
+mgs_find_fsdb_noref(struct mgs_device *mgs, const char *fsname)
+{
+ struct fs_db *fsdb;
struct list_head *tmp;
list_for_each(tmp, &mgs->mgs_fs_db_list) {
fsdb = list_entry(tmp, struct fs_db, fsdb_list);
- if (strcmp(fsdb->fsdb_name, fsname) == 0)
- return fsdb;
- }
- return NULL;
+ if (strcmp(fsdb->fsdb_name, fsname) == 0)
+ return fsdb;
+ }
+
+ return NULL;
+}
+
+/* The caller must hold mgs->mgs_mutex. */
+static void mgs_remove_fsdb_by_name(struct mgs_device *mgs, const char *name)
+{
+ struct fs_db *fsdb;
+
+ fsdb = mgs_find_fsdb_noref(mgs, name);
+ if (fsdb) {
+ list_del_init(&fsdb->fsdb_list);
+ /* Drop the reference on the list.*/
+ mgs_put_fsdb(mgs, fsdb);
+ }
+}
+
+/* The caller must hold mgs->mgs_mutex. */
+struct fs_db *mgs_find_fsdb(struct mgs_device *mgs, const char *fsname)
+{
+ struct fs_db *fsdb;
+
+ fsdb = mgs_find_fsdb_noref(mgs, fsname);
+ if (fsdb)
+ atomic_inc(&fsdb->fsdb_ref);
+
+ return fsdb;
}
-/* caller must hold the mgs->mgs_fs_db_lock */
+/* The caller must hold mgs->mgs_mutex. */
static struct fs_db *mgs_new_fsdb(const struct lu_env *env,
struct mgs_device *mgs, char *fsname)
{
- struct fs_db *fsdb;
- int rc;
- ENTRY;
+ struct fs_db *fsdb;
+ int rc;
+ ENTRY;
+
+ if (strlen(fsname) >= sizeof(fsdb->fsdb_name)) {
+ CERROR("fsname %s is too long\n", fsname);
- if (strlen(fsname) >= sizeof(fsdb->fsdb_name)) {
- CERROR("fsname %s is too long\n", fsname);
RETURN(ERR_PTR(-EINVAL));
- }
+ }
- OBD_ALLOC_PTR(fsdb);
- if (!fsdb)
+ OBD_ALLOC_PTR(fsdb);
+ if (!fsdb)
RETURN(ERR_PTR(-ENOMEM));
- strcpy(fsdb->fsdb_name, fsname);
+ strncpy(fsdb->fsdb_name, fsname, sizeof(fsdb->fsdb_name));
mutex_init(&fsdb->fsdb_mutex);
+ INIT_LIST_HEAD(&fsdb->fsdb_list);
set_bit(FSDB_UDESC, &fsdb->fsdb_flags);
fsdb->fsdb_gen = 1;
+ INIT_LIST_HEAD(&fsdb->fsdb_clients);
+ atomic_set(&fsdb->fsdb_notify_phase, 0);
+ init_waitqueue_head(&fsdb->fsdb_notify_waitq);
+ init_completion(&fsdb->fsdb_notify_comp);
- if (strcmp(fsname, MGSSELF_NAME) == 0) {
+ if (strcmp(fsname, MGSSELF_NAME) == 0) {
set_bit(FSDB_MGS_SELF, &fsdb->fsdb_flags);
fsdb->fsdb_mgs = mgs;
- } else {
- OBD_ALLOC(fsdb->fsdb_ost_index_map, INDEX_MAP_SIZE);
- OBD_ALLOC(fsdb->fsdb_mdt_index_map, INDEX_MAP_SIZE);
- if (!fsdb->fsdb_ost_index_map || !fsdb->fsdb_mdt_index_map) {
- CERROR("No memory for index maps\n");
+ if (logname_is_barrier(fsname))
+ goto add;
+ } else {
+ OBD_ALLOC(fsdb->fsdb_mdt_index_map, INDEX_MAP_SIZE);
+ if (!fsdb->fsdb_mdt_index_map) {
+ CERROR("No memory for MDT index maps\n");
+
GOTO(err, rc = -ENOMEM);
- }
+ }
- rc = name_create(&fsdb->fsdb_clilov, fsname, "-clilov");
- if (rc)
- GOTO(err, rc);
- rc = name_create(&fsdb->fsdb_clilmv, fsname, "-clilmv");
- if (rc)
- GOTO(err, rc);
+ OBD_ALLOC(fsdb->fsdb_ost_index_map, INDEX_MAP_SIZE);
+ if (!fsdb->fsdb_ost_index_map) {
+ CERROR("No memory for OST index maps\n");
- /* initialise data for NID table */
- mgs_ir_init_fs(env, mgs, fsdb);
+ GOTO(err, rc = -ENOMEM);
+ }
+
+ if (logname_is_barrier(fsname))
+ goto add;
+
+ rc = name_create(&fsdb->fsdb_clilov, fsname, "-clilov");
+ if (rc)
+ GOTO(err, rc);
+
+ rc = name_create(&fsdb->fsdb_clilmv, fsname, "-clilmv");
+ if (rc)
+ GOTO(err, rc);
+ /* initialise data for NID table */
+ mgs_ir_init_fs(env, mgs, fsdb);
lproc_mgs_add_live(mgs, fsdb);
- }
+ }
+
+ if (!test_bit(FSDB_MGS_SELF, &fsdb->fsdb_flags) &&
+ strcmp(PARAMS_FILENAME, fsname) != 0) {
+ /* populate the db from the client llog */
+ rc = mgs_get_fsdb_from_llog(env, mgs, fsdb);
+ if (rc) {
+ CERROR("Can't get db from client log %d\n", rc);
+
+ GOTO(err, rc);
+ }
+ }
+ /* populate srpc rules from params llog */
+ rc = mgs_get_fsdb_srpc_from_llog(env, mgs, fsdb);
+ if (rc) {
+ CERROR("Can't get db from params log %d\n", rc);
+
+ GOTO(err, rc);
+ }
+
+add:
+ /* One ref is for the fsdb on the list.
+ * The other ref is for the caller. */
+ atomic_set(&fsdb->fsdb_ref, 2);
list_add(&fsdb->fsdb_list, &mgs->mgs_fs_db_list);
- RETURN(fsdb);
+ RETURN(fsdb);
+
err:
- if (fsdb->fsdb_ost_index_map)
- OBD_FREE(fsdb->fsdb_ost_index_map, INDEX_MAP_SIZE);
- if (fsdb->fsdb_mdt_index_map)
- OBD_FREE(fsdb->fsdb_mdt_index_map, INDEX_MAP_SIZE);
- name_destroy(&fsdb->fsdb_clilov);
- name_destroy(&fsdb->fsdb_clilmv);
- OBD_FREE_PTR(fsdb);
+ atomic_set(&fsdb->fsdb_ref, 1);
+ mgs_put_fsdb(mgs, fsdb);
+
RETURN(ERR_PTR(rc));
}
static void mgs_free_fsdb(struct mgs_device *mgs, struct fs_db *fsdb)
{
- /* wait for anyone with the sem */
- mutex_lock(&fsdb->fsdb_mutex);
+ LASSERT(list_empty(&fsdb->fsdb_list));
+
lproc_mgs_del_live(mgs, fsdb);
- list_del(&fsdb->fsdb_list);
-
- /* deinitialize fsr */
- mgs_ir_fini_fs(mgs, fsdb);
-
- if (fsdb->fsdb_ost_index_map)
- OBD_FREE(fsdb->fsdb_ost_index_map, INDEX_MAP_SIZE);
- if (fsdb->fsdb_mdt_index_map)
- OBD_FREE(fsdb->fsdb_mdt_index_map, INDEX_MAP_SIZE);
- name_destroy(&fsdb->fsdb_clilov);
- name_destroy(&fsdb->fsdb_clilmv);
- mgs_free_fsdb_srpc(fsdb);
- mutex_unlock(&fsdb->fsdb_mutex);
- OBD_FREE_PTR(fsdb);
+
+ /* deinitialize fsr */
+ if (fsdb->fsdb_mgs)
+ mgs_ir_fini_fs(mgs, fsdb);
+
+ if (fsdb->fsdb_ost_index_map)
+ OBD_FREE(fsdb->fsdb_ost_index_map, INDEX_MAP_SIZE);
+ if (fsdb->fsdb_mdt_index_map)
+ OBD_FREE(fsdb->fsdb_mdt_index_map, INDEX_MAP_SIZE);
+ name_destroy(&fsdb->fsdb_clilov);
+ name_destroy(&fsdb->fsdb_clilmv);
+ mgs_free_fsdb_srpc(fsdb);
+ OBD_FREE_PTR(fsdb);
+}
+
+void mgs_put_fsdb(struct mgs_device *mgs, struct fs_db *fsdb)
+{
+ if (atomic_dec_and_test(&fsdb->fsdb_ref))
+ mgs_free_fsdb(mgs, fsdb);
}
int mgs_init_fsdb_list(struct mgs_device *mgs)
mutex_lock(&mgs->mgs_mutex);
list_for_each_safe(tmp, tmp2, &mgs->mgs_fs_db_list) {
fsdb = list_entry(tmp, struct fs_db, fsdb_list);
- mgs_free_fsdb(mgs, fsdb);
+ list_del_init(&fsdb->fsdb_list);
+ mgs_put_fsdb(mgs, fsdb);
}
mutex_unlock(&mgs->mgs_mutex);
return 0;
}
-int mgs_find_or_make_fsdb(const struct lu_env *env,
- struct mgs_device *mgs, char *name,
- struct fs_db **dbh)
+int mgs_find_or_make_fsdb(const struct lu_env *env, struct mgs_device *mgs,
+ char *name, struct fs_db **dbh)
{
- struct fs_db *fsdb;
- int rc = 0;
-
+ struct fs_db *fsdb;
+ int rc = 0;
ENTRY;
+
mutex_lock(&mgs->mgs_mutex);
fsdb = mgs_find_fsdb(mgs, name);
- if (fsdb) {
- mutex_unlock(&mgs->mgs_mutex);
- *dbh = fsdb;
- RETURN(0);
- }
+ if (!fsdb) {
+ fsdb = mgs_new_fsdb(env, mgs, name);
+ if (IS_ERR(fsdb))
+ rc = PTR_ERR(fsdb);
- CDEBUG(D_MGS, "Creating new db\n");
- fsdb = mgs_new_fsdb(env, mgs, name);
- /* lock fsdb_mutex until the db is loaded from llogs */
- if (!IS_ERR(fsdb))
- mutex_lock(&fsdb->fsdb_mutex);
+ CDEBUG(D_MGS, "Created new db: rc = %d\n", rc);
+ }
mutex_unlock(&mgs->mgs_mutex);
- if (IS_ERR(fsdb))
- RETURN(PTR_ERR(fsdb));
-
- if (!test_bit(FSDB_MGS_SELF, &fsdb->fsdb_flags)) {
- /* populate the db from the client llog */
- rc = mgs_get_fsdb_from_llog(env, mgs, fsdb);
- if (rc) {
- CERROR("Can't get db from client log %d\n", rc);
- GOTO(out_free, rc);
- }
- }
-
- /* populate srpc rules from params llog */
- rc = mgs_get_fsdb_srpc_from_llog(env, mgs, fsdb);
- if (rc) {
- CERROR("Can't get db from params log %d\n", rc);
- GOTO(out_free, rc);
- }
-
- mutex_unlock(&fsdb->fsdb_mutex);
- *dbh = fsdb;
- RETURN(0);
+ if (!rc)
+ *dbh = fsdb;
-out_free:
- mutex_unlock(&fsdb->fsdb_mutex);
- mgs_free_fsdb(mgs, fsdb);
- return rc;
+ RETURN(rc);
}
/* 1 = index in use
}
if (test_bit(FSDB_LOG_EMPTY, &fsdb->fsdb_flags))
- RETURN(-1);
+ GOTO(out, rc = -1);
- if (mti->mti_flags & LDD_F_SV_TYPE_OST)
- imap = fsdb->fsdb_ost_index_map;
- else if (mti->mti_flags & LDD_F_SV_TYPE_MDT)
- imap = fsdb->fsdb_mdt_index_map;
- else
- RETURN(-EINVAL);
+ if (mti->mti_flags & LDD_F_SV_TYPE_OST)
+ imap = fsdb->fsdb_ost_index_map;
+ else if (mti->mti_flags & LDD_F_SV_TYPE_MDT)
+ imap = fsdb->fsdb_mdt_index_map;
+ else
+ GOTO(out, rc = -EINVAL);
if (test_bit(mti->mti_stripe_index, imap))
- RETURN(1);
- RETURN(0);
+ GOTO(out, rc = 1);
+
+ GOTO(out, rc = 0);
+
+out:
+ mgs_put_fsdb(mgs, fsdb);
+ return rc;
}
static __inline__ int next_index(void *index_map, int map_len)
return -1;
}
+/* Make the mdt/ost server obd name based on the filesystem name */
+static bool server_make_name(u32 flags, u16 index, const char *fs,
+ char *name_buf, size_t name_buf_size)
+{
+ bool invalid_flag = false;
+
+ if (flags & (LDD_F_SV_TYPE_MDT | LDD_F_SV_TYPE_OST)) {
+ if (!(flags & LDD_F_SV_ALL))
+ snprintf(name_buf, name_buf_size, "%.8s%c%s%04x", fs,
+ (flags & LDD_F_VIRGIN) ? ':' :
+ ((flags & LDD_F_WRITECONF) ? '=' : '-'),
+ (flags & LDD_F_SV_TYPE_MDT) ? "MDT" : "OST",
+ index);
+ } else if (flags & LDD_F_SV_TYPE_MGS) {
+ snprintf(name_buf, name_buf_size, "MGS");
+ } else {
+ CERROR("unknown server type %#x\n", flags);
+ invalid_flag = true;
+ }
+ return invalid_flag;
+}
+
/* Return codes:
0 newly marked as in use
<0 err
if (rc == -1)
GOTO(out_up, rc = -ERANGE);
mti->mti_stripe_index = rc;
- if (mti->mti_flags & LDD_F_SV_TYPE_MDT)
- fsdb->fsdb_mdt_count ++;
}
/* the last index(0xffff) is reserved for default value. */
CDEBUG(D_MGS, "Server %s updating index %d\n",
mti->mti_svname, mti->mti_stripe_index);
GOTO(out_up, rc = EALREADY);
- }
- }
+ }
+ } else {
+ set_bit(mti->mti_stripe_index, imap);
+ if (mti->mti_flags & LDD_F_SV_TYPE_MDT)
+ fsdb->fsdb_mdt_count++;
+ }
set_bit(mti->mti_stripe_index, imap);
clear_bit(FSDB_LOG_EMPTY, &fsdb->fsdb_flags);
- mutex_unlock(&fsdb->fsdb_mutex);
- server_make_name(mti->mti_flags & ~(LDD_F_VIRGIN | LDD_F_WRITECONF),
- mti->mti_stripe_index, mti->mti_fsname, mti->mti_svname);
+ if (server_make_name(mti->mti_flags & ~(LDD_F_VIRGIN | LDD_F_WRITECONF),
+ mti->mti_stripe_index, mti->mti_fsname,
+ mti->mti_svname, sizeof(mti->mti_svname))) {
+ CERROR("unknown server type %#x\n", mti->mti_flags);
+ GOTO(out_up, rc = -EINVAL);
+ }
- CDEBUG(D_MGS, "Set index for %s to %d\n", mti->mti_svname,
- mti->mti_stripe_index);
+ CDEBUG(D_MGS, "Set index for %s to %d\n", mti->mti_svname,
+ mti->mti_stripe_index);
+
+ GOTO(out_up, rc = 0);
- RETURN(0);
out_up:
mutex_unlock(&fsdb->fsdb_mutex);
+ mgs_put_fsdb(mgs, fsdb);
return rc;
}
int mml_modified;
};
+static int mgs_check_record_match(const struct lu_env *env,
+ struct llog_handle *llh,
+ struct llog_rec_hdr *rec, void *data)
+{
+ struct cfg_marker *mc_marker = data;
+ struct cfg_marker *marker;
+ struct lustre_cfg *lcfg = REC_DATA(rec);
+ int cfg_len = REC_DATA_LEN(rec);
+ int rc;
+ ENTRY;
+
+
+ if (rec->lrh_type != OBD_CFG_REC) {
+ CDEBUG(D_ERROR, "Unhandled lrh_type: %#x\n", rec->lrh_type);
+ RETURN(-EINVAL);
+ }
+
+ rc = lustre_cfg_sanity_check(lcfg, cfg_len);
+ if (rc) {
+ CDEBUG(D_ERROR, "Insane cfg\n");
+ RETURN(rc);
+ }
+
+ /* We only care about markers */
+ if (lcfg->lcfg_command != LCFG_MARKER)
+ RETURN(0);
+
+ marker = lustre_cfg_buf(lcfg, 1);
+
+ if (marker->cm_flags & CM_SKIP)
+ RETURN(0);
+
+ if ((strcmp(mc_marker->cm_comment, marker->cm_comment) == 0) &&
+ (strcmp(mc_marker->cm_tgtname, marker->cm_tgtname) == 0)) {
+ /* Found a non-skipped marker match */
+ CDEBUG(D_MGS, "Matched rec %u marker %d flag %x %s %s\n",
+ rec->lrh_index, marker->cm_step,
+ marker->cm_flags, marker->cm_tgtname,
+ marker->cm_comment);
+ rc = LLOG_PROC_BREAK;
+ }
+
+ RETURN(rc);
+}
+
+/**
+ * Check an existing config log record with matching comment and device
+ * Return code:
+ * 0 - checked successfully,
+ * LLOG_PROC_BREAK - record matches
+ * negative - error
+ */
+static int mgs_check_marker(const struct lu_env *env, struct mgs_device *mgs,
+ struct fs_db *fsdb, struct mgs_target_info *mti,
+ char *logname, char *devname, char *comment)
+{
+ struct llog_handle *loghandle;
+ struct llog_ctxt *ctxt;
+ struct cfg_marker *mc_marker;
+ int rc;
+
+ ENTRY;
+
+ LASSERT(mutex_is_locked(&fsdb->fsdb_mutex));
+ CDEBUG(D_MGS, "mgs check %s/%s/%s\n", logname, devname, comment);
+
+ ctxt = llog_get_context(mgs->mgs_obd, LLOG_CONFIG_ORIG_CTXT);
+ LASSERT(ctxt != NULL);
+ rc = llog_open(env, ctxt, &loghandle, NULL, logname, LLOG_OPEN_EXISTS);
+ if (rc < 0) {
+ if (rc == -ENOENT)
+ rc = 0;
+ GOTO(out_pop, rc);
+ }
+
+ rc = llog_init_handle(env, loghandle, LLOG_F_IS_PLAIN, NULL);
+ if (rc)
+ GOTO(out_close, rc);
+
+ if (llog_get_size(loghandle) <= 1)
+ GOTO(out_close, rc = 0);
+
+ OBD_ALLOC_PTR(mc_marker);
+ if (!mc_marker)
+ GOTO(out_close, rc = -ENOMEM);
+ if (strlcpy(mc_marker->cm_comment, comment,
+ sizeof(mc_marker->cm_comment)) >=
+ sizeof(mc_marker->cm_comment))
+ GOTO(out_free, rc = -E2BIG);
+ if (strlcpy(mc_marker->cm_tgtname, devname,
+ sizeof(mc_marker->cm_tgtname)) >=
+ sizeof(mc_marker->cm_tgtname))
+ GOTO(out_free, rc = -E2BIG);
+
+ rc = llog_process(env, loghandle, mgs_check_record_match,
+ (void *)mc_marker, NULL);
+
+out_free:
+ OBD_FREE_PTR(mc_marker);
+
+out_close:
+ llog_close(env, loghandle);
+out_pop:
+ if (rc && rc != LLOG_PROC_BREAK)
+ CDEBUG(D_ERROR, "%s: mgs check %s/%s failed: rc = %d\n",
+ mgs->mgs_obd->obd_name, mti->mti_svname, comment, rc);
+ llog_ctxt_put(ctxt);
+ RETURN(rc);
+}
+
static int mgs_modify_handler(const struct lu_env *env,
struct llog_handle *llh,
struct llog_rec_hdr *rec, void *data)
int rc;
__u32 index;
char *logname;
- struct fs_db *fsdb;
+ struct fs_db *fsdb = NULL;
unsigned int i;
int conn_state;
struct obd_device *mgs_obd = mgs->mgs_obd;
mgs_obd->obd_no_conn = conn_state;
spin_unlock(&mgs_obd->obd_dev_lock);
+ if (fsdb)
+ mgs_put_fsdb(mgs, fsdb);
+
RETURN(rc);
}
CDEBUG(D_MGS, "global '%s'\n", quota);
if (strchr(tmp, 'u') == NULL && strchr(tmp, 'g') == NULL &&
+ strchr(tmp, 'p') == NULL &&
strcmp(tmp, "none") != 0) {
CERROR("enable option(%s) isn't supported\n", tmp);
return -EINVAL;
LCONSOLE_ERROR_MSG(0x144, "%s: MDC0 can not be"
" (de)activated.\n",
mti->mti_svname);
- GOTO(end, rc = -EINVAL);
+ GOTO(end, rc = -EPERM);
}
}
}
/* erase all logs for the given fs */
-int mgs_erase_logs(const struct lu_env *env, struct mgs_device *mgs, char *fsname)
+int mgs_erase_logs(const struct lu_env *env, struct mgs_device *mgs,
+ const char *fsname)
{
- struct fs_db *fsdb;
struct list_head log_list;
struct mgs_direntry *dirent, *n;
- int rc, len = strlen(fsname);
+ char barrier_name[20] = {};
char *suffix;
+ int count = 0;
+ int rc, len = strlen(fsname);
ENTRY;
+ mutex_lock(&mgs->mgs_mutex);
+
/* Find all the logs in the CONFIGS directory */
rc = class_dentry_readdir(env, mgs, &log_list);
- if (rc)
+ if (rc) {
+ mutex_unlock(&mgs->mgs_mutex);
RETURN(rc);
+ }
- mutex_lock(&mgs->mgs_mutex);
-
- /* Delete the fs db */
- fsdb = mgs_find_fsdb(mgs, fsname);
- if (fsdb)
- mgs_free_fsdb(mgs, fsdb);
+ if (list_empty(&log_list)) {
+ mutex_unlock(&mgs->mgs_mutex);
+ RETURN(-ENOENT);
+ }
+ snprintf(barrier_name, sizeof(barrier_name) - 1, "%s-%s",
+ fsname, BARRIER_FILENAME);
+ /* Delete the barrier fsdb */
+ mgs_remove_fsdb_by_name(mgs, barrier_name);
+ /* Delete the fs db */
+ mgs_remove_fsdb_by_name(mgs, fsname);
mutex_unlock(&mgs->mgs_mutex);
list_for_each_entry_safe(dirent, n, &log_list, mde_list) {
CDEBUG(D_MGS, "Removing log %s\n",
dirent->mde_name);
mgs_erase_log(env, mgs, dirent->mde_name);
+ count++;
}
}
mgs_direntry_free(dirent);
}
- RETURN(rc);
+ if (count == 0)
+ rc = -ENOENT;
+
+ RETURN(rc);
}
/* list all logs for the given fs */
list_del_init(&dirent->mde_list);
suffix = strrchr(dirent->mde_name, '-');
if (suffix != NULL) {
- l = snprintf(out, remains, "config log: $%s\n",
+ l = snprintf(out, remains, "config_log: %s\n",
dirent->mde_name);
out += l;
remains -= l;
RETURN(rc);
}
-/* from llog_swab */
-static void print_lustre_cfg(struct lustre_cfg *lcfg)
+struct mgs_lcfg_fork_data {
+ struct lustre_cfg_bufs mlfd_bufs;
+ struct mgs_device *mlfd_mgs;
+ struct llog_handle *mlfd_llh;
+ const char *mlfd_oldname;
+ const char *mlfd_newname;
+ char mlfd_data[0];
+};
+
+static bool contain_valid_fsname(char *buf, const char *fsname,
+ int buflen, int namelen)
{
- int i;
- ENTRY;
+ if (buflen < namelen)
+ return false;
- CDEBUG(D_MGS, "lustre_cfg: %p\n", lcfg);
- CDEBUG(D_MGS, "\tlcfg->lcfg_version: %#x\n", lcfg->lcfg_version);
+ if (memcmp(buf, fsname, namelen) != 0)
+ return false;
- CDEBUG(D_MGS, "\tlcfg->lcfg_command: %#x\n", lcfg->lcfg_command);
- CDEBUG(D_MGS, "\tlcfg->lcfg_num: %#x\n", lcfg->lcfg_num);
- CDEBUG(D_MGS, "\tlcfg->lcfg_flags: %#x\n", lcfg->lcfg_flags);
- CDEBUG(D_MGS, "\tlcfg->lcfg_nid: %s\n", libcfs_nid2str(lcfg->lcfg_nid));
+ if (buf[namelen] != '\0' && buf[namelen] != '-')
+ return false;
- CDEBUG(D_MGS, "\tlcfg->lcfg_bufcount: %d\n", lcfg->lcfg_bufcount);
- if (lcfg->lcfg_bufcount < LUSTRE_CFG_MAX_BUFCOUNT)
- for (i = 0; i < lcfg->lcfg_bufcount; i++) {
- CDEBUG(D_MGS, "\tlcfg->lcfg_buflens[%d]: %d %s\n",
- i, lcfg->lcfg_buflens[i],
- lustre_cfg_string(lcfg, i));
- }
- EXIT;
+ return true;
}
-/* Setup _mgs fsdb and log
- */
-int mgs__mgs_fsdb_setup(const struct lu_env *env, struct mgs_device *mgs,
- struct fs_db *fsdb)
+static int mgs_lcfg_fork_handler(const struct lu_env *env,
+ struct llog_handle *o_llh,
+ struct llog_rec_hdr *o_rec, void *data)
{
- int rc;
+ struct mgs_lcfg_fork_data *mlfd = data;
+ struct lustre_cfg_bufs *n_bufs = &mlfd->mlfd_bufs;
+ struct lustre_cfg *o_lcfg = (struct lustre_cfg *)(o_rec + 1);
+ struct llog_cfg_rec *lcr;
+ char *o_buf;
+ char *n_buf = mlfd->mlfd_data;
+ int o_buflen;
+ int o_namelen = strlen(mlfd->mlfd_oldname);
+ int n_namelen = strlen(mlfd->mlfd_newname);
+ int diff = n_namelen - o_namelen;
+ __u32 cmd = o_lcfg->lcfg_command;
+ __u32 cnt = o_lcfg->lcfg_bufcount;
+ int rc;
+ int i;
ENTRY;
- rc = mgs_find_or_make_fsdb(env, mgs, MGSSELF_NAME, &fsdb);
+ /* buf[0] */
+ o_buf = lustre_cfg_buf(o_lcfg, 0);
+ o_buflen = o_lcfg->lcfg_buflens[0];
+ if (contain_valid_fsname(o_buf, mlfd->mlfd_oldname, o_buflen,
+ o_namelen)) {
+ memcpy(n_buf, mlfd->mlfd_newname, n_namelen);
+ memcpy(n_buf + n_namelen, o_buf + o_namelen,
+ o_buflen - o_namelen);
+ lustre_cfg_bufs_reset(n_bufs, n_buf);
+ n_buf += cfs_size_round(o_buflen + diff);
+ } else {
+ lustre_cfg_bufs_reset(n_bufs, o_buflen != 0 ? o_buf : NULL);
+ }
+
+ switch (cmd) {
+ case LCFG_MARKER: {
+ struct cfg_marker *o_marker;
+ struct cfg_marker *n_marker;
+ int tgt_namelen;
+
+ if (cnt != 2) {
+ CDEBUG(D_MGS, "Unknown cfg marker entry with %d "
+ "buffers\n", cnt);
+ RETURN(-EINVAL);
+ }
+
+ /* buf[1] is marker */
+ o_buf = lustre_cfg_buf(o_lcfg, 1);
+ o_buflen = o_lcfg->lcfg_buflens[1];
+ o_marker = (struct cfg_marker *)o_buf;
+ if (!contain_valid_fsname(o_marker->cm_tgtname,
+ mlfd->mlfd_oldname,
+ sizeof(o_marker->cm_tgtname),
+ o_namelen)) {
+ lustre_cfg_bufs_set(n_bufs, 1, o_marker,
+ sizeof(*o_marker));
+ break;
+ }
+
+ n_marker = (struct cfg_marker *)n_buf;
+ *n_marker = *o_marker;
+ memcpy(n_marker->cm_tgtname, mlfd->mlfd_newname, n_namelen);
+ tgt_namelen = strlen(o_marker->cm_tgtname);
+ if (tgt_namelen > o_namelen)
+ memcpy(n_marker->cm_tgtname + n_namelen,
+ o_marker->cm_tgtname + o_namelen,
+ tgt_namelen - o_namelen);
+ n_marker->cm_tgtname[tgt_namelen + diff] = '\0';
+ lustre_cfg_bufs_set(n_bufs, 1, n_marker, sizeof(*n_marker));
+ break;
+ }
+ case LCFG_PARAM:
+ case LCFG_SET_PARAM: {
+ for (i = 1; i < cnt; i++)
+ /* buf[i] is the param value, reuse it directly */
+ lustre_cfg_bufs_set(n_bufs, i,
+ lustre_cfg_buf(o_lcfg, i),
+ o_lcfg->lcfg_buflens[i]);
+ break;
+ }
+ case LCFG_POOL_NEW:
+ case LCFG_POOL_ADD:
+ case LCFG_POOL_REM:
+ case LCFG_POOL_DEL: {
+ if (cnt < 3 || cnt > 4) {
+ CDEBUG(D_MGS, "Unknown cfg pool (%x) entry with %d "
+ "buffers\n", cmd, cnt);
+ RETURN(-EINVAL);
+ }
+
+ /* buf[1] is fsname */
+ o_buf = lustre_cfg_buf(o_lcfg, 1);
+ o_buflen = o_lcfg->lcfg_buflens[1];
+ memcpy(n_buf, mlfd->mlfd_newname, n_namelen);
+ memcpy(n_buf + n_namelen, o_buf + o_namelen,
+ o_buflen - o_namelen);
+ lustre_cfg_bufs_set(n_bufs, 1, n_buf, o_buflen + diff);
+ n_buf += cfs_size_round(o_buflen + diff);
+
+ /* buf[2] is the pool name, reuse it directly */
+ lustre_cfg_bufs_set(n_bufs, 2, lustre_cfg_buf(o_lcfg, 2),
+ o_lcfg->lcfg_buflens[2]);
+
+ if (cnt == 3)
+ break;
+
+ /* buf[3] is ostname */
+ o_buf = lustre_cfg_buf(o_lcfg, 3);
+ o_buflen = o_lcfg->lcfg_buflens[3];
+ memcpy(n_buf, mlfd->mlfd_newname, n_namelen);
+ memcpy(n_buf + n_namelen, o_buf + o_namelen,
+ o_buflen - o_namelen);
+ lustre_cfg_bufs_set(n_bufs, 3, n_buf, o_buflen + diff);
+ break;
+ }
+ case LCFG_SETUP: {
+ if (cnt == 2) {
+ o_buflen = o_lcfg->lcfg_buflens[1];
+ if (o_buflen == sizeof(struct lov_desc) ||
+ o_buflen == sizeof(struct lmv_desc)) {
+ char *o_uuid;
+ char *n_uuid;
+ int uuid_len;
+
+ /* buf[1] */
+ o_buf = lustre_cfg_buf(o_lcfg, 1);
+ if (o_buflen == sizeof(struct lov_desc)) {
+ struct lov_desc *o_desc =
+ (struct lov_desc *)o_buf;
+ struct lov_desc *n_desc =
+ (struct lov_desc *)n_buf;
+
+ *n_desc = *o_desc;
+ o_uuid = o_desc->ld_uuid.uuid;
+ n_uuid = n_desc->ld_uuid.uuid;
+ uuid_len = sizeof(o_desc->ld_uuid.uuid);
+ } else {
+ struct lmv_desc *o_desc =
+ (struct lmv_desc *)o_buf;
+ struct lmv_desc *n_desc =
+ (struct lmv_desc *)n_buf;
+
+ *n_desc = *o_desc;
+ o_uuid = o_desc->ld_uuid.uuid;
+ n_uuid = n_desc->ld_uuid.uuid;
+ uuid_len = sizeof(o_desc->ld_uuid.uuid);
+ }
+
+ if (unlikely(!contain_valid_fsname(o_uuid,
+ mlfd->mlfd_oldname, uuid_len,
+ o_namelen))) {
+ lustre_cfg_bufs_set(n_bufs, 1, o_buf,
+ o_buflen);
+ break;
+ }
+
+ memcpy(n_uuid, mlfd->mlfd_newname, n_namelen);
+ uuid_len = strlen(o_uuid);
+ if (uuid_len > o_namelen)
+ memcpy(n_uuid + n_namelen,
+ o_uuid + o_namelen,
+ uuid_len - o_namelen);
+ n_uuid[uuid_len + diff] = '\0';
+ lustre_cfg_bufs_set(n_bufs, 1, n_buf, o_buflen);
+ break;
+ } /* else case fall through */
+ } /* else case fall through */
+ }
+ default: {
+ for (i = 1; i < cnt; i++) {
+ o_buflen = o_lcfg->lcfg_buflens[i];
+ if (o_buflen == 0)
+ continue;
+
+ o_buf = lustre_cfg_buf(o_lcfg, i);
+ if (!contain_valid_fsname(o_buf, mlfd->mlfd_oldname,
+ o_buflen, o_namelen)) {
+ lustre_cfg_bufs_set(n_bufs, i, o_buf, o_buflen);
+ continue;
+ }
+
+ memcpy(n_buf, mlfd->mlfd_newname, n_namelen);
+ if (o_buflen == o_namelen) {
+ lustre_cfg_bufs_set(n_bufs, i, n_buf,
+ n_namelen);
+ n_buf += cfs_size_round(n_namelen);
+ continue;
+ }
+
+ memcpy(n_buf + n_namelen, o_buf + o_namelen,
+ o_buflen - o_namelen);
+ lustre_cfg_bufs_set(n_bufs, i, n_buf, o_buflen + diff);
+ n_buf += cfs_size_round(o_buflen + diff);
+ }
+ break;
+ }
+ }
+
+ lcr = lustre_cfg_rec_new(cmd, n_bufs);
+ if (!lcr)
+ RETURN(-ENOMEM);
+
+ lcr->lcr_cfg = *o_lcfg;
+ rc = llog_write(env, mlfd->mlfd_llh, &lcr->lcr_hdr, LLOG_NEXT_IDX);
+ lustre_cfg_rec_free(lcr);
+
+ RETURN(rc);
+}
+
+static int mgs_lcfg_fork_one(const struct lu_env *env, struct mgs_device *mgs,
+ struct mgs_direntry *mde, const char *oldname,
+ const char *newname)
+{
+ struct llog_handle *old_llh = NULL;
+ struct llog_handle *new_llh = NULL;
+ struct llog_ctxt *ctxt = NULL;
+ struct mgs_lcfg_fork_data *mlfd = NULL;
+ char *name_buf = NULL;
+ int name_buflen;
+ int old_namelen = strlen(oldname);
+ int new_namelen = strlen(newname);
+ int rc;
+ ENTRY;
+
+ name_buflen = mde->mde_len + new_namelen - old_namelen;
+ OBD_ALLOC(name_buf, name_buflen);
+ if (!name_buf)
+ RETURN(-ENOMEM);
+
+ memcpy(name_buf, newname, new_namelen);
+ memcpy(name_buf + new_namelen, mde->mde_name + old_namelen,
+ mde->mde_len - old_namelen);
+
+ CDEBUG(D_MGS, "Fork the config-log from %s to %s\n",
+ mde->mde_name, name_buf);
+
+ ctxt = llog_get_context(mgs->mgs_obd, LLOG_CONFIG_ORIG_CTXT);
+ LASSERT(ctxt);
+
+ rc = llog_open_create(env, ctxt, &new_llh, NULL, name_buf);
+ if (rc)
+ GOTO(out, rc);
+
+ rc = llog_init_handle(env, new_llh, LLOG_F_IS_PLAIN, NULL);
+ if (rc)
+ GOTO(out, rc);
+
+ if (unlikely(mgs_log_is_empty(env, mgs, mde->mde_name)))
+ GOTO(out, rc = 0);
+
+ rc = llog_open(env, ctxt, &old_llh, NULL, mde->mde_name,
+ LLOG_OPEN_EXISTS);
+ if (rc)
+ GOTO(out, rc);
+
+ rc = llog_init_handle(env, old_llh, LLOG_F_IS_PLAIN, NULL);
+ if (rc)
+ GOTO(out, rc);
+
+ new_llh->lgh_hdr->llh_tgtuuid = old_llh->lgh_hdr->llh_tgtuuid;
+
+ OBD_ALLOC(mlfd, LLOG_MIN_CHUNK_SIZE);
+ if (!mlfd)
+ GOTO(out, rc = -ENOMEM);
+
+ mlfd->mlfd_mgs = mgs;
+ mlfd->mlfd_llh = new_llh;
+ mlfd->mlfd_oldname = oldname;
+ mlfd->mlfd_newname = newname;
+
+ rc = llog_process(env, old_llh, mgs_lcfg_fork_handler, mlfd, NULL);
+ OBD_FREE(mlfd, LLOG_MIN_CHUNK_SIZE);
+
+ GOTO(out, rc);
+
+out:
+ if (old_llh)
+ llog_close(env, old_llh);
+ if (new_llh)
+ llog_close(env, new_llh);
+ if (name_buf)
+ OBD_FREE(name_buf, name_buflen);
+ if (ctxt)
+ llog_ctxt_put(ctxt);
+
+ return rc;
+}
+
+int mgs_lcfg_fork(const struct lu_env *env, struct mgs_device *mgs,
+ const char *oldname, const char *newname)
+{
+ struct list_head log_list;
+ struct mgs_direntry *dirent, *n;
+ int olen = strlen(oldname);
+ int nlen = strlen(newname);
+ int count = 0;
+ int rc = 0;
+ ENTRY;
+
+ if (unlikely(!oldname || oldname[0] == '\0' ||
+ !newname || newname[0] == '\0'))
+ RETURN(-EINVAL);
+
+ if (strcmp(oldname, newname) == 0)
+ RETURN(-EINVAL);
+
+ /* lock it to prevent fork/erase/register in parallel. */
+ mutex_lock(&mgs->mgs_mutex);
+
+ rc = class_dentry_readdir(env, mgs, &log_list);
+ if (rc) {
+ mutex_unlock(&mgs->mgs_mutex);
+ RETURN(rc);
+ }
+
+ if (list_empty(&log_list)) {
+ mutex_unlock(&mgs->mgs_mutex);
+ RETURN(-ENOENT);
+ }
+
+ list_for_each_entry_safe(dirent, n, &log_list, mde_list) {
+ char *ptr;
+
+ ptr = strrchr(dirent->mde_name, '-');
+ if (ptr) {
+ int tlen = ptr - dirent->mde_name;
+
+ if (tlen == nlen &&
+ strncmp(newname, dirent->mde_name, tlen) == 0)
+ GOTO(out, rc = -EEXIST);
+
+ if (tlen == olen &&
+ strncmp(oldname, dirent->mde_name, tlen) == 0)
+ continue;
+ }
+
+ list_del_init(&dirent->mde_list);
+ mgs_direntry_free(dirent);
+ }
+
+ if (list_empty(&log_list)) {
+ mutex_unlock(&mgs->mgs_mutex);
+ RETURN(-ENOENT);
+ }
+
+ list_for_each_entry(dirent, &log_list, mde_list) {
+ rc = mgs_lcfg_fork_one(env, mgs, dirent, oldname, newname);
+ if (rc)
+ break;
+
+ count++;
+ }
+
+out:
+ mutex_unlock(&mgs->mgs_mutex);
+
+ list_for_each_entry_safe(dirent, n, &log_list, mde_list) {
+ list_del_init(&dirent->mde_list);
+ mgs_direntry_free(dirent);
+ }
+
+ if (rc && count > 0)
+ mgs_erase_logs(env, mgs, newname);
+
+ RETURN(rc);
+}
+
+int mgs_lcfg_erase(const struct lu_env *env, struct mgs_device *mgs,
+ const char *fsname)
+{
+ int rc;
+ ENTRY;
+
+ if (unlikely(!fsname || fsname[0] == '\0'))
+ RETURN(-EINVAL);
+
+ rc = mgs_erase_logs(env, mgs, fsname);
+
+ RETURN(rc);
+}
+
+static int mgs_xattr_del(const struct lu_env *env, struct dt_object *obj)
+{
+ struct dt_device *dev;
+ struct thandle *th = NULL;
+ int rc = 0;
+
+ ENTRY;
+
+ dev = container_of0(obj->do_lu.lo_dev, struct dt_device, dd_lu_dev);
+ th = dt_trans_create(env, dev);
+ if (IS_ERR(th))
+ RETURN(PTR_ERR(th));
+
+ rc = dt_declare_xattr_del(env, obj, XATTR_TARGET_RENAME, th);
+ if (rc)
+ GOTO(stop, rc);
+
+ rc = dt_trans_start_local(env, dev, th);
+ if (rc)
+ GOTO(stop, rc);
+
+ dt_write_lock(env, obj, 0);
+ rc = dt_xattr_del(env, obj, XATTR_TARGET_RENAME, th);
+
+ GOTO(unlock, rc);
+
+unlock:
+ dt_write_unlock(env, obj);
+
+stop:
+ dt_trans_stop(env, dev, th);
+
+ return rc;
+}
+
+int mgs_lcfg_rename(const struct lu_env *env, struct mgs_device *mgs)
+{
+ struct list_head log_list;
+ struct mgs_direntry *dirent, *n;
+ char fsname[16];
+ struct lu_buf buf = {
+ .lb_buf = fsname,
+ .lb_len = sizeof(fsname)
+ };
+ int rc = 0;
+
+ ENTRY;
+
+ rc = class_dentry_readdir(env, mgs, &log_list);
+ if (rc)
+ RETURN(rc);
+
+ if (list_empty(&log_list))
+ RETURN(0);
+
+ list_for_each_entry_safe(dirent, n, &log_list, mde_list) {
+ struct dt_object *o = NULL;
+ char oldname[16];
+ char *ptr;
+ int len;
+
+ list_del_init(&dirent->mde_list);
+ ptr = strrchr(dirent->mde_name, '-');
+ if (!ptr)
+ goto next;
+
+ len = ptr - dirent->mde_name;
+ if (unlikely(len >= sizeof(oldname))) {
+ CDEBUG(D_MGS, "Skip invalid configuration file %s\n",
+ dirent->mde_name);
+ goto next;
+ }
+
+ o = local_file_find(env, mgs->mgs_los, mgs->mgs_configs_dir,
+ dirent->mde_name);
+ if (IS_ERR(o)) {
+ rc = PTR_ERR(o);
+ CDEBUG(D_MGS, "Fail to locate file %s: rc = %d\n",
+ dirent->mde_name, rc);
+ goto next;
+ }
+
+ rc = dt_xattr_get(env, o, &buf, XATTR_TARGET_RENAME);
+ if (rc < 0) {
+ if (rc == -ENODATA)
+ rc = 0;
+ else
+ CDEBUG(D_MGS,
+ "Fail to get EA for %s: rc = %d\n",
+ dirent->mde_name, rc);
+ goto next;
+ }
+
+ if (unlikely(rc == len &&
+ memcmp(fsname, dirent->mde_name, len) == 0)) {
+ /* The new fsname is the same as the old one. */
+ rc = mgs_xattr_del(env, o);
+ goto next;
+ }
+
+ memcpy(oldname, dirent->mde_name, len);
+ oldname[len] = '\0';
+ fsname[rc] = '\0';
+ rc = mgs_lcfg_fork_one(env, mgs, dirent, oldname, fsname);
+ if (rc && rc != -EEXIST) {
+ CDEBUG(D_MGS, "Fail to fork %s: rc = %d\n",
+ dirent->mde_name, rc);
+ goto next;
+ }
+
+ rc = mgs_erase_log(env, mgs, dirent->mde_name);
+ if (rc) {
+ CDEBUG(D_MGS, "Fail to erase old %s: rc = %d\n",
+ dirent->mde_name, rc);
+ /* keep it there if failed to remove it. */
+ rc = 0;
+ }
+
+next:
+ if (o && !IS_ERR(o))
+ lu_object_put(env, &o->do_lu);
+
+ mgs_direntry_free(dirent);
+ if (rc)
+ break;
+ }
+
+ list_for_each_entry_safe(dirent, n, &log_list, mde_list) {
+ list_del_init(&dirent->mde_list);
+ mgs_direntry_free(dirent);
+ }
+
+ RETURN(rc);
+}
+
+/* from llog_swab */
+static void print_lustre_cfg(struct lustre_cfg *lcfg)
+{
+ int i;
+ ENTRY;
+
+ CDEBUG(D_MGS, "lustre_cfg: %p\n", lcfg);
+ CDEBUG(D_MGS, "\tlcfg->lcfg_version: %#x\n", lcfg->lcfg_version);
+
+ CDEBUG(D_MGS, "\tlcfg->lcfg_command: %#x\n", lcfg->lcfg_command);
+ CDEBUG(D_MGS, "\tlcfg->lcfg_num: %#x\n", lcfg->lcfg_num);
+ CDEBUG(D_MGS, "\tlcfg->lcfg_flags: %#x\n", lcfg->lcfg_flags);
+ CDEBUG(D_MGS, "\tlcfg->lcfg_nid: %s\n", libcfs_nid2str(lcfg->lcfg_nid));
+
+ CDEBUG(D_MGS, "\tlcfg->lcfg_bufcount: %d\n", lcfg->lcfg_bufcount);
+ if (lcfg->lcfg_bufcount < LUSTRE_CFG_MAX_BUFCOUNT)
+ for (i = 0; i < lcfg->lcfg_bufcount; i++) {
+ CDEBUG(D_MGS, "\tlcfg->lcfg_buflens[%d]: %d %s\n",
+ i, lcfg->lcfg_buflens[i],
+ lustre_cfg_string(lcfg, i));
+ }
+ EXIT;
+}
+
+/* Setup _mgs fsdb and log
+ */
+int mgs__mgs_fsdb_setup(const struct lu_env *env, struct mgs_device *mgs)
+{
+ struct fs_db *fsdb = NULL;
+ int rc;
+ ENTRY;
+
+ rc = mgs_find_or_make_fsdb(env, mgs, MGSSELF_NAME, &fsdb);
+ if (!rc)
+ mgs_put_fsdb(mgs, fsdb);
RETURN(rc);
}
/* Setup params fsdb and log
*/
-int mgs_params_fsdb_setup(const struct lu_env *env, struct mgs_device *mgs,
- struct fs_db *fsdb)
+int mgs_params_fsdb_setup(const struct lu_env *env, struct mgs_device *mgs)
{
- struct llog_handle *params_llh = NULL;
- int rc;
+ struct fs_db *fsdb = NULL;
+ struct llog_handle *params_llh = NULL;
+ int rc;
ENTRY;
rc = mgs_find_or_make_fsdb(env, mgs, PARAMS_FILENAME, &fsdb);
- if (fsdb != NULL) {
+ if (!rc) {
mutex_lock(&fsdb->fsdb_mutex);
rc = record_start_log(env, mgs, ¶ms_llh, PARAMS_FILENAME);
- if (rc == 0)
+ if (!rc)
rc = record_end_log(env, ¶ms_llh);
mutex_unlock(&fsdb->fsdb_mutex);
+ mgs_put_fsdb(mgs, fsdb);
}
RETURN(rc);
*/
int mgs_params_fsdb_cleanup(const struct lu_env *env, struct mgs_device *mgs)
{
- return mgs_erase_logs(env, mgs, PARAMS_FILENAME);
+ int rc;
+
+ rc = mgs_erase_logs(env, mgs, PARAMS_FILENAME);
+ return rc == -ENOENT ? 0 : rc;
}
/* Set a permanent (config log) param for a target or fs
int mgs_setparam(const struct lu_env *env, struct mgs_device *mgs,
struct lustre_cfg *lcfg, char *fsname)
{
- struct fs_db *fsdb;
- struct mgs_target_info *mti;
- char *devname, *param;
+ struct fs_db *fsdb = NULL;
+ struct mgs_target_info *mti = NULL;
+ char *devname, *param;
char *ptr;
const char *tmp;
__u32 index;
int rc = 0;
+ bool free = false;
ENTRY;
print_lustre_cfg(lcfg);
if (lcfg->lcfg_command != LCFG_SET_PARAM &&
!test_bit(FSDB_MGS_SELF, &fsdb->fsdb_flags) &&
test_bit(FSDB_LOG_EMPTY, &fsdb->fsdb_flags)) {
- CERROR("No filesystem targets for %s. cfg_device from lctl "
- "is '%s'\n", fsname, devname);
- mgs_free_fsdb(mgs, fsdb);
- RETURN(-EINVAL);
- }
+ CERROR("No filesystem targets for %s. cfg_device from lctl "
+ "is '%s'\n", fsname, devname);
+ free = true;
+ GOTO(out, rc = -EINVAL);
+ }
- /* Create a fake mti to hold everything */
- OBD_ALLOC_PTR(mti);
- if (!mti)
- GOTO(out, rc = -ENOMEM);
+ /* Create a fake mti to hold everything */
+ OBD_ALLOC_PTR(mti);
+ if (!mti)
+ GOTO(out, rc = -ENOMEM);
if (strlcpy(mti->mti_fsname, fsname, sizeof(mti->mti_fsname))
>= sizeof(mti->mti_fsname))
GOTO(out, rc = -E2BIG);
else
/* Strip -osc or -mdc suffix from svname */
if (server_make_name(rc, mti->mti_stripe_index, mti->mti_fsname,
- mti->mti_svname))
+ mti->mti_svname, sizeof(mti->mti_svname)))
GOTO(out, rc = -EINVAL);
/*
* Revoke lock so everyone updates. Should be alright if
}
out:
- OBD_FREE_PTR(mti);
- RETURN(rc);
+ if (mti)
+ OBD_FREE_PTR(mti);
+
+ if (fsdb) {
+ if (free)
+ mgs_unlink_fsdb(mgs, fsdb);
+ mgs_put_fsdb(mgs, fsdb);
+ }
+
+ RETURN(rc);
}
static int mgs_write_log_pool(const struct lu_env *env,
bool_switch = simple_strtoul(param, NULL, 10);
rc = nodemap_set_deny_unknown(nodemap_name, bool_switch);
break;
+ case LCFG_NODEMAP_MAP_MODE:
+ if (strcmp("both", param) == 0)
+ rc = nodemap_set_mapping_mode(nodemap_name,
+ NODEMAP_MAP_BOTH);
+ else if (strcmp("uid_only", param) == 0)
+ rc = nodemap_set_mapping_mode(nodemap_name,
+ NODEMAP_MAP_UID_ONLY);
+ else if (strcmp("gid_only", param) == 0)
+ rc = nodemap_set_mapping_mode(nodemap_name,
+ NODEMAP_MAP_GID_ONLY);
+ else
+ rc = -EINVAL;
+ break;
case LCFG_NODEMAP_TRUSTED:
bool_switch = simple_strtoul(param, NULL, 10);
rc = nodemap_set_trust_client_ids(nodemap_name, bool_switch);
char *label = NULL, *canceled_label = NULL;
int label_sz;
struct mgs_target_info *mti = NULL;
- int rc, i;
- ENTRY;
+ bool checked = false;
+ bool locked = false;
+ bool free = false;
+ int rc, i;
+ ENTRY;
rc = mgs_find_or_make_fsdb(env, mgs, fsname, &fsdb);
- if (rc) {
- CERROR("Can't get db for %s\n", fsname);
- RETURN(rc);
- }
+ if (rc) {
+ CERROR("Can't get db for %s\n", fsname);
+ RETURN(rc);
+ }
if (test_bit(FSDB_LOG_EMPTY, &fsdb->fsdb_flags)) {
- CERROR("%s is not defined\n", fsname);
- mgs_free_fsdb(mgs, fsdb);
- RETURN(-EINVAL);
+ CERROR("%s is not defined\n", fsname);
+ free = true;
+ GOTO(out_fsdb, rc = -EINVAL);
}
label_sz = 10 + strlen(fsname) + strlen(poolname);
}
OBD_ALLOC(label, label_sz);
- if (label == NULL)
- RETURN(-ENOMEM);
+ if (!label)
+ GOTO(out_fsdb, rc = -ENOMEM);
switch(cmd) {
case LCFG_POOL_NEW:
break;
}
- if (canceled_label != NULL) {
- OBD_ALLOC_PTR(mti);
- if (mti == NULL)
- GOTO(out_cancel, rc = -ENOMEM);
- }
+ OBD_ALLOC_PTR(mti);
+ if (mti == NULL)
+ GOTO(out_cancel, rc = -ENOMEM);
+ strncpy(mti->mti_svname, "lov pool", sizeof(mti->mti_svname));
mutex_lock(&fsdb->fsdb_mutex);
- /* write pool def to all MDT logs */
- for (i = 0; i < INDEX_MAP_SIZE * 8; i++) {
+ locked = true;
+ /* write pool def to all MDT logs */
+ for (i = 0; i < INDEX_MAP_SIZE * 8; i++) {
if (test_bit(i, fsdb->fsdb_mdt_index_map)) {
rc = name_create_mdt_and_lov(&logname, &lovname,
fsdb, i);
- if (rc) {
- mutex_unlock(&fsdb->fsdb_mutex);
+ if (rc)
GOTO(out_mti, rc);
+
+ if (!checked && (canceled_label == NULL)) {
+ rc = mgs_check_marker(env, mgs, fsdb, mti,
+ logname, lovname, label);
+ if (rc) {
+ name_destroy(&logname);
+ name_destroy(&lovname);
+ GOTO(out_mti,
+ rc = (rc == LLOG_PROC_BREAK ?
+ -EEXIST : rc));
+ }
+ checked = true;
}
- if (canceled_label != NULL) {
- strcpy(mti->mti_svname, "lov pool");
+ if (canceled_label != NULL)
rc = mgs_modify(env, mgs, fsdb, mti, logname,
lovname, canceled_label,
CM_SKIP);
- }
if (rc >= 0)
rc = mgs_write_log_pool(env, mgs, logname,
fsdb, lovname, cmd,
fsname, poolname,
ostname, label);
- name_destroy(&logname);
- name_destroy(&lovname);
- if (rc) {
- mutex_unlock(&fsdb->fsdb_mutex);
+ name_destroy(&logname);
+ name_destroy(&lovname);
+ if (rc)
GOTO(out_mti, rc);
- }
- }
- }
+ }
+ }
rc = name_create(&logname, fsname, "-client");
- if (rc) {
- mutex_unlock(&fsdb->fsdb_mutex);
+ if (rc)
GOTO(out_mti, rc);
+
+ if (!checked && (canceled_label == NULL)) {
+ rc = mgs_check_marker(env, mgs, fsdb, mti, logname,
+ fsdb->fsdb_clilov, label);
+ if (rc) {
+ name_destroy(&logname);
+ GOTO(out_mti, rc = (rc == LLOG_PROC_BREAK ?
+ -EEXIST : rc));
+ }
}
if (canceled_label != NULL) {
rc = mgs_modify(env, mgs, fsdb, mti, logname,
fsdb->fsdb_clilov, canceled_label, CM_SKIP);
if (rc < 0) {
- mutex_unlock(&fsdb->fsdb_mutex);
name_destroy(&logname);
GOTO(out_mti, rc);
}
rc = mgs_write_log_pool(env, mgs, logname, fsdb, fsdb->fsdb_clilov,
cmd, fsname, poolname, ostname, label);
mutex_unlock(&fsdb->fsdb_mutex);
+ locked = false;
name_destroy(&logname);
- /* request for update */
+ /* request for update */
mgs_revoke_lock(mgs, fsdb, CONFIG_T_CONFIG);
- EXIT;
+ GOTO(out_mti, rc);
+
out_mti:
- if (mti != NULL)
- OBD_FREE_PTR(mti);
+ if (locked)
+ mutex_unlock(&fsdb->fsdb_mutex);
+ if (mti != NULL)
+ OBD_FREE_PTR(mti);
out_cancel:
if (canceled_label != NULL)
OBD_FREE(canceled_label, label_sz);
out_label:
OBD_FREE(label, label_sz);
- return rc;
+out_fsdb:
+ if (free)
+ mgs_unlink_fsdb(mgs, fsdb);
+ mgs_put_fsdb(mgs, fsdb);
+
+ return rc;
}