*
* You should have received a copy of the GNU General Public License
* version 2 along with this program; If not, see
- * http://www.sun.com/software/products/lustre/docs/GPLv2.pdf
- *
- * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
- * CA 95054 USA or visit www.sun.com if you need additional information or
- * have any questions.
+ * http://www.gnu.org/licenses/gpl-2.0.html
*
* GPL HEADER END
*/
* Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved.
* Use is subject to license terms.
*
- * Copyright (c) 2011, 2012, Intel Corporation.
+ * Copyright (c) 2011, 2016, Intel Corporation.
*/
/*
* This file is part of Lustre, http://www.lustre.org/
#define D_MGS D_CONFIG
#include <obd.h>
-#include <obd_lov.h>
+#include <lustre_ioctl.h>
#include <lustre_param.h>
#include <lustre_sec.h>
#include <lustre_quota.h>
/********************** Class functions ********************/
-int class_dentry_readdir(const struct lu_env *env,
- struct mgs_device *mgs, cfs_list_t *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;
- CFS_INIT_LIST_HEAD(list);
-
- if (!dt_try_as_dir(env, dir))
- GOTO(out, rc = -ENOTDIR);
+ INIT_LIST_HEAD(log_list);
LASSERT(dir);
LASSERT(dir->do_index_ops);
iops = &dir->do_index_ops->dio_it;
- it = iops->init(env, dir, LUDA_64BITHASH, BYPASS_CAPA);
+ it = iops->init(env, dir, LUDA_64BITHASH);
if (IS_ERR(it))
RETURN(PTR_ERR(it));
goto next;
}
+ /* filter out ".bak" files */
+ /* sizeof(".bak") - 1 == 3 */
+ if (key_sz >= 3 &&
+ !memcmp(".bak", key + key_sz - 3, 3)) {
+ CDEBUG(D_MGS, "Skipping backup file %.*s\n",
+ key_sz, key);
+ goto next;
+ }
+
de = mgs_direntry_alloc(key_sz + 1);
if (de == NULL) {
rc = -ENOMEM;
break;
}
- memcpy(de->name, key, key_sz);
- de->name[key_sz] = 0;
+ memcpy(de->mde_name, key, key_sz);
+ de->mde_name[key_sz] = 0;
- cfs_list_add(&de->list, list);
+ list_add(&de->mde_list, log_list);
next:
rc = iops->next(env, it);
} while (rc == 0);
- rc = 0;
+ if (rc > 0)
+ rc = 0;
iops->put(env, it);
fini:
iops->fini(env, it);
-out:
- 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;
- cfs_list_t *tmp;
+ 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);
+}
- cfs_list_for_each(tmp, &mgs->mgs_fs_db_list) {
- fsdb = cfs_list_entry(tmp, struct fs_db, fsdb_list);
- if (strcmp(fsdb->fsdb_name, fsname) == 0)
- return fsdb;
- }
- return NULL;
+/* 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;
}
-/* caller must hold the mgs->mgs_fs_db_lock */
+/* 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;
+}
+
+/* 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);
- RETURN(NULL);
- }
+ if (strlen(fsname) >= sizeof(fsdb->fsdb_name)) {
+ CERROR("fsname %s is too long\n", fsname);
- OBD_ALLOC_PTR(fsdb);
- if (!fsdb)
- RETURN(NULL);
+ RETURN(ERR_PTR(-EINVAL));
+ }
+
+ 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);
- } 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");
+ fsdb->fsdb_mgs = mgs;
+ 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);
+ }
- cfs_list_add(&fsdb->fsdb_list, &mgs->mgs_fs_db_list);
+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);
- RETURN(NULL);
+ 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);
- cfs_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)
{
- CFS_INIT_LIST_HEAD(&mgs->mgs_fs_db_list);
+ INIT_LIST_HEAD(&mgs->mgs_fs_db_list);
return 0;
}
int mgs_cleanup_fsdb_list(struct mgs_device *mgs)
{
- struct fs_db *fsdb;
- cfs_list_t *tmp, *tmp2;
+ struct fs_db *fsdb;
+ struct list_head *tmp, *tmp2;
+
mutex_lock(&mgs->mgs_mutex);
- cfs_list_for_each_safe(tmp, tmp2, &mgs->mgs_fs_db_list) {
- fsdb = cfs_list_entry(tmp, struct fs_db, fsdb_list);
- mgs_free_fsdb(mgs, fsdb);
- }
+ list_for_each_safe(tmp, tmp2, &mgs->mgs_fs_db_list) {
+ fsdb = list_entry(tmp, struct fs_db, fsdb_list);
+ list_del_init(&fsdb->fsdb_list);
+ mgs_put_fsdb(mgs, fsdb);
+ }
mutex_unlock(&mgs->mgs_mutex);
- return 0;
+ 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 (fsdb)
- mutex_lock(&fsdb->fsdb_mutex);
+ CDEBUG(D_MGS, "Created new db: rc = %d\n", rc);
+ }
mutex_unlock(&mgs->mgs_mutex);
- if (!fsdb)
- RETURN(-ENOMEM);
-
- 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
imap = fsdb->fsdb_ost_index_map;
} else if (mti->mti_flags & LDD_F_SV_TYPE_MDT) {
imap = fsdb->fsdb_mdt_index_map;
- if (fsdb->fsdb_mdt_count >= MAX_MDT_COUNT) {
- LCONSOLE_ERROR_MSG(0x13f, "The max mdt count"
- "is %d\n", (int)MAX_MDT_COUNT);
- GOTO(out_up, rc = -ERANGE);
- }
} else {
GOTO(out_up, rc = -EINVAL);
}
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 ++;
}
- if (mti->mti_stripe_index >= INDEX_MAP_SIZE * 8) {
- LCONSOLE_ERROR_MSG(0x13f, "Server %s requested index %d, "
- "but the max index is %d.\n",
- mti->mti_svname, mti->mti_stripe_index,
- INDEX_MAP_SIZE * 8);
+ /* the last index(0xffff) is reserved for default value. */
+ if (mti->mti_stripe_index >= INDEX_MAP_SIZE * 8 - 1) {
+ LCONSOLE_ERROR_MSG(0x13f, "Server %s requested index %u, "
+ "but index must be less than %u.\n",
+ mti->mti_svname, mti->mti_stripe_index,
+ INDEX_MAP_SIZE * 8 - 1);
GOTO(out_up, rc = -ERANGE);
- }
+ }
if (test_bit(mti->mti_stripe_index, imap)) {
if ((mti->mti_flags & LDD_F_VIRGIN) &&
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)
marker->cm_flags &= ~CM_EXCLUDE; /* in case we're unexcluding */
marker->cm_flags |= mml->mml_marker.cm_flags;
marker->cm_canceltime = mml->mml_marker.cm_canceltime;
- /* Header and tail are added back to lrh_len in
- llog_lvfs_write_rec */
- rec->lrh_len = cfg_len;
- rc = llog_write(env, llh, rec, NULL, 0, (void *)lcfg,
- rec->lrh_index);
+ rc = llog_write(env, llh, rec, rec->lrh_index);
if (!rc)
mml->mml_modified++;
}
OBD_ALLOC_PTR(mml);
if (!mml)
GOTO(out_close, rc = -ENOMEM);
- strcpy(mml->mml_marker.cm_comment, comment);
- strcpy(mml->mml_marker.cm_tgtname, devname);
+ if (strlcpy(mml->mml_marker.cm_comment, comment,
+ sizeof(mml->mml_marker.cm_comment)) >=
+ sizeof(mml->mml_marker.cm_comment))
+ GOTO(out_free, rc = -E2BIG);
+ if (strlcpy(mml->mml_marker.cm_tgtname, devname,
+ sizeof(mml->mml_marker.cm_tgtname)) >=
+ sizeof(mml->mml_marker.cm_tgtname))
+ GOTO(out_free, rc = -E2BIG);
/* Modify mostly means cancel */
mml->mml_marker.cm_flags = flags;
mml->mml_marker.cm_canceltime = flags ? cfs_time_current_sec() : 0;
NULL);
if (!rc && !mml->mml_modified)
rc = 1;
+
+out_free:
OBD_FREE_PTR(mml);
out_close:
return 0;
}
-static int record_lcfg(const struct lu_env *env, struct llog_handle *llh,
- struct lustre_cfg *lcfg)
-{
- struct llog_rec_hdr rec;
- int buflen, rc;
-
- if (!lcfg || !llh)
- return -ENOMEM;
-
- LASSERT(llh->lgh_ctxt);
-
- buflen = lustre_cfg_len(lcfg->lcfg_bufcount,
- lcfg->lcfg_buflens);
- rec.lrh_len = llog_data_len(buflen);
- rec.lrh_type = OBD_CFG_REC;
-
- /* idx = -1 means append */
- rc = llog_write(env, llh, &rec, NULL, 0, (void *)lcfg, -1);
- if (rc)
- CERROR("failed %d\n", rc);
- return rc;
-}
-
static int record_base(const struct lu_env *env, struct llog_handle *llh,
char *cfgname, lnet_nid_t nid, int cmd,
char *s1, char *s2, char *s3, char *s4)
{
- struct mgs_thread_info *mgi = mgs_env_info(env);
- struct lustre_cfg *lcfg;
+ struct mgs_thread_info *mgi = mgs_env_info(env);
+ struct llog_cfg_rec *lcr;
int rc;
CDEBUG(D_MGS, "lcfg %s %#x %s %s %s %s\n", cfgname,
if (s4)
lustre_cfg_bufs_set_string(&mgi->mgi_bufs, 4, s4);
- lcfg = lustre_cfg_new(cmd, &mgi->mgi_bufs);
- if (!lcfg)
+ lcr = lustre_cfg_rec_new(cmd, &mgi->mgi_bufs);
+ if (lcr == NULL)
return -ENOMEM;
- lcfg->lcfg_nid = nid;
- rc = record_lcfg(env, llh, lcfg);
+ lcr->lcr_cfg.lcfg_nid = nid;
+ rc = llog_write(env, llh, &lcr->lcr_hdr, LLOG_NEXT_IDX);
- lustre_cfg_free(lcfg);
+ lustre_cfg_rec_free(lcr);
- if (rc) {
- CERROR("error %d: lcfg %s %#x %s %s %s %s\n", rc, cfgname,
- cmd, s1, s2, s3, s4);
- }
+ if (rc < 0)
+ CDEBUG(D_MGS,
+ "failed to write lcfg %s %#x %s %s %s %s: rc = %d\n",
+ cfgname, cmd, s1, s2, s3, s4, rc);
return rc;
}
struct llog_handle *llh,
uint64_t nid, char *uuid)
{
- return record_base(env, llh, NULL, nid, LCFG_ADD_UUID, uuid, 0, 0, 0);
+ return record_base(env, llh, NULL, nid, LCFG_ADD_UUID, uuid,
+ NULL, NULL, NULL);
}
static inline int record_add_conn(const struct lu_env *env,
struct llog_handle *llh,
char *devname, char *uuid)
{
- return record_base(env, llh, devname, 0, LCFG_ADD_CONN, uuid, 0, 0, 0);
+ return record_base(env, llh, devname, 0, LCFG_ADD_CONN, uuid,
+ NULL, NULL, NULL);
}
static inline int record_attach(const struct lu_env *env,
struct llog_handle *llh, char *devname,
char *type, char *uuid)
{
- return record_base(env, llh,devname, 0, LCFG_ATTACH, type, uuid, 0, 0);
+ return record_base(env, llh, devname, 0, LCFG_ATTACH, type, uuid,
+ NULL, NULL);
}
static inline int record_setup(const struct lu_env *env,
struct llog_rec_hdr *rec,
void *data)
{
- struct llog_rec_hdr local_rec = *rec;
struct mgs_replace_uuid_lookup *mrul;
struct lustre_cfg *lcfg = REC_DATA(rec);
int cfg_len = REC_DATA_LEN(rec);
RETURN(0);
copy_out:
/* Record is placed in temporary llog as is */
- local_rec.lrh_len -= sizeof(*rec) + sizeof(struct llog_rec_tail);
- rc = llog_write(env, mrul->temp_llh, &local_rec, NULL, 0,
- (void *)lcfg, -1);
+ rc = llog_write(env, mrul->temp_llh, rec, LLOG_NEXT_IDX);
CDEBUG(D_MGS, "Copied idx=%d, rc=%d, len=%d, cmd %x %s %s\n",
rec->lrh_index, rc, rec->lrh_len, lcfg->lcfg_command,
RETURN(rc);
}
-static int mgs_backup_llog(const struct lu_env *env,
- struct obd_device *mgs,
- char *fsname, char *backup)
+static int mgs_log_is_empty(const struct lu_env *env,
+ struct mgs_device *mgs, char *name)
{
- struct obd_uuid *uuid;
- struct llog_handle *orig_llh, *bak_llh;
- struct llog_ctxt *lctxt;
- int rc, rc2;
- ENTRY;
-
- lctxt = llog_get_context(mgs, LLOG_CONFIG_ORIG_CTXT);
- if (!lctxt) {
- CERROR("%s: missing llog context\n", mgs->obd_name);
- GOTO(out, rc = -EINVAL);
- }
+ struct llog_ctxt *ctxt;
+ int rc;
- /* Make sure there's no old backup log */
- rc = llog_erase(env, lctxt, NULL, backup);
- if (rc < 0 && rc != -ENOENT)
- GOTO(out_put, rc);
+ ctxt = llog_get_context(mgs->mgs_obd, LLOG_CONFIG_ORIG_CTXT);
+ LASSERT(ctxt != NULL);
- /* open backup log */
- rc = llog_open_create(env, lctxt, &bak_llh, NULL, backup);
- if (rc) {
- CERROR("%s: backup logfile open %s: rc = %d\n",
- mgs->obd_name, backup, rc);
- GOTO(out_put, rc);
- }
-
- /* set the log header uuid */
- OBD_ALLOC_PTR(uuid);
- if (uuid == NULL)
- GOTO(out_put, rc = -ENOMEM);
- obd_str2uuid(uuid, backup);
- rc = llog_init_handle(env, bak_llh, LLOG_F_IS_PLAIN, uuid);
- OBD_FREE_PTR(uuid);
- if (rc)
- GOTO(out_close1, rc);
-
- /* open original log */
- rc = llog_open(env, lctxt, &orig_llh, NULL, fsname,
- LLOG_OPEN_EXISTS);
- if (rc < 0) {
- if (rc == -ENOENT)
- rc = 0;
- GOTO(out_close1, rc);
- }
-
- rc = llog_init_handle(env, orig_llh, LLOG_F_IS_PLAIN, NULL);
- if (rc)
- GOTO(out_close2, rc);
-
- /* Copy remote log */
- rc = llog_process(env, orig_llh, llog_copy_handler,
- (void *)bak_llh, NULL);
-
-out_close2:
- rc2 = llog_close(env, orig_llh);
- if (!rc)
- rc = rc2;
-out_close1:
- rc2 = llog_close(env, bak_llh);
- if (!rc)
- rc = rc2;
-out_put:
- if (lctxt)
- llog_ctxt_put(lctxt);
-out:
- if (rc)
- CERROR("%s: Failed to backup log %s: rc = %d\n",
- mgs->obd_name, fsname, rc);
- RETURN(rc);
+ rc = llog_is_empty(env, ctxt, name);
+ llog_ctxt_put(ctxt);
+ return rc;
}
-static int mgs_log_is_empty(const struct lu_env *env, struct mgs_device *mgs,
- char *name);
-
static int mgs_replace_nids_log(const struct lu_env *env,
struct obd_device *mgs, struct fs_db *fsdb,
char *logname, char *devname, char *nids)
struct llog_ctxt *ctxt;
struct mgs_replace_uuid_lookup *mrul;
struct mgs_device *mgs_dev = lu2mgs_dev(mgs->obd_lu_dev);
+ static struct obd_uuid cfg_uuid = { .uuid = "config_uuid" };
char *backup;
int rc, rc2;
ENTRY;
GOTO(out_put, rc = 0);
}
- OBD_ALLOC(backup, strlen(logname) + 5);
+ OBD_ALLOC(backup, strlen(logname) + strlen(".bak") + 1);
if (backup == NULL)
GOTO(out_put, rc = -ENOMEM);
sprintf(backup, "%s.bak", logname);
- rc = mgs_backup_llog(env, mgs, logname, backup);
- if (rc < 0) {
+ rc = llog_backup(env, mgs, ctxt, ctxt, logname, backup);
+ if (rc == 0) {
+ /* Now erase original log file. Connections are not allowed.
+ Backup is already saved */
+ rc = llog_erase(env, ctxt, NULL, logname);
+ if (rc < 0)
+ GOTO(out_free, rc);
+ } else if (rc != -ENOENT) {
CERROR("%s: can't make backup for %s: rc = %d\n",
mgs->obd_name, logname, rc);
GOTO(out_free,rc);
}
- /* Now erase original log file. Connections are not allowed.
- Backup is already saved */
- rc = llog_erase(env, ctxt, NULL, logname);
- if (rc < 0 && rc != -ENOENT)
- GOTO(out_free, rc);
-
/* open local log */
rc = llog_open_create(env, ctxt, &orig_llh, NULL, logname);
if (rc)
GOTO(out_restore, rc);
- rc = llog_init_handle(env, orig_llh, LLOG_F_IS_PLAIN, NULL);
+ rc = llog_init_handle(env, orig_llh, LLOG_F_IS_PLAIN, &cfg_uuid);
if (rc)
GOTO(out_closel, rc);
if (!mrul)
GOTO(out_close, rc = -ENOMEM);
/* devname is only needed information to replace UUID records */
- strncpy(mrul->target.mti_svname, devname, MTI_NAME_MAXLEN);
+ strlcpy(mrul->target.mti_svname, devname,
+ sizeof(mrul->target.mti_svname));
/* parse nids later */
- strncpy(mrul->target.mti_params, nids, MTI_PARAM_MAXLEN);
+ strlcpy(mrul->target.mti_params, nids, sizeof(mrul->target.mti_params));
/* Copy records to this temporary llog */
mrul->temp_llh = orig_llh;
if (rc) {
CERROR("%s: llog should be restored: rc = %d\n",
mgs->obd_name, rc);
- rc2 = mgs_backup_llog(env, mgs, backup, logname);
+ rc2 = llog_backup(env, mgs, ctxt, ctxt, backup,
+ logname);
if (rc2 < 0)
CERROR("%s: can't restore backup %s: rc = %d\n",
mgs->obd_name, logname, rc2);
}
out_free:
- OBD_FREE(backup, strlen(backup) + 5);
+ OBD_FREE(backup, strlen(backup) + 1);
out_put:
llog_ctxt_put(ctxt);
*/
static int mgs_parse_devname(char *devname, char *fsname, __u32 *index)
{
- char *ptr;
+ int rc;
ENTRY;
/* Extract fsname */
- ptr = strrchr(devname, '-');
-
if (fsname) {
- if (!ptr) {
+ rc = server_name2fsname(devname, fsname, NULL);
+ if (rc < 0) {
CDEBUG(D_MGS, "Device name %s without fsname\n",
devname);
RETURN(-EINVAL);
}
- memset(fsname, 0, MTI_NAME_MAXLEN);
- strncpy(fsname, devname, ptr - devname);
- fsname[MTI_NAME_MAXLEN - 1] = 0;
}
if (index) {
- if (server_name2index(ptr, index, NULL) < 0) {
- CDEBUG(D_MGS, "Device name with wrong index\n");
+ rc = server_name2index(devname, index, NULL);
+ if (rc < 0) {
+ CDEBUG(D_MGS, "Device name %s with wrong index\n",
+ devname);
RETURN(-EINVAL);
}
}
RETURN(0);
}
+/* This is only called during replace_nids */
static int only_mgs_is_running(struct obd_device *mgs_obd)
{
/* TDB: Is global variable with devices count exists? */
int num_devices = get_devices_count();
+ int num_exports = 0;
+ struct obd_export *exp;
+
+ spin_lock(&mgs_obd->obd_dev_lock);
+ list_for_each_entry(exp, &mgs_obd->obd_exports, exp_obd_chain) {
+ /* skip self export */
+ if (exp == mgs_obd->obd_self_export)
+ continue;
+ if (exp_connect_flags(exp) & OBD_CONNECT_MDS_MDS)
+ continue;
+
+ ++num_exports;
+
+ CERROR("%s: node %s still connected during replace_nids "
+ "connect_flags:%llx\n",
+ mgs_obd->obd_name,
+ libcfs_nid2str(exp->exp_nid_stats->nid),
+ exp_connect_flags(exp));
+
+ }
+ spin_unlock(&mgs_obd->obd_dev_lock);
+
/* osd, MGS and MGC + self_export
- (wc -l /proc/fs/lustre/devices <= 2) && (num_exports <= 2) */
- return (num_devices <= 3) && (mgs_obd->obd_num_exports <= 2);
+ (wc -l /proc/fs/lustre/devices <= 2) && (non self exports == 0) */
+ return (num_devices <= 3) && (num_exports == 0);
}
static int name_create_mdt(char **logname, char *fsname, int i)
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);
}
static int record_lov_setup(const struct lu_env *env, struct llog_handle *llh,
char *devname, struct lov_desc *desc)
{
- struct mgs_thread_info *mgi = mgs_env_info(env);
- struct lustre_cfg *lcfg;
+ struct mgs_thread_info *mgi = mgs_env_info(env);
+ struct llog_cfg_rec *lcr;
int rc;
lustre_cfg_bufs_reset(&mgi->mgi_bufs, devname);
lustre_cfg_bufs_set(&mgi->mgi_bufs, 1, desc, sizeof(*desc));
- lcfg = lustre_cfg_new(LCFG_SETUP, &mgi->mgi_bufs);
- if (!lcfg)
+ lcr = lustre_cfg_rec_new(LCFG_SETUP, &mgi->mgi_bufs);
+ if (lcr == NULL)
return -ENOMEM;
- rc = record_lcfg(env, llh, lcfg);
- lustre_cfg_free(lcfg);
+ rc = llog_write(env, llh, &lcr->lcr_hdr, LLOG_NEXT_IDX);
+ lustre_cfg_rec_free(lcr);
return rc;
}
static int record_lmv_setup(const struct lu_env *env, struct llog_handle *llh,
char *devname, struct lmv_desc *desc)
{
- struct mgs_thread_info *mgi = mgs_env_info(env);
- struct lustre_cfg *lcfg;
+ struct mgs_thread_info *mgi = mgs_env_info(env);
+ struct llog_cfg_rec *lcr;
int rc;
lustre_cfg_bufs_reset(&mgi->mgi_bufs, devname);
lustre_cfg_bufs_set(&mgi->mgi_bufs, 1, desc, sizeof(*desc));
- lcfg = lustre_cfg_new(LCFG_SETUP, &mgi->mgi_bufs);
-
- rc = record_lcfg(env, llh, lcfg);
+ lcr = lustre_cfg_rec_new(LCFG_SETUP, &mgi->mgi_bufs);
+ if (lcr == NULL)
+ return -ENOMEM;
- lustre_cfg_free(lcfg);
+ rc = llog_write(env, llh, &lcr->lcr_hdr, LLOG_NEXT_IDX);
+ lustre_cfg_rec_free(lcr);
return rc;
}
char *lov_name, char *ost_uuid,
char *index, char *gen)
{
- return record_base(env,llh,lov_name,0,LCFG_LOV_ADD_OBD,
- ost_uuid,index,gen,0);
+ return record_base(env, llh, lov_name, 0, LCFG_LOV_ADD_OBD,
+ ost_uuid, index, gen, NULL);
}
static inline int record_mount_opt(const struct lu_env *env,
char *profile, char *lov_name,
char *mdc_name)
{
- return record_base(env,llh,NULL,0,LCFG_MOUNTOPT,
- profile,lov_name,mdc_name,0);
+ return record_base(env, llh, NULL, 0, LCFG_MOUNTOPT,
+ profile, lov_name, mdc_name, NULL);
}
static int record_marker(const struct lu_env *env,
char *tgtname, char *comment)
{
struct mgs_thread_info *mgi = mgs_env_info(env);
- struct lustre_cfg *lcfg;
+ struct llog_cfg_rec *lcr;
int rc;
+ int cplen = 0;
if (flags & CM_START)
fsdb->fsdb_gen++;
mgi->mgi_marker.cm_step = fsdb->fsdb_gen;
mgi->mgi_marker.cm_flags = flags;
mgi->mgi_marker.cm_vers = LUSTRE_VERSION_CODE;
- strncpy(mgi->mgi_marker.cm_tgtname, tgtname,
- sizeof(mgi->mgi_marker.cm_tgtname));
- strncpy(mgi->mgi_marker.cm_comment, comment,
- sizeof(mgi->mgi_marker.cm_comment));
+ cplen = strlcpy(mgi->mgi_marker.cm_tgtname, tgtname,
+ sizeof(mgi->mgi_marker.cm_tgtname));
+ if (cplen >= sizeof(mgi->mgi_marker.cm_tgtname))
+ return -E2BIG;
+ cplen = strlcpy(mgi->mgi_marker.cm_comment, comment,
+ sizeof(mgi->mgi_marker.cm_comment));
+ if (cplen >= sizeof(mgi->mgi_marker.cm_comment))
+ return -E2BIG;
mgi->mgi_marker.cm_createtime = cfs_time_current_sec();
mgi->mgi_marker.cm_canceltime = 0;
lustre_cfg_bufs_reset(&mgi->mgi_bufs, NULL);
lustre_cfg_bufs_set(&mgi->mgi_bufs, 1, &mgi->mgi_marker,
sizeof(mgi->mgi_marker));
- lcfg = lustre_cfg_new(LCFG_MARKER, &mgi->mgi_bufs);
- if (!lcfg)
+ lcr = lustre_cfg_rec_new(LCFG_MARKER, &mgi->mgi_bufs);
+ if (lcr == NULL)
return -ENOMEM;
- rc = record_lcfg(env, llh, lcfg);
- lustre_cfg_free(lcfg);
+ rc = llog_write(env, llh, &lcr->lcr_hdr, LLOG_NEXT_IDX);
+ lustre_cfg_rec_free(lcr);
return rc;
}
static struct obd_uuid cfg_uuid = { .uuid = "config_uuid" };
struct llog_ctxt *ctxt;
int rc = 0;
+ ENTRY;
if (*llh)
GOTO(out, rc = -EBUSY);
return rc;
}
-static int mgs_log_is_empty(const struct lu_env *env,
- struct mgs_device *mgs, char *name)
-{
- struct llog_handle *llh;
- struct llog_ctxt *ctxt;
- int rc = 0;
-
- ctxt = llog_get_context(mgs->mgs_obd, LLOG_CONFIG_ORIG_CTXT);
- LASSERT(ctxt != NULL);
- rc = llog_open(env, ctxt, &llh, NULL, name, LLOG_OPEN_EXISTS);
- if (rc < 0) {
- if (rc == -ENOENT)
- rc = 0;
- GOTO(out_ctxt, rc);
- }
-
- llog_init_handle(env, llh, LLOG_F_IS_PLAIN, NULL);
- if (rc)
- GOTO(out_close, rc);
- rc = llog_get_size(llh);
-
-out_close:
- llog_close(env, llh);
-out_ctxt:
- llog_ctxt_put(ctxt);
- /* header is record 1 */
- return (rc <= 1);
-}
-
/******************** config "macros" *********************/
/* write an lcfg directly into a log (with markers) */
static int mgs_write_log_direct(const struct lu_env *env,
struct mgs_device *mgs, struct fs_db *fsdb,
- char *logname, struct lustre_cfg *lcfg,
- char *devname, char *comment)
+ char *logname, struct llog_cfg_rec *lcr,
+ char *devname, char *comment)
{
- struct llog_handle *llh = NULL;
- int rc;
- ENTRY;
+ struct llog_handle *llh = NULL;
+ int rc;
- if (!lcfg)
- RETURN(-ENOMEM);
+ ENTRY;
rc = record_start_log(env, mgs, &llh, logname);
- if (rc)
- RETURN(rc);
+ if (rc)
+ RETURN(rc);
/* FIXME These should be a single journal transaction */
rc = record_marker(env, llh, fsdb, CM_START, devname, comment);
if (rc)
GOTO(out_end, rc);
- rc = record_lcfg(env, llh, lcfg);
+ rc = llog_write(env, llh, &lcr->lcr_hdr, LLOG_NEXT_IDX);
if (rc)
GOTO(out_end, rc);
rc = record_marker(env, llh, fsdb, CM_END, devname, comment);
}
/* write the lcfg in all logs for the given fs */
-int mgs_write_log_direct_all(const struct lu_env *env,
- struct mgs_device *mgs,
- struct fs_db *fsdb,
- struct mgs_target_info *mti,
- struct lustre_cfg *lcfg,
- char *devname, char *comment,
- int server_only)
+static int mgs_write_log_direct_all(const struct lu_env *env,
+ struct mgs_device *mgs,
+ struct fs_db *fsdb,
+ struct mgs_target_info *mti,
+ struct llog_cfg_rec *lcr, char *devname,
+ char *comment, int server_only)
{
- cfs_list_t list;
- struct mgs_direntry *dirent, *n;
- char *fsname = mti->mti_fsname;
- char *logname;
- int rc = 0, len = strlen(fsname);
- ENTRY;
+ struct list_head log_list;
+ struct mgs_direntry *dirent, *n;
+ char *fsname = mti->mti_fsname;
+ int rc = 0, len = strlen(fsname);
- /* We need to set params for any future logs
- as well. FIXME Append this file to every new log.
- Actually, we should store as params (text), not llogs. Or
- in a database. */
- rc = name_create(&logname, fsname, "-params");
+ ENTRY;
+ /* Find all the logs in the CONFIGS directory */
+ rc = class_dentry_readdir(env, mgs, &log_list);
if (rc)
RETURN(rc);
- if (mgs_log_is_empty(env, mgs, logname)) {
- struct llog_handle *llh = NULL;
- rc = record_start_log(env, mgs, &llh, logname);
- record_end_log(env, &llh);
- }
- name_destroy(&logname);
- if (rc)
- RETURN(rc);
-
- /* Find all the logs in the CONFIGS directory */
- rc = class_dentry_readdir(env, mgs, &list);
- if (rc)
- RETURN(rc);
- /* Could use fsdb index maps instead of directory listing */
- cfs_list_for_each_entry_safe(dirent, n, &list, list) {
- cfs_list_del(&dirent->list);
- /* don't write to sptlrpc rule log */
- if (strstr(dirent->name, "-sptlrpc") != NULL)
+ /* Could use fsdb index maps instead of directory listing */
+ list_for_each_entry_safe(dirent, n, &log_list, mde_list) {
+ list_del_init(&dirent->mde_list);
+ /* don't write to sptlrpc rule log */
+ if (strstr(dirent->mde_name, "-sptlrpc") != NULL)
goto next;
/* caller wants write server logs only */
- if (server_only && strstr(dirent->name, "-client") != NULL)
+ if (server_only && strstr(dirent->mde_name, "-client") != NULL)
goto next;
- if (strncmp(fsname, dirent->name, len) == 0) {
- CDEBUG(D_MGS, "Changing log %s\n", dirent->name);
- /* Erase any old settings of this same parameter */
- rc = mgs_modify(env, mgs, fsdb, mti, dirent->name,
- devname, comment, CM_SKIP);
- if (rc < 0)
- CERROR("%s: Can't modify llog %s: rc = %d\n",
- mgs->mgs_obd->obd_name, dirent->name,rc);
- /* Write the new one */
- if (lcfg) {
- rc = mgs_write_log_direct(env, mgs, fsdb,
- dirent->name,
- lcfg, devname,
- comment);
- if (rc)
- CERROR("%s: writing log %s: rc = %d\n",
- mgs->mgs_obd->obd_name,
- dirent->name, rc);
- }
- }
+ if (strlen(dirent->mde_name) <= len ||
+ strncmp(fsname, dirent->mde_name, len) != 0 ||
+ dirent->mde_name[len] != '-')
+ goto next;
+
+ CDEBUG(D_MGS, "Changing log %s\n", dirent->mde_name);
+ /* Erase any old settings of this same parameter */
+ rc = mgs_modify(env, mgs, fsdb, mti, dirent->mde_name,
+ devname, comment, CM_SKIP);
+ if (rc < 0)
+ CERROR("%s: Can't modify llog %s: rc = %d\n",
+ mgs->mgs_obd->obd_name, dirent->mde_name, rc);
+ if (lcr == NULL)
+ goto next;
+ /* Write the new one */
+ rc = mgs_write_log_direct(env, mgs, fsdb, dirent->mde_name,
+ lcr, devname, comment);
+ if (rc != 0)
+ CERROR("%s: writing log %s: rc = %d\n",
+ mgs->mgs_obd->obd_name, dirent->mde_name, rc);
next:
mgs_direntry_free(dirent);
- }
+ }
- RETURN(rc);
+ RETURN(rc);
}
-static int mgs_write_log_mdc_to_mdt(const struct lu_env *env,
+static int mgs_write_log_osp_to_mdt(const struct lu_env *env,
struct mgs_device *mgs,
struct fs_db *fsdb,
struct mgs_target_info *mti,
- char *logname);
+ int index, char *logname);
static int mgs_write_log_osc_to_lov(const struct lu_env *env,
struct mgs_device *mgs,
struct fs_db *fsdb,
struct mgs_target_info *mti,
- char *logname, char *suffix, char *lovname,
+ char *logname, char *suffix, char *lovname,
enum lustre_sec_part sec_part, int flags);
static int name_create_mdt_and_lov(char **logname, char **lovname,
struct fs_db *fsdb, int i);
return 0;
}
-static int mgs_steal_llog_handler(const struct lu_env *env,
- struct llog_handle *llh,
- struct llog_rec_hdr *rec, void *data)
+/**
+ * Walk through client config log record and convert the related records
+ * into the target.
+ **/
+static int mgs_steal_client_llog_handler(const struct lu_env *env,
+ struct llog_handle *llh,
+ struct llog_rec_hdr *rec, void *data)
{
struct mgs_device *mgs;
struct obd_device *obd;
2: found mdc;
*/
static int last_step = -1;
+ int cplen = 0;
ENTRY;
lcfg = (struct lustre_cfg *)cfg_buf;
- if (lcfg->lcfg_command == LCFG_MARKER) {
- struct cfg_marker *marker;
- marker = lustre_cfg_buf(lcfg, 1);
- if (!strncmp(marker->cm_comment,"add osc",7) &&
- (marker->cm_flags & CM_START)){
- got_an_osc_or_mdc = 1;
- strncpy(tmti->mti_svname, marker->cm_tgtname,
- sizeof(tmti->mti_svname));
+ if (lcfg->lcfg_command == LCFG_MARKER) {
+ struct cfg_marker *marker;
+ marker = lustre_cfg_buf(lcfg, 1);
+ if (!strncmp(marker->cm_comment, "add osc", 7) &&
+ (marker->cm_flags & CM_START) &&
+ !(marker->cm_flags & CM_SKIP)) {
+ got_an_osc_or_mdc = 1;
+ cplen = strlcpy(tmti->mti_svname, marker->cm_tgtname,
+ sizeof(tmti->mti_svname));
+ if (cplen >= sizeof(tmti->mti_svname))
+ RETURN(-E2BIG);
rc = record_start_log(env, mgs, &mdt_llh,
mti->mti_svname);
if (rc)
RETURN(rc);
rc = record_marker(env, mdt_llh, fsdb, CM_START,
- mti->mti_svname,"add osc(copied)");
+ mti->mti_svname, "add osc(copied)");
record_end_log(env, &mdt_llh);
- last_step = marker->cm_step;
- RETURN(rc);
- }
- if (!strncmp(marker->cm_comment,"add osc",7) &&
- (marker->cm_flags & CM_END)){
- LASSERT(last_step == marker->cm_step);
- last_step = -1;
- got_an_osc_or_mdc = 0;
+ last_step = marker->cm_step;
+ RETURN(rc);
+ }
+ if (!strncmp(marker->cm_comment, "add osc", 7) &&
+ (marker->cm_flags & CM_END) &&
+ !(marker->cm_flags & CM_SKIP)) {
+ LASSERT(last_step == marker->cm_step);
+ last_step = -1;
+ got_an_osc_or_mdc = 0;
+ memset(tmti, 0, sizeof(*tmti));
rc = record_start_log(env, mgs, &mdt_llh,
mti->mti_svname);
if (rc)
RETURN(rc);
rc = record_marker(env, mdt_llh, fsdb, CM_END,
- mti->mti_svname,"add osc(copied)");
+ mti->mti_svname, "add osc(copied)");
record_end_log(env, &mdt_llh);
- RETURN(rc);
- }
- if (!strncmp(marker->cm_comment,"add mdc",7) &&
- (marker->cm_flags & CM_START)){
- got_an_osc_or_mdc = 2;
- last_step = marker->cm_step;
- memcpy(tmti->mti_svname, marker->cm_tgtname,
- strlen(marker->cm_tgtname));
-
- RETURN(rc);
- }
- if (!strncmp(marker->cm_comment,"add mdc",7) &&
- (marker->cm_flags & CM_END)){
- LASSERT(last_step == marker->cm_step);
- last_step = -1;
- got_an_osc_or_mdc = 0;
- RETURN(rc);
- }
- }
+ RETURN(rc);
+ }
+ if (!strncmp(marker->cm_comment, "add mdc", 7) &&
+ (marker->cm_flags & CM_START) &&
+ !(marker->cm_flags & CM_SKIP)) {
+ got_an_osc_or_mdc = 2;
+ last_step = marker->cm_step;
+ memcpy(tmti->mti_svname, marker->cm_tgtname,
+ strlen(marker->cm_tgtname));
+
+ RETURN(rc);
+ }
+ if (!strncmp(marker->cm_comment, "add mdc", 7) &&
+ (marker->cm_flags & CM_END) &&
+ !(marker->cm_flags & CM_SKIP)) {
+ LASSERT(last_step == marker->cm_step);
+ last_step = -1;
+ got_an_osc_or_mdc = 0;
+ memset(tmti, 0, sizeof(*tmti));
+ RETURN(rc);
+ }
+ }
if (got_an_osc_or_mdc == 0 || last_step < 0)
RETURN(rc);
if (lcfg->lcfg_command == LCFG_ADD_UUID) {
- uint64_t nodenid = lcfg->lcfg_nid;
+ __u64 nodenid = lcfg->lcfg_nid;
if (strlen(tmti->mti_uuid) == 0) {
/* target uuid not set, this config record is before
tmti->mti_nids[tmti->mti_nid_count] = nodenid;
tmti->mti_nid_count++;
} else {
+ char nidstr[LNET_NIDSTR_SIZE];
+
/* failover node nid */
+ libcfs_nid2str_r(nodenid, nidstr, sizeof(nidstr));
rc = add_param(tmti->mti_params, PARAM_FAILNODE,
- libcfs_nid2str(nodenid));
+ nidstr);
}
RETURN(rc);
strlen(mti->mti_fsname));
tmti->mti_stripe_index = index;
- rc = mgs_write_log_mdc_to_mdt(env, mgs, fsdb, tmti,
+ rc = mgs_write_log_osp_to_mdt(env, mgs, fsdb, tmti,
+ mti->mti_stripe_index,
mti->mti_svname);
memset(tmti, 0, sizeof(*tmti));
RETURN(rc);
if (rc)
GOTO(out_close, rc);
- rc = llog_process_or_fork(env, loghandle, mgs_steal_llog_handler,
+ rc = llog_process_or_fork(env, loghandle, mgs_steal_client_llog_handler,
(void *)comp, NULL, false);
CDEBUG(D_MGS, "steal llog re = %d\n", rc);
out_close:
/* Defaults. Can be changed later by lcfg config_param */
lovdesc->ld_default_stripe_count = 1;
lovdesc->ld_pattern = LOV_PATTERN_RAID0;
- lovdesc->ld_default_stripe_size = 1024 * 1024;
+ lovdesc->ld_default_stripe_size = LOV_DESC_STRIPE_SIZE_DEFAULT;
lovdesc->ld_default_stripe_offset = -1;
- lovdesc->ld_qos_maxage = QOS_DEFAULT_MAXAGE;
+ lovdesc->ld_qos_maxage = LOV_DESC_QOS_MAXAGE_DEFAULT;
sprintf((char*)lovdesc->ld_uuid.uuid, "%s_UUID", lovname);
/* can these be the same? */
uuid = (char *)lovdesc->ld_uuid.uuid;
#07 L add_conn 0:OSC_uml1_ost1_mdsA 1:uml2_UUID
*/
- /* Pull failnid info out of params string */
+ /*
+ * Pull failnid info out of params string, which may contain something
+ * like "<nid1>,<nid2>:<nid3>,<nid4>". class_parse_nid() does not
+ * complain about abnormal inputs like ",:<nid1>", "<nid1>:,<nid2>",
+ * etc. However, convert_hostnames() should have caught those.
+ */
while (class_find_param(ptr, PARAM_FAILNODE, &ptr) == 0) {
while (class_parse_nid(ptr, &nid, &ptr) == 0) {
- if (failnodeuuid == NULL) {
- /* We don't know the failover node name,
- so just use the first nid as the uuid */
- rc = name_create(&failnodeuuid,
- libcfs_nid2str(nid), "");
- if (rc)
- return rc;
- }
- CDEBUG(D_MGS, "add nid %s for failover uuid %s, "
- "client %s\n", libcfs_nid2str(nid),
- failnodeuuid, cliname);
+ char nidstr[LNET_NIDSTR_SIZE];
+
+ if (failnodeuuid == NULL) {
+ /* We don't know the failover node name,
+ * so just use the first nid as the uuid */
+ libcfs_nid2str_r(nid, nidstr, sizeof(nidstr));
+ rc = name_create(&failnodeuuid, nidstr, "");
+ if (rc != 0)
+ return rc;
+ }
+ CDEBUG(D_MGS, "add nid %s for failover uuid %s, "
+ "client %s\n",
+ libcfs_nid2str_r(nid, nidstr, sizeof(nidstr)),
+ failnodeuuid, cliname);
rc = record_add_uuid(env, llh, nid, failnodeuuid);
- }
- if (failnodeuuid)
+ /*
+ * If *ptr is ':', we have added all NIDs for
+ * failnodeuuid.
+ */
+ if (*ptr == ':') {
+ rc = record_add_conn(env, llh, cliname,
+ failnodeuuid);
+ name_destroy(&failnodeuuid);
+ failnodeuuid = NULL;
+ }
+ }
+ if (failnodeuuid) {
rc = record_add_conn(env, llh, cliname, failnodeuuid);
- }
+ name_destroy(&failnodeuuid);
+ failnodeuuid = NULL;
+ }
+ }
- name_destroy(&failnodeuuid);
- return rc;
+ return rc;
}
static int mgs_write_log_mdc_to_lmv(const struct lu_env *env,
char *nodeuuid = NULL;
char *mdcuuid = NULL;
char *lmvuuid = NULL;
- char index[6];
- int i, rc;
- ENTRY;
+ char index[6];
+ char nidstr[LNET_NIDSTR_SIZE];
+ int i, rc;
+ ENTRY;
if (mgs_log_is_empty(env, mgs, logname)) {
CERROR("log is empty! Logical error\n");
CDEBUG(D_MGS, "adding mdc for %s to log %s:lmv(%s)\n",
mti->mti_svname, logname, lmvname);
- rc = name_create(&nodeuuid, libcfs_nid2str(mti->mti_nids[0]), "");
+ libcfs_nid2str_r(mti->mti_nids[0], nidstr, sizeof(nidstr));
+ rc = name_create(&nodeuuid, nidstr, "");
if (rc)
RETURN(rc);
rc = name_create(&mdcname, mti->mti_svname, "-mdc");
"add mdc");
if (rc)
GOTO(out_end, rc);
- for (i = 0; i < mti->mti_nid_count; i++) {
- CDEBUG(D_MGS, "add nid %s for mdt\n",
- libcfs_nid2str(mti->mti_nids[i]));
+ for (i = 0; i < mti->mti_nid_count; i++) {
+ CDEBUG(D_MGS, "add nid %s for mdt\n",
+ libcfs_nid2str_r(mti->mti_nids[i],
+ nidstr, sizeof(nidstr)));
rc = record_add_uuid(env, llh, mti->mti_nids[i], nodeuuid);
if (rc)
GOTO(out_end, rc);
- }
+ }
rc = record_attach(env, llh, mdcname, LUSTRE_MDC_NAME, lmvuuid);
if (rc)
GOTO(out_end, rc);
- rc = record_setup(env, llh, mdcname, mti->mti_uuid, nodeuuid, 0, 0);
+ rc = record_setup(env, llh, mdcname, mti->mti_uuid, nodeuuid,
+ NULL, NULL);
if (rc)
GOTO(out_end, rc);
rc = mgs_write_log_failnids(env, mti, llh, mdcname);
RETURN(rc);
}
+static inline int name_create_lov(char **lovname, char *mdtname,
+ struct fs_db *fsdb, int index)
+{
+ /* COMPAT_180 */
+ if (index == 0 && test_bit(FSDB_OSCNAME18, &fsdb->fsdb_flags))
+ return name_create(lovname, fsdb->fsdb_name, "-mdtlov");
+ else
+ return name_create(lovname, mdtname, "-mdtlov");
+}
+
+static int name_create_mdt_and_lov(char **logname, char **lovname,
+ struct fs_db *fsdb, int i)
+{
+ int rc;
+
+ rc = name_create_mdt(logname, fsdb->fsdb_name, i);
+ if (rc)
+ return rc;
+ /* COMPAT_180 */
+ if (i == 0 && test_bit(FSDB_OSCNAME18, &fsdb->fsdb_flags))
+ rc = name_create(lovname, fsdb->fsdb_name, "-mdtlov");
+ else
+ rc = name_create(lovname, *logname, "-mdtlov");
+ if (rc) {
+ name_destroy(logname);
+ *logname = NULL;
+ }
+ return rc;
+}
+
+static inline int name_create_mdt_osc(char **oscname, char *ostname,
+ struct fs_db *fsdb, int i)
+{
+ char suffix[16];
+
+ if (i == 0 && test_bit(FSDB_OSCNAME18, &fsdb->fsdb_flags))
+ sprintf(suffix, "-osc");
+ else
+ sprintf(suffix, "-osc-MDT%04x", i);
+ return name_create(oscname, ostname, suffix);
+}
+
/* add new mdc to already existent MDS */
-static int mgs_write_log_mdc_to_mdt(const struct lu_env *env,
+static int mgs_write_log_osp_to_mdt(const struct lu_env *env,
struct mgs_device *mgs,
struct fs_db *fsdb,
struct mgs_target_info *mti,
- char *logname)
+ int mdt_index, char *logname)
{
- struct llog_handle *llh = NULL;
- char *nodeuuid = NULL;
- char *mdcname = NULL;
- char *mdcuuid = NULL;
- char *mdtuuid = NULL;
- int idx = mti->mti_stripe_index;
- char index[9];
- int i, rc;
+ struct llog_handle *llh = NULL;
+ char *nodeuuid = NULL;
+ char *ospname = NULL;
+ char *lovuuid = NULL;
+ char *mdtuuid = NULL;
+ char *svname = NULL;
+ char *mdtname = NULL;
+ char *lovname = NULL;
+ char index_str[16];
+ char nidstr[LNET_NIDSTR_SIZE];
+ int i, rc;
- ENTRY;
- if (mgs_log_is_empty(env, mgs, logname)) {
+ ENTRY;
+ if (mgs_log_is_empty(env, mgs, mti->mti_svname)) {
CERROR("log is empty! Logical error\n");
RETURN (-EINVAL);
}
- CDEBUG(D_MGS, "adding mdc index %d to %s\n", idx, logname);
+ CDEBUG(D_MGS, "adding osp index %d to %s\n", mti->mti_stripe_index,
+ logname);
- rc = name_create(&nodeuuid, libcfs_nid2str(mti->mti_nids[0]), "");
+ rc = name_create_mdt(&mdtname, fsdb->fsdb_name, mti->mti_stripe_index);
if (rc)
RETURN(rc);
- snprintf(index, sizeof(index), "-mdc%04x", idx);
- rc = name_create(&mdcname, logname, index);
+
+ libcfs_nid2str_r(mti->mti_nids[0], nidstr, sizeof(nidstr));
+ rc = name_create(&nodeuuid, nidstr, "");
if (rc)
- GOTO(out_free, rc);
- rc = name_create(&mdcuuid, mdcname, "_UUID");
+ GOTO(out_destory, rc);
+
+ rc = name_create(&svname, mdtname, "-osp");
if (rc)
- GOTO(out_free, rc);
- rc = name_create(&mdtuuid, logname, "_UUID");
+ GOTO(out_destory, rc);
+
+ sprintf(index_str, "-MDT%04x", mdt_index);
+ rc = name_create(&ospname, svname, index_str);
if (rc)
- GOTO(out_free, rc);
+ GOTO(out_destory, rc);
+
+ rc = name_create_lov(&lovname, logname, fsdb, mdt_index);
+ if (rc)
+ GOTO(out_destory, rc);
+
+ rc = name_create(&lovuuid, lovname, "_UUID");
+ if (rc)
+ GOTO(out_destory, rc);
+
+ rc = name_create(&mdtuuid, mdtname, "_UUID");
+ if (rc)
+ GOTO(out_destory, rc);
rc = record_start_log(env, mgs, &llh, logname);
if (rc)
- GOTO(out_free, rc);
- rc = record_marker(env, llh, fsdb, CM_START, mti->mti_svname, "add mdc");
+ GOTO(out_destory, rc);
+
+ rc = record_marker(env, llh, fsdb, CM_START, mti->mti_svname,
+ "add osp");
if (rc)
- GOTO(out_end, rc);
- for (i = 0; i < mti->mti_nid_count; i++) {
- CDEBUG(D_MGS, "add nid %s for mdt\n",
- libcfs_nid2str(mti->mti_nids[i]));
+ GOTO(out_destory, rc);
+
+ for (i = 0; i < mti->mti_nid_count; i++) {
+ CDEBUG(D_MGS, "add nid %s for mdt\n",
+ libcfs_nid2str_r(mti->mti_nids[i],
+ nidstr, sizeof(nidstr)));
rc = record_add_uuid(env, llh, mti->mti_nids[i], nodeuuid);
if (rc)
GOTO(out_end, rc);
- }
- rc = record_attach(env, llh, mdcname, LUSTRE_MDC_NAME, mdcuuid);
+ }
+
+ rc = record_attach(env, llh, ospname, LUSTRE_OSP_NAME, lovuuid);
if (rc)
GOTO(out_end, rc);
- rc = record_setup(env, llh, mdcname, mti->mti_uuid, nodeuuid, 0, 0);
+
+ rc = record_setup(env, llh, ospname, mti->mti_uuid, nodeuuid,
+ NULL, NULL);
if (rc)
GOTO(out_end, rc);
- rc = mgs_write_log_failnids(env, mti, llh, mdcname);
+
+ rc = mgs_write_log_failnids(env, mti, llh, ospname);
if (rc)
GOTO(out_end, rc);
- snprintf(index, sizeof(index), "%d", idx);
- rc = record_mdc_add(env, llh, logname, mdcuuid, mti->mti_uuid,
- index, "1");
+ /* Add mdc(osp) to lod */
+ snprintf(index_str, sizeof(index_str), "%d", mti->mti_stripe_index);
+ rc = record_base(env, llh, lovname, 0, LCFG_ADD_MDC, mti->mti_uuid,
+ index_str, "1", NULL);
if (rc)
GOTO(out_end, rc);
- rc = record_marker(env, llh, fsdb, CM_END, mti->mti_svname, "add mdc");
+
+ rc = record_marker(env, llh, fsdb, CM_END, mti->mti_svname, "add osp");
if (rc)
GOTO(out_end, rc);
+
out_end:
record_end_log(env, &llh);
-out_free:
+
+out_destory:
name_destroy(&mdtuuid);
- name_destroy(&mdcuuid);
- name_destroy(&mdcname);
+ name_destroy(&lovuuid);
+ name_destroy(&lovname);
+ name_destroy(&ospname);
+ name_destroy(&svname);
name_destroy(&nodeuuid);
- RETURN(rc);
+ name_destroy(&mdtname);
+ RETURN(rc);
}
static int mgs_write_log_mdt0(const struct lu_env *env,
RETURN(rc);
}
-static int name_create_mdt_and_lov(char **logname, char **lovname,
- struct fs_db *fsdb, int i)
+/* envelope method for all layers log */
+static int mgs_write_log_mdt(const struct lu_env *env,
+ struct mgs_device *mgs,
+ struct fs_db *fsdb,
+ struct mgs_target_info *mti)
{
- int rc;
+ struct mgs_thread_info *mgi = mgs_env_info(env);
+ struct llog_handle *llh = NULL;
+ char *cliname;
+ int rc, i = 0;
+ ENTRY;
- rc = name_create_mdt(logname, fsdb->fsdb_name, i);
- if (rc)
- return rc;
- /* COMPAT_180 */
- if (i == 0 && test_bit(FSDB_OSCNAME18, &fsdb->fsdb_flags))
- rc = name_create(lovname, fsdb->fsdb_name, "-mdtlov");
- else
- rc = name_create(lovname, *logname, "-mdtlov");
- if (rc) {
- name_destroy(logname);
- *logname = NULL;
- }
- return rc;
-}
-
-static inline int name_create_mdt_osc(char **oscname, char *ostname,
- struct fs_db *fsdb, int i)
-{
- char suffix[16];
-
- if (i == 0 && test_bit(FSDB_OSCNAME18, &fsdb->fsdb_flags))
- sprintf(suffix, "-osc");
- else
- sprintf(suffix, "-osc-MDT%04x", i);
- return name_create(oscname, ostname, suffix);
-}
-
-/* envelope method for all layers log */
-static int mgs_write_log_mdt(const struct lu_env *env,
- struct mgs_device *mgs,
- struct fs_db *fsdb,
- struct mgs_target_info *mti)
-{
- struct mgs_thread_info *mgi = mgs_env_info(env);
- struct llog_handle *llh = NULL;
- char *cliname;
- int rc, i = 0;
- ENTRY;
-
- CDEBUG(D_MGS, "writing new mdt %s\n", mti->mti_svname);
-
- if (mti->mti_uuid[0] == '\0') {
- /* Make up our own uuid */
- snprintf(mti->mti_uuid, sizeof(mti->mti_uuid),
- "%s_UUID", mti->mti_svname);
- }
-
- /* add mdt */
- rc = mgs_write_log_mdt0(env, mgs, fsdb, mti);
+ CDEBUG(D_MGS, "writing new mdt %s\n", mti->mti_svname);
+
+ if (mti->mti_uuid[0] == '\0') {
+ /* Make up our own uuid */
+ snprintf(mti->mti_uuid, sizeof(mti->mti_uuid),
+ "%s_UUID", mti->mti_svname);
+ }
+
+ /* add mdt */
+ rc = mgs_write_log_mdt0(env, mgs, fsdb, mti);
if (rc)
RETURN(rc);
/* Append the mdt info to the client log */
#14 L mount_option 0: 1:client 2:lov1 3:MDC_uml1_mdsA_MNT_client
*/
- /* copy client info about lov/lmv */
- mgi->mgi_comp.comp_mti = mti;
- mgi->mgi_comp.comp_fsdb = fsdb;
+ /* copy client info about lov/lmv */
+ mgi->mgi_comp.comp_mti = mti;
+ mgi->mgi_comp.comp_fsdb = fsdb;
- rc = mgs_steal_llog_for_mdt_from_client(env, mgs, cliname,
- &mgi->mgi_comp);
- if (rc)
- GOTO(out_free, rc);
- rc = mgs_write_log_mdc_to_lmv(env, mgs, fsdb, mti, cliname,
- fsdb->fsdb_clilmv);
- if (rc)
- GOTO(out_free, rc);
+ rc = mgs_steal_llog_for_mdt_from_client(env, mgs, cliname,
+ &mgi->mgi_comp);
+ if (rc)
+ GOTO(out_free, rc);
+ rc = mgs_write_log_mdc_to_lmv(env, mgs, fsdb, mti, cliname,
+ fsdb->fsdb_clilmv);
+ if (rc)
+ GOTO(out_free, rc);
- /* add mountopts */
- rc = record_start_log(env, mgs, &llh, cliname);
- if (rc)
- GOTO(out_free, rc);
+ /* add mountopts */
+ rc = record_start_log(env, mgs, &llh, cliname);
+ if (rc)
+ GOTO(out_free, rc);
- rc = record_marker(env, llh, fsdb, CM_START, cliname,
- "mount opts");
- if (rc)
- GOTO(out_end, rc);
- rc = record_mount_opt(env, llh, cliname, fsdb->fsdb_clilov,
- fsdb->fsdb_clilmv);
- if (rc)
- GOTO(out_end, rc);
- rc = record_marker(env, llh, fsdb, CM_END, cliname,
- "mount opts");
+ rc = record_marker(env, llh, fsdb, CM_START, cliname,
+ "mount opts");
+ if (rc)
+ GOTO(out_end, rc);
+ rc = record_mount_opt(env, llh, cliname, fsdb->fsdb_clilov,
+ fsdb->fsdb_clilmv);
+ if (rc)
+ GOTO(out_end, rc);
+ rc = record_marker(env, llh, fsdb, CM_END, cliname,
+ "mount opts");
if (rc)
GOTO(out_end, rc);
+
/* for_all_existing_mdt except current one */
- for (i = 0; i < INDEX_MAP_SIZE * 8; i++){
- char *mdtname;
- if (i != mti->mti_stripe_index &&
- test_bit(i, fsdb->fsdb_mdt_index_map)) {
- rc = name_create_mdt(&mdtname, mti->mti_fsname, i);
+ for (i = 0; i < INDEX_MAP_SIZE * 8; i++) {
+ if (i != mti->mti_stripe_index &&
+ test_bit(i, fsdb->fsdb_mdt_index_map)) {
+ char *logname;
+
+ rc = name_create_mdt(&logname, fsdb->fsdb_name, i);
if (rc)
GOTO(out_end, rc);
- rc = mgs_write_log_mdc_to_mdt(env, mgs, fsdb, mti, mdtname);
- name_destroy(&mdtname);
+
+ /* NB: If the log for the MDT is empty, it means
+ * the MDT is only added to the index
+ * map, and not being process yet, i.e. this
+ * is an unregistered MDT, see mgs_write_log_target().
+ * so we should skip it. Otherwise
+ *
+ * 1. MGS get register request for MDT1 and MDT2.
+ *
+ * 2. Then both MDT1 and MDT2 are added into
+ * fsdb_mdt_index_map. (see mgs_set_index()).
+ *
+ * 3. Then MDT1 get the lock of fsdb_mutex, then
+ * generate the config log, here, it will regard MDT2
+ * as an existent MDT, and generate "add osp" for
+ * lustre-MDT0001-osp-MDT0002. Note: at the moment
+ * MDT0002 config log is still empty, so it will
+ * add "add osp" even before "lov setup", which
+ * will definitly cause trouble.
+ *
+ * 4. MDT1 registeration finished, fsdb_mutex is
+ * released, then MDT2 get in, then in above
+ * mgs_steal_llog_for_mdt_from_client(), it will
+ * add another osp log for lustre-MDT0001-osp-MDT0002,
+ * which will cause another trouble.*/
+ if (!mgs_log_is_empty(env, mgs, logname))
+ rc = mgs_write_log_osp_to_mdt(env, mgs, fsdb,
+ mti, i, logname);
+
+ name_destroy(&logname);
if (rc)
GOTO(out_end, rc);
- }
- }
+ }
+ }
out_end:
record_end_log(env, &llh);
out_free:
char *logname, char *suffix, char *lovname,
enum lustre_sec_part sec_part, int flags)
{
- struct llog_handle *llh = NULL;
+ struct llog_handle *llh = NULL;
char *nodeuuid = NULL;
char *oscname = NULL;
char *oscuuid = NULL;
char *lovuuid = NULL;
char *svname = NULL;
- char index[6];
- int i, rc;
+ char index[6];
+ char nidstr[LNET_NIDSTR_SIZE];
+ int i, rc;
+ ENTRY;
- ENTRY;
- CDEBUG(D_INFO, "adding osc for %s to log %s\n",
- mti->mti_svname, logname);
+ CDEBUG(D_INFO, "adding osc for %s to log %s\n",
+ mti->mti_svname, logname);
if (mgs_log_is_empty(env, mgs, logname)) {
- CERROR("log is empty! Logical error\n");
- RETURN (-EINVAL);
- }
+ CERROR("log is empty! Logical error\n");
+ RETURN(-EINVAL);
+ }
- rc = name_create(&nodeuuid, libcfs_nid2str(mti->mti_nids[0]), "");
+ libcfs_nid2str_r(mti->mti_nids[0], nidstr, sizeof(nidstr));
+ rc = name_create(&nodeuuid, nidstr, "");
if (rc)
RETURN(rc);
rc = name_create(&svname, mti->mti_svname, "-osc");
if (rc)
GOTO(out_free, rc);
+
/* for the system upgraded from old 1.8, keep using the old osc naming
* style for mdt, see name_create_mdt_osc(). LU-1257 */
if (test_bit(FSDB_OSCNAME18, &fsdb->fsdb_flags))
rc = name_create(&oscname, svname, suffix);
if (rc)
GOTO(out_free, rc);
+
rc = name_create(&oscuuid, oscname, "_UUID");
if (rc)
GOTO(out_free, rc);
if (rc)
GOTO(out_free, rc);
+
/*
#03 L add_uuid nid=uml1@tcp(0x20000c0a80201) 0: 1:uml1_UUID
multihomed (#4)
/* NB: don't change record order, because upon MDT steal OSC config
* from client, it treats all nids before LCFG_SETUP as target nids
* (multiple interfaces), while nids after as failover node nids.
- * See mgs_steal_llog_handler() LCFG_ADD_UUID.
+ * See mgs_steal_client_llog_handler() LCFG_ADD_UUID.
*/
- for (i = 0; i < mti->mti_nid_count; i++) {
- CDEBUG(D_MGS, "add nid %s\n", libcfs_nid2str(mti->mti_nids[i]));
+ for (i = 0; i < mti->mti_nid_count; i++) {
+ CDEBUG(D_MGS, "add nid %s\n",
+ libcfs_nid2str_r(mti->mti_nids[i],
+ nidstr, sizeof(nidstr)));
rc = record_add_uuid(env, llh, mti->mti_nids[i], nodeuuid);
if (rc)
GOTO(out_end, rc);
- }
+ }
rc = record_attach(env, llh, oscname, LUSTRE_OSC_NAME, lovuuid);
if (rc)
GOTO(out_end, rc);
- rc = record_setup(env, llh, oscname, mti->mti_uuid, nodeuuid, 0, 0);
+ rc = record_setup(env, llh, oscname, mti->mti_uuid, nodeuuid,
+ NULL, NULL);
if (rc)
GOTO(out_end, rc);
rc = mgs_write_log_failnids(env, mti, llh, oscname);
if (rc)
GOTO(out_end, rc);
- snprintf(index, sizeof(index), "%d", mti->mti_stripe_index);
+
+ snprintf(index, sizeof(index), "%d", mti->mti_stripe_index);
+
rc = record_lov_add(env, llh, lovname, mti->mti_uuid, index, "1");
if (rc)
GOTO(out_end, rc);
GOTO(out_end, rc);
rc = record_setup(env, llh, mti->mti_svname,
"dev"/*ignored*/, "type"/*ignored*/,
- failout ? "n" : "f", 0/*options*/);
+ failout ? "n" : "f", NULL/*options*/);
if (rc)
GOTO(out_end, rc);
rc = record_marker(env, llh, fsdb, CM_END, mti->mti_svname, "add ost");
GOTO(out_free, rc);
}
rc = mgs_write_log_osc_to_lov(env, mgs, fsdb, mti, logname, "",
- fsdb->fsdb_clilov, LUSTRE_SP_CLI, 0);
+ fsdb->fsdb_clilov, LUSTRE_SP_CLI, flags);
out_free:
name_destroy(&logname);
RETURN(rc);
static int mgs_wlp_lcfg(const struct lu_env *env,
struct mgs_device *mgs, struct fs_db *fsdb,
- struct mgs_target_info *mti,
- char *logname, struct lustre_cfg_bufs *bufs,
- char *tgtname, char *ptr)
+ struct mgs_target_info *mti,
+ char *logname, struct lustre_cfg_bufs *bufs,
+ char *tgtname, char *ptr)
{
- char comment[MTI_NAME_MAXLEN];
- char *tmp;
- struct lustre_cfg *lcfg;
- int rc, del;
-
- /* Erase any old settings of this same parameter */
- memcpy(comment, ptr, MTI_NAME_MAXLEN);
- comment[MTI_NAME_MAXLEN - 1] = 0;
- /* But don't try to match the value. */
- if ((tmp = strchr(comment, '=')))
- *tmp = 0;
- /* FIXME we should skip settings that are the same as old values */
+ char comment[MTI_NAME_MAXLEN];
+ char *tmp;
+ struct llog_cfg_rec *lcr;
+ int rc, del;
+
+ /* Erase any old settings of this same parameter */
+ memcpy(comment, ptr, MTI_NAME_MAXLEN);
+ comment[MTI_NAME_MAXLEN - 1] = 0;
+ /* But don't try to match the value. */
+ tmp = strchr(comment, '=');
+ if (tmp != NULL)
+ *tmp = 0;
+ /* FIXME we should skip settings that are the same as old values */
rc = mgs_modify(env, mgs, fsdb, mti, logname, tgtname, comment,CM_SKIP);
if (rc < 0)
return rc;
- del = mgs_param_empty(ptr);
+ del = mgs_param_empty(ptr);
- LCONSOLE_INFO("%sing parameter %s.%s in log %s\n", del ? "Disabl" : rc ?
- "Sett" : "Modify", tgtname, comment, logname);
- if (del)
- return rc;
+ LCONSOLE_INFO("%s parameter %s.%s in log %s\n", del ? "Disabling" : rc ?
+ "Setting" : "Modifying", tgtname, comment, logname);
+ if (del) {
+ /* mgs_modify() will return 1 if nothing had to be done */
+ if (rc == 1)
+ rc = 0;
+ return rc;
+ }
- lustre_cfg_bufs_reset(bufs, tgtname);
- lustre_cfg_bufs_set_string(bufs, 1, ptr);
- lcfg = lustre_cfg_new(LCFG_PARAM, bufs);
- if (!lcfg)
- return -ENOMEM;
- rc = mgs_write_log_direct(env, mgs, fsdb, logname,lcfg,tgtname,comment);
- lustre_cfg_free(lcfg);
- return rc;
+ lustre_cfg_bufs_reset(bufs, tgtname);
+ lustre_cfg_bufs_set_string(bufs, 1, ptr);
+ if (mti->mti_flags & LDD_F_PARAM2)
+ lustre_cfg_bufs_set_string(bufs, 2, LCTL_UPCALL);
+
+ lcr = lustre_cfg_rec_new((mti->mti_flags & LDD_F_PARAM2) ?
+ LCFG_SET_PARAM : LCFG_PARAM, bufs);
+ if (lcr == NULL)
+ return -ENOMEM;
+
+ rc = mgs_write_log_direct(env, mgs, fsdb, logname, lcr, tgtname,
+ comment);
+ lustre_cfg_rec_free(lcr);
+ return rc;
+}
+
+static int mgs_write_log_param2(const struct lu_env *env,
+ struct mgs_device *mgs,
+ struct fs_db *fsdb,
+ struct mgs_target_info *mti, char *ptr)
+{
+ struct lustre_cfg_bufs bufs;
+ int rc = 0;
+ ENTRY;
+
+ CDEBUG(D_MGS, "next param '%s'\n", ptr);
+ rc = mgs_wlp_lcfg(env, mgs, fsdb, mti, PARAMS_FILENAME, &bufs,
+ mti->mti_svname, ptr);
+
+ RETURN(rc);
}
/* write global variable settings into log */
struct mgs_device *mgs, struct fs_db *fsdb,
struct mgs_target_info *mti, char *sys, char *ptr)
{
- struct mgs_thread_info *mgi = mgs_env_info(env);
- struct lustre_cfg *lcfg;
+ struct mgs_thread_info *mgi = mgs_env_info(env);
+ struct lustre_cfg *lcfg;
+ struct llog_cfg_rec *lcr;
char *tmp, sep;
int rc, cmd, convert = 1;
lustre_cfg_bufs_set_string(&mgi->mgi_bufs, 1, sys);
if (!convert && *tmp != '\0')
lustre_cfg_bufs_set_string(&mgi->mgi_bufs, 2, tmp);
- lcfg = lustre_cfg_new(cmd, &mgi->mgi_bufs);
+ lcr = lustre_cfg_rec_new(cmd, &mgi->mgi_bufs);
+ if (lcr == NULL)
+ return -ENOMEM;
+
+ lcfg = &lcr->lcr_cfg;
lcfg->lcfg_num = convert ? simple_strtoul(tmp, NULL, 0) : 0;
/* truncate the comment to the parameter name */
ptr = tmp - 1;
*ptr = '\0';
/* modify all servers and clients */
rc = mgs_write_log_direct_all(env, mgs, fsdb, mti,
- *tmp == '\0' ? NULL : lcfg,
+ *tmp == '\0' ? NULL : lcr,
mti->mti_fsname, sys, 0);
if (rc == 0 && *tmp != '\0') {
switch (cmd) {
}
}
*ptr = sep;
- lustre_cfg_free(lcfg);
+ lustre_cfg_rec_free(lcr);
return rc;
}
char *quota, char *ptr)
{
struct mgs_thread_info *mgi = mgs_env_info(env);
- struct lustre_cfg *lcfg;
+ struct llog_cfg_rec *lcr;
char *tmp;
char sep;
int rc, cmd = LCFG_PARAM;
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;
lustre_cfg_bufs_reset(&mgi->mgi_bufs, mti->mti_fsname);
lustre_cfg_bufs_set_string(&mgi->mgi_bufs, 1, quota);
- lcfg = lustre_cfg_new(cmd, &mgi->mgi_bufs);
+ lcr = lustre_cfg_rec_new(cmd, &mgi->mgi_bufs);
+ if (lcr == NULL)
+ return -ENOMEM;
+
/* truncate the comment to the parameter name */
ptr = tmp - 1;
sep = *ptr;
* log once we cleanup the config log for global param. */
/* modify all servers */
rc = mgs_write_log_direct_all(env, mgs, fsdb, mti,
- *tmp == '\0' ? NULL : lcfg,
+ *tmp == '\0' ? NULL : lcr,
mti->mti_fsname, quota, 1);
*ptr = sep;
- lustre_cfg_free(lcfg);
- return rc;
+ lustre_cfg_rec_free(lcr);
+ return rc < 0 ? rc : 0;
}
static int mgs_srpc_set_param_disk(const struct lu_env *env,
struct mgs_target_info *mti,
char *param)
{
- struct mgs_thread_info *mgi = mgs_env_info(env);
- struct llog_handle *llh = NULL;
- char *logname;
- char *comment, *ptr;
- struct lustre_cfg *lcfg;
- int rc, len;
- ENTRY;
+ struct mgs_thread_info *mgi = mgs_env_info(env);
+ struct llog_cfg_rec *lcr;
+ struct llog_handle *llh = NULL;
+ char *logname;
+ char *comment, *ptr;
+ int rc, len;
- /* get comment */
- ptr = strchr(param, '=');
- LASSERT(ptr);
- len = ptr - param;
+ ENTRY;
- OBD_ALLOC(comment, len + 1);
- if (comment == NULL)
- RETURN(-ENOMEM);
- strncpy(comment, param, len);
- comment[len] = '\0';
+ /* get comment */
+ ptr = strchr(param, '=');
+ LASSERT(ptr != NULL);
+ len = ptr - param;
- /* prepare lcfg */
+ OBD_ALLOC(comment, len + 1);
+ if (comment == NULL)
+ RETURN(-ENOMEM);
+ strncpy(comment, param, len);
+ comment[len] = '\0';
+
+ /* prepare lcfg */
lustre_cfg_bufs_reset(&mgi->mgi_bufs, mti->mti_svname);
lustre_cfg_bufs_set_string(&mgi->mgi_bufs, 1, param);
- lcfg = lustre_cfg_new(LCFG_SPTLRPC_CONF, &mgi->mgi_bufs);
- if (lcfg == NULL)
- GOTO(out_comment, rc = -ENOMEM);
+ lcr = lustre_cfg_rec_new(LCFG_SPTLRPC_CONF, &mgi->mgi_bufs);
+ if (lcr == NULL)
+ GOTO(out_comment, rc = -ENOMEM);
- /* construct log name */
- rc = name_create(&logname, mti->mti_fsname, "-sptlrpc");
- if (rc)
- GOTO(out_lcfg, rc);
+ /* construct log name */
+ rc = name_create(&logname, mti->mti_fsname, "-sptlrpc");
+ if (rc < 0)
+ GOTO(out_lcfg, rc);
if (mgs_log_is_empty(env, mgs, logname)) {
rc = record_start_log(env, mgs, &llh, logname);
- if (rc)
- GOTO(out, rc);
+ if (rc < 0)
+ GOTO(out, rc);
record_end_log(env, &llh);
- }
+ }
- /* obsolete old one */
+ /* obsolete old one */
rc = mgs_modify(env, mgs, fsdb, mti, logname, mti->mti_svname,
comment, CM_SKIP);
if (rc < 0)
GOTO(out, rc);
- /* write the new one */
- rc = mgs_write_log_direct(env, mgs, fsdb, logname, lcfg,
- mti->mti_svname, comment);
+ /* write the new one */
+ rc = mgs_write_log_direct(env, mgs, fsdb, logname, lcr,
+ mti->mti_svname, comment);
if (rc)
- CERROR("err %d writing log %s\n", rc, logname);
+ CERROR("%s: error writing log %s: rc = %d\n",
+ mgs->mgs_obd->obd_name, logname, rc);
out:
- name_destroy(&logname);
+ name_destroy(&logname);
out_lcfg:
- lustre_cfg_free(lcfg);
+ lustre_cfg_rec_free(lcr);
out_comment:
- OBD_FREE(comment, len + 1);
- RETURN(rc);
+ OBD_FREE(comment, len + 1);
+ RETURN(rc);
}
static int mgs_srpc_set_param_udesc_mem(struct fs_db *fsdb,
}
rset = &tgtconf->mtsc_rset;
+ } else if (strcmp(svname, MGSSELF_NAME) == 0) {
+ /* put _mgs related srpc rule directly in mgs ruleset */
+ rset = &fsdb->fsdb_mgs->mgs_lut.lut_sptlrpc_rset;
} else {
rset = &fsdb->fsdb_srpc_gen;
}
RETURN(-EINVAL);
}
- cfg_len = rec->lrh_len - sizeof(struct llog_rec_hdr) -
- sizeof(struct llog_rec_tail);
+ cfg_len = REC_DATA_LEN(rec);
rc = lustre_cfg_sanity_check(lcfg, cfg_len);
if (rc) {
struct mgs_thread_info *mgi = mgs_env_info(env);
char *logname;
char *tmp;
- int rc = 0, rc2 = 0;
+ int rc = 0;
ENTRY;
/* For various parameter settings, we have to figure out which logs
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;
- int i;
+ if (class_match_param(ptr, PARAM_OSC PARAM_ACTIVE, &tmp) == 0 ||
+ class_match_param(ptr, PARAM_MDC PARAM_ACTIVE, &tmp) == 0) {
+ /* active=0 means off, anything else means on */
+ int flag = (*tmp == '0') ? CM_EXCLUDE : 0;
+ bool deactive_osc = memcmp(ptr, PARAM_OSC PARAM_ACTIVE,
+ strlen(PARAM_OSC PARAM_ACTIVE)) == 0;
+ int i;
- if (!(mti->mti_flags & LDD_F_SV_TYPE_OST)) {
- LCONSOLE_ERROR_MSG(0x144, "%s: Only OSCs can "
- "be (de)activated.\n",
- mti->mti_svname);
- GOTO(end, rc = -EINVAL);
- }
- LCONSOLE_WARN("Permanently %sactivating %s\n",
- flag ? "de": "re", mti->mti_svname);
- /* Modify clilov */
+ if (!deactive_osc) {
+ __u32 index;
+
+ rc = server_name2index(mti->mti_svname, &index, NULL);
+ if (rc < 0)
+ GOTO(end, rc);
+
+ if (index == 0) {
+ LCONSOLE_ERROR_MSG(0x144, "%s: MDC0 can not be"
+ " (de)activated.\n",
+ mti->mti_svname);
+ GOTO(end, rc = -EPERM);
+ }
+ }
+
+ LCONSOLE_WARN("Permanently %sactivating %s\n",
+ flag ? "de" : "re", mti->mti_svname);
+ /* Modify clilov */
rc = name_create(&logname, mti->mti_fsname, "-client");
- if (rc)
+ if (rc < 0)
GOTO(end, rc);
rc = mgs_modify(env, mgs, fsdb, mti, logname,
- mti->mti_svname, "add osc", flag);
- name_destroy(&logname);
- if (rc)
- goto active_err;
- /* Modify mdtlov */
- /* Add to all MDT logs for CMD */
- for (i = 0; i < INDEX_MAP_SIZE * 8; i++) {
+ mti->mti_svname,
+ deactive_osc ? "add osc" : "add mdc", flag);
+ name_destroy(&logname);
+ if (rc < 0)
+ goto active_err;
+
+ /* Modify mdtlov */
+ /* Add to all MDT logs for DNE */
+ for (i = 0; i < INDEX_MAP_SIZE * 8; i++) {
if (!test_bit(i, fsdb->fsdb_mdt_index_map))
- continue;
+ continue;
rc = name_create_mdt(&logname, mti->mti_fsname, i);
- if (rc)
+ if (rc < 0)
GOTO(end, rc);
rc = mgs_modify(env, mgs, fsdb, mti, logname,
- mti->mti_svname, "add osc", flag);
- name_destroy(&logname);
- if (rc)
- goto active_err;
- }
- active_err:
- if (rc) {
- LCONSOLE_ERROR_MSG(0x145, "Couldn't find %s in"
- "log (%d). No permanent "
- "changes were made to the "
- "config log.\n",
- mti->mti_svname, rc);
+ mti->mti_svname,
+ deactive_osc ? "add osc" : "add osp",
+ flag);
+ name_destroy(&logname);
+ if (rc < 0)
+ goto active_err;
+ }
+active_err:
+ if (rc < 0) {
+ LCONSOLE_ERROR_MSG(0x145, "Couldn't find %s in"
+ "log (%d). No permanent "
+ "changes were made to the "
+ "config log.\n",
+ mti->mti_svname, rc);
if (test_bit(FSDB_OLDLOG14, &fsdb->fsdb_flags))
- LCONSOLE_ERROR_MSG(0x146, "This may be"
- " because the log"
- "is in the old 1.4"
- "style. Consider "
- " --writeconf to "
- "update the logs.\n");
- GOTO(end, rc);
- }
- /* Fall through to osc proc for deactivating live OSC
- on running MDT / clients. */
- }
+ LCONSOLE_ERROR_MSG(0x146, "This may be"
+ " because the log"
+ "is in the old 1.4"
+ "style. Consider "
+ " --writeconf to "
+ "update the logs.\n");
+ GOTO(end, rc);
+ }
+ /* Fall through to osc/mdc proc for deactivating live
+ OSC/OSP on running MDT / clients. */
+ }
/* Below here, let obd's XXX_process_config methods handle it */
/* All lov. in proc */
if (rc)
GOTO(end, rc);
- CDEBUG(D_MGS, "%.3s param %s\n", ptr, ptr + 4);
+ /* Forbid direct update of llite root squash parameters.
+ * These parameters are indirectly set via the MDT settings.
+ * See (LU-1778) */
+ if ((class_match_param(ptr, PARAM_LLITE, &tmp) == 0) &&
+ ((memcmp(tmp, "root_squash=", 12) == 0) ||
+ (memcmp(tmp, "nosquash_nids=", 14) == 0))) {
+ LCONSOLE_ERROR("%s: root squash parameters can only "
+ "be updated through MDT component\n",
+ mti->mti_fsname);
+ name_destroy(&cname);
+ GOTO(end, rc = -EINVAL);
+ }
- /* Modify client */
+ CDEBUG(D_MGS, "%.3s param %s\n", ptr, ptr + 4);
+
+ /* Modify client */
rc = name_create(&logname, mti->mti_fsname, "-client");
if (rc) {
name_destroy(&cname);
}
}
}
- name_destroy(&logname);
- name_destroy(&cname);
- GOTO(end, rc);
- }
- /* All mdt. params in proc */
- if (class_match_param(ptr, PARAM_MDT, NULL) == 0) {
+ /* For mdc activate/deactivate, it affects OSP on MDT as well */
+ if (class_match_param(ptr, PARAM_MDC PARAM_ACTIVE, &tmp) == 0 &&
+ rc == 0) {
+ char suffix[16];
+ char *lodname = NULL;
+ char *param_str = NULL;
+ int i;
+ int index;
+
+ /* replace mdc with osp */
+ memcpy(ptr, PARAM_OSP, strlen(PARAM_OSP));
+ rc = server_name2index(mti->mti_svname, &index, NULL);
+ if (rc < 0) {
+ memcpy(ptr, PARAM_MDC, strlen(PARAM_MDC));
+ GOTO(end, rc);
+ }
+
+ for (i = 0; i < INDEX_MAP_SIZE * 8; i++) {
+ if (!test_bit(i, fsdb->fsdb_mdt_index_map))
+ continue;
+
+ if (i == index)
+ continue;
+
+ name_destroy(&logname);
+ rc = name_create_mdt(&logname, mti->mti_fsname,
+ i);
+ if (rc < 0)
+ break;
+
+ if (mgs_log_is_empty(env, mgs, logname))
+ continue;
+
+ snprintf(suffix, sizeof(suffix), "-osp-MDT%04x",
+ i);
+ name_destroy(&cname);
+ rc = name_create(&cname, mti->mti_svname,
+ suffix);
+ if (rc < 0)
+ break;
+
+ rc = mgs_wlp_lcfg(env, mgs, fsdb, mti, logname,
+ &mgi->mgi_bufs, cname, ptr);
+ if (rc < 0)
+ break;
+
+ /* Add configuration log for noitfying LOD
+ * to active/deactive the OSP. */
+ name_destroy(¶m_str);
+ rc = name_create(¶m_str, cname,
+ (*tmp == '0') ? ".active=0" :
+ ".active=1");
+ if (rc < 0)
+ break;
+
+ name_destroy(&lodname);
+ rc = name_create(&lodname, logname, "-mdtlov");
+ if (rc < 0)
+ break;
+
+ rc = mgs_wlp_lcfg(env, mgs, fsdb, mti, logname,
+ &mgi->mgi_bufs, lodname,
+ param_str);
+ if (rc < 0)
+ break;
+ }
+ memcpy(ptr, PARAM_MDC, strlen(PARAM_MDC));
+ name_destroy(&lodname);
+ name_destroy(¶m_str);
+ }
+
+ name_destroy(&logname);
+ name_destroy(&cname);
+ GOTO(end, rc);
+ }
+
+ /* All mdt. params in proc */
+ if (class_match_param(ptr, PARAM_MDT, &tmp) == 0) {
int i;
__u32 idx;
goto active_err;
rc = mgs_wlp_lcfg(env, mgs, fsdb, mti,
logname, &mgi->mgi_bufs,
- logname, ptr);
- name_destroy(&logname);
- if (rc)
- goto active_err;
- }
- } else {
+ logname, ptr);
+ name_destroy(&logname);
+ if (rc)
+ goto active_err;
+ }
+ } else {
+ if ((memcmp(tmp, "root_squash=", 12) == 0) ||
+ (memcmp(tmp, "nosquash_nids=", 14) == 0)) {
+ LCONSOLE_ERROR("%s: root squash parameters "
+ "cannot be applied to a single MDT\n",
+ mti->mti_fsname);
+ GOTO(end, rc = -EINVAL);
+ }
rc = mgs_wlp_lcfg(env, mgs, fsdb, mti,
mti->mti_svname, &mgi->mgi_bufs,
- mti->mti_svname, ptr);
- if (rc)
- goto active_err;
- }
- GOTO(end, rc);
- }
+ mti->mti_svname, ptr);
+ if (rc)
+ goto active_err;
+ }
- /* All mdd., ost. params in proc */
- if ((class_match_param(ptr, PARAM_MDD, NULL) == 0) ||
- (class_match_param(ptr, PARAM_OST, NULL) == 0)) {
- CDEBUG(D_MGS, "%.3s param %s\n", ptr, ptr + 4);
+ /* root squash settings are also applied to llite
+ * config log (see LU-1778) */
+ if (rc == 0 &&
+ ((memcmp(tmp, "root_squash=", 12) == 0) ||
+ (memcmp(tmp, "nosquash_nids=", 14) == 0))) {
+ char *cname;
+ char *ptr2;
+
+ rc = name_create(&cname, mti->mti_fsname, "-client");
+ if (rc)
+ GOTO(end, rc);
+ rc = name_create(&logname, mti->mti_fsname, "-client");
+ if (rc) {
+ name_destroy(&cname);
+ GOTO(end, rc);
+ }
+ rc = name_create(&ptr2, PARAM_LLITE, tmp);
+ if (rc) {
+ name_destroy(&cname);
+ name_destroy(&logname);
+ GOTO(end, rc);
+ }
+ rc = mgs_wlp_lcfg(env, mgs, fsdb, mti, logname,
+ &mgi->mgi_bufs, cname, ptr2);
+ name_destroy(&ptr2);
+ name_destroy(&logname);
+ name_destroy(&cname);
+ }
+ GOTO(end, rc);
+ }
+
+ /* All mdd., ost. and osd. params in proc */
+ if ((class_match_param(ptr, PARAM_MDD, NULL) == 0) ||
+ (class_match_param(ptr, PARAM_OST, NULL) == 0) ||
+ (class_match_param(ptr, PARAM_OSD, NULL) == 0)) {
+ CDEBUG(D_MGS, "%.3s param %s\n", ptr, ptr + 4);
if (mgs_log_is_empty(env, mgs, mti->mti_svname))
- GOTO(end, rc = -ENODEV);
+ GOTO(end, rc = -ENODEV);
rc = mgs_wlp_lcfg(env, mgs, fsdb, mti, mti->mti_svname,
&mgi->mgi_bufs, mti->mti_svname, ptr);
- GOTO(end, rc);
- }
+ GOTO(end, rc);
+ }
LCONSOLE_WARN("Ignoring unrecognized param '%s'\n", ptr);
- rc2 = -ENOSYS;
end:
if (rc)
CERROR("err %d on param '%s'\n", rc, ptr);
- RETURN(rc ?: rc2);
+ RETURN(rc);
}
-/* Not implementing automatic failover nid addition at this time. */
-int mgs_check_failnid(const struct lu_env *env, struct mgs_device *mgs,
- struct mgs_target_info *mti)
+int mgs_write_log_target(const struct lu_env *env, struct mgs_device *mgs,
+ struct mgs_target_info *mti, struct fs_db *fsdb)
{
-#if 0
- struct fs_db *fsdb;
- int rc;
- ENTRY;
+ char *buf, *params;
+ int rc = -EINVAL;
- rc = mgs_find_or_make_fsdb(obd, fsname, &fsdb);
- if (rc)
- RETURN(rc);
-
- if (mgs_log_is_empty(obd, mti->mti_svname))
- /* should never happen */
- RETURN(-ENOENT);
+ ENTRY;
- CDEBUG(D_MGS, "Checking for new failnids for %s\n", mti->mti_svname);
-
- /* FIXME We can just check mti->params to see if we're already in
- the failover list. Modify mti->params for rewriting back at
- server_register_target(). */
-
- mutex_lock(&fsdb->fsdb_mutex);
- rc = mgs_write_log_add_failnid(obd, fsdb, mti);
- mutex_unlock(&fsdb->fsdb_mutex);
-
- RETURN(rc);
-#endif
- return 0;
-}
-
-int mgs_write_log_target(const struct lu_env *env,
- struct mgs_device *mgs,
- struct mgs_target_info *mti,
- struct fs_db *fsdb)
-{
- int rc = -EINVAL;
- char *buf, *params;
- ENTRY;
-
- /* set/check the new target index */
- rc = mgs_set_index(env, mgs, mti);
- if (rc < 0) {
- CERROR("Can't get index (%d)\n", rc);
- RETURN(rc);
- }
+ /* set/check the new target index */
+ rc = mgs_set_index(env, mgs, mti);
+ if (rc < 0)
+ RETURN(rc);
if (rc == EALREADY) {
LCONSOLE_WARN("Found index %d for %s, updating log\n",
get repeat setup instructions for already running
osc's. So don't update the client/mdt logs. */
mti->mti_flags &= ~LDD_F_UPDATE;
+ rc = 0;
}
+ OBD_FAIL_TIMEOUT(OBD_FAIL_MGS_WRITE_TARGET_DELAY, cfs_fail_val > 0 ?
+ cfs_fail_val : 10);
+
mutex_lock(&fsdb->fsdb_mutex);
if (mti->mti_flags &
}
/* 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;
- cfs_list_t list;
+ 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, &list);
- if (rc)
+ rc = class_dentry_readdir(env, mgs, &log_list);
+ 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);
- cfs_list_for_each_entry_safe(dirent, n, &list, list) {
- cfs_list_del(&dirent->list);
- suffix = strrchr(dirent->name, '-');
+ list_for_each_entry_safe(dirent, n, &log_list, mde_list) {
+ list_del_init(&dirent->mde_list);
+ suffix = strrchr(dirent->mde_name, '-');
if (suffix != NULL) {
- if ((len == suffix - dirent->name) &&
- (strncmp(fsname, dirent->name, len) == 0)) {
+ if ((len == suffix - dirent->mde_name) &&
+ (strncmp(fsname, dirent->mde_name, len) == 0)) {
CDEBUG(D_MGS, "Removing log %s\n",
- dirent->name);
- mgs_erase_log(env, mgs, dirent->name);
+ 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 */
+int mgs_list_logs(const struct lu_env *env, struct mgs_device *mgs,
+ struct obd_ioctl_data *data)
+{
+ struct list_head log_list;
+ struct mgs_direntry *dirent, *n;
+ char *out, *suffix;
+ int l, remains, rc;
+
+ ENTRY;
+
+ /* Find all the logs in the CONFIGS directory */
+ rc = class_dentry_readdir(env, mgs, &log_list);
+ if (rc)
+ RETURN(rc);
+
+ out = data->ioc_bulk;
+ remains = data->ioc_inllen1;
+ list_for_each_entry_safe(dirent, n, &log_list, mde_list) {
+ list_del_init(&dirent->mde_list);
+ suffix = strrchr(dirent->mde_name, '-');
+ if (suffix != NULL) {
+ l = snprintf(out, remains, "config_log: %s\n",
+ dirent->mde_name);
+ out += l;
+ remains -= l;
+ }
+ mgs_direntry_free(dirent);
+ if (remains <= 0)
+ break;
+ }
+ RETURN(rc);
+}
+
+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)
+{
+ if (buflen < namelen)
+ return false;
+
+ if (memcmp(buf, fsname, namelen) != 0)
+ return false;
+
+ if (buf[namelen] != '\0' && buf[namelen] != '-')
+ return false;
+
+ return true;
+}
+
+static int mgs_lcfg_fork_handler(const struct lu_env *env,
+ struct llog_handle *o_llh,
+ struct llog_rec_hdr *o_rec, void *data)
+{
+ 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;
+
+ /* 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 */
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 = NULL;
+ struct llog_handle *params_llh = NULL;
+ int rc;
+ ENTRY;
+
+ rc = mgs_find_or_make_fsdb(env, mgs, PARAMS_FILENAME, &fsdb);
+ if (!rc) {
+ mutex_lock(&fsdb->fsdb_mutex);
+ rc = record_start_log(env, mgs, ¶ms_llh, PARAMS_FILENAME);
+ if (!rc)
+ rc = record_end_log(env, ¶ms_llh);
+ mutex_unlock(&fsdb->fsdb_mutex);
+ mgs_put_fsdb(mgs, fsdb);
+ }
+
+ RETURN(rc);
+}
+
+/* Cleanup params fsdb and log
+ */
+int mgs_params_fsdb_cleanup(const struct lu_env *env, struct mgs_device *mgs)
+{
+ 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
* \param lcfg buf0 may contain the device (testfs-MDT0000) name
* buf1 contains the single parameter
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;
- char *ptr, *tmp;
- __u32 index;
- int rc = 0;
- ENTRY;
+ 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 (rc == 0 && !mgs_parse_devname(devname, NULL, &index)) {
/* param related to llite isn't allowed to set by OST or MDT */
if (rc == 0 && strncmp(param, PARAM_LLITE,
- sizeof(PARAM_LLITE)) == 0)
+ sizeof(PARAM_LLITE) - 1) == 0)
RETURN(-EINVAL);
} else {
/* assume devname is the fsname */
- memset(fsname, 0, MTI_NAME_MAXLEN);
- strncpy(fsname, devname, MTI_NAME_MAXLEN);
- fsname[MTI_NAME_MAXLEN - 1] = 0;
+ strlcpy(fsname, devname, MTI_NAME_MAXLEN);
}
CDEBUG(D_MGS, "setparam fs='%s' device='%s'\n", fsname, devname);
- rc = mgs_find_or_make_fsdb(env, mgs, fsname, &fsdb);
- if (rc)
- RETURN(rc);
- if (!test_bit(FSDB_MGS_SELF, &fsdb->fsdb_flags) &&
+ rc = mgs_find_or_make_fsdb(env, mgs,
+ lcfg->lcfg_command == LCFG_SET_PARAM ?
+ PARAMS_FILENAME : fsname, &fsdb);
+ if (rc)
+ RETURN(rc);
+
+ 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);
- strncpy(mti->mti_fsname, fsname, MTI_NAME_MAXLEN);
- strncpy(mti->mti_svname, devname, MTI_NAME_MAXLEN);
- strncpy(mti->mti_params, param, sizeof(mti->mti_params));
+ /* 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);
+ if (strlcpy(mti->mti_svname, devname, sizeof(mti->mti_svname))
+ >= sizeof(mti->mti_svname))
+ GOTO(out, rc = -E2BIG);
+ if (strlcpy(mti->mti_params, param, sizeof(mti->mti_params))
+ >= sizeof(mti->mti_params))
+ GOTO(out, rc = -E2BIG);
rc = server_name2index(mti->mti_svname, &mti->mti_stripe_index, &tmp);
if (rc < 0)
/* Not a valid server; may be only fsname */
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
+ * someone was already reading while we were updating the logs,
+ * so we don't really need to hold the lock while we're
+ * writing (above).
+ */
+ if (lcfg->lcfg_command == LCFG_SET_PARAM) {
+ mti->mti_flags = rc | LDD_F_PARAM2;
+ mutex_lock(&fsdb->fsdb_mutex);
+ rc = mgs_write_log_param2(env, mgs, fsdb, mti, mti->mti_params);
+ mutex_unlock(&fsdb->fsdb_mutex);
+ mgs_revoke_lock(mgs, fsdb, CONFIG_T_PARAMS);
+ } else {
+ mti->mti_flags = rc | LDD_F_PARAM;
+ mutex_lock(&fsdb->fsdb_mutex);
+ rc = mgs_write_log_param(env, mgs, fsdb, mti, mti->mti_params);
+ mutex_unlock(&fsdb->fsdb_mutex);
+ mgs_revoke_lock(mgs, fsdb, CONFIG_T_CONFIG);
+ }
- mti->mti_flags = rc | LDD_F_PARAM;
+out:
+ if (mti)
+ OBD_FREE_PTR(mti);
- mutex_lock(&fsdb->fsdb_mutex);
- rc = mgs_write_log_param(env, mgs, fsdb, mti, mti->mti_params);
- mutex_unlock(&fsdb->fsdb_mutex);
+ if (fsdb) {
+ if (free)
+ mgs_unlink_fsdb(mgs, fsdb);
+ mgs_put_fsdb(mgs, fsdb);
+ }
- /*
- * Revoke lock so everyone updates. Should be alright if
- * someone was already reading while we were updating the logs,
- * so we don't really need to hold the lock while we're
- * writing (above).
- */
- mgs_revoke_lock(mgs, fsdb, CONFIG_T_CONFIG);
-out:
- OBD_FREE_PTR(mti);
- RETURN(rc);
+ RETURN(rc);
}
static int mgs_write_log_pool(const struct lu_env *env,
struct mgs_device *mgs, char *logname,
- struct fs_db *fsdb, char *lovname,
+ struct fs_db *fsdb, char *tgtname,
enum lcfg_command_type cmd,
- char *poolname, char *fsname,
+ char *fsname, char *poolname,
char *ostname, char *comment)
{
struct llog_handle *llh = NULL;
rc = record_start_log(env, mgs, &llh, logname);
if (rc)
return rc;
- rc = record_marker(env, llh, fsdb, CM_START, lovname, comment);
+ rc = record_marker(env, llh, fsdb, CM_START, tgtname, comment);
if (rc)
goto out;
- rc = record_base(env, llh, lovname, 0, cmd, poolname, fsname, ostname, 0);
+ rc = record_base(env, llh, tgtname, 0, cmd,
+ fsname, poolname, ostname, NULL);
if (rc)
goto out;
- rc = record_marker(env, llh, fsdb, CM_END, lovname, comment);
+ rc = record_marker(env, llh, fsdb, CM_END, tgtname, comment);
out:
record_end_log(env, &llh);
return rc;
}
+int mgs_nodemap_cmd(const struct lu_env *env, struct mgs_device *mgs,
+ enum lcfg_command_type cmd, const char *nodemap_name,
+ char *param)
+{
+ lnet_nid_t nid[2];
+ __u32 idmap[2];
+ bool bool_switch;
+ __u32 int_id;
+ int rc = 0;
+ ENTRY;
+
+ switch (cmd) {
+ case LCFG_NODEMAP_ADD:
+ rc = nodemap_add(nodemap_name);
+ break;
+ case LCFG_NODEMAP_DEL:
+ rc = nodemap_del(nodemap_name);
+ break;
+ case LCFG_NODEMAP_ADD_RANGE:
+ rc = nodemap_parse_range(param, nid);
+ if (rc != 0)
+ break;
+ rc = nodemap_add_range(nodemap_name, nid);
+ break;
+ case LCFG_NODEMAP_DEL_RANGE:
+ rc = nodemap_parse_range(param, nid);
+ if (rc != 0)
+ break;
+ rc = nodemap_del_range(nodemap_name, nid);
+ break;
+ case LCFG_NODEMAP_ADMIN:
+ bool_switch = simple_strtoul(param, NULL, 10);
+ rc = nodemap_set_allow_root(nodemap_name, bool_switch);
+ break;
+ case LCFG_NODEMAP_DENY_UNKNOWN:
+ 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);
+ break;
+ case LCFG_NODEMAP_SQUASH_UID:
+ int_id = simple_strtoul(param, NULL, 10);
+ rc = nodemap_set_squash_uid(nodemap_name, int_id);
+ break;
+ case LCFG_NODEMAP_SQUASH_GID:
+ int_id = simple_strtoul(param, NULL, 10);
+ rc = nodemap_set_squash_gid(nodemap_name, int_id);
+ break;
+ case LCFG_NODEMAP_ADD_UIDMAP:
+ case LCFG_NODEMAP_ADD_GIDMAP:
+ rc = nodemap_parse_idmap(param, idmap);
+ if (rc != 0)
+ break;
+ if (cmd == LCFG_NODEMAP_ADD_UIDMAP)
+ rc = nodemap_add_idmap(nodemap_name, NODEMAP_UID,
+ idmap);
+ else
+ rc = nodemap_add_idmap(nodemap_name, NODEMAP_GID,
+ idmap);
+ break;
+ case LCFG_NODEMAP_DEL_UIDMAP:
+ case LCFG_NODEMAP_DEL_GIDMAP:
+ rc = nodemap_parse_idmap(param, idmap);
+ if (rc != 0)
+ break;
+ if (cmd == LCFG_NODEMAP_DEL_UIDMAP)
+ rc = nodemap_del_idmap(nodemap_name, NODEMAP_UID,
+ idmap);
+ else
+ rc = nodemap_del_idmap(nodemap_name, NODEMAP_GID,
+ idmap);
+ break;
+ case LCFG_NODEMAP_SET_FILESET:
+ rc = nodemap_set_fileset(nodemap_name, param);
+ break;
+ default:
+ rc = -EINVAL;
+ }
+
+ RETURN(rc);
+}
+
int mgs_pool_cmd(const struct lu_env *env, struct mgs_device *mgs,
enum lcfg_command_type cmd, char *fsname,
char *poolname, char *ostname)
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;
}
- mutex_lock(&fsdb->fsdb_mutex);
-
- 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));
- /* write pool def to all MDT logs */
- for (i = 0; i < INDEX_MAP_SIZE * 8; i++) {
+ mutex_lock(&fsdb->fsdb_mutex);
+ 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;
+}