X-Git-Url: https://git.whamcloud.com/?p=fs%2Flustre-release.git;a=blobdiff_plain;f=lustre%2Fmgs%2Fmgs_llog.c;h=5d9c53591daf34f83a5ca96d5b0f5b8c5fee4092;hp=d0ff8f3d7392aeb3643ab6ac94d49ec6b3121c49;hb=b78fb445555916e380b1661546c821df14098596;hpb=aa37f159e721723c3a719592c4d75df4c774b46c diff --git a/lustre/mgs/mgs_llog.c b/lustre/mgs/mgs_llog.c index d0ff8f3..5d9c535 100644 --- a/lustre/mgs/mgs_llog.c +++ b/lustre/mgs/mgs_llog.c @@ -15,11 +15,7 @@ * * 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 */ @@ -27,7 +23,7 @@ * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved. * Use is subject to license terms. * - * Copyright (c) 2011, Whamcloud, Inc. + * Copyright (c) 2011, 2016, Intel Corporation. */ /* * This file is part of Lustre, http://www.lustre.org/ @@ -38,57 +34,102 @@ * Lustre Management Server (mgs) config llog creation * * Author: Nathan Rutman + * Author: Alex Zhuravlev + * Author: Mikhail Pershin */ #define DEBUG_SUBSYSTEM S_MGS #define D_MGS D_CONFIG #include -#include +#include #include #include -#include -#include +#include #include "mgs_internal.h" /********************** Class functions ********************/ -/* Caller must list_del and OBD_FREE each dentry from the list */ +/* Find all logs in CONFIG directory and link then into list */ int class_dentry_readdir(const struct lu_env *env, - struct mgs_device *mgs, cfs_list_t *dentry_list) + struct mgs_device *mgs, struct list_head *log_list) { - /* see mds_cleanup_pending */ - struct lvfs_run_ctxt saved; - struct file *file; - struct dentry *dentry; - struct vfsmount *mnt; - int rc = 0; - ENTRY; + struct dt_object *dir = mgs->mgs_configs_dir; + const struct dt_it_ops *iops; + struct dt_it *it; + struct mgs_direntry *de; + char *key; + int rc, key_sz; + + 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); + if (IS_ERR(it)) + RETURN(PTR_ERR(it)); + + rc = iops->load(env, it, 0); + if (rc <= 0) + GOTO(fini, rc = 0); + + /* main cycle */ + do { + key = (void *)iops->key(env, it); + if (IS_ERR(key)) { + CERROR("%s: key failed when listing %s: rc = %d\n", + mgs->mgs_obd->obd_name, MOUNT_CONFIGS_DIR, + (int) PTR_ERR(key)); + goto next; + } + key_sz = iops->key_size(env, it); + LASSERT(key_sz > 0); + + /* filter out "." and ".." entries */ + if (key[0] == '.') { + if (key_sz == 1) + goto next; + if (key_sz == 2 && key[1] == '.') + goto next; + } - push_ctxt(&saved, &mgs->mgs_obd->obd_lvfs_ctxt, NULL); - dentry = dget(mgs->mgs_configs_dir); - if (IS_ERR(dentry)) - GOTO(out_pop, rc = PTR_ERR(dentry)); - mnt = mntget(mgs->mgs_vfsmnt); - if (IS_ERR(mnt)) { - l_dput(dentry); - GOTO(out_pop, rc = PTR_ERR(mnt)); - } + /* 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; + } - file = ll_dentry_open(dentry, mnt, O_RDONLY, current_cred()); - if (IS_ERR(file)) - /* dentry_open_it() drops the dentry, mnt refs */ - GOTO(out_pop, rc = PTR_ERR(file)); + memcpy(de->mde_name, key, key_sz); + de->mde_name[key_sz] = 0; - CFS_INIT_LIST_HEAD(dentry_list); - rc = l_readdir(file, dentry_list); - filp_close(file, 0); - /* filp_close->fput() drops the dentry, mnt refs */ + list_add(&de->mde_list, log_list); -out_pop: - pop_ctxt(&saved, &mgs->mgs_obd->obd_lvfs_ctxt, NULL); - RETURN(rc); +next: + rc = iops->next(env, it); + } while (rc == 0); + if (rc > 0) + rc = 0; + + iops->put(env, it); + +fini: + iops->fini(env, it); + if (rc) + CERROR("%s: key failed when listing %s: rc = %d\n", + mgs->mgs_obd->obd_name, MOUNT_CONFIGS_DIR, rc); + RETURN(rc); } /******************** DB functions *********************/ @@ -160,7 +201,7 @@ static int mgs_fsdb_handler(const struct lu_env *env, struct llog_handle *llh, CDEBUG(D_MGS, "OST index for %s is %u (%s)\n", lustre_cfg_string(lcfg, 1), index, lustre_cfg_string(lcfg, 2)); - cfs_set_bit(index, fsdb->fsdb_ost_index_map); + set_bit(index, fsdb->fsdb_ost_index_map); } /* Figure out mdt indicies */ @@ -176,7 +217,7 @@ static int mgs_fsdb_handler(const struct lu_env *env, struct llog_handle *llh, } rc = 0; CDEBUG(D_MGS, "MDT index is %u\n", index); - cfs_set_bit(index, fsdb->fsdb_mdt_index_map); + set_bit(index, fsdb->fsdb_mdt_index_map); fsdb->fsdb_mdt_count ++; } @@ -192,13 +233,13 @@ static int mgs_fsdb_handler(const struct lu_env *env, struct llog_handle *llh, /* * compat to 1.8, check osc name used by MDT0 to OSTs, bz18548. */ - if (!cfs_test_bit(FSDB_OSCNAME18, &fsdb->fsdb_flags) && + if (!test_bit(FSDB_OSCNAME18, &fsdb->fsdb_flags) && lcfg->lcfg_command == LCFG_ATTACH && strcmp(lustre_cfg_string(lcfg, 1), LUSTRE_OSC_NAME) == 0) { if (OBD_OCD_VERSION_MAJOR(d->ver) == 1 && OBD_OCD_VERSION_MINOR(d->ver) <= 8) { CWARN("MDT using 1.8 OSC name scheme\n"); - cfs_set_bit(FSDB_OSCNAME18, &fsdb->fsdb_flags); + set_bit(FSDB_OSCNAME18, &fsdb->fsdb_flags); } } @@ -220,42 +261,37 @@ static int mgs_get_fsdb_from_llog(const struct lu_env *env, struct mgs_device *mgs, struct fs_db *fsdb) { - char *logname; - struct llog_handle *loghandle; - struct lvfs_run_ctxt saved; - struct llog_ctxt *ctxt; - struct mgs_fsdb_handler_data d = { fsdb, 0 }; - int rc, rc2; - ENTRY; + char *logname; + struct llog_handle *loghandle; + struct llog_ctxt *ctxt; + struct mgs_fsdb_handler_data d = { + .fsdb = fsdb, + }; + int rc; + + ENTRY; ctxt = llog_get_context(mgs->mgs_obd, LLOG_CONFIG_ORIG_CTXT); LASSERT(ctxt != NULL); rc = name_create(&logname, fsdb->fsdb_name, "-client"); if (rc) GOTO(out_put, rc); - cfs_mutex_lock(&fsdb->fsdb_mutex); - push_ctxt(&saved, &mgs->mgs_obd->obd_lvfs_ctxt, NULL); - rc = llog_open_create(NULL, ctxt, &loghandle, NULL, logname); + rc = llog_open_create(env, ctxt, &loghandle, NULL, logname); if (rc) GOTO(out_pop, rc); - rc = llog_init_handle(NULL, loghandle, LLOG_F_IS_PLAIN, NULL); + rc = llog_init_handle(env, loghandle, LLOG_F_IS_PLAIN, NULL); if (rc) GOTO(out_close, rc); if (llog_get_size(loghandle) <= 1) - cfs_set_bit(FSDB_LOG_EMPTY, &fsdb->fsdb_flags); + set_bit(FSDB_LOG_EMPTY, &fsdb->fsdb_flags); - rc = llog_process_or_fork(env, loghandle, mgs_fsdb_handler, (void *)&d, - NULL, false); + rc = llog_process(env, loghandle, mgs_fsdb_handler, (void *)&d, NULL); CDEBUG(D_INFO, "get_db = %d\n", rc); out_close: - rc2 = llog_close(NULL, loghandle); - if (!rc) - rc = rc2; + llog_close(env, loghandle); out_pop: - pop_ctxt(&saved, &mgs->mgs_obd->obd_lvfs_ctxt, NULL); - cfs_mutex_unlock(&fsdb->fsdb_mutex); name_destroy(&logname); out_put: llog_ctxt_put(ctxt); @@ -286,10 +322,10 @@ static void mgs_free_fsdb_srpc(struct fs_db *fsdb) struct fs_db *mgs_find_fsdb(struct mgs_device *mgs, char *fsname) { struct fs_db *fsdb; - cfs_list_t *tmp; + struct list_head *tmp; - cfs_list_for_each(tmp, &mgs->mgs_fs_db_list) { - fsdb = cfs_list_entry(tmp, struct fs_db, fsdb_list); + 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; } @@ -306,20 +342,21 @@ static struct fs_db *mgs_new_fsdb(const struct lu_env *env, if (strlen(fsname) >= sizeof(fsdb->fsdb_name)) { CERROR("fsname %s is too long\n", fsname); - RETURN(NULL); + RETURN(ERR_PTR(-EINVAL)); } OBD_ALLOC_PTR(fsdb); if (!fsdb) - RETURN(NULL); + RETURN(ERR_PTR(-ENOMEM)); strcpy(fsdb->fsdb_name, fsname); - cfs_mutex_init(&fsdb->fsdb_mutex); - cfs_set_bit(FSDB_UDESC, &fsdb->fsdb_flags); + mutex_init(&fsdb->fsdb_mutex); + set_bit(FSDB_UDESC, &fsdb->fsdb_flags); fsdb->fsdb_gen = 1; if (strcmp(fsname, MGSSELF_NAME) == 0) { - cfs_set_bit(FSDB_MGS_SELF, &fsdb->fsdb_flags); + set_bit(FSDB_MGS_SELF, &fsdb->fsdb_flags); + fsdb->fsdb_mgs = mgs; } else { OBD_ALLOC(fsdb->fsdb_ost_index_map, INDEX_MAP_SIZE); OBD_ALLOC(fsdb->fsdb_mdt_index_map, INDEX_MAP_SIZE); @@ -341,7 +378,7 @@ static struct fs_db *mgs_new_fsdb(const struct lu_env *env, lproc_mgs_add_live(mgs, fsdb); } - cfs_list_add(&fsdb->fsdb_list, &mgs->mgs_fs_db_list); + list_add(&fsdb->fsdb_list, &mgs->mgs_fs_db_list); RETURN(fsdb); err: @@ -352,15 +389,15 @@ err: name_destroy(&fsdb->fsdb_clilov); name_destroy(&fsdb->fsdb_clilmv); OBD_FREE_PTR(fsdb); - RETURN(NULL); + RETURN(ERR_PTR(rc)); } static void mgs_free_fsdb(struct mgs_device *mgs, struct fs_db *fsdb) { - /* wait for anyone with the sem */ - cfs_mutex_lock(&fsdb->fsdb_mutex); + /* wait for anyone with the sem */ + mutex_lock(&fsdb->fsdb_mutex); lproc_mgs_del_live(mgs, fsdb); - cfs_list_del(&fsdb->fsdb_list); + list_del(&fsdb->fsdb_list); /* deinitialize fsr */ mgs_ir_fini_fs(mgs, fsdb); @@ -372,27 +409,28 @@ static void mgs_free_fsdb(struct mgs_device *mgs, struct fs_db *fsdb) name_destroy(&fsdb->fsdb_clilov); name_destroy(&fsdb->fsdb_clilmv); mgs_free_fsdb_srpc(fsdb); - cfs_mutex_unlock(&fsdb->fsdb_mutex); + mutex_unlock(&fsdb->fsdb_mutex); OBD_FREE_PTR(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; - cfs_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); + struct fs_db *fsdb; + struct list_head *tmp, *tmp2; + + mutex_lock(&mgs->mgs_mutex); + list_for_each_safe(tmp, tmp2, &mgs->mgs_fs_db_list) { + fsdb = list_entry(tmp, struct fs_db, fsdb_list); mgs_free_fsdb(mgs, fsdb); - } - cfs_mutex_unlock(&mgs->mgs_mutex); - return 0; + } + mutex_unlock(&mgs->mgs_mutex); + return 0; } int mgs_find_or_make_fsdb(const struct lu_env *env, @@ -402,27 +440,30 @@ int mgs_find_or_make_fsdb(const struct lu_env *env, struct fs_db *fsdb; int rc = 0; - cfs_mutex_lock(&mgs->mgs_mutex); + ENTRY; + mutex_lock(&mgs->mgs_mutex); fsdb = mgs_find_fsdb(mgs, name); if (fsdb) { - cfs_mutex_unlock(&mgs->mgs_mutex); + mutex_unlock(&mgs->mgs_mutex); *dbh = fsdb; - return 0; + RETURN(0); } CDEBUG(D_MGS, "Creating new db\n"); fsdb = mgs_new_fsdb(env, mgs, name); - cfs_mutex_unlock(&mgs->mgs_mutex); - if (!fsdb) - return -ENOMEM; - - if (!cfs_test_bit(FSDB_MGS_SELF, &fsdb->fsdb_flags)) { + /* lock fsdb_mutex until the db is loaded from llogs */ + if (!IS_ERR(fsdb)) + mutex_lock(&fsdb->fsdb_mutex); + mutex_unlock(&mgs->mgs_mutex); + if (IS_ERR(fsdb)) + RETURN(PTR_ERR(fsdb)); + + if (!test_bit(FSDB_MGS_SELF, &fsdb->fsdb_flags)) { /* populate the db from the client llog */ rc = mgs_get_fsdb_from_llog(env, mgs, fsdb); if (rc) { CERROR("Can't get db from client log %d\n", rc); - mgs_free_fsdb(mgs, fsdb); - return rc; + GOTO(out_free, rc); } } @@ -430,13 +471,18 @@ int mgs_find_or_make_fsdb(const struct lu_env *env, rc = mgs_get_fsdb_srpc_from_llog(env, mgs, fsdb); if (rc) { CERROR("Can't get db from params log %d\n", rc); - mgs_free_fsdb(mgs, fsdb); - return rc; + GOTO(out_free, rc); } + mutex_unlock(&fsdb->fsdb_mutex); *dbh = fsdb; - return 0; + RETURN(0); + +out_free: + mutex_unlock(&fsdb->fsdb_mutex); + mgs_free_fsdb(mgs, fsdb); + return rc; } /* 1 = index in use @@ -459,7 +505,7 @@ int mgs_check_index(const struct lu_env *env, RETURN(rc); } - if (cfs_test_bit(FSDB_LOG_EMPTY, &fsdb->fsdb_flags)) + if (test_bit(FSDB_LOG_EMPTY, &fsdb->fsdb_flags)) RETURN(-1); if (mti->mti_flags & LDD_F_SV_TYPE_OST) @@ -469,7 +515,7 @@ int mgs_check_index(const struct lu_env *env, else RETURN(-EINVAL); - if (cfs_test_bit(mti->mti_stripe_index, imap)) + if (test_bit(mti->mti_stripe_index, imap)) RETURN(1); RETURN(0); } @@ -478,7 +524,7 @@ static __inline__ int next_index(void *index_map, int map_len) { int i; for (i = 0; i < map_len * 8; i++) - if (!cfs_test_bit(i, index_map)) { + if (!test_bit(i, index_map)) { return i; } CERROR("max index %d exceeded.\n", i); @@ -504,37 +550,34 @@ static int mgs_set_index(const struct lu_env *env, RETURN(rc); } + mutex_lock(&fsdb->fsdb_mutex); 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; - if (fsdb->fsdb_mdt_count >= MAX_MDT_COUNT) { - LCONSOLE_ERROR_MSG(0x13f, "The max mdt count" - "is %d\n", (int)MAX_MDT_COUNT); - RETURN(-ERANGE); - } } else { - RETURN(-EINVAL); + GOTO(out_up, rc = -EINVAL); } if (mti->mti_flags & LDD_F_NEED_INDEX) { rc = next_index(imap, INDEX_MAP_SIZE); if (rc == -1) - RETURN(-ERANGE); + 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); - RETURN(-ERANGE); - } + /* 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 (cfs_test_bit(mti->mti_stripe_index, imap)) { + if (test_bit(mti->mti_stripe_index, imap)) { if ((mti->mti_flags & LDD_F_VIRGIN) && !(mti->mti_flags & LDD_F_WRITECONF)) { LCONSOLE_ERROR_MSG(0x140, "Server %s requested index " @@ -542,23 +585,31 @@ static int mgs_set_index(const struct lu_env *env, "use. Use --writeconf to force\n", mti->mti_svname, mti->mti_stripe_index); - RETURN(-EADDRINUSE); + GOTO(out_up, rc = -EADDRINUSE); } else { CDEBUG(D_MGS, "Server %s updating index %d\n", mti->mti_svname, mti->mti_stripe_index); - RETURN(EALREADY); + GOTO(out_up, rc = EALREADY); } } - cfs_set_bit(mti->mti_stripe_index, imap); - cfs_clear_bit(FSDB_LOG_EMPTY, &fsdb->fsdb_flags); - server_make_name(mti->mti_flags & ~(LDD_F_VIRGIN | LDD_F_WRITECONF), - mti->mti_stripe_index, mti->mti_fsname, mti->mti_svname); + set_bit(mti->mti_stripe_index, imap); + clear_bit(FSDB_LOG_EMPTY, &fsdb->fsdb_flags); + mutex_unlock(&fsdb->fsdb_mutex); + if (server_make_name(mti->mti_flags & ~(LDD_F_VIRGIN | LDD_F_WRITECONF), + mti->mti_stripe_index, mti->mti_fsname, + mti->mti_svname)) { + CERROR("unknown server type %#x\n", mti->mti_flags); + return -EINVAL; + } CDEBUG(D_MGS, "Set index for %s to %d\n", mti->mti_svname, mti->mti_stripe_index); RETURN(0); +out_up: + mutex_unlock(&fsdb->fsdb_mutex); + return rc; } struct mgs_modify_lookup { @@ -566,15 +617,124 @@ struct mgs_modify_lookup { 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) { struct mgs_modify_lookup *mml = data; struct cfg_marker *marker; - struct lustre_cfg *lcfg = (struct lustre_cfg *)(rec + 1); - int cfg_len = rec->lrh_len - sizeof(struct llog_rec_hdr) - - sizeof(struct llog_rec_tail); + struct lustre_cfg *lcfg = REC_DATA(rec); + int cfg_len = REC_DATA_LEN(rec); int rc; ENTRY; @@ -606,11 +766,7 @@ static int mgs_modify_handler(const struct lu_env *env, 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_rec(NULL, llh, rec, NULL, 0, (void *)lcfg, - rec->lrh_index); + rc = llog_write(env, llh, rec, rec->lrh_index); if (!rc) mml->mml_modified++; } @@ -618,33 +774,38 @@ static int mgs_modify_handler(const struct lu_env *env, RETURN(rc); } -/* Modify an existing config log record (for CM_SKIP or CM_EXCLUDE) */ +/** + * Modify an existing config log record (for CM_SKIP or CM_EXCLUDE) + * Return code: + * 0 - modified successfully, + * 1 - no modification was done + * negative - error + */ static int mgs_modify(const struct lu_env *env, struct mgs_device *mgs, struct fs_db *fsdb, struct mgs_target_info *mti, char *logname, char *devname, char *comment, int flags) { struct llog_handle *loghandle; - struct lvfs_run_ctxt saved; struct llog_ctxt *ctxt; struct mgs_modify_lookup *mml; - int rc, rc2; + int rc; + ENTRY; - CDEBUG(D_MGS, "modify %s/%s/%s fl=%x\n", logname, devname, comment, - flags); + LASSERT(mutex_is_locked(&fsdb->fsdb_mutex)); + CDEBUG(D_MGS, "modify %s/%s/%s fl=%x\n", logname, devname, comment, + flags); ctxt = llog_get_context(mgs->mgs_obd, LLOG_CONFIG_ORIG_CTXT); LASSERT(ctxt != NULL); - push_ctxt(&saved, &mgs->mgs_obd->obd_lvfs_ctxt, NULL); - rc = llog_open(NULL, ctxt, &loghandle, NULL, logname, - LLOG_OPEN_EXISTS); + 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(NULL, loghandle, LLOG_F_IS_PLAIN, NULL); + rc = llog_init_handle(env, loghandle, LLOG_F_IS_PLAIN, NULL); if (rc) GOTO(out_close, rc); @@ -654,66 +815,103 @@ static int mgs_modify(const struct lu_env *env, struct mgs_device *mgs, 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; mml->mml_modified = 0; - rc = llog_process_or_fork(env, loghandle, mgs_modify_handler, - (void *)mml, NULL, false); - if (!rc && !mml->mml_modified) + rc = llog_process(env, loghandle, mgs_modify_handler, (void *)mml, + NULL); + if (!rc && !mml->mml_modified) rc = 1; + +out_free: OBD_FREE_PTR(mml); out_close: - rc2 = llog_close(NULL, loghandle); - if (!rc) - rc = rc2; + llog_close(env, loghandle); out_pop: - pop_ctxt(&saved, &mgs->mgs_obd->obd_lvfs_ctxt, NULL); if (rc < 0) - CERROR("modify %s/%s failed %d\n", - mti->mti_svname, comment, rc); + CERROR("%s: modify %s/%s failed: rc = %d\n", + mgs->mgs_obd->obd_name, mti->mti_svname, comment, rc); llog_ctxt_put(ctxt); RETURN(rc); } -/******************** config log recording functions *********************/ +/** This structure is passed to mgs_replace_handler */ +struct mgs_replace_uuid_lookup { + /* Nids are replaced for this target device */ + struct mgs_target_info target; + /* Temporary modified llog */ + struct llog_handle *temp_llh; + /* Flag is set if in target block*/ + int in_target_device; + /* Nids already added. Just skip (multiple nids) */ + int device_nids_added; + /* Flag is set if this block should not be copied */ + int skip_it; +}; -static int record_lcfg(const struct lu_env *env, struct llog_handle *llh, - struct lustre_cfg *lcfg) +/** + * Check: a) if block should be skipped + * b) is it target block + * + * \param[in] lcfg + * \param[in] mrul + * + * \retval 0 should not to be skipped + * \retval 1 should to be skipped + */ +static int check_markers(struct lustre_cfg *lcfg, + struct mgs_replace_uuid_lookup *mrul) { - struct lvfs_run_ctxt saved; - struct llog_rec_hdr rec; - int buflen, rc; - struct obd_device *obd = llh->lgh_ctxt->loc_obd; - - if (!lcfg || !llh) - return -ENOMEM; + struct cfg_marker *marker; + + /* Track markers. Find given device */ + if (lcfg->lcfg_command == LCFG_MARKER) { + marker = lustre_cfg_buf(lcfg, 1); + /* Clean llog from records marked as CM_EXCLUDE. + CM_SKIP records are used for "active" command + and can be restored if needed */ + if ((marker->cm_flags & (CM_EXCLUDE | CM_START)) == + (CM_EXCLUDE | CM_START)) { + mrul->skip_it = 1; + return 1; + } - LASSERT(llh->lgh_ctxt); + if ((marker->cm_flags & (CM_EXCLUDE | CM_END)) == + (CM_EXCLUDE | CM_END)) { + mrul->skip_it = 0; + return 1; + } - buflen = lustre_cfg_len(lcfg->lcfg_bufcount, - lcfg->lcfg_buflens); - rec.lrh_len = llog_data_len(buflen); - rec.lrh_type = OBD_CFG_REC; + if (strcmp(mrul->target.mti_svname, marker->cm_tgtname) == 0) { + LASSERT(!(marker->cm_flags & CM_START) || + !(marker->cm_flags & CM_END)); + if (marker->cm_flags & CM_START) { + mrul->in_target_device = 1; + mrul->device_nids_added = 0; + } else if (marker->cm_flags & CM_END) + mrul->in_target_device = 0; + } + } - push_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL); - /* idx = -1 means append */ - rc = llog_write_rec(NULL, llh, &rec, NULL, 0, (void *)lcfg, -1); - pop_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL); - if (rc) - CERROR("failed %d\n", rc); - return rc; + return 0; } 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, @@ -729,43 +927,44 @@ static int record_base(const struct lu_env *env, struct llog_handle *llh, 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; } - static inline int record_add_uuid(const struct lu_env *env, 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, @@ -775,38 +974,456 @@ static inline int record_setup(const struct lu_env *env, return record_base(env, llh, devname, 0, LCFG_SETUP, s1, s2, s3, s4); } +/** + * \retval <0 record processing error + * \retval n record is processed. No need copy original one. + * \retval 0 record is not processed. + */ +static int process_command(const struct lu_env *env, struct lustre_cfg *lcfg, + struct mgs_replace_uuid_lookup *mrul) +{ + int nids_added = 0; + lnet_nid_t nid; + char *ptr; + int rc; + + if (lcfg->lcfg_command == LCFG_ADD_UUID) { + /* LCFG_ADD_UUID command found. Let's skip original command + and add passed nids */ + ptr = mrul->target.mti_params; + while (class_parse_nid(ptr, &nid, &ptr) == 0) { + CDEBUG(D_MGS, "add nid %s with uuid %s, " + "device %s\n", libcfs_nid2str(nid), + mrul->target.mti_params, + mrul->target.mti_svname); + rc = record_add_uuid(env, + mrul->temp_llh, nid, + mrul->target.mti_params); + if (!rc) + nids_added++; + } + + if (nids_added == 0) { + CERROR("No new nids were added, nid %s with uuid %s, " + "device %s\n", libcfs_nid2str(nid), + mrul->target.mti_params, + mrul->target.mti_svname); + RETURN(-ENXIO); + } else { + mrul->device_nids_added = 1; + } + + return nids_added; + } + + if (mrul->device_nids_added && lcfg->lcfg_command == LCFG_SETUP) { + /* LCFG_SETUP command found. UUID should be changed */ + rc = record_setup(env, + mrul->temp_llh, + /* devname the same */ + lustre_cfg_string(lcfg, 0), + /* s1 is not changed */ + lustre_cfg_string(lcfg, 1), + /* new uuid should be + the full nidlist */ + mrul->target.mti_params, + /* s3 is not changed */ + lustre_cfg_string(lcfg, 3), + /* s4 is not changed */ + lustre_cfg_string(lcfg, 4)); + return rc ? rc : 1; + } + + /* Another commands in target device block */ + return 0; +} + +/** + * Handler that called for every record in llog. + * Records are processed in order they placed in llog. + * + * \param[in] llh log to be processed + * \param[in] rec current record + * \param[in] data mgs_replace_uuid_lookup structure + * + * \retval 0 success + */ +static int mgs_replace_handler(const struct lu_env *env, + struct llog_handle *llh, + struct llog_rec_hdr *rec, + void *data) +{ + struct mgs_replace_uuid_lookup *mrul; + struct lustre_cfg *lcfg = REC_DATA(rec); + int cfg_len = REC_DATA_LEN(rec); + int rc; + ENTRY; + + mrul = (struct mgs_replace_uuid_lookup *)data; + + if (rec->lrh_type != OBD_CFG_REC) { + CERROR("unhandled lrh_type: %#x, cmd %x %s %s\n", + rec->lrh_type, lcfg->lcfg_command, + lustre_cfg_string(lcfg, 0), + lustre_cfg_string(lcfg, 1)); + RETURN(-EINVAL); + } + + rc = lustre_cfg_sanity_check(lcfg, cfg_len); + if (rc) { + /* Do not copy any invalidated records */ + GOTO(skip_out, rc = 0); + } + + rc = check_markers(lcfg, mrul); + if (rc || mrul->skip_it) + GOTO(skip_out, rc = 0); + + /* Write to new log all commands outside target device block */ + if (!mrul->in_target_device) + GOTO(copy_out, rc = 0); + + /* Skip all other LCFG_ADD_UUID and LCFG_ADD_CONN records + (failover nids) for this target, assuming that if then + primary is changing then so is the failover */ + if (mrul->device_nids_added && + (lcfg->lcfg_command == LCFG_ADD_UUID || + lcfg->lcfg_command == LCFG_ADD_CONN)) + GOTO(skip_out, rc = 0); + + rc = process_command(env, lcfg, mrul); + if (rc < 0) + RETURN(rc); + + if (rc) + RETURN(0); +copy_out: + /* Record is placed in temporary llog as is */ + 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, + lustre_cfg_string(lcfg, 0), lustre_cfg_string(lcfg, 1)); + RETURN(rc); + +skip_out: + CDEBUG(D_MGS, "Skipped idx=%d, rc=%d, len=%d, cmd %x %s %s\n", + rec->lrh_index, rc, rec->lrh_len, lcfg->lcfg_command, + lustre_cfg_string(lcfg, 0), lustre_cfg_string(lcfg, 1)); + RETURN(rc); +} + +static int mgs_log_is_empty(const struct lu_env *env, + struct mgs_device *mgs, char *name) +{ + struct llog_ctxt *ctxt; + int rc; + + ctxt = llog_get_context(mgs->mgs_obd, LLOG_CONFIG_ORIG_CTXT); + LASSERT(ctxt != NULL); + + rc = llog_is_empty(env, ctxt, name); + llog_ctxt_put(ctxt); + return rc; +} + +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_handle *orig_llh, *backup_llh; + 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; + + CDEBUG(D_MGS, "Replace nids for %s in %s\n", devname, logname); + + ctxt = llog_get_context(mgs, LLOG_CONFIG_ORIG_CTXT); + LASSERT(ctxt != NULL); + + if (mgs_log_is_empty(env, mgs_dev, logname)) { + /* Log is empty. Nothing to replace */ + GOTO(out_put, rc = 0); + } + + OBD_ALLOC(backup, strlen(logname) + strlen(".bak") + 1); + if (backup == NULL) + GOTO(out_put, rc = -ENOMEM); + + sprintf(backup, "%s.bak", logname); + + 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); + } + + /* 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, &cfg_uuid); + if (rc) + GOTO(out_closel, rc); + + /* open backup llog */ + rc = llog_open(env, ctxt, &backup_llh, NULL, backup, + LLOG_OPEN_EXISTS); + if (rc) + GOTO(out_closel, rc); + + rc = llog_init_handle(env, backup_llh, LLOG_F_IS_PLAIN, NULL); + if (rc) + GOTO(out_close, rc); + + if (llog_get_size(backup_llh) <= 1) + GOTO(out_close, rc = 0); + + OBD_ALLOC_PTR(mrul); + if (!mrul) + GOTO(out_close, rc = -ENOMEM); + /* devname is only needed information to replace UUID records */ + strlcpy(mrul->target.mti_svname, devname, + sizeof(mrul->target.mti_svname)); + /* parse nids later */ + strlcpy(mrul->target.mti_params, nids, sizeof(mrul->target.mti_params)); + /* Copy records to this temporary llog */ + mrul->temp_llh = orig_llh; + + rc = llog_process(env, backup_llh, mgs_replace_handler, + (void *)mrul, NULL); + OBD_FREE_PTR(mrul); +out_close: + rc2 = llog_close(NULL, backup_llh); + if (!rc) + rc = rc2; +out_closel: + rc2 = llog_close(NULL, orig_llh); + if (!rc) + rc = rc2; + +out_restore: + if (rc) { + CERROR("%s: llog should be restored: rc = %d\n", + mgs->obd_name, rc); + 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) + 1); + +out_put: + llog_ctxt_put(ctxt); + + if (rc) + CERROR("%s: failed to replace nids in log %s: rc = %d\n", + mgs->obd_name, logname, rc); + + RETURN(rc); +} + +/** + * Parse device name and get file system name and/or device index + * + * \param[in] devname device name (ex. lustre-MDT0000) + * \param[out] fsname file system name(optional) + * \param[out] index device index(optional) + * + * \retval 0 success + */ +static int mgs_parse_devname(char *devname, char *fsname, __u32 *index) +{ + int rc; + ENTRY; + + /* Extract fsname */ + if (fsname) { + rc = server_name2fsname(devname, fsname, NULL); + if (rc < 0) { + CDEBUG(D_MGS, "Device name %s without fsname\n", + devname); + RETURN(-EINVAL); + } + } + + if (index) { + 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) && (non self exports == 0) */ + return (num_devices <= 3) && (num_exports == 0); +} + +static int name_create_mdt(char **logname, char *fsname, int i) +{ + char mdt_index[9]; + + sprintf(mdt_index, "-MDT%04x", i); + return name_create(logname, fsname, mdt_index); +} + +/** + * Replace nids for \a device to \a nids values + * + * \param obd MGS obd device + * \param devname nids need to be replaced for this device + * (ex. lustre-OST0000) + * \param nids nids list (ex. nid1,nid2,nid3) + * + * \retval 0 success + */ +int mgs_replace_nids(const struct lu_env *env, + struct mgs_device *mgs, + char *devname, char *nids) +{ + /* Assume fsname is part of device name */ + char fsname[MTI_NAME_MAXLEN]; + int rc; + __u32 index; + char *logname; + struct fs_db *fsdb; + unsigned int i; + int conn_state; + struct obd_device *mgs_obd = mgs->mgs_obd; + ENTRY; + + /* We can only change NIDs if no other nodes are connected */ + spin_lock(&mgs_obd->obd_dev_lock); + conn_state = mgs_obd->obd_no_conn; + mgs_obd->obd_no_conn = 1; + spin_unlock(&mgs_obd->obd_dev_lock); + + /* We can not change nids if not only MGS is started */ + if (!only_mgs_is_running(mgs_obd)) { + CERROR("Only MGS is allowed to be started\n"); + GOTO(out, rc = -EINPROGRESS); + } + + /* Get fsname and index*/ + rc = mgs_parse_devname(devname, fsname, &index); + if (rc) + GOTO(out, rc); + + rc = mgs_find_or_make_fsdb(env, mgs, fsname, &fsdb); + if (rc) { + CERROR("%s: can't find fsdb: rc = %d\n", fsname, rc); + GOTO(out, rc); + } + + /* Process client llogs */ + name_create(&logname, fsname, "-client"); + rc = mgs_replace_nids_log(env, mgs_obd, fsdb, logname, devname, nids); + name_destroy(&logname); + if (rc) { + CERROR("%s: error while replacing NIDs for %s: rc = %d\n", + fsname, devname, rc); + GOTO(out, rc); + } + + /* Process MDT llogs */ + for (i = 0; i < INDEX_MAP_SIZE * 8; i++) { + if (!test_bit(i, fsdb->fsdb_mdt_index_map)) + continue; + name_create_mdt(&logname, fsname, i); + rc = mgs_replace_nids_log(env, mgs_obd, fsdb, logname, devname, nids); + name_destroy(&logname); + if (rc) + GOTO(out, rc); + } + +out: + spin_lock(&mgs_obd->obd_dev_lock); + mgs_obd->obd_no_conn = conn_state; + spin_unlock(&mgs_obd->obd_dev_lock); + + 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; } @@ -825,8 +1442,8 @@ static inline int record_lov_add(const struct lu_env *env, 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, @@ -834,8 +1451,8 @@ 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, @@ -844,112 +1461,78 @@ 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 int record_start_log(const struct lu_env *env, - struct mgs_device *mgs, - struct llog_handle **llh, char *name) +static int record_start_log(const struct lu_env *env, struct mgs_device *mgs, + struct llog_handle **llh, char *name) { - static struct obd_uuid cfg_uuid = { .uuid = "config_uuid" }; - struct lvfs_run_ctxt saved; - struct llog_ctxt *ctxt; - int rc = 0; + static struct obd_uuid cfg_uuid = { .uuid = "config_uuid" }; + struct llog_ctxt *ctxt; + int rc = 0; + ENTRY; - if (*llh) - GOTO(out, rc = -EBUSY); + if (*llh) + GOTO(out, rc = -EBUSY); ctxt = llog_get_context(mgs->mgs_obd, LLOG_CONFIG_ORIG_CTXT); if (!ctxt) GOTO(out, rc = -ENODEV); LASSERT(ctxt->loc_obd == mgs->mgs_obd); - push_ctxt(&saved, &mgs->mgs_obd->obd_lvfs_ctxt, NULL); - rc = llog_open_create(NULL, ctxt, llh, NULL, name); + rc = llog_open_create(env, ctxt, llh, NULL, name); if (rc) GOTO(out_ctxt, rc); - rc = llog_init_handle(NULL, *llh, LLOG_F_IS_PLAIN, &cfg_uuid); - if (rc) { - llog_close(NULL, *llh); - *llh = NULL; - } + rc = llog_init_handle(env, *llh, LLOG_F_IS_PLAIN, &cfg_uuid); + if (rc) + llog_close(env, *llh); out_ctxt: - pop_ctxt(&saved, &mgs->mgs_obd->obd_lvfs_ctxt, NULL); llog_ctxt_put(ctxt); out: - if (rc) - CERROR("Can't start log %s: %d\n", name, rc); + if (rc) { + CERROR("%s: can't start log %s: rc = %d\n", + mgs->mgs_obd->obd_name, name, rc); + *llh = NULL; + } RETURN(rc); } static int record_end_log(const struct lu_env *env, struct llog_handle **llh) { - struct lvfs_run_ctxt saved; - struct obd_device *obd = (*llh)->lgh_ctxt->loc_obd; - int rc = 0; - - push_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL); - - rc = llog_close(NULL, *llh); - *llh = NULL; - - pop_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL); - RETURN(rc); -} - -static int mgs_log_is_empty(const struct lu_env *env, - struct mgs_device *mgs, char *name) -{ - struct lvfs_run_ctxt saved; - 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); - push_ctxt(&saved, &mgs->mgs_obd->obd_lvfs_ctxt, NULL); - rc = llog_open(NULL, ctxt, &llh, NULL, name, LLOG_OPEN_EXISTS); - if (rc < 0) { - if (rc == -ENOENT) - rc = 0; - GOTO(out_ctxt, rc); - } + int rc; - llog_init_handle(NULL, llh, LLOG_F_IS_PLAIN, NULL); - if (rc) - GOTO(out_close, rc); - rc = llog_get_size(llh); + rc = llog_close(env, *llh); + *llh = NULL; -out_close: - llog_close(NULL, llh); -out_ctxt: - pop_ctxt(&saved, &mgs->mgs_obd->obd_lvfs_ctxt, NULL); - llog_ctxt_put(ctxt); - /* header is record 1 */ - return (rc <= 1); + return rc; } /******************** config "macros" *********************/ @@ -957,25 +1540,23 @@ out_ctxt: /* 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); @@ -987,97 +1568,104 @@ out_end: } /* 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) -{ - cfs_list_t dentry_list; - struct l_linux_dirent *dirent, *n; - char *fsname = mti->mti_fsname; - char *logname; - int rc = 0, len = strlen(fsname); - ENTRY; - - /* 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"); +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) +{ + struct list_head log_list; + struct mgs_direntry *dirent, *n; + char *fsname = mti->mti_fsname; + int rc = 0, len = strlen(fsname); + + 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, &dentry_list); - if (rc) { - CERROR("Can't read %s dir\n", MOUNT_CONFIGS_DIR); - RETURN(rc); - } - /* Could use fsdb index maps instead of directory listing */ - cfs_list_for_each_entry_safe(dirent, n, &dentry_list, lld_list) { - cfs_list_del(&dirent->lld_list); - /* don't write to sptlrpc rule log */ - if (strstr(dirent->lld_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->lld_name, "-client") != NULL) + if (server_only && strstr(dirent->mde_name, "-client") != NULL) goto next; - if (strncmp(fsname, dirent->lld_name, len) == 0) { - CDEBUG(D_MGS, "Changing log %s\n", dirent->lld_name); - /* Erase any old settings of this same parameter */ - mgs_modify(env, mgs, fsdb, mti, dirent->lld_name, - devname, comment, CM_SKIP); - /* Write the new one */ - if (lcfg) { - rc = mgs_write_log_direct(env, mgs, fsdb, - dirent->lld_name, - lcfg, devname, - comment); - if (rc) - CERROR("err %d writing log %s\n", rc, - dirent->lld_name); - } - } + 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: - OBD_FREE(dirent, sizeof(*dirent)); - } + 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); -static int mgs_steal_llog_handler(const struct lu_env *env, - struct llog_handle *llh, - struct llog_rec_hdr *rec, void *data) +static int add_param(char *params, char *key, char *val) +{ + char *start = params + strlen(params); + char *end = params + sizeof(((struct mgs_target_info *)0)->mti_params); + int keylen = 0; + + if (key != NULL) + keylen = strlen(key); + if (start + 1 + keylen + strlen(val) >= end) { + CERROR("params are too long: %s %s%s\n", + params, key != NULL ? key : "", val); + return -EINVAL; + } + + sprintf(start, " %s%s", key != NULL ? key : "", val); + return 0; +} + +/** + * 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; struct mgs_target_info *mti, *tmti; struct fs_db *fsdb; int cfg_len = rec->lrh_len; @@ -1091,13 +1679,16 @@ static int mgs_steal_llog_handler(const struct lu_env *env, 2: found mdc; */ static int last_step = -1; + int cplen = 0; ENTRY; mti = ((struct temp_comp*)data)->comp_mti; tmti = ((struct temp_comp*)data)->comp_tmti; fsdb = ((struct temp_comp*)data)->comp_fsdb; - mgs = ((struct temp_comp*)data)->comp_mgs; + obd = ((struct temp_comp *)data)->comp_obd; + mgs = lu2mgs_dev(obd->obd_lu_dev); + LASSERT(mgs); if (rec->lrh_type != OBD_CFG_REC) { CERROR("unhandled lrh_type: %#x\n", rec->lrh_type); @@ -1112,68 +1703,87 @@ static int mgs_steal_llog_handler(const struct lu_env *env, 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; - nodenid = lcfg->lcfg_nid; + if (lcfg->lcfg_command == LCFG_ADD_UUID) { + __u64 nodenid = lcfg->lcfg_nid; - tmti->mti_nids[tmti->mti_nid_count] = nodenid; - tmti->mti_nid_count++; + if (strlen(tmti->mti_uuid) == 0) { + /* target uuid not set, this config record is before + * LCFG_SETUP, this nid is one of target node nid. + */ + tmti->mti_nids[tmti->mti_nid_count] = nodenid; + tmti->mti_nid_count++; + } else { + char nidstr[LNET_NIDSTR_SIZE]; - RETURN(rc); - } + /* failover node nid */ + libcfs_nid2str_r(nodenid, nidstr, sizeof(nidstr)); + rc = add_param(tmti->mti_params, PARAM_FAILNODE, + nidstr); + } + + RETURN(rc); + } if (lcfg->lcfg_command == LCFG_SETUP) { char *target; @@ -1197,7 +1807,8 @@ static int mgs_steal_llog_handler(const struct lu_env *env, 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); @@ -1239,7 +1850,6 @@ static int mgs_steal_llog_for_mdt_from_client(const struct lu_env *env, struct temp_comp* comp) { struct llog_handle *loghandle; - struct lvfs_run_ctxt saved; struct mgs_target_info *tmti; struct llog_ctxt *ctxt; int rc; @@ -1254,11 +1864,9 @@ static int mgs_steal_llog_for_mdt_from_client(const struct lu_env *env, GOTO(out_ctxt, rc = -ENOMEM); comp->comp_tmti = tmti; - comp->comp_mgs = mgs; + comp->comp_obd = mgs->mgs_obd; - push_ctxt(&saved, &mgs->mgs_obd->obd_lvfs_ctxt, NULL); - - rc = llog_open(NULL, ctxt, &loghandle, NULL, client_name, + rc = llog_open(env, ctxt, &loghandle, NULL, client_name, LLOG_OPEN_EXISTS); if (rc < 0) { if (rc == -ENOENT) @@ -1266,17 +1874,16 @@ static int mgs_steal_llog_for_mdt_from_client(const struct lu_env *env, GOTO(out_pop, rc); } - rc = llog_init_handle(NULL, loghandle, LLOG_F_IS_PLAIN, NULL); + rc = llog_init_handle(env, loghandle, LLOG_F_IS_PLAIN, NULL); 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: - llog_close(NULL, loghandle); + llog_close(env, loghandle); out_pop: - pop_ctxt(&saved, &mgs->mgs_obd->obd_lvfs_ctxt, NULL); OBD_FREE_PTR(tmti); out_ctxt: llog_ctxt_put(ctxt); @@ -1357,9 +1964,9 @@ static int mgs_write_log_lov(const struct lu_env *env, struct mgs_device *mgs, /* 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; @@ -1410,28 +2017,48 @@ static int mgs_write_log_failnids(const struct lu_env *env, #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 ",:,". class_parse_nid() does not + * complain about abnormal inputs like ",:", ":,", + * 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, @@ -1445,9 +2072,10 @@ 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"); @@ -1457,7 +2085,8 @@ static int mgs_write_log_mdc_to_lmv(const struct lu_env *env, 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"); @@ -1477,19 +2106,21 @@ static int mgs_write_log_mdc_to_lmv(const struct lu_env *env, "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); @@ -1514,83 +2145,160 @@ out_free: 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; - - ENTRY; - if (mgs_log_is_empty(env, mgs, logname)) { + 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, 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, @@ -1657,46 +2365,6 @@ out_free: RETURN(rc); } -static inline int name_create_mdt(char **logname, char *fsname, int i) -{ - char mdt_index[9]; - - sprintf(mdt_index, "-MDT%04x", i); - return name_create(logname, fsname, mdt_index); -} - -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 && cfs_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 && cfs_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, @@ -1747,51 +2415,81 @@ static int mgs_write_log_mdt(const struct lu_env *env, #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 && - cfs_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: @@ -1806,33 +2504,42 @@ static int mgs_write_log_osc_to_lov(const struct lu_env *env, 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); - rc = name_create(&oscname, svname, suffix); + + /* 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, ""); + else + rc = name_create(&oscname, svname, suffix); if (rc) GOTO(out_free, rc); + rc = name_create(&oscuuid, oscname, "_UUID"); if (rc) GOTO(out_free, rc); @@ -1840,6 +2547,7 @@ static int mgs_write_log_osc_to_lov(const struct lu_env *env, if (rc) GOTO(out_free, rc); + /* #03 L add_uuid nid=uml1@tcp(0x20000c0a80201) 0: 1:uml1_UUID multihomed (#4) @@ -1855,27 +2563,39 @@ static int mgs_write_log_osc_to_lov(const struct lu_env *env, rc = record_start_log(env, mgs, &llh, logname); if (rc) GOTO(out_free, rc); + /* FIXME these should be a single journal transaction */ rc = record_marker(env, llh, fsdb, CM_START | flags, mti->mti_svname, "add osc"); if (rc) GOTO(out_end, rc); - for (i = 0; i < mti->mti_nid_count; i++) { - CDEBUG(D_MGS, "add nid %s\n", libcfs_nid2str(mti->mti_nids[i])); + + /* 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_client_llog_handler() LCFG_ADD_UUID. + */ + 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); @@ -1941,7 +2661,7 @@ static int mgs_write_log_ost(const struct lu_env *env, 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"); @@ -1954,7 +2674,7 @@ out_end: /* We also have to update the other logs where this osc is part of the lov */ - if (cfs_test_bit(FSDB_OLDLOG14, &fsdb->fsdb_flags)) { + if (test_bit(FSDB_OLDLOG14, &fsdb->fsdb_flags)) { /* If we're upgrading, the old mdt log already has our entry. Let's do a fake one for fun. */ /* Note that we can't add any new failnids, since we don't @@ -1972,7 +2692,7 @@ out_end: /* Add ost to all MDT lov defs */ for (i = 0; i < INDEX_MAP_SIZE * 8; i++){ - if (cfs_test_bit(i, fsdb->fsdb_mdt_index_map)) { + if (test_bit(i, fsdb->fsdb_mdt_index_map)) { char mdt_index[9]; rc = name_create_mdt_and_lov(&logname, &lovname, fsdb, @@ -2007,7 +2727,7 @@ out_end: 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); @@ -2110,7 +2830,7 @@ static int mgs_write_log_add_failnid(const struct lu_env *env, int i; for (i = 0; i < INDEX_MAP_SIZE * 8; i++) { - if (!cfs_test_bit(i, fsdb->fsdb_mdt_index_map)) + if (!test_bit(i, fsdb->fsdb_mdt_index_map)) continue; rc = name_create_mdt(&logname, mti->mti_fsname, i); if (rc) @@ -2136,40 +2856,67 @@ static int mgs_write_log_add_failnid(const struct lu_env *env, 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("%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; + } - LCONSOLE_INFO("%sing parameter %s.%s in log %s\n", del ? "Disabl" : rc ? - "Sett" : "Modify", tgtname, comment, logname); - if (del) - 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); - 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; + 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 */ @@ -2177,8 +2924,9 @@ static int mgs_write_log_sys(const struct lu_env *env, 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; @@ -2209,7 +2957,11 @@ static int mgs_write_log_sys(const struct lu_env *env, 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; @@ -2217,7 +2969,7 @@ static int mgs_write_log_sys(const struct lu_env *env, *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) { @@ -2234,7 +2986,7 @@ static int mgs_write_log_sys(const struct lu_env *env, } } *ptr = sep; - lustre_cfg_free(lcfg); + lustre_cfg_rec_free(lcr); return rc; } @@ -2243,12 +2995,11 @@ static int mgs_write_log_quota(const struct lu_env *env, struct mgs_device *mgs, struct fs_db *fsdb, struct mgs_target_info *mti, char *quota, char *ptr) { - struct lustre_cfg_bufs bufs; - struct lustre_cfg *lcfg; - char *tmp; - char sep; - int cmd = LCFG_PARAM; - int rc; + struct mgs_thread_info *mgi = mgs_env_info(env); + struct llog_cfg_rec *lcr; + char *tmp; + char sep; + int rc, cmd = LCFG_PARAM; /* support only 'meta' and 'data' pools so far */ if (class_match_param(ptr, QUOTA_METAPOOL_NAME, &tmp) != 0 && @@ -2270,9 +3021,12 @@ static int mgs_write_log_quota(const struct lu_env *env, struct mgs_device *mgs, } } - lustre_cfg_bufs_reset(&bufs, NULL); - lustre_cfg_bufs_set_string(&bufs, 1, quota); - lcfg = lustre_cfg_new(cmd, &bufs); + lustre_cfg_bufs_reset(&mgi->mgi_bufs, mti->mti_fsname); + lustre_cfg_bufs_set_string(&mgi->mgi_bufs, 1, quota); + 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; @@ -2283,11 +3037,11 @@ static int mgs_write_log_quota(const struct lu_env *env, struct mgs_device *mgs, * 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, @@ -2296,61 +3050,63 @@ 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; - - /* get comment */ - ptr = strchr(param, '='); - LASSERT(ptr); - len = ptr - param; - - OBD_ALLOC(comment, len + 1); - if (comment == NULL) - RETURN(-ENOMEM); - strncpy(comment, param, len); - comment[len] = '\0'; + 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; + + ENTRY; + + /* get comment */ + ptr = strchr(param, '='); + LASSERT(ptr != NULL); + len = ptr - param; + + OBD_ALLOC(comment, len + 1); + if (comment == NULL) + RETURN(-ENOMEM); + strncpy(comment, param, len); + comment[len] = '\0'; - /* prepare lcfg */ + /* 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, @@ -2372,10 +3128,10 @@ static int mgs_srpc_set_param_udesc_mem(struct fs_db *fsdb, goto error_out; if (strcmp(ptr, "yes") == 0) { - cfs_set_bit(FSDB_UDESC, &fsdb->fsdb_flags); + set_bit(FSDB_UDESC, &fsdb->fsdb_flags); CWARN("Enable user descriptor shipping from client to MDT\n"); } else if (strcmp(ptr, "no") == 0) { - cfs_clear_bit(FSDB_UDESC, &fsdb->fsdb_flags); + clear_bit(FSDB_UDESC, &fsdb->fsdb_flags); CWARN("Disable user descriptor shipping from client to MDT\n"); } else { *(ptr - 1) = '='; @@ -2419,7 +3175,7 @@ static int mgs_srpc_set_param_mem(struct fs_db *fsdb, RETURN(rc); /* mgs rules implies must be mgc->mgs */ - if (cfs_test_bit(FSDB_MGS_SELF, &fsdb->fsdb_flags)) { + if (test_bit(FSDB_MGS_SELF, &fsdb->fsdb_flags)) { if ((rule.sr_from != LUSTRE_SP_MGC && rule.sr_from != LUSTRE_SP_ANY) || (rule.sr_to != LUSTRE_SP_MGS && @@ -2464,6 +3220,9 @@ static int mgs_srpc_set_param_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; } @@ -2503,7 +3262,7 @@ static int mgs_srpc_set_param(const struct lu_env *env, if (rc) goto out_free; - if (cfs_test_bit(FSDB_MGS_SELF, &fsdb->fsdb_flags)) { + if (test_bit(FSDB_MGS_SELF, &fsdb->fsdb_flags)) { /* * for mgs rules, make them effective immediately. */ @@ -2528,7 +3287,7 @@ static int mgs_srpc_read_handler(const struct lu_env *env, { struct mgs_srpc_read_data *msrd = data; struct cfg_marker *marker; - struct lustre_cfg *lcfg = (struct lustre_cfg *)(rec + 1); + struct lustre_cfg *lcfg = REC_DATA(rec); char *svname, *param; int cfg_len, rc; ENTRY; @@ -2538,8 +3297,7 @@ static int mgs_srpc_read_handler(const struct lu_env *env, 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) { @@ -2591,7 +3349,6 @@ int mgs_get_fsdb_srpc_from_llog(const struct lu_env *env, struct fs_db *fsdb) { struct llog_handle *llh = NULL; - struct lvfs_run_ctxt saved; struct llog_ctxt *ctxt; char *logname; struct mgs_srpc_read_data msrd; @@ -2609,17 +3366,15 @@ int mgs_get_fsdb_srpc_from_llog(const struct lu_env *env, if (mgs_log_is_empty(env, mgs, logname)) GOTO(out, rc = 0); - push_ctxt(&saved, &mgs->mgs_obd->obd_lvfs_ctxt, NULL); - - rc = llog_open(NULL, ctxt, &llh, NULL, logname, + rc = llog_open(env, ctxt, &llh, NULL, logname, LLOG_OPEN_EXISTS); if (rc < 0) { if (rc == -ENOENT) rc = 0; - GOTO(out_pop, rc); + GOTO(out, rc); } - rc = llog_init_handle(NULL, llh, LLOG_F_IS_PLAIN, NULL); + rc = llog_init_handle(env, llh, LLOG_F_IS_PLAIN, NULL); if (rc) GOTO(out_close, rc); @@ -2629,13 +3384,11 @@ int mgs_get_fsdb_srpc_from_llog(const struct lu_env *env, msrd.msrd_fsdb = fsdb; msrd.msrd_skip = 0; - rc = llog_process_or_fork(env, llh, mgs_srpc_read_handler, - (void *)&msrd, NULL, false); + rc = llog_process(env, llh, mgs_srpc_read_handler, (void *)&msrd, + NULL); out_close: - llog_close(NULL, llh); -out_pop: - pop_ctxt(&saved, &mgs->mgs_obd->obd_lvfs_ctxt, NULL); + llog_close(env, llh); out: llog_ctxt_put(ctxt); name_destroy(&logname); @@ -2657,7 +3410,7 @@ static int mgs_write_log_param(const struct lu_env *env, 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 @@ -2713,61 +3466,77 @@ static int mgs_write_log_param(const struct lu_env *env, 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 = -EINVAL); + } + } + + 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++) { - if (!cfs_test_bit(i, fsdb->fsdb_mdt_index_map)) - continue; + 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; 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); - if (cfs_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. */ - } + 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/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 */ @@ -2814,7 +3583,7 @@ static int mgs_write_log_param(const struct lu_env *env, (class_match_param(ptr, PARAM_LLITE, NULL) == 0)) { char *cname; - if (cfs_test_bit(FSDB_OLDLOG14, &fsdb->fsdb_flags)) { + if (test_bit(FSDB_OLDLOG14, &fsdb->fsdb_flags)) { LCONSOLE_ERROR_MSG(0x148, "Upgraded client logs for %s" " cannot be modified. Consider" " updating the configuration with" @@ -2836,9 +3605,22 @@ static int mgs_write_log_param(const struct lu_env *env, 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); @@ -2852,7 +3634,7 @@ static int mgs_write_log_param(const struct lu_env *env, int i; for (i = 0; i < INDEX_MAP_SIZE * 8; i++){ - if (!cfs_test_bit(i, fsdb->fsdb_mdt_index_map)) + if (!test_bit(i, fsdb->fsdb_mdt_index_map)) continue; name_destroy(&cname); rc = name_create_mdt_osc(&cname, mti->mti_svname, @@ -2874,13 +3656,85 @@ static int mgs_write_log_param(const struct lu_env *env, } } } - 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; @@ -2897,7 +3751,7 @@ static int mgs_write_log_param(const struct lu_env *env, goto active_err; if (rc & LDD_F_SV_ALL) { for (i = 0; i < INDEX_MAP_SIZE * 8; i++) { - if (!cfs_test_bit(i, + if (!test_bit(i, fsdb->fsdb_mdt_index_map)) continue; rc = name_create_mdt(&logname, @@ -2906,90 +3760,91 @@ static int mgs_write_log_param(const struct lu_env *env, 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; - - 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); - - 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(). */ - - cfs_mutex_lock(&fsdb->fsdb_mutex); - rc = mgs_write_log_add_failnid(obd, fsdb, mti); - cfs_mutex_unlock(&fsdb->fsdb_mutex); - - RETURN(rc); -#endif - return 0; -} + char *buf, *params; + int rc = -EINVAL; -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; + ENTRY; - /* set/check the new target index */ + /* 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); - } + if (rc < 0) + RETURN(rc); if (rc == EALREADY) { LCONSOLE_WARN("Found index %d for %s, updating log\n", @@ -3000,9 +3855,13 @@ int mgs_write_log_target(const struct lu_env *env, 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; } - cfs_mutex_lock(&fsdb->fsdb_mutex); + 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 & (LDD_F_VIRGIN | LDD_F_UPGRADE14 | LDD_F_WRITECONF)) { @@ -3051,35 +3910,31 @@ int mgs_write_log_target(const struct lu_env *env, OBD_FREE(buf, strlen(mti->mti_params) + 1); out_up: - cfs_mutex_unlock(&fsdb->fsdb_mutex); + mutex_unlock(&fsdb->fsdb_mutex); RETURN(rc); } int mgs_erase_log(const struct lu_env *env, struct mgs_device *mgs, char *name) { - struct lvfs_run_ctxt saved; struct llog_ctxt *ctxt; int rc = 0; - struct obd_device *obd = mgs->mgs_obd; - ctxt = llog_get_context(obd, LLOG_CONFIG_ORIG_CTXT); + ctxt = llog_get_context(mgs->mgs_obd, LLOG_CONFIG_ORIG_CTXT); if (ctxt == NULL) { CERROR("%s: MGS config context doesn't exist\n", - obd->obd_name); + mgs->mgs_obd->obd_name); rc = -ENODEV; } else { - push_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL); - rc = llog_erase(NULL, ctxt, NULL, name); + rc = llog_erase(env, ctxt, NULL, name); /* llog may not exist */ if (rc == -ENOENT) rc = 0; - pop_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL); llog_ctxt_put(ctxt); } if (rc) - CERROR("%s: failed to clear log %s: %d\n", obd->obd_name, - name, rc); + CERROR("%s: failed to clear log %s: %d\n", + mgs->mgs_obd->obd_name, name, rc); return rc; } @@ -3087,46 +3942,78 @@ int mgs_erase_log(const struct lu_env *env, struct mgs_device *mgs, char *name) /* erase all logs for the given fs */ int mgs_erase_logs(const struct lu_env *env, struct mgs_device *mgs, char *fsname) { - struct fs_db *fsdb; - cfs_list_t dentry_list; - struct l_linux_dirent *dirent, *n; - int rc, len = strlen(fsname); - char *suffix; - ENTRY; - - /* Find all the logs in the CONFIGS directory */ - rc = class_dentry_readdir(env, mgs, &dentry_list); - if (rc) { - CERROR("Can't read %s dir\n", MOUNT_CONFIGS_DIR); - RETURN(rc); - } + struct fs_db *fsdb; + struct list_head log_list; + struct mgs_direntry *dirent, *n; + int rc, len = strlen(fsname); + char *suffix; + ENTRY; + + /* Find all the logs in the CONFIGS directory */ + rc = class_dentry_readdir(env, mgs, &log_list); + if (rc) + RETURN(rc); - cfs_mutex_lock(&mgs->mgs_mutex); + mutex_lock(&mgs->mgs_mutex); /* Delete the fs db */ fsdb = mgs_find_fsdb(mgs, fsname); if (fsdb) mgs_free_fsdb(mgs, fsdb); - cfs_list_for_each_entry_safe(dirent, n, &dentry_list, lld_list) { - cfs_list_del(&dirent->lld_list); - suffix = strrchr(dirent->lld_name, '-'); - if (suffix != NULL) { - if ((len == suffix - dirent->lld_name) && - (strncmp(fsname, dirent->lld_name, len) == 0)) { - CDEBUG(D_MGS, "Removing log %s\n", - dirent->lld_name); - mgs_erase_log(env, mgs, dirent->lld_name); - } - } - OBD_FREE(dirent, sizeof(*dirent)); - } - - cfs_mutex_unlock(&mgs->mgs_mutex); + mutex_unlock(&mgs->mgs_mutex); + + 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->mde_name) && + (strncmp(fsname, dirent->mde_name, len) == 0)) { + CDEBUG(D_MGS, "Removing log %s\n", + dirent->mde_name); + mgs_erase_log(env, mgs, dirent->mde_name); + } + } + mgs_direntry_free(dirent); + } 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); +} + /* from llog_swab */ static void print_lustre_cfg(struct lustre_cfg *lcfg) { @@ -3151,6 +4038,47 @@ static void print_lustre_cfg(struct lustre_cfg *lcfg) EXIT; } +/* Setup _mgs fsdb and log + */ +int mgs__mgs_fsdb_setup(const struct lu_env *env, struct mgs_device *mgs, + struct fs_db *fsdb) +{ + int rc; + ENTRY; + + rc = mgs_find_or_make_fsdb(env, mgs, MGSSELF_NAME, &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) +{ + struct llog_handle *params_llh = NULL; + int rc; + ENTRY; + + rc = mgs_find_or_make_fsdb(env, mgs, PARAMS_FILENAME, &fsdb); + if (fsdb != NULL) { + mutex_lock(&fsdb->fsdb_mutex); + rc = record_start_log(env, mgs, ¶ms_llh, PARAMS_FILENAME); + if (rc == 0) + rc = record_end_log(env, ¶ms_llh); + mutex_unlock(&fsdb->fsdb_mutex); + } + + RETURN(rc); +} + +/* Cleanup params fsdb and log + */ +int mgs_params_fsdb_cleanup(const struct lu_env *env, struct mgs_device *mgs) +{ + return mgs_erase_logs(env, mgs, PARAMS_FILENAME); +} + /* 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 @@ -3158,13 +4086,14 @@ static void print_lustre_cfg(struct lustre_cfg *lcfg) 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; + struct fs_db *fsdb; + struct mgs_target_info *mti; char *devname, *param; - char *ptr, *tmp; - __u32 index; - int rc = 0; - ENTRY; + char *ptr; + const char *tmp; + __u32 index; + int rc = 0; + ENTRY; print_lustre_cfg(lcfg); @@ -3186,27 +4115,27 @@ int mgs_setparam(const struct lu_env *env, struct mgs_device *mgs, RETURN(-ENOSYS); } - /* Extract fsname */ - ptr = strrchr(devname, '-'); - memset(fsname, 0, MTI_NAME_MAXLEN); - if (ptr && (server_name2index(ptr, &index, NULL) >= 0)) { + rc = mgs_parse_devname(devname, fsname, NULL); + if (rc == 0 && !mgs_parse_devname(devname, NULL, &index)) { /* param related to llite isn't allowed to set by OST or MDT */ - if (strncmp(param, PARAM_LLITE, sizeof(PARAM_LLITE)) == 0) + if (rc == 0 && strncmp(param, PARAM_LLITE, + sizeof(PARAM_LLITE) - 1) == 0) RETURN(-EINVAL); - - strncpy(fsname, devname, ptr - devname); } else { /* assume devname is the fsname */ - strncpy(fsname, devname, MTI_NAME_MAXLEN); + strlcpy(fsname, devname, MTI_NAME_MAXLEN); } - fsname[MTI_NAME_MAXLEN - 1] = 0; 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 (!cfs_test_bit(FSDB_MGS_SELF, &fsdb->fsdb_flags) && - cfs_test_bit(FSDB_LOG_EMPTY, &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); @@ -3217,9 +4146,15 @@ int mgs_setparam(const struct lu_env *env, struct mgs_device *mgs, 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)); + 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 */ @@ -3229,20 +4164,26 @@ int mgs_setparam(const struct lu_env *env, struct mgs_device *mgs, if (server_make_name(rc, mti->mti_stripe_index, mti->mti_fsname, 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; - - cfs_mutex_lock(&fsdb->fsdb_mutex); - rc = mgs_write_log_param(env, mgs, fsdb, mti, mti->mti_params); - cfs_mutex_unlock(&fsdb->fsdb_mutex); - - /* - * 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); @@ -3250,9 +4191,9 @@ out: 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; @@ -3261,18 +4202,103 @@ static int mgs_write_log_pool(const struct lu_env *env, 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_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) @@ -3283,6 +4309,7 @@ int mgs_pool_cmd(const struct lu_env *env, struct mgs_device *mgs, char *label = NULL, *canceled_label = NULL; int label_sz; struct mgs_target_info *mti = NULL; + bool checked = false; int rc, i; ENTRY; @@ -3291,7 +4318,7 @@ int mgs_pool_cmd(const struct lu_env *env, struct mgs_device *mgs, CERROR("Can't get db for %s\n", fsname); RETURN(rc); } - if (cfs_test_bit(FSDB_LOG_EMPTY, &fsdb->fsdb_flags)) { + if (test_bit(FSDB_LOG_EMPTY, &fsdb->fsdb_flags)) { CERROR("%s is not defined\n", fsname); mgs_free_fsdb(mgs, fsdb); RETURN(-EINVAL); @@ -3345,29 +4372,39 @@ int mgs_pool_cmd(const struct lu_env *env, struct mgs_device *mgs, break; } - cfs_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)); + mutex_lock(&fsdb->fsdb_mutex); /* write pool def to all MDT logs */ for (i = 0; i < INDEX_MAP_SIZE * 8; i++) { - if (cfs_test_bit(i, fsdb->fsdb_mdt_index_map)) { + if (test_bit(i, fsdb->fsdb_mdt_index_map)) { rc = name_create_mdt_and_lov(&logname, &lovname, fsdb, i); if (rc) { - cfs_mutex_unlock(&fsdb->fsdb_mutex); + mutex_unlock(&fsdb->fsdb_mutex); GOTO(out_mti, rc); } - if (canceled_label != NULL) { - strcpy(mti->mti_svname, "lov pool"); + + if (!checked && (canceled_label == NULL)) { + rc = mgs_check_marker(env, mgs, fsdb, mti, + logname, lovname, label); + if (rc) { + name_destroy(&logname); + name_destroy(&lovname); + mutex_unlock(&fsdb->fsdb_mutex); + GOTO(out_mti, + rc = (rc == LLOG_PROC_BREAK ? + -EEXIST : rc)); + } + checked = true; + } + 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, @@ -3377,7 +4414,7 @@ int mgs_pool_cmd(const struct lu_env *env, struct mgs_device *mgs, name_destroy(&logname); name_destroy(&lovname); if (rc) { - cfs_mutex_unlock(&fsdb->fsdb_mutex); + mutex_unlock(&fsdb->fsdb_mutex); GOTO(out_mti, rc); } } @@ -3385,14 +4422,25 @@ int mgs_pool_cmd(const struct lu_env *env, struct mgs_device *mgs, rc = name_create(&logname, fsname, "-client"); if (rc) { - cfs_mutex_unlock(&fsdb->fsdb_mutex); + mutex_unlock(&fsdb->fsdb_mutex); 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); + mutex_unlock(&fsdb->fsdb_mutex); + 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) { - cfs_mutex_unlock(&fsdb->fsdb_mutex); + mutex_unlock(&fsdb->fsdb_mutex); name_destroy(&logname); GOTO(out_mti, rc); } @@ -3400,7 +4448,7 @@ int mgs_pool_cmd(const struct lu_env *env, struct mgs_device *mgs, rc = mgs_write_log_pool(env, mgs, logname, fsdb, fsdb->fsdb_clilov, cmd, fsname, poolname, ostname, label); - cfs_mutex_unlock(&fsdb->fsdb_mutex); + mutex_unlock(&fsdb->fsdb_mutex); name_destroy(&logname); /* request for update */ mgs_revoke_lock(mgs, fsdb, CONFIG_T_CONFIG); @@ -3416,64 +4464,3 @@ out_label: OBD_FREE(label, label_sz); return rc; } - -#if 0 -/******************** unused *********************/ -static int mgs_backup_llog(struct obd_device *obd, char* fsname) -{ - struct file *filp, *bak_filp; - struct lvfs_run_ctxt saved; - char *logname, *buf; - loff_t soff = 0 , doff = 0; - int count = 4096, len; - int rc = 0; - - OBD_ALLOC(logname, PATH_MAX); - if (logname == NULL) - return -ENOMEM; - - OBD_ALLOC(buf, count); - if (!buf) - GOTO(out , rc = -ENOMEM); - - len = snprintf(logname, PATH_MAX, "%s/%s.bak", - MOUNT_CONFIGS_DIR, fsname); - - if (len >= PATH_MAX - 1) { - GOTO(out, -ENAMETOOLONG); - } - - push_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL); - - bak_filp = l_filp_open(logname, O_RDWR|O_CREAT|O_TRUNC, 0660); - if (IS_ERR(bak_filp)) { - rc = PTR_ERR(bak_filp); - CERROR("backup logfile open %s: %d\n", logname, rc); - GOTO(pop, rc); - } - sprintf(logname, "%s/%s", MOUNT_CONFIGS_DIR, fsname); - filp = l_filp_open(logname, O_RDONLY, 0); - if (IS_ERR(filp)) { - rc = PTR_ERR(filp); - CERROR("logfile open %s: %d\n", logname, rc); - GOTO(close1f, rc); - } - - while ((rc = lustre_fread(filp, buf, count, &soff)) > 0) { - rc = lustre_fwrite(bak_filp, buf, count, &doff); - break; - } - - filp_close(filp, 0); -close1f: - filp_close(bak_filp, 0); -pop: - pop_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL); -out: - if (buf) - OBD_FREE(buf, count); - OBD_FREE(logname, PATH_MAX); - return rc; -} - -#endif