4 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License version 2 only,
8 * as published by the Free Software Foundation.
10 * This program is distributed in the hope that it will be useful, but
11 * WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * General Public License version 2 for more details (a copy is included
14 * in the LICENSE file that accompanied this code).
16 * You should have received a copy of the GNU General Public License
17 * version 2 along with this program; If not, see
18 * http://www.gnu.org/licenses/gpl-2.0.html
23 * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved.
24 * Use is subject to license terms.
26 * Copyright (c) 2011, 2017, Intel Corporation.
29 * This file is part of Lustre, http://www.lustre.org/
30 * Lustre is a trademark of Sun Microsystems, Inc.
32 * lustre/mgs/mgs_llog.c
34 * Lustre Management Server (mgs) config llog creation
36 * Author: Nathan Rutman <nathan@clusterfs.com>
37 * Author: Alex Zhuravlev <bzzz@whamcloud.com>
38 * Author: Mikhail Pershin <tappro@whamcloud.com>
41 #define DEBUG_SUBSYSTEM S_MGS
42 #define D_MGS D_CONFIG
45 #include <uapi/linux/lustre/lustre_ioctl.h>
46 #include <uapi/linux/lustre/lustre_param.h>
47 #include <lustre_sec.h>
48 #include <lustre_quota.h>
49 #include <lustre_sec.h>
51 #include "mgs_internal.h"
53 /********************** Class functions ********************/
56 * Find all logs in CONFIG directory and link then into list.
58 * \param[in] env pointer to the thread context
59 * \param[in] mgs pointer to the mgs device
60 * \param[out] log_list the list to hold the found llog name entry
62 * \retval 0 for success
63 * \retval negative error number on failure
65 int class_dentry_readdir(const struct lu_env *env, struct mgs_device *mgs,
66 struct list_head *log_list)
68 struct dt_object *dir = mgs->mgs_configs_dir;
69 const struct dt_it_ops *iops;
71 struct mgs_direntry *de;
74 size_t suffix_len = sizeof(".bak") - 1;
76 INIT_LIST_HEAD(log_list);
79 LASSERT(dir->do_index_ops);
81 iops = &dir->do_index_ops->dio_it;
82 it = iops->init(env, dir, LUDA_64BITHASH);
86 rc = iops->load(env, it, 0);
92 key = (void *)iops->key(env, it);
94 CERROR("%s: key failed when listing %s: rc = %d\n",
95 mgs->mgs_obd->obd_name, MOUNT_CONFIGS_DIR,
99 key_sz = iops->key_size(env, it);
102 /* filter out "." and ".." entries */
106 if (key_sz == 2 && key[1] == '.')
110 /* filter out ".bak" files */
111 if (key_sz >= suffix_len &&
112 !memcmp(".bak", key + key_sz - suffix_len, suffix_len)) {
113 CDEBUG(D_MGS, "Skipping backup file %.*s\n",
118 de = mgs_direntry_alloc(key_sz + 1);
124 memcpy(de->mde_name, key, key_sz);
125 de->mde_name[key_sz] = 0;
127 list_add(&de->mde_list, log_list);
130 rc = iops->next(env, it);
140 struct mgs_direntry *n;
142 CERROR("%s: key failed when listing %s: rc = %d\n",
143 mgs->mgs_obd->obd_name, MOUNT_CONFIGS_DIR, rc);
145 list_for_each_entry_safe(de, n, log_list, mde_list) {
146 list_del_init(&de->mde_list);
147 mgs_direntry_free(de);
154 /******************** DB functions *********************/
156 static inline int name_create(char **newname, char *prefix, char *suffix)
159 OBD_ALLOC(*newname, strlen(prefix) + strlen(suffix) + 1);
162 sprintf(*newname, "%s%s", prefix, suffix);
166 static inline void name_destroy(char **name)
169 OBD_FREE(*name, strlen(*name) + 1);
173 struct mgs_fsdb_handler_data
179 /* from the (client) config log, figure out:
180 1. which ost's/mdt's are configured (by index)
181 2. what the last config step is
182 3. COMPAT_18 osc name
184 /* It might be better to have a separate db file, instead of parsing the info
185 out of the client log. This is slow and potentially error-prone. */
186 static int mgs_fsdb_handler(const struct lu_env *env, struct llog_handle *llh,
187 struct llog_rec_hdr *rec, void *data)
189 struct mgs_fsdb_handler_data *d = data;
190 struct fs_db *fsdb = d->fsdb;
191 int cfg_len = rec->lrh_len;
192 char *cfg_buf = (char*) (rec + 1);
193 struct lustre_cfg *lcfg;
198 if (rec->lrh_type != OBD_CFG_REC) {
199 CERROR("unhandled lrh_type: %#x\n", rec->lrh_type);
203 rc = lustre_cfg_sanity_check(cfg_buf, cfg_len);
205 CERROR("Insane cfg\n");
209 lcfg = (struct lustre_cfg *)cfg_buf;
211 CDEBUG(D_INFO, "cmd %x %s %s\n", lcfg->lcfg_command,
212 lustre_cfg_string(lcfg, 0), lustre_cfg_string(lcfg, 1));
214 /* Figure out ost indicies */
215 /* lov_modify_tgts add 0:lov1 1:ost1_UUID 2(index):0 3(gen):1 */
216 if (lcfg->lcfg_command == LCFG_LOV_ADD_OBD ||
217 lcfg->lcfg_command == LCFG_LOV_DEL_OBD) {
218 rc = kstrtouint(lustre_cfg_string(lcfg, 2), 10, &index);
222 CDEBUG(D_MGS, "OST index for %s is %u (%s)\n",
223 lustre_cfg_string(lcfg, 1), index,
224 lustre_cfg_string(lcfg, 2));
225 set_bit(index, fsdb->fsdb_ost_index_map);
228 /* Figure out mdt indicies */
229 /* attach 0:MDC_uml1_mdsA_MNT_client 1:mdc 2:1d834_MNT_client_03f */
230 if ((lcfg->lcfg_command == LCFG_ATTACH) &&
231 (strcmp(lustre_cfg_string(lcfg, 1), LUSTRE_MDC_NAME) == 0)) {
232 rc = server_name2index(lustre_cfg_string(lcfg, 0),
234 if (rc != LDD_F_SV_TYPE_MDT) {
235 CWARN("Unparsable MDC name %s, assuming index 0\n",
236 lustre_cfg_string(lcfg, 0));
240 CDEBUG(D_MGS, "MDT index is %u\n", index);
241 if (!test_bit(index, fsdb->fsdb_mdt_index_map)) {
242 set_bit(index, fsdb->fsdb_mdt_index_map);
243 fsdb->fsdb_mdt_count++;
248 * figure out the old config. fsdb_gen = 0 means old log
249 * It is obsoleted and not supported anymore
251 if (fsdb->fsdb_gen == 0) {
252 CERROR("Old config format is not supported\n");
257 * compat to 1.8, check osc name used by MDT0 to OSTs, bz18548.
259 if (!test_bit(FSDB_OSCNAME18, &fsdb->fsdb_flags) &&
260 lcfg->lcfg_command == LCFG_ATTACH &&
261 strcmp(lustre_cfg_string(lcfg, 1), LUSTRE_OSC_NAME) == 0) {
262 if (OBD_OCD_VERSION_MAJOR(d->ver) == 1 &&
263 OBD_OCD_VERSION_MINOR(d->ver) <= 8) {
264 CWARN("MDT using 1.8 OSC name scheme\n");
265 set_bit(FSDB_OSCNAME18, &fsdb->fsdb_flags);
269 if (lcfg->lcfg_command == LCFG_MARKER) {
270 struct cfg_marker *marker;
271 marker = lustre_cfg_buf(lcfg, 1);
273 d->ver = marker->cm_vers;
275 /* Keep track of the latest marker step */
276 fsdb->fsdb_gen = max(fsdb->fsdb_gen, marker->cm_step);
282 /* fsdb->fsdb_mutex is already held in mgs_find_or_make_fsdb*/
283 static int mgs_get_fsdb_from_llog(const struct lu_env *env,
284 struct mgs_device *mgs,
288 struct llog_handle *loghandle;
289 struct llog_ctxt *ctxt;
290 struct mgs_fsdb_handler_data d = {
297 ctxt = llog_get_context(mgs->mgs_obd, LLOG_CONFIG_ORIG_CTXT);
298 LASSERT(ctxt != NULL);
299 rc = name_create(&logname, fsdb->fsdb_name, "-client");
302 rc = llog_open_create(env, ctxt, &loghandle, NULL, logname);
306 rc = llog_init_handle(env, loghandle, LLOG_F_IS_PLAIN, NULL);
310 if (llog_get_size(loghandle) <= 1)
311 set_bit(FSDB_LOG_EMPTY, &fsdb->fsdb_flags);
313 rc = llog_process(env, loghandle, mgs_fsdb_handler, (void *)&d, NULL);
314 CDEBUG(D_INFO, "get_db = %d\n", rc);
316 llog_close(env, loghandle);
318 name_destroy(&logname);
325 static void mgs_free_fsdb_srpc(struct fs_db *fsdb)
327 struct mgs_tgt_srpc_conf *tgtconf;
329 /* free target-specific rules */
330 while (fsdb->fsdb_srpc_tgt) {
331 tgtconf = fsdb->fsdb_srpc_tgt;
332 fsdb->fsdb_srpc_tgt = tgtconf->mtsc_next;
334 LASSERT(tgtconf->mtsc_tgt);
336 sptlrpc_rule_set_free(&tgtconf->mtsc_rset);
337 OBD_FREE(tgtconf->mtsc_tgt, strlen(tgtconf->mtsc_tgt) + 1);
338 OBD_FREE_PTR(tgtconf);
341 /* free general rules */
342 sptlrpc_rule_set_free(&fsdb->fsdb_srpc_gen);
345 static void mgs_unlink_fsdb(struct mgs_device *mgs, struct fs_db *fsdb)
347 mutex_lock(&mgs->mgs_mutex);
348 if (likely(!list_empty(&fsdb->fsdb_list))) {
349 LASSERTF(atomic_read(&fsdb->fsdb_ref) >= 2,
350 "Invalid ref %d on %s\n",
351 atomic_read(&fsdb->fsdb_ref),
354 list_del_init(&fsdb->fsdb_list);
355 /* Drop the reference on the list.*/
356 mgs_put_fsdb(mgs, fsdb);
358 mutex_unlock(&mgs->mgs_mutex);
361 /* The caller must hold mgs->mgs_mutex. */
362 static inline struct fs_db *
363 mgs_find_fsdb_noref(struct mgs_device *mgs, const char *fsname)
366 struct list_head *tmp;
368 list_for_each(tmp, &mgs->mgs_fs_db_list) {
369 fsdb = list_entry(tmp, struct fs_db, fsdb_list);
370 if (strcmp(fsdb->fsdb_name, fsname) == 0)
377 /* The caller must hold mgs->mgs_mutex. */
378 static void mgs_remove_fsdb_by_name(struct mgs_device *mgs, const char *name)
382 fsdb = mgs_find_fsdb_noref(mgs, name);
384 list_del_init(&fsdb->fsdb_list);
385 /* Drop the reference on the list.*/
386 mgs_put_fsdb(mgs, fsdb);
390 /* The caller must hold mgs->mgs_mutex. */
391 struct fs_db *mgs_find_fsdb(struct mgs_device *mgs, const char *fsname)
395 fsdb = mgs_find_fsdb_noref(mgs, fsname);
397 atomic_inc(&fsdb->fsdb_ref);
402 /* The caller must hold mgs->mgs_mutex. */
403 static struct fs_db *mgs_new_fsdb(const struct lu_env *env,
404 struct mgs_device *mgs, char *fsname)
410 if (strlen(fsname) >= sizeof(fsdb->fsdb_name)) {
411 CERROR("fsname %s is too long\n", fsname);
413 RETURN(ERR_PTR(-EINVAL));
418 RETURN(ERR_PTR(-ENOMEM));
420 strncpy(fsdb->fsdb_name, fsname, sizeof(fsdb->fsdb_name));
421 mutex_init(&fsdb->fsdb_mutex);
422 INIT_LIST_HEAD(&fsdb->fsdb_list);
423 set_bit(FSDB_UDESC, &fsdb->fsdb_flags);
425 INIT_LIST_HEAD(&fsdb->fsdb_clients);
426 atomic_set(&fsdb->fsdb_notify_phase, 0);
427 init_waitqueue_head(&fsdb->fsdb_notify_waitq);
428 init_completion(&fsdb->fsdb_notify_comp);
430 if (strcmp(fsname, MGSSELF_NAME) == 0) {
431 set_bit(FSDB_MGS_SELF, &fsdb->fsdb_flags);
432 fsdb->fsdb_mgs = mgs;
433 if (logname_is_barrier(fsname))
436 OBD_ALLOC(fsdb->fsdb_mdt_index_map, INDEX_MAP_SIZE);
437 if (!fsdb->fsdb_mdt_index_map) {
438 CERROR("No memory for MDT index maps\n");
440 GOTO(err, rc = -ENOMEM);
443 OBD_ALLOC(fsdb->fsdb_ost_index_map, INDEX_MAP_SIZE);
444 if (!fsdb->fsdb_ost_index_map) {
445 CERROR("No memory for OST index maps\n");
447 GOTO(err, rc = -ENOMEM);
450 if (logname_is_barrier(fsname))
453 rc = name_create(&fsdb->fsdb_clilov, fsname, "-clilov");
457 rc = name_create(&fsdb->fsdb_clilmv, fsname, "-clilmv");
461 /* initialise data for NID table */
462 mgs_ir_init_fs(env, mgs, fsdb);
463 lproc_mgs_add_live(mgs, fsdb);
466 if (!test_bit(FSDB_MGS_SELF, &fsdb->fsdb_flags) &&
467 strcmp(PARAMS_FILENAME, fsname) != 0) {
468 /* populate the db from the client llog */
469 rc = mgs_get_fsdb_from_llog(env, mgs, fsdb);
471 CERROR("Can't get db from client log %d\n", rc);
477 /* populate srpc rules from params llog */
478 rc = mgs_get_fsdb_srpc_from_llog(env, mgs, fsdb);
480 CERROR("Can't get db from params log %d\n", rc);
486 /* One ref is for the fsdb on the list.
487 * The other ref is for the caller. */
488 atomic_set(&fsdb->fsdb_ref, 2);
489 list_add(&fsdb->fsdb_list, &mgs->mgs_fs_db_list);
494 atomic_set(&fsdb->fsdb_ref, 1);
495 mgs_put_fsdb(mgs, fsdb);
500 static void mgs_free_fsdb(struct mgs_device *mgs, struct fs_db *fsdb)
502 LASSERT(list_empty(&fsdb->fsdb_list));
504 lproc_mgs_del_live(mgs, fsdb);
506 /* deinitialize fsr */
508 mgs_ir_fini_fs(mgs, fsdb);
510 if (fsdb->fsdb_ost_index_map)
511 OBD_FREE(fsdb->fsdb_ost_index_map, INDEX_MAP_SIZE);
512 if (fsdb->fsdb_mdt_index_map)
513 OBD_FREE(fsdb->fsdb_mdt_index_map, INDEX_MAP_SIZE);
514 name_destroy(&fsdb->fsdb_clilov);
515 name_destroy(&fsdb->fsdb_clilmv);
516 mgs_free_fsdb_srpc(fsdb);
520 void mgs_put_fsdb(struct mgs_device *mgs, struct fs_db *fsdb)
522 if (atomic_dec_and_test(&fsdb->fsdb_ref))
523 mgs_free_fsdb(mgs, fsdb);
526 int mgs_init_fsdb_list(struct mgs_device *mgs)
528 INIT_LIST_HEAD(&mgs->mgs_fs_db_list);
532 int mgs_cleanup_fsdb_list(struct mgs_device *mgs)
535 struct list_head *tmp, *tmp2;
537 mutex_lock(&mgs->mgs_mutex);
538 list_for_each_safe(tmp, tmp2, &mgs->mgs_fs_db_list) {
539 fsdb = list_entry(tmp, struct fs_db, fsdb_list);
540 list_del_init(&fsdb->fsdb_list);
541 mgs_put_fsdb(mgs, fsdb);
543 mutex_unlock(&mgs->mgs_mutex);
547 /* The caller must hold mgs->mgs_mutex. */
548 int mgs_find_or_make_fsdb_nolock(const struct lu_env *env,
549 struct mgs_device *mgs,
550 char *name, struct fs_db **dbh)
556 fsdb = mgs_find_fsdb(mgs, name);
558 fsdb = mgs_new_fsdb(env, mgs, name);
562 CDEBUG(D_MGS, "Created new db: rc = %d\n", rc);
571 int mgs_find_or_make_fsdb(const struct lu_env *env, struct mgs_device *mgs,
572 char *name, struct fs_db **dbh)
577 mutex_lock(&mgs->mgs_mutex);
578 rc = mgs_find_or_make_fsdb_nolock(env, mgs, name, dbh);
579 mutex_unlock(&mgs->mgs_mutex);
586 -1= empty client log */
587 int mgs_check_index(const struct lu_env *env,
588 struct mgs_device *mgs,
589 struct mgs_target_info *mti)
596 LASSERT(!(mti->mti_flags & LDD_F_NEED_INDEX));
598 rc = mgs_find_or_make_fsdb(env, mgs, mti->mti_fsname, &fsdb);
600 CERROR("Can't get db for %s\n", mti->mti_fsname);
604 if (test_bit(FSDB_LOG_EMPTY, &fsdb->fsdb_flags))
607 if (mti->mti_flags & LDD_F_SV_TYPE_OST)
608 imap = fsdb->fsdb_ost_index_map;
609 else if (mti->mti_flags & LDD_F_SV_TYPE_MDT)
610 imap = fsdb->fsdb_mdt_index_map;
612 GOTO(out, rc = -EINVAL);
614 if (test_bit(mti->mti_stripe_index, imap))
620 mgs_put_fsdb(mgs, fsdb);
624 static __inline__ int next_index(void *index_map, int map_len)
627 for (i = 0; i < map_len * 8; i++)
628 if (!test_bit(i, index_map)) {
631 CERROR("max index %d exceeded.\n", i);
635 /* Make the mdt/ost server obd name based on the filesystem name */
636 static bool server_make_name(u32 flags, u16 index, const char *fs,
637 char *name_buf, size_t name_buf_size)
639 bool invalid_flag = false;
641 if (flags & (LDD_F_SV_TYPE_MDT | LDD_F_SV_TYPE_OST)) {
642 if (!(flags & LDD_F_SV_ALL))
643 snprintf(name_buf, name_buf_size, "%.8s%c%s%04x", fs,
644 (flags & LDD_F_VIRGIN) ? ':' :
645 ((flags & LDD_F_WRITECONF) ? '=' : '-'),
646 (flags & LDD_F_SV_TYPE_MDT) ? "MDT" : "OST",
648 } else if (flags & LDD_F_SV_TYPE_MGS) {
649 snprintf(name_buf, name_buf_size, "MGS");
651 CERROR("unknown server type %#x\n", flags);
658 0 newly marked as in use
660 +EALREADY for update of an old index */
661 static int mgs_set_index(const struct lu_env *env,
662 struct mgs_device *mgs,
663 struct mgs_target_info *mti)
670 rc = mgs_find_or_make_fsdb(env, mgs, mti->mti_fsname, &fsdb);
672 CERROR("Can't get db for %s\n", mti->mti_fsname);
676 mutex_lock(&fsdb->fsdb_mutex);
677 if (mti->mti_flags & LDD_F_SV_TYPE_OST) {
678 imap = fsdb->fsdb_ost_index_map;
679 } else if (mti->mti_flags & LDD_F_SV_TYPE_MDT) {
680 imap = fsdb->fsdb_mdt_index_map;
682 GOTO(out_up, rc = -EINVAL);
685 if (mti->mti_flags & LDD_F_NEED_INDEX) {
686 rc = next_index(imap, INDEX_MAP_SIZE);
688 GOTO(out_up, rc = -ERANGE);
689 mti->mti_stripe_index = rc;
692 /* the last index(0xffff) is reserved for default value. */
693 if (mti->mti_stripe_index >= INDEX_MAP_SIZE * 8 - 1) {
694 LCONSOLE_ERROR_MSG(0x13f, "Server %s requested index %u, "
695 "but index must be less than %u.\n",
696 mti->mti_svname, mti->mti_stripe_index,
697 INDEX_MAP_SIZE * 8 - 1);
698 GOTO(out_up, rc = -ERANGE);
701 if (test_bit(mti->mti_stripe_index, imap)) {
702 if ((mti->mti_flags & LDD_F_VIRGIN) &&
703 !(mti->mti_flags & LDD_F_WRITECONF)) {
704 LCONSOLE_ERROR_MSG(0x140, "Server %s requested index "
705 "%d, but that index is already in "
706 "use. Use --writeconf to force\n",
708 mti->mti_stripe_index);
709 GOTO(out_up, rc = -EADDRINUSE);
711 CDEBUG(D_MGS, "Server %s updating index %d\n",
712 mti->mti_svname, mti->mti_stripe_index);
713 GOTO(out_up, rc = EALREADY);
716 set_bit(mti->mti_stripe_index, imap);
717 if (mti->mti_flags & LDD_F_SV_TYPE_MDT)
718 fsdb->fsdb_mdt_count++;
721 set_bit(mti->mti_stripe_index, imap);
722 clear_bit(FSDB_LOG_EMPTY, &fsdb->fsdb_flags);
723 if (server_make_name(mti->mti_flags & ~(LDD_F_VIRGIN | LDD_F_WRITECONF),
724 mti->mti_stripe_index, mti->mti_fsname,
725 mti->mti_svname, sizeof(mti->mti_svname))) {
726 CERROR("unknown server type %#x\n", mti->mti_flags);
727 GOTO(out_up, rc = -EINVAL);
730 CDEBUG(D_MGS, "Set index for %s to %d\n", mti->mti_svname,
731 mti->mti_stripe_index);
733 GOTO(out_up, rc = 0);
736 mutex_unlock(&fsdb->fsdb_mutex);
737 mgs_put_fsdb(mgs, fsdb);
741 struct mgs_modify_lookup {
742 struct cfg_marker mml_marker;
746 static int mgs_check_record_match(const struct lu_env *env,
747 struct llog_handle *llh,
748 struct llog_rec_hdr *rec, void *data)
750 struct cfg_marker *mc_marker = data;
751 struct cfg_marker *marker;
752 struct lustre_cfg *lcfg = REC_DATA(rec);
753 int cfg_len = REC_DATA_LEN(rec);
758 if (rec->lrh_type != OBD_CFG_REC) {
759 CDEBUG(D_ERROR, "Unhandled lrh_type: %#x\n", rec->lrh_type);
763 rc = lustre_cfg_sanity_check(lcfg, cfg_len);
765 CDEBUG(D_ERROR, "Insane cfg\n");
769 /* We only care about markers */
770 if (lcfg->lcfg_command != LCFG_MARKER)
773 marker = lustre_cfg_buf(lcfg, 1);
775 if (marker->cm_flags & CM_SKIP)
778 if ((strcmp(mc_marker->cm_comment, marker->cm_comment) == 0) &&
779 (strcmp(mc_marker->cm_tgtname, marker->cm_tgtname) == 0)) {
780 /* Found a non-skipped marker match */
781 CDEBUG(D_MGS, "Matched rec %u marker %d flag %x %s %s\n",
782 rec->lrh_index, marker->cm_step,
783 marker->cm_flags, marker->cm_tgtname,
785 rc = LLOG_PROC_BREAK;
792 * Check an existing config log record with matching comment and device
794 * 0 - checked successfully,
795 * LLOG_PROC_BREAK - record matches
798 static int mgs_check_marker(const struct lu_env *env, struct mgs_device *mgs,
799 struct fs_db *fsdb, struct mgs_target_info *mti,
800 char *logname, char *devname, char *comment)
802 struct llog_handle *loghandle;
803 struct llog_ctxt *ctxt;
804 struct cfg_marker *mc_marker;
809 LASSERT(mutex_is_locked(&fsdb->fsdb_mutex));
810 CDEBUG(D_MGS, "mgs check %s/%s/%s\n", logname, devname, comment);
812 ctxt = llog_get_context(mgs->mgs_obd, LLOG_CONFIG_ORIG_CTXT);
813 LASSERT(ctxt != NULL);
814 rc = llog_open(env, ctxt, &loghandle, NULL, logname, LLOG_OPEN_EXISTS);
821 rc = llog_init_handle(env, loghandle, LLOG_F_IS_PLAIN, NULL);
825 if (llog_get_size(loghandle) <= 1)
826 GOTO(out_close, rc = 0);
828 OBD_ALLOC_PTR(mc_marker);
830 GOTO(out_close, rc = -ENOMEM);
831 if (strlcpy(mc_marker->cm_comment, comment,
832 sizeof(mc_marker->cm_comment)) >=
833 sizeof(mc_marker->cm_comment))
834 GOTO(out_free, rc = -E2BIG);
835 if (strlcpy(mc_marker->cm_tgtname, devname,
836 sizeof(mc_marker->cm_tgtname)) >=
837 sizeof(mc_marker->cm_tgtname))
838 GOTO(out_free, rc = -E2BIG);
840 rc = llog_process(env, loghandle, mgs_check_record_match,
841 (void *)mc_marker, NULL);
844 OBD_FREE_PTR(mc_marker);
847 llog_close(env, loghandle);
849 if (rc && rc != LLOG_PROC_BREAK)
850 CDEBUG(D_ERROR, "%s: mgs check %s/%s failed: rc = %d\n",
851 mgs->mgs_obd->obd_name, mti->mti_svname, comment, rc);
856 static int mgs_modify_handler(const struct lu_env *env,
857 struct llog_handle *llh,
858 struct llog_rec_hdr *rec, void *data)
860 struct mgs_modify_lookup *mml = data;
861 struct cfg_marker *marker;
862 struct lustre_cfg *lcfg = REC_DATA(rec);
863 int cfg_len = REC_DATA_LEN(rec);
867 if (rec->lrh_type != OBD_CFG_REC) {
868 CERROR("unhandled lrh_type: %#x\n", rec->lrh_type);
872 rc = lustre_cfg_sanity_check(lcfg, cfg_len);
874 CERROR("Insane cfg\n");
878 /* We only care about markers */
879 if (lcfg->lcfg_command != LCFG_MARKER)
882 marker = lustre_cfg_buf(lcfg, 1);
883 if ((strcmp(mml->mml_marker.cm_comment, marker->cm_comment) == 0) &&
884 (strcmp(mml->mml_marker.cm_tgtname, marker->cm_tgtname) == 0) &&
885 !(marker->cm_flags & CM_SKIP)) {
886 /* Found a non-skipped marker match */
887 CDEBUG(D_MGS, "Changing rec %u marker %d %x->%x: %s %s\n",
888 rec->lrh_index, marker->cm_step,
889 marker->cm_flags, mml->mml_marker.cm_flags,
890 marker->cm_tgtname, marker->cm_comment);
891 /* Overwrite the old marker llog entry */
892 marker->cm_flags &= ~CM_EXCLUDE; /* in case we're unexcluding */
893 marker->cm_flags |= mml->mml_marker.cm_flags;
894 marker->cm_canceltime = mml->mml_marker.cm_canceltime;
895 rc = llog_write(env, llh, rec, rec->lrh_index);
904 * Modify an existing config log record (for CM_SKIP or CM_EXCLUDE)
906 * 0 - modified successfully,
907 * 1 - no modification was done
910 static int mgs_modify(const struct lu_env *env, struct mgs_device *mgs,
911 struct fs_db *fsdb, struct mgs_target_info *mti,
912 char *logname, char *devname, char *comment, int flags)
914 struct llog_handle *loghandle;
915 struct llog_ctxt *ctxt;
916 struct mgs_modify_lookup *mml;
921 LASSERT(mutex_is_locked(&fsdb->fsdb_mutex));
922 CDEBUG(D_MGS, "modify %s/%s/%s fl=%x\n", logname, devname, comment,
925 ctxt = llog_get_context(mgs->mgs_obd, LLOG_CONFIG_ORIG_CTXT);
926 LASSERT(ctxt != NULL);
927 rc = llog_open(env, ctxt, &loghandle, NULL, logname, LLOG_OPEN_EXISTS);
934 rc = llog_init_handle(env, loghandle, LLOG_F_IS_PLAIN, NULL);
938 if (llog_get_size(loghandle) <= 1)
939 GOTO(out_close, rc = 0);
943 GOTO(out_close, rc = -ENOMEM);
944 if (strlcpy(mml->mml_marker.cm_comment, comment,
945 sizeof(mml->mml_marker.cm_comment)) >=
946 sizeof(mml->mml_marker.cm_comment))
947 GOTO(out_free, rc = -E2BIG);
948 if (strlcpy(mml->mml_marker.cm_tgtname, devname,
949 sizeof(mml->mml_marker.cm_tgtname)) >=
950 sizeof(mml->mml_marker.cm_tgtname))
951 GOTO(out_free, rc = -E2BIG);
952 /* Modify mostly means cancel */
953 mml->mml_marker.cm_flags = flags;
954 mml->mml_marker.cm_canceltime = flags ? ktime_get_real_seconds() : 0;
955 mml->mml_modified = 0;
956 rc = llog_process(env, loghandle, mgs_modify_handler, (void *)mml,
958 if (!rc && !mml->mml_modified)
965 llog_close(env, loghandle);
968 CERROR("%s: modify %s/%s failed: rc = %d\n",
969 mgs->mgs_obd->obd_name, mti->mti_svname, comment, rc);
982 /** This structure is passed to mgs_replace_handler */
983 struct mgs_replace_data {
984 /* Nids are replaced for this target device */
985 struct mgs_target_info target;
986 /* Temporary modified llog */
987 struct llog_handle *temp_llh;
988 enum replace_state state;
994 * Check: a) if block should be skipped
995 * b) is it target block
1000 * \retval 0 should not to be skipped
1001 * \retval 1 should to be skipped
1003 static int check_markers(struct lustre_cfg *lcfg,
1004 struct mgs_replace_data *mrd)
1006 struct cfg_marker *marker;
1008 /* Track markers. Find given device */
1009 if (lcfg->lcfg_command == LCFG_MARKER) {
1010 marker = lustre_cfg_buf(lcfg, 1);
1011 /* Clean llog from records marked as CM_SKIP.
1012 CM_EXCLUDE records are used for "active" command
1013 and can be restored if needed */
1014 if ((marker->cm_flags & (CM_SKIP | CM_START)) ==
1015 (CM_SKIP | CM_START)) {
1016 mrd->state = REPLACE_SKIP;
1020 if ((marker->cm_flags & (CM_SKIP | CM_END)) ==
1021 (CM_SKIP | CM_END)) {
1022 mrd->state = REPLACE_COPY;
1026 if (strcmp(mrd->target.mti_svname, marker->cm_tgtname) == 0) {
1027 LASSERT(!(marker->cm_flags & CM_START) ||
1028 !(marker->cm_flags & CM_END));
1029 if (marker->cm_flags & CM_START) {
1030 mrd->state = REPLACE_UUID;
1031 mrd->failover = NULL;
1032 } else if (marker->cm_flags & CM_END)
1033 mrd->state = REPLACE_COPY;
1040 static int record_base(const struct lu_env *env, struct llog_handle *llh,
1041 char *cfgname, lnet_nid_t nid, int cmd,
1042 char *s1, char *s2, char *s3, char *s4)
1044 struct mgs_thread_info *mgi = mgs_env_info(env);
1045 struct llog_cfg_rec *lcr;
1048 CDEBUG(D_MGS, "lcfg %s %#x %s %s %s %s\n", cfgname,
1049 cmd, s1, s2, s3, s4);
1051 lustre_cfg_bufs_reset(&mgi->mgi_bufs, cfgname);
1053 lustre_cfg_bufs_set_string(&mgi->mgi_bufs, 1, s1);
1055 lustre_cfg_bufs_set_string(&mgi->mgi_bufs, 2, s2);
1057 lustre_cfg_bufs_set_string(&mgi->mgi_bufs, 3, s3);
1059 lustre_cfg_bufs_set_string(&mgi->mgi_bufs, 4, s4);
1061 lcr = lustre_cfg_rec_new(cmd, &mgi->mgi_bufs);
1065 lcr->lcr_cfg.lcfg_nid = nid;
1066 rc = llog_write(env, llh, &lcr->lcr_hdr, LLOG_NEXT_IDX);
1068 lustre_cfg_rec_free(lcr);
1072 "failed to write lcfg %s %#x %s %s %s %s: rc = %d\n",
1073 cfgname, cmd, s1, s2, s3, s4, rc);
1077 static inline int record_add_uuid(const struct lu_env *env,
1078 struct llog_handle *llh,
1079 uint64_t nid, char *uuid)
1081 return record_base(env, llh, NULL, nid, LCFG_ADD_UUID, uuid,
1085 static inline int record_add_conn(const struct lu_env *env,
1086 struct llog_handle *llh,
1087 char *devname, char *uuid)
1089 return record_base(env, llh, devname, 0, LCFG_ADD_CONN, uuid,
1093 static inline int record_attach(const struct lu_env *env,
1094 struct llog_handle *llh, char *devname,
1095 char *type, char *uuid)
1097 return record_base(env, llh, devname, 0, LCFG_ATTACH, type, uuid,
1101 static inline int record_setup(const struct lu_env *env,
1102 struct llog_handle *llh, char *devname,
1103 char *s1, char *s2, char *s3, char *s4)
1105 return record_base(env, llh, devname, 0, LCFG_SETUP, s1, s2, s3, s4);
1109 * \retval <0 record processing error
1110 * \retval n record is processed. No need copy original one.
1111 * \retval 0 record is not processed.
1113 static int process_command(const struct lu_env *env, struct lustre_cfg *lcfg,
1114 struct mgs_replace_data *mrd)
1121 if (mrd->state == REPLACE_UUID &&
1122 lcfg->lcfg_command == LCFG_ADD_UUID) {
1123 /* LCFG_ADD_UUID command found. Let's skip original command
1124 and add passed nids */
1125 ptr = mrd->target.mti_params;
1126 while (class_parse_nid(ptr, &nid, &ptr) == 0) {
1127 if (!mrd->nodeuuid) {
1128 rc = name_create(&mrd->nodeuuid,
1129 libcfs_nid2str(nid), "");
1131 CERROR("Can't create uuid for "
1132 "nid %s, device %s\n",
1133 libcfs_nid2str(nid),
1134 mrd->target.mti_svname);
1138 CDEBUG(D_MGS, "add nid %s with uuid %s, "
1139 "device %s\n", libcfs_nid2str(nid),
1140 mrd->target.mti_params,
1142 rc = record_add_uuid(env,
1149 mrd->failover = ptr;
1154 if (nids_added == 0) {
1155 CERROR("No new nids were added, nid %s with uuid %s, "
1156 "device %s\n", libcfs_nid2str(nid),
1157 mrd->nodeuuid ? mrd->nodeuuid : "NULL",
1158 mrd->target.mti_svname);
1159 name_destroy(&mrd->nodeuuid);
1162 mrd->state = REPLACE_SETUP;
1168 if (mrd->state == REPLACE_SETUP && lcfg->lcfg_command == LCFG_SETUP) {
1169 /* LCFG_SETUP command found. UUID should be changed */
1170 rc = record_setup(env,
1172 /* devname the same */
1173 lustre_cfg_string(lcfg, 0),
1174 /* s1 is not changed */
1175 lustre_cfg_string(lcfg, 1),
1177 /* s3 is not changed */
1178 lustre_cfg_string(lcfg, 3),
1179 /* s4 is not changed */
1180 lustre_cfg_string(lcfg, 4));
1182 name_destroy(&mrd->nodeuuid);
1186 if (mrd->failover) {
1187 ptr = mrd->failover;
1188 while (class_parse_nid(ptr, &nid, &ptr) == 0) {
1189 if (mrd->nodeuuid == NULL) {
1190 rc = name_create(&mrd->nodeuuid,
1191 libcfs_nid2str(nid),
1197 CDEBUG(D_MGS, "add nid %s for failover %s\n",
1198 libcfs_nid2str(nid), mrd->nodeuuid);
1199 rc = record_add_uuid(env, mrd->temp_llh, nid,
1202 name_destroy(&mrd->nodeuuid);
1206 rc = record_add_conn(env,
1208 lustre_cfg_string(lcfg, 0),
1210 name_destroy(&mrd->nodeuuid);
1215 if (mrd->nodeuuid) {
1216 rc = record_add_conn(env, mrd->temp_llh,
1217 lustre_cfg_string(lcfg, 0),
1219 name_destroy(&mrd->nodeuuid);
1224 mrd->state = REPLACE_DONE;
1228 /* Another commands in target device block */
1233 * Handler that called for every record in llog.
1234 * Records are processed in order they placed in llog.
1236 * \param[in] llh log to be processed
1237 * \param[in] rec current record
1238 * \param[in] data mgs_replace_data structure
1242 static int mgs_replace_nids_handler(const struct lu_env *env,
1243 struct llog_handle *llh,
1244 struct llog_rec_hdr *rec,
1247 struct mgs_replace_data *mrd;
1248 struct lustre_cfg *lcfg = REC_DATA(rec);
1249 int cfg_len = REC_DATA_LEN(rec);
1253 mrd = (struct mgs_replace_data *)data;
1255 if (rec->lrh_type != OBD_CFG_REC) {
1256 CERROR("unhandled lrh_type: %#x, cmd %x %s %s\n",
1257 rec->lrh_type, lcfg->lcfg_command,
1258 lustre_cfg_string(lcfg, 0),
1259 lustre_cfg_string(lcfg, 1));
1263 rc = lustre_cfg_sanity_check(lcfg, cfg_len);
1265 /* Do not copy any invalidated records */
1266 GOTO(skip_out, rc = 0);
1269 rc = check_markers(lcfg, mrd);
1270 if (rc || mrd->state == REPLACE_SKIP)
1271 GOTO(skip_out, rc = 0);
1273 /* Write to new log all commands outside target device block */
1274 if (mrd->state == REPLACE_COPY)
1275 GOTO(copy_out, rc = 0);
1277 if (mrd->state == REPLACE_DONE &&
1278 (lcfg->lcfg_command == LCFG_ADD_UUID ||
1279 lcfg->lcfg_command == LCFG_ADD_CONN)) {
1281 CWARN("Previous failover is deleted, but new one is "
1282 "not set. This means you configure system "
1283 "without failover or passed wrong replace_nids "
1284 "command parameters. Device %s, passed nids %s\n",
1285 mrd->target.mti_svname, mrd->target.mti_params);
1286 GOTO(skip_out, rc = 0);
1289 rc = process_command(env, lcfg, mrd);
1296 /* Record is placed in temporary llog as is */
1297 rc = llog_write(env, mrd->temp_llh, rec, LLOG_NEXT_IDX);
1299 CDEBUG(D_MGS, "Copied idx=%d, rc=%d, len=%d, cmd %x %s %s\n",
1300 rec->lrh_index, rc, rec->lrh_len, lcfg->lcfg_command,
1301 lustre_cfg_string(lcfg, 0), lustre_cfg_string(lcfg, 1));
1305 CDEBUG(D_MGS, "Skipped idx=%d, rc=%d, len=%d, cmd %x %s %s\n",
1306 rec->lrh_index, rc, rec->lrh_len, lcfg->lcfg_command,
1307 lustre_cfg_string(lcfg, 0), lustre_cfg_string(lcfg, 1));
1311 static int mgs_log_is_empty(const struct lu_env *env,
1312 struct mgs_device *mgs, char *name)
1314 struct llog_ctxt *ctxt;
1317 ctxt = llog_get_context(mgs->mgs_obd, LLOG_CONFIG_ORIG_CTXT);
1318 LASSERT(ctxt != NULL);
1320 rc = llog_is_empty(env, ctxt, name);
1321 llog_ctxt_put(ctxt);
1325 static int mgs_replace_log(const struct lu_env *env,
1326 struct obd_device *mgs,
1327 char *logname, char *devname,
1328 llog_cb_t replace_handler, void *data)
1330 struct llog_handle *orig_llh, *backup_llh;
1331 struct llog_ctxt *ctxt;
1332 struct mgs_replace_data *mrd;
1333 struct mgs_device *mgs_dev = lu2mgs_dev(mgs->obd_lu_dev);
1334 static struct obd_uuid cfg_uuid = { .uuid = "config_uuid" };
1336 int rc, rc2, buf_size;
1340 ctxt = llog_get_context(mgs, LLOG_CONFIG_ORIG_CTXT);
1341 LASSERT(ctxt != NULL);
1343 if (mgs_log_is_empty(env, mgs_dev, logname)) {
1344 /* Log is empty. Nothing to replace */
1345 GOTO(out_put, rc = 0);
1348 now = ktime_get_real_seconds();
1350 /* max time64_t in decimal fits into 20 bytes long string */
1351 buf_size = strlen(logname) + 1 + 20 + 1 + strlen(".bak") + 1;
1352 OBD_ALLOC(backup, buf_size);
1354 GOTO(out_put, rc = -ENOMEM);
1356 snprintf(backup, buf_size, "%s.%llu.bak", logname, now);
1358 rc = llog_backup(env, mgs, ctxt, ctxt, logname, backup);
1360 /* Now erase original log file. Connections are not allowed.
1361 Backup is already saved */
1362 rc = llog_erase(env, ctxt, NULL, logname);
1365 } else if (rc != -ENOENT) {
1366 CERROR("%s: can't make backup for %s: rc = %d\n",
1367 mgs->obd_name, logname, rc);
1371 /* open local log */
1372 rc = llog_open_create(env, ctxt, &orig_llh, NULL, logname);
1374 GOTO(out_restore, rc);
1376 rc = llog_init_handle(env, orig_llh, LLOG_F_IS_PLAIN, &cfg_uuid);
1378 GOTO(out_closel, rc);
1380 /* open backup llog */
1381 rc = llog_open(env, ctxt, &backup_llh, NULL, backup,
1384 GOTO(out_closel, rc);
1386 rc = llog_init_handle(env, backup_llh, LLOG_F_IS_PLAIN, NULL);
1388 GOTO(out_close, rc);
1390 if (llog_get_size(backup_llh) <= 1)
1391 GOTO(out_close, rc = 0);
1395 GOTO(out_close, rc = -ENOMEM);
1396 /* devname is only needed information to replace UUID records */
1398 strlcpy(mrd->target.mti_svname, devname,
1399 sizeof(mrd->target.mti_svname));
1400 /* data is parsed in llog callback */
1402 strlcpy(mrd->target.mti_params, data,
1403 sizeof(mrd->target.mti_params));
1404 /* Copy records to this temporary llog */
1405 mrd->temp_llh = orig_llh;
1407 rc = llog_process(env, backup_llh, replace_handler,
1411 rc2 = llog_close(NULL, backup_llh);
1415 rc2 = llog_close(NULL, orig_llh);
1421 CERROR("%s: llog should be restored: rc = %d\n",
1423 rc2 = llog_backup(env, mgs, ctxt, ctxt, backup,
1426 CERROR("%s: can't restore backup %s: rc = %d\n",
1427 mgs->obd_name, logname, rc2);
1431 OBD_FREE(backup, buf_size);
1434 llog_ctxt_put(ctxt);
1437 CERROR("%s: failed to replace log %s: rc = %d\n",
1438 mgs->obd_name, logname, rc);
1443 static int mgs_replace_nids_log(const struct lu_env *env,
1444 struct obd_device *obd,
1445 char *logname, char *devname, char *nids)
1447 CDEBUG(D_MGS, "Replace NIDs for %s in %s\n", devname, logname);
1448 return mgs_replace_log(env, obd, logname, devname,
1449 mgs_replace_nids_handler, nids);
1453 * Parse device name and get file system name and/or device index
1455 * @devname device name (ex. lustre-MDT0000)
1456 * @fsname file system name extracted from @devname and returned
1457 * to the caller (optional)
1458 * @index device index extracted from @devname and returned to
1459 * the caller (optional)
1461 * RETURN 0 success if we are only interested in
1462 * extracting fsname from devname.
1465 * LDD_F_SV_TYPE_* Besides extracting the fsname the
1466 * user also wants the index. Report to
1467 * the user the type of obd device the
1468 * returned index belongs too.
1470 * -EINVAL The obd device name is improper so
1471 * fsname could not be extracted.
1473 * -ENXIO Failed to extract the index out of
1474 * the obd device name. Most likely an
1475 * invalid obd device name
1477 static int mgs_parse_devname(char *devname, char *fsname, u32 *index)
1482 /* Extract fsname */
1484 rc = server_name2fsname(devname, fsname, NULL);
1486 CDEBUG(D_MGS, "Device name %s without fsname\n",
1493 rc = server_name2index(devname, index, NULL);
1495 CDEBUG(D_MGS, "Device name %s with wrong index\n",
1501 /* server_name2index can return LDD_F_SV_TYPE_* so always return rc */
1505 /* This is only called during replace_nids */
1506 static int only_mgs_is_running(struct obd_device *mgs_obd)
1508 /* TDB: Is global variable with devices count exists? */
1509 int num_devices = get_devices_count();
1510 int num_exports = 0;
1511 struct obd_export *exp;
1513 spin_lock(&mgs_obd->obd_dev_lock);
1514 list_for_each_entry(exp, &mgs_obd->obd_exports, exp_obd_chain) {
1515 /* skip self export */
1516 if (exp == mgs_obd->obd_self_export)
1518 if (exp_connect_flags(exp) & OBD_CONNECT_MDS_MDS)
1523 CERROR("%s: node %s still connected during replace_nids "
1524 "connect_flags:%llx\n",
1526 libcfs_nid2str(exp->exp_nid_stats->nid),
1527 exp_connect_flags(exp));
1530 spin_unlock(&mgs_obd->obd_dev_lock);
1532 /* osd, MGS and MGC + self_export
1533 (wc -l /proc/fs/lustre/devices <= 2) && (non self exports == 0) */
1534 return (num_devices <= 3) && (num_exports == 0);
1537 static int name_create_mdt(char **logname, char *fsname, int mdt_idx)
1541 if (mdt_idx > INDEX_MAP_MAX_VALUE)
1544 snprintf(postfix, sizeof(postfix), "-MDT%04x", mdt_idx);
1545 return name_create(logname, fsname, postfix);
1549 * Replace nids for \a device to \a nids values
1551 * \param obd MGS obd device
1552 * \param devname nids need to be replaced for this device
1553 * (ex. lustre-OST0000)
1554 * \param nids nids list (ex. nid1,nid2,nid3)
1558 int mgs_replace_nids(const struct lu_env *env,
1559 struct mgs_device *mgs,
1560 char *devname, char *nids)
1562 /* Assume fsname is part of device name */
1563 char fsname[MTI_NAME_MAXLEN];
1567 struct fs_db *fsdb = NULL;
1570 struct obd_device *mgs_obd = mgs->mgs_obd;
1573 /* We can only change NIDs if no other nodes are connected */
1574 spin_lock(&mgs_obd->obd_dev_lock);
1575 conn_state = mgs_obd->obd_no_conn;
1576 mgs_obd->obd_no_conn = 1;
1577 spin_unlock(&mgs_obd->obd_dev_lock);
1579 /* We can not change nids if not only MGS is started */
1580 if (!only_mgs_is_running(mgs_obd)) {
1581 CERROR("Only MGS is allowed to be started\n");
1582 GOTO(out, rc = -EINPROGRESS);
1585 /* Get fsname and index */
1586 rc = mgs_parse_devname(devname, fsname, &index);
1590 rc = mgs_find_or_make_fsdb(env, mgs, fsname, &fsdb);
1592 CERROR("%s: can't find fsdb: rc = %d\n", fsname, rc);
1596 /* Process client llogs */
1597 name_create(&logname, fsname, "-client");
1598 rc = mgs_replace_nids_log(env, mgs_obd, logname, devname, nids);
1599 name_destroy(&logname);
1601 CERROR("%s: error while replacing NIDs for %s: rc = %d\n",
1602 fsname, devname, rc);
1606 /* Process MDT llogs */
1607 for (i = 0; i < INDEX_MAP_SIZE * 8; i++) {
1608 if (!test_bit(i, fsdb->fsdb_mdt_index_map))
1610 name_create_mdt(&logname, fsname, i);
1611 rc = mgs_replace_nids_log(env, mgs_obd, logname, devname, nids);
1612 name_destroy(&logname);
1618 spin_lock(&mgs_obd->obd_dev_lock);
1619 mgs_obd->obd_no_conn = conn_state;
1620 spin_unlock(&mgs_obd->obd_dev_lock);
1623 mgs_put_fsdb(mgs, fsdb);
1629 * This is called for every record in llog. Some of records are
1630 * skipped, others are copied to new log as is.
1631 * Records to be skipped are
1632 * marker records marked SKIP
1633 * records enclosed between SKIP markers
1635 * \param[in] llh log to be processed
1636 * \param[in] rec current record
1637 * \param[in] data mgs_replace_data structure
1641 static int mgs_clear_config_handler(const struct lu_env *env,
1642 struct llog_handle *llh,
1643 struct llog_rec_hdr *rec, void *data)
1645 struct mgs_replace_data *mrd;
1646 struct lustre_cfg *lcfg = REC_DATA(rec);
1647 int cfg_len = REC_DATA_LEN(rec);
1652 mrd = (struct mgs_replace_data *)data;
1654 if (rec->lrh_type != OBD_CFG_REC) {
1655 CDEBUG(D_MGS, "Config llog Name=%s, Record Index=%u, "
1656 "Unhandled Record Type=%#x\n", llh->lgh_name,
1657 rec->lrh_index, rec->lrh_type);
1661 rc = lustre_cfg_sanity_check(lcfg, cfg_len);
1663 CDEBUG(D_MGS, "Config llog Name=%s, Invalid config file.",
1668 if (lcfg->lcfg_command == LCFG_MARKER) {
1669 struct cfg_marker *marker;
1671 marker = lustre_cfg_buf(lcfg, 1);
1672 if (marker->cm_flags & CM_SKIP) {
1673 if (marker->cm_flags & CM_START)
1674 mrd->state = REPLACE_SKIP;
1675 if (marker->cm_flags & CM_END)
1676 mrd->state = REPLACE_COPY;
1677 /* SKIP section started or finished */
1678 CDEBUG(D_MGS, "Skip idx=%d, rc=%d, len=%d, "
1679 "cmd %x %s %s\n", rec->lrh_index, rc,
1680 rec->lrh_len, lcfg->lcfg_command,
1681 lustre_cfg_string(lcfg, 0),
1682 lustre_cfg_string(lcfg, 1));
1686 if (mrd->state == REPLACE_SKIP) {
1687 /* record enclosed between SKIP markers, skip it */
1688 CDEBUG(D_MGS, "Skip idx=%d, rc=%d, len=%d, "
1689 "cmd %x %s %s\n", rec->lrh_index, rc,
1690 rec->lrh_len, lcfg->lcfg_command,
1691 lustre_cfg_string(lcfg, 0),
1692 lustre_cfg_string(lcfg, 1));
1697 /* Record is placed in temporary llog as is */
1698 rc = llog_write(env, mrd->temp_llh, rec, LLOG_NEXT_IDX);
1700 CDEBUG(D_MGS, "Copied idx=%d, rc=%d, len=%d, cmd %x %s %s\n",
1701 rec->lrh_index, rc, rec->lrh_len, lcfg->lcfg_command,
1702 lustre_cfg_string(lcfg, 0), lustre_cfg_string(lcfg, 1));
1707 * Directory CONFIGS/ may contain files which are not config logs to
1708 * be cleared. Skip any llogs with a non-alphanumeric character after
1709 * the last '-'. For example, fsname-MDT0000.sav, fsname-MDT0000.bak,
1710 * fsname-MDT0000.orig, fsname-MDT0000~, fsname-MDT0000.20150516, etc.
1712 static bool config_to_clear(const char *logname)
1717 str = strrchr(logname, '-');
1722 while (isalnum(str[++i]));
1723 return str[i] == '\0';
1727 * Clear config logs for \a name
1730 * \param mgs MGS device
1731 * \param name name of device or of filesystem
1732 * (ex. lustre-OST0000 or lustre) in later case all logs
1737 int mgs_clear_configs(const struct lu_env *env,
1738 struct mgs_device *mgs, const char *name)
1740 struct list_head dentry_list;
1741 struct mgs_direntry *dirent, *n;
1744 struct obd_device *mgs_obd = mgs->mgs_obd;
1749 /* Prevent clients and servers from connecting to mgs */
1750 spin_lock(&mgs_obd->obd_dev_lock);
1751 conn_state = mgs_obd->obd_no_conn;
1752 mgs_obd->obd_no_conn = 1;
1753 spin_unlock(&mgs_obd->obd_dev_lock);
1756 * config logs cannot be cleaned if anything other than
1759 if (!only_mgs_is_running(mgs_obd)) {
1760 CERROR("Only MGS is allowed to be started\n");
1761 GOTO(out, rc = -EBUSY);
1764 /* Find all the logs in the CONFIGS directory */
1765 rc = class_dentry_readdir(env, mgs, &dentry_list);
1767 CERROR("%s: cannot read config directory '%s': rc = %d\n",
1768 mgs_obd->obd_name, MOUNT_CONFIGS_DIR, rc);
1772 if (list_empty(&dentry_list)) {
1773 CERROR("%s: list empty reading config dir '%s': rc = %d\n",
1774 mgs_obd->obd_name, MOUNT_CONFIGS_DIR, -ENOENT);
1775 GOTO(out, rc = -ENOENT);
1778 OBD_ALLOC(namedash, strlen(name) + 2);
1779 if (namedash == NULL)
1780 GOTO(out, rc = -ENOMEM);
1781 snprintf(namedash, strlen(name) + 2, "%s-", name);
1783 list_for_each_entry(dirent, &dentry_list, mde_list) {
1784 if (strcmp(name, dirent->mde_name) &&
1785 strncmp(namedash, dirent->mde_name, strlen(namedash)))
1787 if (!config_to_clear(dirent->mde_name))
1789 CDEBUG(D_MGS, "%s: Clear config log %s\n",
1790 mgs_obd->obd_name, dirent->mde_name);
1791 rc = mgs_replace_log(env, mgs_obd, dirent->mde_name, NULL,
1792 mgs_clear_config_handler, NULL);
1797 list_for_each_entry_safe(dirent, n, &dentry_list, mde_list) {
1798 list_del_init(&dirent->mde_list);
1799 mgs_direntry_free(dirent);
1801 OBD_FREE(namedash, strlen(name) + 2);
1803 spin_lock(&mgs_obd->obd_dev_lock);
1804 mgs_obd->obd_no_conn = conn_state;
1805 spin_unlock(&mgs_obd->obd_dev_lock);
1810 static int record_lov_setup(const struct lu_env *env, struct llog_handle *llh,
1811 char *devname, struct lov_desc *desc)
1813 struct mgs_thread_info *mgi = mgs_env_info(env);
1814 struct llog_cfg_rec *lcr;
1817 lustre_cfg_bufs_reset(&mgi->mgi_bufs, devname);
1818 lustre_cfg_bufs_set(&mgi->mgi_bufs, 1, desc, sizeof(*desc));
1819 lcr = lustre_cfg_rec_new(LCFG_SETUP, &mgi->mgi_bufs);
1823 rc = llog_write(env, llh, &lcr->lcr_hdr, LLOG_NEXT_IDX);
1824 lustre_cfg_rec_free(lcr);
1828 static int record_lmv_setup(const struct lu_env *env, struct llog_handle *llh,
1829 char *devname, struct lmv_desc *desc)
1831 struct mgs_thread_info *mgi = mgs_env_info(env);
1832 struct llog_cfg_rec *lcr;
1835 lustre_cfg_bufs_reset(&mgi->mgi_bufs, devname);
1836 lustre_cfg_bufs_set(&mgi->mgi_bufs, 1, desc, sizeof(*desc));
1837 lcr = lustre_cfg_rec_new(LCFG_SETUP, &mgi->mgi_bufs);
1841 rc = llog_write(env, llh, &lcr->lcr_hdr, LLOG_NEXT_IDX);
1842 lustre_cfg_rec_free(lcr);
1846 static inline int record_mdc_add(const struct lu_env *env,
1847 struct llog_handle *llh,
1848 char *logname, char *mdcuuid,
1849 char *mdtuuid, char *index,
1852 return record_base(env,llh,logname,0,LCFG_ADD_MDC,
1853 mdtuuid,index,gen,mdcuuid);
1856 static inline int record_lov_add(const struct lu_env *env,
1857 struct llog_handle *llh,
1858 char *lov_name, char *ost_uuid,
1859 char *index, char *gen)
1861 return record_base(env, llh, lov_name, 0, LCFG_LOV_ADD_OBD,
1862 ost_uuid, index, gen, NULL);
1865 static inline int record_mount_opt(const struct lu_env *env,
1866 struct llog_handle *llh,
1867 char *profile, char *lov_name,
1870 return record_base(env, llh, NULL, 0, LCFG_MOUNTOPT,
1871 profile, lov_name, mdc_name, NULL);
1874 static int record_marker(const struct lu_env *env,
1875 struct llog_handle *llh,
1876 struct fs_db *fsdb, __u32 flags,
1877 char *tgtname, char *comment)
1879 struct mgs_thread_info *mgi = mgs_env_info(env);
1880 struct llog_cfg_rec *lcr;
1884 if (flags & CM_START)
1886 mgi->mgi_marker.cm_step = fsdb->fsdb_gen;
1887 mgi->mgi_marker.cm_flags = flags;
1888 mgi->mgi_marker.cm_vers = LUSTRE_VERSION_CODE;
1889 cplen = strlcpy(mgi->mgi_marker.cm_tgtname, tgtname,
1890 sizeof(mgi->mgi_marker.cm_tgtname));
1891 if (cplen >= sizeof(mgi->mgi_marker.cm_tgtname))
1893 cplen = strlcpy(mgi->mgi_marker.cm_comment, comment,
1894 sizeof(mgi->mgi_marker.cm_comment));
1895 if (cplen >= sizeof(mgi->mgi_marker.cm_comment))
1897 mgi->mgi_marker.cm_createtime = ktime_get_real_seconds();
1898 mgi->mgi_marker.cm_canceltime = 0;
1899 lustre_cfg_bufs_reset(&mgi->mgi_bufs, NULL);
1900 lustre_cfg_bufs_set(&mgi->mgi_bufs, 1, &mgi->mgi_marker,
1901 sizeof(mgi->mgi_marker));
1902 lcr = lustre_cfg_rec_new(LCFG_MARKER, &mgi->mgi_bufs);
1906 rc = llog_write(env, llh, &lcr->lcr_hdr, LLOG_NEXT_IDX);
1907 lustre_cfg_rec_free(lcr);
1911 static int record_start_log(const struct lu_env *env, struct mgs_device *mgs,
1912 struct llog_handle **llh, char *name)
1914 static struct obd_uuid cfg_uuid = { .uuid = "config_uuid" };
1915 struct llog_ctxt *ctxt;
1920 GOTO(out, rc = -EBUSY);
1922 ctxt = llog_get_context(mgs->mgs_obd, LLOG_CONFIG_ORIG_CTXT);
1924 GOTO(out, rc = -ENODEV);
1925 LASSERT(ctxt->loc_obd == mgs->mgs_obd);
1927 rc = llog_open_create(env, ctxt, llh, NULL, name);
1930 rc = llog_init_handle(env, *llh, LLOG_F_IS_PLAIN, &cfg_uuid);
1932 llog_close(env, *llh);
1934 llog_ctxt_put(ctxt);
1937 CERROR("%s: can't start log %s: rc = %d\n",
1938 mgs->mgs_obd->obd_name, name, rc);
1944 static int record_end_log(const struct lu_env *env, struct llog_handle **llh)
1948 rc = llog_close(env, *llh);
1954 /******************** config "macros" *********************/
1956 /* write an lcfg directly into a log (with markers) */
1957 static int mgs_write_log_direct(const struct lu_env *env,
1958 struct mgs_device *mgs, struct fs_db *fsdb,
1959 char *logname, struct llog_cfg_rec *lcr,
1960 char *devname, char *comment)
1962 struct llog_handle *llh = NULL;
1967 rc = record_start_log(env, mgs, &llh, logname);
1971 /* FIXME These should be a single journal transaction */
1972 rc = record_marker(env, llh, fsdb, CM_START, devname, comment);
1975 rc = llog_write(env, llh, &lcr->lcr_hdr, LLOG_NEXT_IDX);
1978 rc = record_marker(env, llh, fsdb, CM_END, devname, comment);
1982 record_end_log(env, &llh);
1986 /* write the lcfg in all logs for the given fs */
1987 static int mgs_write_log_direct_all(const struct lu_env *env,
1988 struct mgs_device *mgs,
1990 struct mgs_target_info *mti,
1991 struct llog_cfg_rec *lcr, char *devname,
1992 char *comment, int server_only)
1994 struct list_head log_list;
1995 struct mgs_direntry *dirent, *n;
1996 char *fsname = mti->mti_fsname;
1997 int rc = 0, len = strlen(fsname);
2000 /* Find all the logs in the CONFIGS directory */
2001 rc = class_dentry_readdir(env, mgs, &log_list);
2005 /* Could use fsdb index maps instead of directory listing */
2006 list_for_each_entry_safe(dirent, n, &log_list, mde_list) {
2007 list_del_init(&dirent->mde_list);
2008 /* don't write to sptlrpc rule log */
2009 if (strstr(dirent->mde_name, "-sptlrpc") != NULL)
2012 /* caller wants write server logs only */
2013 if (server_only && strstr(dirent->mde_name, "-client") != NULL)
2016 if (strlen(dirent->mde_name) <= len ||
2017 strncmp(fsname, dirent->mde_name, len) != 0 ||
2018 dirent->mde_name[len] != '-')
2021 CDEBUG(D_MGS, "Changing log %s\n", dirent->mde_name);
2022 /* Erase any old settings of this same parameter */
2023 rc = mgs_modify(env, mgs, fsdb, mti, dirent->mde_name,
2024 devname, comment, CM_SKIP);
2026 CERROR("%s: Can't modify llog %s: rc = %d\n",
2027 mgs->mgs_obd->obd_name, dirent->mde_name, rc);
2030 /* Write the new one */
2031 rc = mgs_write_log_direct(env, mgs, fsdb, dirent->mde_name,
2032 lcr, devname, comment);
2034 CERROR("%s: writing log %s: rc = %d\n",
2035 mgs->mgs_obd->obd_name, dirent->mde_name, rc);
2037 mgs_direntry_free(dirent);
2043 static int mgs_write_log_osp_to_mdt(const struct lu_env *env,
2044 struct mgs_device *mgs,
2046 struct mgs_target_info *mti,
2047 int index, char *logname);
2048 static int mgs_write_log_osc_to_lov(const struct lu_env *env,
2049 struct mgs_device *mgs,
2051 struct mgs_target_info *mti,
2052 char *logname, char *suffix, char *lovname,
2053 enum lustre_sec_part sec_part, int flags);
2054 static int name_create_mdt_and_lov(char **logname, char **lovname,
2055 struct fs_db *fsdb, int i);
2057 static int add_param(char *params, char *key, char *val)
2059 char *start = params + strlen(params);
2060 char *end = params + sizeof(((struct mgs_target_info *)0)->mti_params);
2064 keylen = strlen(key);
2065 if (start + 1 + keylen + strlen(val) >= end) {
2066 CERROR("params are too long: %s %s%s\n",
2067 params, key != NULL ? key : "", val);
2071 sprintf(start, " %s%s", key != NULL ? key : "", val);
2076 * Walk through client config log record and convert the related records
2079 static int mgs_steal_client_llog_handler(const struct lu_env *env,
2080 struct llog_handle *llh,
2081 struct llog_rec_hdr *rec, void *data)
2083 struct mgs_device *mgs;
2084 struct obd_device *obd;
2085 struct mgs_target_info *mti, *tmti;
2087 int cfg_len = rec->lrh_len;
2088 char *cfg_buf = (char*) (rec + 1);
2089 struct lustre_cfg *lcfg;
2091 struct llog_handle *mdt_llh = NULL;
2092 static int got_an_osc_or_mdc = 0;
2093 /* 0: not found any osc/mdc;
2097 static int last_step = -1;
2102 mti = ((struct temp_comp*)data)->comp_mti;
2103 tmti = ((struct temp_comp*)data)->comp_tmti;
2104 fsdb = ((struct temp_comp*)data)->comp_fsdb;
2105 obd = ((struct temp_comp *)data)->comp_obd;
2106 mgs = lu2mgs_dev(obd->obd_lu_dev);
2109 if (rec->lrh_type != OBD_CFG_REC) {
2110 CERROR("unhandled lrh_type: %#x\n", rec->lrh_type);
2114 rc = lustre_cfg_sanity_check(cfg_buf, cfg_len);
2116 CERROR("Insane cfg\n");
2120 lcfg = (struct lustre_cfg *)cfg_buf;
2122 if (lcfg->lcfg_command == LCFG_MARKER) {
2123 struct cfg_marker *marker;
2124 marker = lustre_cfg_buf(lcfg, 1);
2125 if (!strncmp(marker->cm_comment, "add osc", 7) &&
2126 (marker->cm_flags & CM_START) &&
2127 !(marker->cm_flags & CM_SKIP)) {
2128 got_an_osc_or_mdc = 1;
2129 cplen = strlcpy(tmti->mti_svname, marker->cm_tgtname,
2130 sizeof(tmti->mti_svname));
2131 if (cplen >= sizeof(tmti->mti_svname))
2133 rc = record_start_log(env, mgs, &mdt_llh,
2137 rc = record_marker(env, mdt_llh, fsdb, CM_START,
2138 mti->mti_svname, "add osc(copied)");
2139 record_end_log(env, &mdt_llh);
2140 last_step = marker->cm_step;
2143 if (!strncmp(marker->cm_comment, "add osc", 7) &&
2144 (marker->cm_flags & CM_END) &&
2145 !(marker->cm_flags & CM_SKIP)) {
2146 LASSERT(last_step == marker->cm_step);
2148 got_an_osc_or_mdc = 0;
2149 memset(tmti, 0, sizeof(*tmti));
2150 rc = record_start_log(env, mgs, &mdt_llh,
2154 rc = record_marker(env, mdt_llh, fsdb, CM_END,
2155 mti->mti_svname, "add osc(copied)");
2156 record_end_log(env, &mdt_llh);
2159 if (!strncmp(marker->cm_comment, "add mdc", 7) &&
2160 (marker->cm_flags & CM_START) &&
2161 !(marker->cm_flags & CM_SKIP)) {
2162 got_an_osc_or_mdc = 2;
2163 last_step = marker->cm_step;
2164 memcpy(tmti->mti_svname, marker->cm_tgtname,
2165 strlen(marker->cm_tgtname));
2169 if (!strncmp(marker->cm_comment, "add mdc", 7) &&
2170 (marker->cm_flags & CM_END) &&
2171 !(marker->cm_flags & CM_SKIP)) {
2172 LASSERT(last_step == marker->cm_step);
2174 got_an_osc_or_mdc = 0;
2175 memset(tmti, 0, sizeof(*tmti));
2180 if (got_an_osc_or_mdc == 0 || last_step < 0)
2183 if (lcfg->lcfg_command == LCFG_ADD_UUID) {
2184 __u64 nodenid = lcfg->lcfg_nid;
2186 if (strlen(tmti->mti_uuid) == 0) {
2187 /* target uuid not set, this config record is before
2188 * LCFG_SETUP, this nid is one of target node nid.
2190 tmti->mti_nids[tmti->mti_nid_count] = nodenid;
2191 tmti->mti_nid_count++;
2193 char nidstr[LNET_NIDSTR_SIZE];
2195 /* failover node nid */
2196 libcfs_nid2str_r(nodenid, nidstr, sizeof(nidstr));
2197 rc = add_param(tmti->mti_params, PARAM_FAILNODE,
2204 if (lcfg->lcfg_command == LCFG_SETUP) {
2207 target = lustre_cfg_string(lcfg, 1);
2208 memcpy(tmti->mti_uuid, target, strlen(target));
2212 /* ignore client side sptlrpc_conf_log */
2213 if (lcfg->lcfg_command == LCFG_SPTLRPC_CONF)
2216 if (lcfg->lcfg_command == LCFG_ADD_MDC &&
2217 strstr(lustre_cfg_string(lcfg, 0), "-clilmv") != NULL) {
2220 if (sscanf(lustre_cfg_buf(lcfg, 2), "%d", &index) != 1)
2223 memcpy(tmti->mti_fsname, mti->mti_fsname,
2224 strlen(mti->mti_fsname));
2225 tmti->mti_stripe_index = index;
2227 rc = mgs_write_log_osp_to_mdt(env, mgs, fsdb, tmti,
2228 mti->mti_stripe_index,
2230 memset(tmti, 0, sizeof(*tmti));
2234 if (lcfg->lcfg_command == LCFG_LOV_ADD_OBD) {
2237 char *logname, *lovname;
2239 rc = name_create_mdt_and_lov(&logname, &lovname, fsdb,
2240 mti->mti_stripe_index);
2243 sprintf(mdt_index, "-MDT%04x", mti->mti_stripe_index);
2245 if (sscanf(lustre_cfg_buf(lcfg, 2), "%d", &index) != 1) {
2246 name_destroy(&logname);
2247 name_destroy(&lovname);
2251 tmti->mti_stripe_index = index;
2252 rc = mgs_write_log_osc_to_lov(env, mgs, fsdb, tmti, logname,
2255 name_destroy(&logname);
2256 name_destroy(&lovname);
2262 /* fsdb->fsdb_mutex is already held in mgs_write_log_target*/
2263 /* stealed from mgs_get_fsdb_from_llog*/
2264 static int mgs_steal_llog_for_mdt_from_client(const struct lu_env *env,
2265 struct mgs_device *mgs,
2267 struct temp_comp* comp)
2269 struct llog_handle *loghandle;
2270 struct mgs_target_info *tmti;
2271 struct llog_ctxt *ctxt;
2276 ctxt = llog_get_context(mgs->mgs_obd, LLOG_CONFIG_ORIG_CTXT);
2277 LASSERT(ctxt != NULL);
2279 OBD_ALLOC_PTR(tmti);
2281 GOTO(out_ctxt, rc = -ENOMEM);
2283 comp->comp_tmti = tmti;
2284 comp->comp_obd = mgs->mgs_obd;
2286 rc = llog_open(env, ctxt, &loghandle, NULL, client_name,
2294 rc = llog_init_handle(env, loghandle, LLOG_F_IS_PLAIN, NULL);
2296 GOTO(out_close, rc);
2298 rc = llog_process_or_fork(env, loghandle, mgs_steal_client_llog_handler,
2299 (void *)comp, NULL, false);
2300 CDEBUG(D_MGS, "steal llog re = %d\n", rc);
2302 llog_close(env, loghandle);
2306 llog_ctxt_put(ctxt);
2310 /* lmv is the second thing for client logs */
2311 /* copied from mgs_write_log_lov. Please refer to that. */
2312 static int mgs_write_log_lmv(const struct lu_env *env,
2313 struct mgs_device *mgs,
2315 struct mgs_target_info *mti,
2316 char *logname, char *lmvname)
2318 struct llog_handle *llh = NULL;
2319 struct lmv_desc *lmvdesc;
2324 CDEBUG(D_MGS, "Writing lmv(%s) log for %s\n", lmvname,logname);
2326 OBD_ALLOC_PTR(lmvdesc);
2327 if (lmvdesc == NULL)
2329 lmvdesc->ld_active_tgt_count = 0;
2330 lmvdesc->ld_tgt_count = 0;
2331 sprintf((char*)lmvdesc->ld_uuid.uuid, "%s_UUID", lmvname);
2332 uuid = (char *)lmvdesc->ld_uuid.uuid;
2334 rc = record_start_log(env, mgs, &llh, logname);
2337 rc = record_marker(env, llh, fsdb, CM_START, lmvname, "lmv setup");
2340 rc = record_attach(env, llh, lmvname, "lmv", uuid);
2343 rc = record_lmv_setup(env, llh, lmvname, lmvdesc);
2346 rc = record_marker(env, llh, fsdb, CM_END, lmvname, "lmv setup");
2350 record_end_log(env, &llh);
2352 OBD_FREE_PTR(lmvdesc);
2356 /* lov is the first thing in the mdt and client logs */
2357 static int mgs_write_log_lov(const struct lu_env *env, struct mgs_device *mgs,
2358 struct fs_db *fsdb, struct mgs_target_info *mti,
2359 char *logname, char *lovname)
2361 struct llog_handle *llh = NULL;
2362 struct lov_desc *lovdesc;
2367 CDEBUG(D_MGS, "Writing lov(%s) log for %s\n", lovname, logname);
2370 #01 L attach 0:lov_mdsA 1:lov 2:71ccb_lov_mdsA_19f961a9e1
2371 #02 L lov_setup 0:lov_mdsA 1:(struct lov_desc)
2372 uuid=lov1_UUID, stripe count=1, size=1048576, offset=0, pattern=0
2375 /* FIXME just make lov_setup accept empty desc (put uuid in buf 2) */
2376 OBD_ALLOC_PTR(lovdesc);
2377 if (lovdesc == NULL)
2379 lovdesc->ld_magic = LOV_DESC_MAGIC;
2380 lovdesc->ld_tgt_count = 0;
2381 /* Defaults. Can be changed later by lcfg config_param */
2382 lovdesc->ld_default_stripe_count = 1;
2383 lovdesc->ld_pattern = LOV_PATTERN_RAID0;
2384 lovdesc->ld_default_stripe_size = LOV_DESC_STRIPE_SIZE_DEFAULT;
2385 lovdesc->ld_default_stripe_offset = -1;
2386 lovdesc->ld_qos_maxage = LOV_DESC_QOS_MAXAGE_DEFAULT;
2387 sprintf((char*)lovdesc->ld_uuid.uuid, "%s_UUID", lovname);
2388 /* can these be the same? */
2389 uuid = (char *)lovdesc->ld_uuid.uuid;
2391 /* This should always be the first entry in a log.
2392 rc = mgs_clear_log(obd, logname); */
2393 rc = record_start_log(env, mgs, &llh, logname);
2396 /* FIXME these should be a single journal transaction */
2397 rc = record_marker(env, llh, fsdb, CM_START, lovname, "lov setup");
2400 rc = record_attach(env, llh, lovname, "lov", uuid);
2403 rc = record_lov_setup(env, llh, lovname, lovdesc);
2406 rc = record_marker(env, llh, fsdb, CM_END, lovname, "lov setup");
2411 record_end_log(env, &llh);
2413 OBD_FREE_PTR(lovdesc);
2417 /* add failnids to open log */
2418 static int mgs_write_log_failnids(const struct lu_env *env,
2419 struct mgs_target_info *mti,
2420 struct llog_handle *llh,
2423 char *failnodeuuid = NULL;
2424 char *ptr = mti->mti_params;
2429 #03 L add_uuid nid=uml1@tcp(0x20000c0a80201) nal=90 0: 1:uml1_UUID
2430 #04 L add_uuid nid=1@elan(0x1000000000001) nal=90 0: 1:uml1_UUID
2431 #05 L setup 0:OSC_uml1_ost1_mdsA 1:ost1_UUID 2:uml1_UUID
2432 #06 L add_uuid nid=uml2@tcp(0x20000c0a80202) nal=90 0: 1:uml2_UUID
2433 #0x L add_uuid nid=2@elan(0x1000000000002) nal=90 0: 1:uml2_UUID
2434 #07 L add_conn 0:OSC_uml1_ost1_mdsA 1:uml2_UUID
2438 * Pull failnid info out of params string, which may contain something
2439 * like "<nid1>,<nid2>:<nid3>,<nid4>". class_parse_nid() does not
2440 * complain about abnormal inputs like ",:<nid1>", "<nid1>:,<nid2>",
2441 * etc. However, convert_hostnames() should have caught those.
2443 while (class_find_param(ptr, PARAM_FAILNODE, &ptr) == 0) {
2444 while (class_parse_nid(ptr, &nid, &ptr) == 0) {
2445 char nidstr[LNET_NIDSTR_SIZE];
2447 if (failnodeuuid == NULL) {
2448 /* We don't know the failover node name,
2449 * so just use the first nid as the uuid */
2450 libcfs_nid2str_r(nid, nidstr, sizeof(nidstr));
2451 rc = name_create(&failnodeuuid, nidstr, "");
2455 CDEBUG(D_MGS, "add nid %s for failover uuid %s, "
2457 libcfs_nid2str_r(nid, nidstr, sizeof(nidstr)),
2458 failnodeuuid, cliname);
2459 rc = record_add_uuid(env, llh, nid, failnodeuuid);
2461 * If *ptr is ':', we have added all NIDs for
2465 rc = record_add_conn(env, llh, cliname,
2467 name_destroy(&failnodeuuid);
2468 failnodeuuid = NULL;
2472 rc = record_add_conn(env, llh, cliname, failnodeuuid);
2473 name_destroy(&failnodeuuid);
2474 failnodeuuid = NULL;
2481 static int mgs_write_log_mdc_to_lmv(const struct lu_env *env,
2482 struct mgs_device *mgs,
2484 struct mgs_target_info *mti,
2485 char *logname, char *lmvname)
2487 struct llog_handle *llh = NULL;
2488 char *mdcname = NULL;
2489 char *nodeuuid = NULL;
2490 char *mdcuuid = NULL;
2491 char *lmvuuid = NULL;
2493 char nidstr[LNET_NIDSTR_SIZE];
2497 if (mgs_log_is_empty(env, mgs, logname)) {
2498 CERROR("log is empty! Logical error\n");
2502 CDEBUG(D_MGS, "adding mdc for %s to log %s:lmv(%s)\n",
2503 mti->mti_svname, logname, lmvname);
2505 libcfs_nid2str_r(mti->mti_nids[0], nidstr, sizeof(nidstr));
2506 rc = name_create(&nodeuuid, nidstr, "");
2509 rc = name_create(&mdcname, mti->mti_svname, "-mdc");
2512 rc = name_create(&mdcuuid, mdcname, "_UUID");
2515 rc = name_create(&lmvuuid, lmvname, "_UUID");
2519 rc = record_start_log(env, mgs, &llh, logname);
2522 rc = record_marker(env, llh, fsdb, CM_START, mti->mti_svname,
2526 for (i = 0; i < mti->mti_nid_count; i++) {
2527 CDEBUG(D_MGS, "add nid %s for mdt\n",
2528 libcfs_nid2str_r(mti->mti_nids[i],
2529 nidstr, sizeof(nidstr)));
2531 rc = record_add_uuid(env, llh, mti->mti_nids[i], nodeuuid);
2536 rc = record_attach(env, llh, mdcname, LUSTRE_MDC_NAME, lmvuuid);
2539 rc = record_setup(env, llh, mdcname, mti->mti_uuid, nodeuuid,
2543 rc = mgs_write_log_failnids(env, mti, llh, mdcname);
2546 snprintf(index, sizeof(index), "%d", mti->mti_stripe_index);
2547 rc = record_mdc_add(env, llh, lmvname, mdcuuid, mti->mti_uuid,
2551 rc = record_marker(env, llh, fsdb, CM_END, mti->mti_svname,
2556 record_end_log(env, &llh);
2558 name_destroy(&lmvuuid);
2559 name_destroy(&mdcuuid);
2560 name_destroy(&mdcname);
2561 name_destroy(&nodeuuid);
2565 static inline int name_create_lov(char **lovname, char *mdtname,
2566 struct fs_db *fsdb, int index)
2569 if (index == 0 && test_bit(FSDB_OSCNAME18, &fsdb->fsdb_flags))
2570 return name_create(lovname, fsdb->fsdb_name, "-mdtlov");
2572 return name_create(lovname, mdtname, "-mdtlov");
2575 static int name_create_mdt_and_lov(char **logname, char **lovname,
2576 struct fs_db *fsdb, int i)
2580 rc = name_create_mdt(logname, fsdb->fsdb_name, i);
2584 if (i == 0 && test_bit(FSDB_OSCNAME18, &fsdb->fsdb_flags))
2585 rc = name_create(lovname, fsdb->fsdb_name, "-mdtlov");
2587 rc = name_create(lovname, *logname, "-mdtlov");
2589 name_destroy(logname);
2595 static inline int name_create_mdt_osc(char **oscname, char *ostname,
2596 struct fs_db *fsdb, int i)
2600 if (i == 0 && test_bit(FSDB_OSCNAME18, &fsdb->fsdb_flags))
2601 sprintf(suffix, "-osc");
2603 sprintf(suffix, "-osc-MDT%04x", i);
2604 return name_create(oscname, ostname, suffix);
2607 /* add new mdc to already existent MDS */
2608 static int mgs_write_log_osp_to_mdt(const struct lu_env *env,
2609 struct mgs_device *mgs,
2611 struct mgs_target_info *mti,
2612 int mdt_index, char *logname)
2614 struct llog_handle *llh = NULL;
2615 char *nodeuuid = NULL;
2616 char *ospname = NULL;
2617 char *lovuuid = NULL;
2618 char *mdtuuid = NULL;
2619 char *svname = NULL;
2620 char *mdtname = NULL;
2621 char *lovname = NULL;
2623 char nidstr[LNET_NIDSTR_SIZE];
2627 if (mgs_log_is_empty(env, mgs, mti->mti_svname)) {
2628 CERROR("log is empty! Logical error\n");
2632 CDEBUG(D_MGS, "adding osp index %d to %s\n", mti->mti_stripe_index,
2635 rc = name_create_mdt(&mdtname, fsdb->fsdb_name, mti->mti_stripe_index);
2639 libcfs_nid2str_r(mti->mti_nids[0], nidstr, sizeof(nidstr));
2640 rc = name_create(&nodeuuid, nidstr, "");
2642 GOTO(out_destory, rc);
2644 rc = name_create(&svname, mdtname, "-osp");
2646 GOTO(out_destory, rc);
2648 sprintf(index_str, "-MDT%04x", mdt_index);
2649 rc = name_create(&ospname, svname, index_str);
2651 GOTO(out_destory, rc);
2653 rc = name_create_lov(&lovname, logname, fsdb, mdt_index);
2655 GOTO(out_destory, rc);
2657 rc = name_create(&lovuuid, lovname, "_UUID");
2659 GOTO(out_destory, rc);
2661 rc = name_create(&mdtuuid, mdtname, "_UUID");
2663 GOTO(out_destory, rc);
2665 rc = record_start_log(env, mgs, &llh, logname);
2667 GOTO(out_destory, rc);
2669 rc = record_marker(env, llh, fsdb, CM_START, mti->mti_svname,
2672 GOTO(out_destory, rc);
2674 for (i = 0; i < mti->mti_nid_count; i++) {
2675 CDEBUG(D_MGS, "add nid %s for mdt\n",
2676 libcfs_nid2str_r(mti->mti_nids[i],
2677 nidstr, sizeof(nidstr)));
2678 rc = record_add_uuid(env, llh, mti->mti_nids[i], nodeuuid);
2683 rc = record_attach(env, llh, ospname, LUSTRE_OSP_NAME, lovuuid);
2687 rc = record_setup(env, llh, ospname, mti->mti_uuid, nodeuuid,
2692 rc = mgs_write_log_failnids(env, mti, llh, ospname);
2696 /* Add mdc(osp) to lod */
2697 snprintf(index_str, sizeof(index_str), "%d", mti->mti_stripe_index);
2698 rc = record_base(env, llh, lovname, 0, LCFG_ADD_MDC, mti->mti_uuid,
2699 index_str, "1", NULL);
2703 rc = record_marker(env, llh, fsdb, CM_END, mti->mti_svname, "add osp");
2708 record_end_log(env, &llh);
2711 name_destroy(&mdtuuid);
2712 name_destroy(&lovuuid);
2713 name_destroy(&lovname);
2714 name_destroy(&ospname);
2715 name_destroy(&svname);
2716 name_destroy(&nodeuuid);
2717 name_destroy(&mdtname);
2721 static int mgs_write_log_mdt0(const struct lu_env *env,
2722 struct mgs_device *mgs,
2724 struct mgs_target_info *mti)
2726 char *log = mti->mti_svname;
2727 struct llog_handle *llh = NULL;
2728 struct obd_uuid *uuid;
2731 char *ptr = mti->mti_params;
2732 int rc = 0, failout = 0;
2735 OBD_ALLOC_PTR(uuid);
2739 if (class_find_param(ptr, PARAM_FAILMODE, &ptr) == 0)
2740 failout = (strncmp(ptr, "failout", 7) == 0);
2742 rc = name_create(&lovname, log, "-mdtlov");
2745 if (mgs_log_is_empty(env, mgs, log)) {
2746 rc = mgs_write_log_lov(env, mgs, fsdb, mti, log, lovname);
2751 sprintf(mdt_index, "%d", mti->mti_stripe_index);
2753 rc = record_start_log(env, mgs, &llh, log);
2757 /* add MDT itself */
2759 /* FIXME this whole fn should be a single journal transaction */
2760 sprintf(uuid->uuid, "%s_UUID", log);
2761 rc = record_marker(env, llh, fsdb, CM_START, log, "add mdt");
2764 rc = record_attach(env, llh, log, LUSTRE_MDT_NAME, uuid->uuid);
2767 rc = record_mount_opt(env, llh, log, lovname, NULL);
2770 rc = record_setup(env, llh, log, uuid->uuid, mdt_index, lovname,
2771 failout ? "n" : "f");
2774 rc = record_marker(env, llh, fsdb, CM_END, log, "add mdt");
2778 record_end_log(env, &llh);
2780 name_destroy(&lovname);
2786 /* envelope method for all layers log */
2787 static int mgs_write_log_mdt(const struct lu_env *env,
2788 struct mgs_device *mgs,
2790 struct mgs_target_info *mti)
2792 struct mgs_thread_info *mgi = mgs_env_info(env);
2793 struct llog_handle *llh = NULL;
2798 CDEBUG(D_MGS, "writing new mdt %s\n", mti->mti_svname);
2800 if (mti->mti_uuid[0] == '\0') {
2801 /* Make up our own uuid */
2802 snprintf(mti->mti_uuid, sizeof(mti->mti_uuid),
2803 "%s_UUID", mti->mti_svname);
2807 rc = mgs_write_log_mdt0(env, mgs, fsdb, mti);
2810 /* Append the mdt info to the client log */
2811 rc = name_create(&cliname, mti->mti_fsname, "-client");
2815 if (mgs_log_is_empty(env, mgs, cliname)) {
2816 /* Start client log */
2817 rc = mgs_write_log_lov(env, mgs, fsdb, mti, cliname,
2821 rc = mgs_write_log_lmv(env, mgs, fsdb, mti, cliname,
2828 #09 L add_uuid nid=uml1@tcp(0x20000c0a80201) 0: 1:uml1_UUID
2829 #10 L attach 0:MDC_uml1_mdsA_MNT_client 1:mdc 2:1d834_MNT_client_03f
2830 #11 L setup 0:MDC_uml1_mdsA_MNT_client 1:mdsA_UUID 2:uml1_UUID
2831 #12 L add_uuid nid=uml2@tcp(0x20000c0a80202) 0: 1:uml2_UUID
2832 #13 L add_conn 0:MDC_uml1_mdsA_MNT_client 1:uml2_UUID
2833 #14 L mount_option 0: 1:client 2:lov1 3:MDC_uml1_mdsA_MNT_client
2836 /* copy client info about lov/lmv */
2837 mgi->mgi_comp.comp_mti = mti;
2838 mgi->mgi_comp.comp_fsdb = fsdb;
2840 rc = mgs_steal_llog_for_mdt_from_client(env, mgs, cliname,
2844 rc = mgs_write_log_mdc_to_lmv(env, mgs, fsdb, mti, cliname,
2850 rc = record_start_log(env, mgs, &llh, cliname);
2854 rc = record_marker(env, llh, fsdb, CM_START, cliname, "mount opts");
2857 rc = record_mount_opt(env, llh, cliname, fsdb->fsdb_clilov,
2861 rc = record_marker(env, llh, fsdb, CM_END, cliname, "mount opts");
2865 /* for_all_existing_mdt except current one */
2866 for (i = 0; i < INDEX_MAP_SIZE * 8; i++) {
2867 if (i != mti->mti_stripe_index &&
2868 test_bit(i, fsdb->fsdb_mdt_index_map)) {
2871 rc = name_create_mdt(&logname, fsdb->fsdb_name, i);
2875 /* NB: If the log for the MDT is empty, it means
2876 * the MDT is only added to the index
2877 * map, and not being process yet, i.e. this
2878 * is an unregistered MDT, see mgs_write_log_target().
2879 * so we should skip it. Otherwise
2881 * 1. MGS get register request for MDT1 and MDT2.
2883 * 2. Then both MDT1 and MDT2 are added into
2884 * fsdb_mdt_index_map. (see mgs_set_index()).
2886 * 3. Then MDT1 get the lock of fsdb_mutex, then
2887 * generate the config log, here, it will regard MDT2
2888 * as an existent MDT, and generate "add osp" for
2889 * lustre-MDT0001-osp-MDT0002. Note: at the moment
2890 * MDT0002 config log is still empty, so it will
2891 * add "add osp" even before "lov setup", which
2892 * will definitly cause trouble.
2894 * 4. MDT1 registeration finished, fsdb_mutex is
2895 * released, then MDT2 get in, then in above
2896 * mgs_steal_llog_for_mdt_from_client(), it will
2897 * add another osp log for lustre-MDT0001-osp-MDT0002,
2898 * which will cause another trouble.*/
2899 if (!mgs_log_is_empty(env, mgs, logname))
2900 rc = mgs_write_log_osp_to_mdt(env, mgs, fsdb,
2903 name_destroy(&logname);
2909 record_end_log(env, &llh);
2911 name_destroy(&cliname);
2915 /* Add the ost info to the client/mdt lov */
2916 static int mgs_write_log_osc_to_lov(const struct lu_env *env,
2917 struct mgs_device *mgs, struct fs_db *fsdb,
2918 struct mgs_target_info *mti,
2919 char *logname, char *suffix, char *lovname,
2920 enum lustre_sec_part sec_part, int flags)
2922 struct llog_handle *llh = NULL;
2923 char *nodeuuid = NULL;
2924 char *oscname = NULL;
2925 char *oscuuid = NULL;
2926 char *lovuuid = NULL;
2927 char *svname = NULL;
2929 char nidstr[LNET_NIDSTR_SIZE];
2933 CDEBUG(D_INFO, "adding osc for %s to log %s\n",
2934 mti->mti_svname, logname);
2936 if (mgs_log_is_empty(env, mgs, logname)) {
2937 CERROR("log is empty! Logical error\n");
2941 libcfs_nid2str_r(mti->mti_nids[0], nidstr, sizeof(nidstr));
2942 rc = name_create(&nodeuuid, nidstr, "");
2945 rc = name_create(&svname, mti->mti_svname, "-osc");
2949 /* for the system upgraded from old 1.8, keep using the old osc naming
2950 * style for mdt, see name_create_mdt_osc(). LU-1257 */
2951 if (test_bit(FSDB_OSCNAME18, &fsdb->fsdb_flags))
2952 rc = name_create(&oscname, svname, "");
2954 rc = name_create(&oscname, svname, suffix);
2958 rc = name_create(&oscuuid, oscname, "_UUID");
2961 rc = name_create(&lovuuid, lovname, "_UUID");
2967 #03 L add_uuid nid=uml1@tcp(0x20000c0a80201) 0: 1:uml1_UUID
2969 #04 L add_uuid nid=1@elan(0x1000000000001) nal=90 0: 1:uml1_UUID
2970 #04 L attach 0:OSC_uml1_ost1_MNT_client 1:osc 2:89070_lov1_a41dff51a
2971 #05 L setup 0:OSC_uml1_ost1_MNT_client 1:ost1_UUID 2:uml1_UUID
2973 #06 L add_uuid nid=uml2@tcp(0x20000c0a80202) 0: 1:uml2_UUID
2974 #07 L add_conn 0:OSC_uml1_ost1_MNT_client 1:uml2_UUID
2975 #08 L lov_modify_tgts add 0:lov1 1:ost1_UUID 2(index):0 3(gen):1
2978 rc = record_start_log(env, mgs, &llh, logname);
2982 /* FIXME these should be a single journal transaction */
2983 rc = record_marker(env, llh, fsdb, CM_START | flags, mti->mti_svname,
2988 /* NB: don't change record order, because upon MDT steal OSC config
2989 * from client, it treats all nids before LCFG_SETUP as target nids
2990 * (multiple interfaces), while nids after as failover node nids.
2991 * See mgs_steal_client_llog_handler() LCFG_ADD_UUID.
2993 for (i = 0; i < mti->mti_nid_count; i++) {
2994 CDEBUG(D_MGS, "add nid %s\n",
2995 libcfs_nid2str_r(mti->mti_nids[i],
2996 nidstr, sizeof(nidstr)));
2997 rc = record_add_uuid(env, llh, mti->mti_nids[i], nodeuuid);
3001 rc = record_attach(env, llh, oscname, LUSTRE_OSC_NAME, lovuuid);
3004 rc = record_setup(env, llh, oscname, mti->mti_uuid, nodeuuid,
3008 rc = mgs_write_log_failnids(env, mti, llh, oscname);
3012 snprintf(index, sizeof(index), "%d", mti->mti_stripe_index);
3014 rc = record_lov_add(env, llh, lovname, mti->mti_uuid, index, "1");
3017 rc = record_marker(env, llh, fsdb, CM_END | flags, mti->mti_svname,
3022 record_end_log(env, &llh);
3024 name_destroy(&lovuuid);
3025 name_destroy(&oscuuid);
3026 name_destroy(&oscname);
3027 name_destroy(&svname);
3028 name_destroy(&nodeuuid);
3032 static int mgs_write_log_ost(const struct lu_env *env,
3033 struct mgs_device *mgs, struct fs_db *fsdb,
3034 struct mgs_target_info *mti)
3036 struct llog_handle *llh = NULL;
3037 char *logname, *lovname;
3038 char *ptr = mti->mti_params;
3039 int rc, flags = 0, failout = 0, i;
3042 CDEBUG(D_MGS, "writing new ost %s\n", mti->mti_svname);
3044 /* The ost startup log */
3046 /* If the ost log already exists, that means that someone reformatted
3047 the ost and it called target_add again. */
3048 if (!mgs_log_is_empty(env, mgs, mti->mti_svname)) {
3049 LCONSOLE_ERROR_MSG(0x141, "The config log for %s already "
3050 "exists, yet the server claims it never "
3051 "registered. It may have been reformatted, "
3052 "or the index changed. writeconf the MDT to "
3053 "regenerate all logs.\n", mti->mti_svname);
3058 attach obdfilter ost1 ost1_UUID
3059 setup /dev/loop2 ldiskfs f|n errors=remount-ro,user_xattr
3061 if (class_find_param(ptr, PARAM_FAILMODE, &ptr) == 0)
3062 failout = (strncmp(ptr, "failout", 7) == 0);
3063 rc = record_start_log(env, mgs, &llh, mti->mti_svname);
3066 /* FIXME these should be a single journal transaction */
3067 rc = record_marker(env, llh, fsdb, CM_START, mti->mti_svname,"add ost");
3070 if (*mti->mti_uuid == '\0')
3071 snprintf(mti->mti_uuid, sizeof(mti->mti_uuid),
3072 "%s_UUID", mti->mti_svname);
3073 rc = record_attach(env, llh, mti->mti_svname,
3074 "obdfilter"/*LUSTRE_OST_NAME*/, mti->mti_uuid);
3077 rc = record_setup(env, llh, mti->mti_svname,
3078 "dev"/*ignored*/, "type"/*ignored*/,
3079 failout ? "n" : "f", NULL/*options*/);
3082 rc = record_marker(env, llh, fsdb, CM_END, mti->mti_svname, "add ost");
3086 record_end_log(env, &llh);
3089 /* We also have to update the other logs where this osc is part of
3092 if (test_bit(FSDB_OLDLOG14, &fsdb->fsdb_flags)) {
3093 /* If we're upgrading, the old mdt log already has our
3094 entry. Let's do a fake one for fun. */
3095 /* Note that we can't add any new failnids, since we don't
3096 know the old osc names. */
3097 flags = CM_SKIP | CM_UPGRADE146;
3099 } else if ((mti->mti_flags & LDD_F_UPDATE) != LDD_F_UPDATE) {
3100 /* If the update flag isn't set, don't update client/mdt
3103 LCONSOLE_WARN("Client log for %s was not updated; writeconf "
3104 "the MDT first to regenerate it.\n",
3108 /* Add ost to all MDT lov defs */
3109 for (i = 0; i < INDEX_MAP_SIZE * 8; i++){
3110 if (test_bit(i, fsdb->fsdb_mdt_index_map)) {
3113 rc = name_create_mdt_and_lov(&logname, &lovname, fsdb,
3118 snprintf(mdt_index, sizeof(mdt_index), "-MDT%04x", i);
3119 rc = mgs_write_log_osc_to_lov(env, mgs, fsdb, mti,
3121 lovname, LUSTRE_SP_MDT,
3123 name_destroy(&logname);
3124 name_destroy(&lovname);
3130 /* Append ost info to the client log */
3131 rc = name_create(&logname, mti->mti_fsname, "-client");
3134 if (mgs_log_is_empty(env, mgs, logname)) {
3135 /* Start client log */
3136 rc = mgs_write_log_lov(env, mgs, fsdb, mti, logname,
3140 rc = mgs_write_log_lmv(env, mgs, fsdb, mti, logname,
3145 rc = mgs_write_log_osc_to_lov(env, mgs, fsdb, mti, logname, "",
3146 fsdb->fsdb_clilov, LUSTRE_SP_CLI, flags);
3148 name_destroy(&logname);
3152 static __inline__ int mgs_param_empty(char *ptr)
3156 if ((tmp = strchr(ptr, '=')) && (*(++tmp) == '\0'))
3161 static int mgs_write_log_failnid_internal(const struct lu_env *env,
3162 struct mgs_device *mgs,
3164 struct mgs_target_info *mti,
3165 char *logname, char *cliname)
3168 struct llog_handle *llh = NULL;
3170 if (mgs_param_empty(mti->mti_params)) {
3171 /* Remove _all_ failnids */
3172 rc = mgs_modify(env, mgs, fsdb, mti, logname,
3173 mti->mti_svname, "add failnid", CM_SKIP);
3174 return rc < 0 ? rc : 0;
3177 /* Otherwise failover nids are additive */
3178 rc = record_start_log(env, mgs, &llh, logname);
3181 /* FIXME this should be a single journal transaction */
3182 rc = record_marker(env, llh, fsdb, CM_START, mti->mti_svname,
3186 rc = mgs_write_log_failnids(env, mti, llh, cliname);
3189 rc = record_marker(env, llh, fsdb, CM_END,
3190 mti->mti_svname, "add failnid");
3192 record_end_log(env, &llh);
3197 /* Add additional failnids to an existing log.
3198 The mdc/osc must have been added to logs first */
3199 /* tcp nids must be in dotted-quad ascii -
3200 we can't resolve hostnames from the kernel. */
3201 static int mgs_write_log_add_failnid(const struct lu_env *env,
3202 struct mgs_device *mgs,
3204 struct mgs_target_info *mti)
3206 char *logname, *cliname;
3210 /* FIXME we currently can't erase the failnids
3211 * given when a target first registers, since they aren't part of
3212 * an "add uuid" stanza
3215 /* Verify that we know about this target */
3216 if (mgs_log_is_empty(env, mgs, mti->mti_svname)) {
3217 LCONSOLE_ERROR_MSG(0x142, "The target %s has not registered "
3218 "yet. It must be started before failnids "
3219 "can be added.\n", mti->mti_svname);
3223 /* Create mdc/osc client name (e.g. lustre-OST0001-osc) */
3224 if (mti->mti_flags & LDD_F_SV_TYPE_MDT) {
3225 rc = name_create(&cliname, mti->mti_svname, "-mdc");
3226 } else if (mti->mti_flags & LDD_F_SV_TYPE_OST) {
3227 rc = name_create(&cliname, mti->mti_svname, "-osc");
3234 /* Add failover nids to the client log */
3235 rc = name_create(&logname, mti->mti_fsname, "-client");
3237 name_destroy(&cliname);
3241 rc = mgs_write_log_failnid_internal(env, mgs, fsdb,mti,logname,cliname);
3242 name_destroy(&logname);
3243 name_destroy(&cliname);
3247 if (mti->mti_flags & LDD_F_SV_TYPE_OST) {
3248 /* Add OST failover nids to the MDT logs as well */
3251 for (i = 0; i < INDEX_MAP_SIZE * 8; i++) {
3252 if (!test_bit(i, fsdb->fsdb_mdt_index_map))
3254 rc = name_create_mdt(&logname, mti->mti_fsname, i);
3257 rc = name_create_mdt_osc(&cliname, mti->mti_svname,
3260 name_destroy(&logname);
3263 rc = mgs_write_log_failnid_internal(env, mgs, fsdb,
3266 name_destroy(&cliname);
3267 name_destroy(&logname);
3276 static int mgs_wlp_lcfg(const struct lu_env *env,
3277 struct mgs_device *mgs, struct fs_db *fsdb,
3278 struct mgs_target_info *mti,
3279 char *logname, struct lustre_cfg_bufs *bufs,
3280 char *tgtname, char *ptr)
3282 char comment[MTI_NAME_MAXLEN];
3284 struct llog_cfg_rec *lcr;
3287 /* Erase any old settings of this same parameter */
3288 memcpy(comment, ptr, MTI_NAME_MAXLEN);
3289 comment[MTI_NAME_MAXLEN - 1] = 0;
3290 /* But don't try to match the value. */
3291 tmp = strchr(comment, '=');
3294 /* FIXME we should skip settings that are the same as old values */
3295 rc = mgs_modify(env, mgs, fsdb, mti, logname, tgtname, comment,CM_SKIP);
3298 del = mgs_param_empty(ptr);
3300 LCONSOLE_INFO("%s parameter %s.%s in log %s\n", del ? "Disabling" : rc ?
3301 "Setting" : "Modifying", tgtname, comment, logname);
3303 /* mgs_modify() will return 1 if nothing had to be done */
3309 lustre_cfg_bufs_reset(bufs, tgtname);
3310 lustre_cfg_bufs_set_string(bufs, 1, ptr);
3311 if (mti->mti_flags & LDD_F_PARAM2)
3312 lustre_cfg_bufs_set_string(bufs, 2, LCTL_UPCALL);
3314 lcr = lustre_cfg_rec_new((mti->mti_flags & LDD_F_PARAM2) ?
3315 LCFG_SET_PARAM : LCFG_PARAM, bufs);
3319 rc = mgs_write_log_direct(env, mgs, fsdb, logname, lcr, tgtname,
3321 lustre_cfg_rec_free(lcr);
3325 /* write global variable settings into log */
3326 static int mgs_write_log_sys(const struct lu_env *env,
3327 struct mgs_device *mgs, struct fs_db *fsdb,
3328 struct mgs_target_info *mti, char *sys, char *ptr)
3330 struct mgs_thread_info *mgi = mgs_env_info(env);
3331 struct lustre_cfg *lcfg;
3332 struct llog_cfg_rec *lcr;
3334 int rc, cmd, convert = 1;
3336 if (class_match_param(ptr, PARAM_TIMEOUT, &tmp) == 0) {
3337 cmd = LCFG_SET_TIMEOUT;
3338 } else if (class_match_param(ptr, PARAM_LDLM_TIMEOUT, &tmp) == 0) {
3339 cmd = LCFG_SET_LDLM_TIMEOUT;
3340 /* Check for known params here so we can return error to lctl */
3341 } else if ((class_match_param(ptr, PARAM_AT_MIN, &tmp) == 0) ||
3342 (class_match_param(ptr, PARAM_AT_MAX, &tmp) == 0) ||
3343 (class_match_param(ptr, PARAM_AT_EXTRA, &tmp) == 0) ||
3344 (class_match_param(ptr, PARAM_AT_EARLY_MARGIN, &tmp) == 0) ||
3345 (class_match_param(ptr, PARAM_AT_HISTORY, &tmp) == 0)) {
3347 } else if (class_match_param(ptr, PARAM_JOBID_VAR, &tmp) == 0) {
3348 convert = 0; /* Don't convert string value to integer */
3354 if (mgs_param_empty(ptr))
3355 CDEBUG(D_MGS, "global '%s' removed\n", sys);
3357 CDEBUG(D_MGS, "global '%s' val=%s\n", sys, tmp);
3359 lustre_cfg_bufs_reset(&mgi->mgi_bufs, NULL);
3360 lustre_cfg_bufs_set_string(&mgi->mgi_bufs, 1, sys);
3361 if (!convert && *tmp != '\0')
3362 lustre_cfg_bufs_set_string(&mgi->mgi_bufs, 2, tmp);
3363 lcr = lustre_cfg_rec_new(cmd, &mgi->mgi_bufs);
3367 lcfg = &lcr->lcr_cfg;
3369 rc = kstrtouint(tmp, 0, &lcfg->lcfg_num);
3371 GOTO(out_rec_free, rc);
3376 /* truncate the comment to the parameter name */
3380 /* modify all servers and clients */
3381 rc = mgs_write_log_direct_all(env, mgs, fsdb, mti,
3382 *tmp == '\0' ? NULL : lcr,
3383 mti->mti_fsname, sys, 0);
3384 if (rc == 0 && *tmp != '\0') {
3386 case LCFG_SET_TIMEOUT:
3387 if (!obd_timeout_set || lcfg->lcfg_num > obd_timeout)
3388 class_process_config(lcfg);
3390 case LCFG_SET_LDLM_TIMEOUT:
3391 if (!ldlm_timeout_set || lcfg->lcfg_num > ldlm_timeout)
3392 class_process_config(lcfg);
3400 lustre_cfg_rec_free(lcr);
3404 /* write quota settings into log */
3405 static int mgs_write_log_quota(const struct lu_env *env, struct mgs_device *mgs,
3406 struct fs_db *fsdb, struct mgs_target_info *mti,
3407 char *quota, char *ptr)
3409 struct mgs_thread_info *mgi = mgs_env_info(env);
3410 struct llog_cfg_rec *lcr;
3413 int rc, cmd = LCFG_PARAM;
3415 /* support only 'meta' and 'data' pools so far */
3416 if (class_match_param(ptr, QUOTA_METAPOOL_NAME, &tmp) != 0 &&
3417 class_match_param(ptr, QUOTA_DATAPOOL_NAME, &tmp) != 0) {
3418 CERROR("parameter quota.%s isn't supported (only quota.mdt "
3419 "& quota.ost are)\n", ptr);
3424 CDEBUG(D_MGS, "global '%s' removed\n", quota);
3426 CDEBUG(D_MGS, "global '%s'\n", quota);
3428 if (strchr(tmp, 'u') == NULL && strchr(tmp, 'g') == NULL &&
3429 strchr(tmp, 'p') == NULL &&
3430 strcmp(tmp, "none") != 0) {
3431 CERROR("enable option(%s) isn't supported\n", tmp);
3436 lustre_cfg_bufs_reset(&mgi->mgi_bufs, mti->mti_fsname);
3437 lustre_cfg_bufs_set_string(&mgi->mgi_bufs, 1, quota);
3438 lcr = lustre_cfg_rec_new(cmd, &mgi->mgi_bufs);
3442 /* truncate the comment to the parameter name */
3447 /* XXX we duplicated quota enable information in all server
3448 * config logs, it should be moved to a separate config
3449 * log once we cleanup the config log for global param. */
3450 /* modify all servers */
3451 rc = mgs_write_log_direct_all(env, mgs, fsdb, mti,
3452 *tmp == '\0' ? NULL : lcr,
3453 mti->mti_fsname, quota, 1);
3455 lustre_cfg_rec_free(lcr);
3456 return rc < 0 ? rc : 0;
3459 static int mgs_srpc_set_param_disk(const struct lu_env *env,
3460 struct mgs_device *mgs,
3462 struct mgs_target_info *mti,
3465 struct mgs_thread_info *mgi = mgs_env_info(env);
3466 struct llog_cfg_rec *lcr;
3467 struct llog_handle *llh = NULL;
3469 char *comment, *ptr;
3475 ptr = strchr(param, '=');
3476 LASSERT(ptr != NULL);
3479 OBD_ALLOC(comment, len + 1);
3480 if (comment == NULL)
3482 strncpy(comment, param, len);
3483 comment[len] = '\0';
3486 lustre_cfg_bufs_reset(&mgi->mgi_bufs, mti->mti_svname);
3487 lustre_cfg_bufs_set_string(&mgi->mgi_bufs, 1, param);
3488 lcr = lustre_cfg_rec_new(LCFG_SPTLRPC_CONF, &mgi->mgi_bufs);
3490 GOTO(out_comment, rc = -ENOMEM);
3492 /* construct log name */
3493 rc = name_create(&logname, mti->mti_fsname, "-sptlrpc");
3497 if (mgs_log_is_empty(env, mgs, logname)) {
3498 rc = record_start_log(env, mgs, &llh, logname);
3501 record_end_log(env, &llh);
3504 /* obsolete old one */
3505 rc = mgs_modify(env, mgs, fsdb, mti, logname, mti->mti_svname,
3509 /* write the new one */
3510 rc = mgs_write_log_direct(env, mgs, fsdb, logname, lcr,
3511 mti->mti_svname, comment);
3513 CERROR("%s: error writing log %s: rc = %d\n",
3514 mgs->mgs_obd->obd_name, logname, rc);
3516 name_destroy(&logname);
3518 lustre_cfg_rec_free(lcr);
3520 OBD_FREE(comment, len + 1);
3524 static int mgs_srpc_set_param_udesc_mem(struct fs_db *fsdb,
3529 /* disable the adjustable udesc parameter for now, i.e. use default
3530 * setting that client always ship udesc to MDT if possible. to enable
3531 * it simply remove the following line */
3534 ptr = strchr(param, '=');
3539 if (strcmp(param, PARAM_SRPC_UDESC))
3542 if (strcmp(ptr, "yes") == 0) {
3543 set_bit(FSDB_UDESC, &fsdb->fsdb_flags);
3544 CWARN("Enable user descriptor shipping from client to MDT\n");
3545 } else if (strcmp(ptr, "no") == 0) {
3546 clear_bit(FSDB_UDESC, &fsdb->fsdb_flags);
3547 CWARN("Disable user descriptor shipping from client to MDT\n");
3555 CERROR("Invalid param: %s\n", param);
3559 static int mgs_srpc_set_param_mem(struct fs_db *fsdb,
3563 struct sptlrpc_rule rule;
3564 struct sptlrpc_rule_set *rset;
3568 if (strncmp(param, PARAM_SRPC, sizeof(PARAM_SRPC) - 1) != 0) {
3569 CERROR("Invalid sptlrpc parameter: %s\n", param);
3573 if (strncmp(param, PARAM_SRPC_UDESC,
3574 sizeof(PARAM_SRPC_UDESC) - 1) == 0) {
3575 RETURN(mgs_srpc_set_param_udesc_mem(fsdb, param));
3578 if (strncmp(param, PARAM_SRPC_FLVR, sizeof(PARAM_SRPC_FLVR) - 1) != 0) {
3579 CERROR("Invalid sptlrpc flavor parameter: %s\n", param);
3583 param += sizeof(PARAM_SRPC_FLVR) - 1;
3585 rc = sptlrpc_parse_rule(param, &rule);
3589 /* mgs rules implies must be mgc->mgs */
3590 if (test_bit(FSDB_MGS_SELF, &fsdb->fsdb_flags)) {
3591 if ((rule.sr_from != LUSTRE_SP_MGC &&
3592 rule.sr_from != LUSTRE_SP_ANY) ||
3593 (rule.sr_to != LUSTRE_SP_MGS &&
3594 rule.sr_to != LUSTRE_SP_ANY))
3598 /* preapre room for this coming rule. svcname format should be:
3599 * - fsname: general rule
3600 * - fsname-tgtname: target-specific rule
3602 if (strchr(svname, '-')) {
3603 struct mgs_tgt_srpc_conf *tgtconf;
3606 for (tgtconf = fsdb->fsdb_srpc_tgt; tgtconf != NULL;
3607 tgtconf = tgtconf->mtsc_next) {
3608 if (!strcmp(tgtconf->mtsc_tgt, svname)) {
3617 OBD_ALLOC_PTR(tgtconf);
3618 if (tgtconf == NULL)
3621 name_len = strlen(svname);
3623 OBD_ALLOC(tgtconf->mtsc_tgt, name_len + 1);
3624 if (tgtconf->mtsc_tgt == NULL) {
3625 OBD_FREE_PTR(tgtconf);
3628 memcpy(tgtconf->mtsc_tgt, svname, name_len);
3630 tgtconf->mtsc_next = fsdb->fsdb_srpc_tgt;
3631 fsdb->fsdb_srpc_tgt = tgtconf;
3634 rset = &tgtconf->mtsc_rset;
3635 } else if (strcmp(svname, MGSSELF_NAME) == 0) {
3636 /* put _mgs related srpc rule directly in mgs ruleset */
3637 rset = &fsdb->fsdb_mgs->mgs_lut.lut_sptlrpc_rset;
3639 rset = &fsdb->fsdb_srpc_gen;
3642 rc = sptlrpc_rule_set_merge(rset, &rule);
3647 static int mgs_srpc_set_param(const struct lu_env *env,
3648 struct mgs_device *mgs,
3650 struct mgs_target_info *mti,
3660 /* keep a copy of original param, which could be destroied
3662 copy_size = strlen(param) + 1;
3663 OBD_ALLOC(copy, copy_size);
3666 memcpy(copy, param, copy_size);
3668 rc = mgs_srpc_set_param_mem(fsdb, mti->mti_svname, param);
3672 /* previous steps guaranteed the syntax is correct */
3673 rc = mgs_srpc_set_param_disk(env, mgs, fsdb, mti, copy);
3677 if (test_bit(FSDB_MGS_SELF, &fsdb->fsdb_flags)) {
3679 * for mgs rules, make them effective immediately.
3681 LASSERT(fsdb->fsdb_srpc_tgt == NULL);
3682 sptlrpc_target_update_exp_flavor(mgs->mgs_obd,
3683 &fsdb->fsdb_srpc_gen);
3687 OBD_FREE(copy, copy_size);
3691 struct mgs_srpc_read_data {
3692 struct fs_db *msrd_fsdb;
3696 static int mgs_srpc_read_handler(const struct lu_env *env,
3697 struct llog_handle *llh,
3698 struct llog_rec_hdr *rec, void *data)
3700 struct mgs_srpc_read_data *msrd = data;
3701 struct cfg_marker *marker;
3702 struct lustre_cfg *lcfg = REC_DATA(rec);
3703 char *svname, *param;
3707 if (rec->lrh_type != OBD_CFG_REC) {
3708 CERROR("unhandled lrh_type: %#x\n", rec->lrh_type);
3712 cfg_len = REC_DATA_LEN(rec);
3714 rc = lustre_cfg_sanity_check(lcfg, cfg_len);
3716 CERROR("Insane cfg\n");
3720 if (lcfg->lcfg_command == LCFG_MARKER) {
3721 marker = lustre_cfg_buf(lcfg, 1);
3723 if (marker->cm_flags & CM_START &&
3724 marker->cm_flags & CM_SKIP)
3725 msrd->msrd_skip = 1;
3726 if (marker->cm_flags & CM_END)
3727 msrd->msrd_skip = 0;
3732 if (msrd->msrd_skip)
3735 if (lcfg->lcfg_command != LCFG_SPTLRPC_CONF) {
3736 CERROR("invalid command (%x)\n", lcfg->lcfg_command);
3740 svname = lustre_cfg_string(lcfg, 0);
3741 if (svname == NULL) {
3742 CERROR("svname is empty\n");
3746 param = lustre_cfg_string(lcfg, 1);
3747 if (param == NULL) {
3748 CERROR("param is empty\n");
3752 rc = mgs_srpc_set_param_mem(msrd->msrd_fsdb, svname, param);
3754 CERROR("read sptlrpc record error (%d): %s\n", rc, param);
3759 int mgs_get_fsdb_srpc_from_llog(const struct lu_env *env,
3760 struct mgs_device *mgs,
3763 struct llog_handle *llh = NULL;
3764 struct llog_ctxt *ctxt;
3766 struct mgs_srpc_read_data msrd;
3770 /* construct log name */
3771 rc = name_create(&logname, fsdb->fsdb_name, "-sptlrpc");
3775 ctxt = llog_get_context(mgs->mgs_obd, LLOG_CONFIG_ORIG_CTXT);
3776 LASSERT(ctxt != NULL);
3778 if (mgs_log_is_empty(env, mgs, logname))
3781 rc = llog_open(env, ctxt, &llh, NULL, logname,
3789 rc = llog_init_handle(env, llh, LLOG_F_IS_PLAIN, NULL);
3791 GOTO(out_close, rc);
3793 if (llog_get_size(llh) <= 1)
3794 GOTO(out_close, rc = 0);
3796 msrd.msrd_fsdb = fsdb;
3799 rc = llog_process(env, llh, mgs_srpc_read_handler, (void *)&msrd,
3803 llog_close(env, llh);
3805 llog_ctxt_put(ctxt);
3806 name_destroy(&logname);
3809 CERROR("failed to read sptlrpc config database: %d\n", rc);
3813 static int mgs_write_log_param2(const struct lu_env *env,
3814 struct mgs_device *mgs,
3816 struct mgs_target_info *mti, char *ptr)
3818 struct lustre_cfg_bufs bufs;
3822 CDEBUG(D_MGS, "next param '%s'\n", ptr);
3824 /* PARAM_MGSNODE and PARAM_NETWORK are set only when formating
3825 * or during the inital mount. It can never change after that.
3827 if (!class_match_param(ptr, PARAM_MGSNODE, NULL) ||
3828 !class_match_param(ptr, PARAM_NETWORK, NULL)) {
3833 /* Processed in mgs_write_log_ost. Another value that can't
3834 * be changed by lctl set_param -P.
3836 if (!class_match_param(ptr, PARAM_FAILMODE, NULL)) {
3837 LCONSOLE_ERROR_MSG(0x169,
3838 "%s can only be changed with tunefs.lustre and --writeconf\n",
3844 /* FIXME !!! Support for sptlrpc is incomplete. Currently the change
3845 * doesn't transmit to the client. See LU-7183.
3847 if (!class_match_param(ptr, PARAM_SRPC, NULL)) {
3848 rc = mgs_srpc_set_param(env, mgs, fsdb, mti, ptr);
3852 /* Can't use class_match_param since ptr doesn't start with
3853 * PARAM_FAILNODE. So we look for PARAM_FAILNODE contained in ptr.
3855 if (strstr(ptr, PARAM_FAILNODE)) {
3856 /* Add a failover nidlist. We already processed failovers
3857 * params for new targets in mgs_write_log_target.
3861 /* can't use wildcards with failover.node */
3862 if (strchr(ptr, '*')) {
3867 param = strstr(ptr, PARAM_FAILNODE);
3868 if (strlcpy(mti->mti_params, param, sizeof(mti->mti_params)) >=
3869 sizeof(mti->mti_params)) {
3874 CDEBUG(D_MGS, "Adding failnode with param %s\n",
3876 rc = mgs_write_log_add_failnid(env, mgs, fsdb, mti);
3880 rc = mgs_wlp_lcfg(env, mgs, fsdb, mti, PARAMS_FILENAME, &bufs,
3881 mti->mti_svname, ptr);
3886 /* Permanent settings of all parameters by writing into the appropriate
3887 * configuration logs.
3888 * A parameter with null value ("<param>='\0'") means to erase it out of
3891 static int mgs_write_log_param(const struct lu_env *env,
3892 struct mgs_device *mgs, struct fs_db *fsdb,
3893 struct mgs_target_info *mti, char *ptr)
3895 struct mgs_thread_info *mgi = mgs_env_info(env);
3901 /* For various parameter settings, we have to figure out which logs
3902 care about them (e.g. both mdt and client for lov settings) */
3903 CDEBUG(D_MGS, "next param '%s'\n", ptr);
3905 /* The params are stored in MOUNT_DATA_FILE and modified via
3906 tunefs.lustre, or set using lctl conf_param */
3908 /* Processed in lustre_start_mgc */
3909 if (class_match_param(ptr, PARAM_MGSNODE, NULL) == 0)
3912 /* Processed in ost/mdt */
3913 if (class_match_param(ptr, PARAM_NETWORK, NULL) == 0)
3916 /* Processed in mgs_write_log_ost */
3917 if (class_match_param(ptr, PARAM_FAILMODE, NULL) == 0) {
3918 if (mti->mti_flags & LDD_F_PARAM) {
3919 LCONSOLE_ERROR_MSG(0x169, "%s can only be "
3920 "changed with tunefs.lustre"
3921 "and --writeconf\n", ptr);
3927 if (class_match_param(ptr, PARAM_SRPC, NULL) == 0) {
3928 rc = mgs_srpc_set_param(env, mgs, fsdb, mti, ptr);
3932 if (class_match_param(ptr, PARAM_FAILNODE, NULL) == 0) {
3933 /* Add a failover nidlist */
3935 /* We already processed failovers params for new
3936 targets in mgs_write_log_target */
3937 if (mti->mti_flags & LDD_F_PARAM) {
3938 CDEBUG(D_MGS, "Adding failnode\n");
3939 rc = mgs_write_log_add_failnid(env, mgs, fsdb, mti);
3944 if (class_match_param(ptr, PARAM_SYS, &tmp) == 0) {
3945 rc = mgs_write_log_sys(env, mgs, fsdb, mti, ptr, tmp);
3949 if (class_match_param(ptr, PARAM_QUOTA, &tmp) == 0) {
3950 rc = mgs_write_log_quota(env, mgs, fsdb, mti, ptr, tmp);
3954 if (class_match_param(ptr, PARAM_OSC PARAM_ACTIVE, &tmp) == 0 ||
3955 class_match_param(ptr, PARAM_MDC PARAM_ACTIVE, &tmp) == 0) {
3956 /* active=0 means off, anything else means on */
3957 int flag = (*tmp == '0') ? CM_EXCLUDE : 0;
3958 bool deactive_osc = memcmp(ptr, PARAM_OSC PARAM_ACTIVE,
3959 strlen(PARAM_OSC PARAM_ACTIVE)) == 0;
3962 if (!deactive_osc) {
3965 rc = server_name2index(mti->mti_svname, &index, NULL);
3970 LCONSOLE_ERROR_MSG(0x144, "%s: MDC0 can not be"
3971 " (de)activated.\n",
3973 GOTO(end, rc = -EPERM);
3977 LCONSOLE_WARN("Permanently %sactivating %s\n",
3978 flag ? "de" : "re", mti->mti_svname);
3980 rc = name_create(&logname, mti->mti_fsname, "-client");
3983 rc = mgs_modify(env, mgs, fsdb, mti, logname,
3985 deactive_osc ? "add osc" : "add mdc", flag);
3986 name_destroy(&logname);
3991 /* Add to all MDT logs for DNE */
3992 for (i = 0; i < INDEX_MAP_SIZE * 8; i++) {
3993 if (!test_bit(i, fsdb->fsdb_mdt_index_map))
3995 rc = name_create_mdt(&logname, mti->mti_fsname, i);
3998 rc = mgs_modify(env, mgs, fsdb, mti, logname,
4000 deactive_osc ? "add osc" : "add osp",
4002 name_destroy(&logname);
4008 LCONSOLE_ERROR_MSG(0x145, "Couldn't find %s in"
4009 "log (%d). No permanent "
4010 "changes were made to the "
4012 mti->mti_svname, rc);
4013 if (test_bit(FSDB_OLDLOG14, &fsdb->fsdb_flags))
4014 LCONSOLE_ERROR_MSG(0x146, "This may be"
4019 "update the logs.\n");
4022 /* Fall through to osc/mdc proc for deactivating live
4023 OSC/OSP on running MDT / clients. */
4025 /* Below here, let obd's XXX_process_config methods handle it */
4027 /* All lov. in proc */
4028 if (class_match_param(ptr, PARAM_LOV, NULL) == 0) {
4031 CDEBUG(D_MGS, "lov param %s\n", ptr);
4032 if (!(mti->mti_flags & LDD_F_SV_TYPE_MDT)) {
4033 LCONSOLE_ERROR_MSG(0x147, "LOV params must be "
4034 "set on the MDT, not %s. "
4041 if (mgs_log_is_empty(env, mgs, mti->mti_svname))
4042 GOTO(end, rc = -ENODEV);
4044 rc = name_create_mdt_and_lov(&logname, &mdtlovname, fsdb,
4045 mti->mti_stripe_index);
4048 rc = mgs_wlp_lcfg(env, mgs, fsdb, mti, mti->mti_svname,
4049 &mgi->mgi_bufs, mdtlovname, ptr);
4050 name_destroy(&logname);
4051 name_destroy(&mdtlovname);
4056 rc = name_create(&logname, mti->mti_fsname, "-client");
4059 rc = mgs_wlp_lcfg(env, mgs, fsdb, mti, logname, &mgi->mgi_bufs,
4060 fsdb->fsdb_clilov, ptr);
4061 name_destroy(&logname);
4065 /* All osc., mdc., llite. params in proc */
4066 if ((class_match_param(ptr, PARAM_OSC, NULL) == 0) ||
4067 (class_match_param(ptr, PARAM_MDC, NULL) == 0) ||
4068 (class_match_param(ptr, PARAM_LLITE, NULL) == 0)) {
4071 if (test_bit(FSDB_OLDLOG14, &fsdb->fsdb_flags)) {
4072 LCONSOLE_ERROR_MSG(0x148, "Upgraded client logs for %s"
4073 " cannot be modified. Consider"
4074 " updating the configuration with"
4077 GOTO(end, rc = -EINVAL);
4079 if (memcmp(ptr, PARAM_LLITE, strlen(PARAM_LLITE)) == 0) {
4080 rc = name_create(&cname, mti->mti_fsname, "-client");
4081 /* Add the client type to match the obdname in
4082 class_config_llog_handler */
4083 } else if (mti->mti_flags & LDD_F_SV_TYPE_MDT) {
4084 rc = name_create(&cname, mti->mti_svname, "-mdc");
4085 } else if (mti->mti_flags & LDD_F_SV_TYPE_OST) {
4086 rc = name_create(&cname, mti->mti_svname, "-osc");
4088 GOTO(end, rc = -EINVAL);
4093 /* Forbid direct update of llite root squash parameters.
4094 * These parameters are indirectly set via the MDT settings.
4096 if ((class_match_param(ptr, PARAM_LLITE, &tmp) == 0) &&
4097 ((memcmp(tmp, "root_squash=", 12) == 0) ||
4098 (memcmp(tmp, "nosquash_nids=", 14) == 0))) {
4099 LCONSOLE_ERROR("%s: root squash parameters can only "
4100 "be updated through MDT component\n",
4102 name_destroy(&cname);
4103 GOTO(end, rc = -EINVAL);
4106 CDEBUG(D_MGS, "%.3s param %s\n", ptr, ptr + 4);
4109 rc = name_create(&logname, mti->mti_fsname, "-client");
4111 name_destroy(&cname);
4114 rc = mgs_wlp_lcfg(env, mgs, fsdb, mti, logname, &mgi->mgi_bufs,
4117 /* osc params affect the MDT as well */
4118 if (!rc && (mti->mti_flags & LDD_F_SV_TYPE_OST)) {
4121 for (i = 0; i < INDEX_MAP_SIZE * 8; i++){
4122 if (!test_bit(i, fsdb->fsdb_mdt_index_map))
4124 name_destroy(&cname);
4125 rc = name_create_mdt_osc(&cname, mti->mti_svname,
4127 name_destroy(&logname);
4130 rc = name_create_mdt(&logname,
4131 mti->mti_fsname, i);
4134 if (!mgs_log_is_empty(env, mgs, logname)) {
4135 rc = mgs_wlp_lcfg(env, mgs, fsdb,
4145 /* For mdc activate/deactivate, it affects OSP on MDT as well */
4146 if (class_match_param(ptr, PARAM_MDC PARAM_ACTIVE, &tmp) == 0 &&
4149 char *lodname = NULL;
4150 char *param_str = NULL;
4154 /* replace mdc with osp */
4155 memcpy(ptr, PARAM_OSP, strlen(PARAM_OSP));
4156 rc = server_name2index(mti->mti_svname, &index, NULL);
4158 memcpy(ptr, PARAM_MDC, strlen(PARAM_MDC));
4162 for (i = 0; i < INDEX_MAP_SIZE * 8; i++) {
4163 if (!test_bit(i, fsdb->fsdb_mdt_index_map))
4169 name_destroy(&logname);
4170 rc = name_create_mdt(&logname, mti->mti_fsname,
4175 if (mgs_log_is_empty(env, mgs, logname))
4178 snprintf(suffix, sizeof(suffix), "-osp-MDT%04x",
4180 name_destroy(&cname);
4181 rc = name_create(&cname, mti->mti_svname,
4186 rc = mgs_wlp_lcfg(env, mgs, fsdb, mti, logname,
4187 &mgi->mgi_bufs, cname, ptr);
4191 /* Add configuration log for noitfying LOD
4192 * to active/deactive the OSP. */
4193 name_destroy(¶m_str);
4194 rc = name_create(¶m_str, cname,
4195 (*tmp == '0') ? ".active=0" :
4200 name_destroy(&lodname);
4201 rc = name_create(&lodname, logname, "-mdtlov");
4205 rc = mgs_wlp_lcfg(env, mgs, fsdb, mti, logname,
4206 &mgi->mgi_bufs, lodname,
4211 memcpy(ptr, PARAM_MDC, strlen(PARAM_MDC));
4212 name_destroy(&lodname);
4213 name_destroy(¶m_str);
4216 name_destroy(&logname);
4217 name_destroy(&cname);
4221 /* All mdt. params in proc */
4222 if (class_match_param(ptr, PARAM_MDT, &tmp) == 0) {
4226 CDEBUG(D_MGS, "%.3s param %s\n", ptr, ptr + 4);
4227 if (strncmp(mti->mti_svname, mti->mti_fsname,
4228 MTI_NAME_MAXLEN) == 0)
4229 /* device is unspecified completely? */
4230 rc = LDD_F_SV_TYPE_MDT | LDD_F_SV_ALL;
4232 rc = server_name2index(mti->mti_svname, &idx, NULL);
4235 if ((rc & LDD_F_SV_TYPE_MDT) == 0)
4237 if (rc & LDD_F_SV_ALL) {
4238 for (i = 0; i < INDEX_MAP_SIZE * 8; i++) {
4240 fsdb->fsdb_mdt_index_map))
4242 rc = name_create_mdt(&logname,
4243 mti->mti_fsname, i);
4246 rc = mgs_wlp_lcfg(env, mgs, fsdb, mti,
4247 logname, &mgi->mgi_bufs,
4249 name_destroy(&logname);
4254 if ((memcmp(tmp, "root_squash=", 12) == 0) ||
4255 (memcmp(tmp, "nosquash_nids=", 14) == 0)) {
4256 LCONSOLE_ERROR("%s: root squash parameters "
4257 "cannot be applied to a single MDT\n",
4259 GOTO(end, rc = -EINVAL);
4261 rc = mgs_wlp_lcfg(env, mgs, fsdb, mti,
4262 mti->mti_svname, &mgi->mgi_bufs,
4263 mti->mti_svname, ptr);
4268 /* root squash settings are also applied to llite
4269 * config log (see LU-1778) */
4271 ((memcmp(tmp, "root_squash=", 12) == 0) ||
4272 (memcmp(tmp, "nosquash_nids=", 14) == 0))) {
4276 rc = name_create(&cname, mti->mti_fsname, "-client");
4279 rc = name_create(&logname, mti->mti_fsname, "-client");
4281 name_destroy(&cname);
4284 rc = name_create(&ptr2, PARAM_LLITE, tmp);
4286 name_destroy(&cname);
4287 name_destroy(&logname);
4290 rc = mgs_wlp_lcfg(env, mgs, fsdb, mti, logname,
4291 &mgi->mgi_bufs, cname, ptr2);
4292 name_destroy(&ptr2);
4293 name_destroy(&logname);
4294 name_destroy(&cname);
4299 /* All mdd., ost. and osd. params in proc */
4300 if ((class_match_param(ptr, PARAM_MDD, NULL) == 0) ||
4301 (class_match_param(ptr, PARAM_LOD, NULL) == 0) ||
4302 (class_match_param(ptr, PARAM_OST, NULL) == 0) ||
4303 (class_match_param(ptr, PARAM_OSD, NULL) == 0)) {
4304 CDEBUG(D_MGS, "%.3s param %s\n", ptr, ptr + 4);
4305 if (mgs_log_is_empty(env, mgs, mti->mti_svname))
4306 GOTO(end, rc = -ENODEV);
4308 rc = mgs_wlp_lcfg(env, mgs, fsdb, mti, mti->mti_svname,
4309 &mgi->mgi_bufs, mti->mti_svname, ptr);
4313 LCONSOLE_WARN("Ignoring unrecognized param '%s'\n", ptr);
4317 CERROR("err %d on param '%s'\n", rc, ptr);
4322 int mgs_write_log_target(const struct lu_env *env, struct mgs_device *mgs,
4323 struct mgs_target_info *mti, struct fs_db *fsdb)
4330 /* set/check the new target index */
4331 rc = mgs_set_index(env, mgs, mti);
4335 if (rc == EALREADY) {
4336 LCONSOLE_WARN("Found index %d for %s, updating log\n",
4337 mti->mti_stripe_index, mti->mti_svname);
4338 /* We would like to mark old log sections as invalid
4339 and add new log sections in the client and mdt logs.
4340 But if we add new sections, then live clients will
4341 get repeat setup instructions for already running
4342 osc's. So don't update the client/mdt logs. */
4343 mti->mti_flags &= ~LDD_F_UPDATE;
4347 OBD_FAIL_TIMEOUT(OBD_FAIL_MGS_WRITE_TARGET_DELAY, cfs_fail_val > 0 ?
4350 mutex_lock(&fsdb->fsdb_mutex);
4352 if (mti->mti_flags & (LDD_F_VIRGIN | LDD_F_WRITECONF)) {
4353 /* Generate a log from scratch */
4354 if (mti->mti_flags & LDD_F_SV_TYPE_MDT) {
4355 rc = mgs_write_log_mdt(env, mgs, fsdb, mti);
4356 } else if (mti->mti_flags & LDD_F_SV_TYPE_OST) {
4357 rc = mgs_write_log_ost(env, mgs, fsdb, mti);
4359 CERROR("Unknown target type %#x, can't create log for %s\n",
4360 mti->mti_flags, mti->mti_svname);
4363 CERROR("Can't write logs for %s (%d)\n",
4364 mti->mti_svname, rc);
4368 /* Just update the params from tunefs in mgs_write_log_params */
4369 CDEBUG(D_MGS, "Update params for %s\n", mti->mti_svname);
4370 mti->mti_flags |= LDD_F_PARAM;
4373 /* allocate temporary buffer, where class_get_next_param will
4374 make copy of a current parameter */
4375 OBD_ALLOC(buf, strlen(mti->mti_params) + 1);
4377 GOTO(out_up, rc = -ENOMEM);
4378 params = mti->mti_params;
4379 while (params != NULL) {
4380 rc = class_get_next_param(¶ms, buf);
4383 /* there is no next parameter, that is
4388 CDEBUG(D_MGS, "remaining string: '%s', param: '%s'\n",
4390 rc = mgs_write_log_param(env, mgs, fsdb, mti, buf);
4395 OBD_FREE(buf, strlen(mti->mti_params) + 1);
4398 mutex_unlock(&fsdb->fsdb_mutex);
4402 int mgs_erase_log(const struct lu_env *env, struct mgs_device *mgs, char *name)
4404 struct llog_ctxt *ctxt;
4407 ctxt = llog_get_context(mgs->mgs_obd, LLOG_CONFIG_ORIG_CTXT);
4409 CERROR("%s: MGS config context doesn't exist\n",
4410 mgs->mgs_obd->obd_name);
4413 rc = llog_erase(env, ctxt, NULL, name);
4414 /* llog may not exist */
4417 llog_ctxt_put(ctxt);
4421 CERROR("%s: failed to clear log %s: %d\n",
4422 mgs->mgs_obd->obd_name, name, rc);
4427 /* erase all logs for the given fs */
4428 int mgs_erase_logs(const struct lu_env *env, struct mgs_device *mgs,
4431 struct list_head log_list;
4432 struct mgs_direntry *dirent, *n;
4433 char barrier_name[20] = {};
4436 int rc, len = strlen(fsname);
4439 mutex_lock(&mgs->mgs_mutex);
4441 /* Find all the logs in the CONFIGS directory */
4442 rc = class_dentry_readdir(env, mgs, &log_list);
4444 mutex_unlock(&mgs->mgs_mutex);
4448 if (list_empty(&log_list)) {
4449 mutex_unlock(&mgs->mgs_mutex);
4453 snprintf(barrier_name, sizeof(barrier_name) - 1, "%s-%s",
4454 fsname, BARRIER_FILENAME);
4455 /* Delete the barrier fsdb */
4456 mgs_remove_fsdb_by_name(mgs, barrier_name);
4457 /* Delete the fs db */
4458 mgs_remove_fsdb_by_name(mgs, fsname);
4459 mutex_unlock(&mgs->mgs_mutex);
4461 list_for_each_entry_safe(dirent, n, &log_list, mde_list) {
4462 list_del_init(&dirent->mde_list);
4463 suffix = strrchr(dirent->mde_name, '-');
4464 if (suffix != NULL) {
4465 if ((len == suffix - dirent->mde_name) &&
4466 (strncmp(fsname, dirent->mde_name, len) == 0)) {
4467 CDEBUG(D_MGS, "Removing log %s\n",
4469 mgs_erase_log(env, mgs, dirent->mde_name);
4473 mgs_direntry_free(dirent);
4482 /* list all logs for the given fs */
4483 int mgs_list_logs(const struct lu_env *env, struct mgs_device *mgs,
4484 struct obd_ioctl_data *data)
4486 struct list_head log_list;
4487 struct mgs_direntry *dirent, *n;
4493 /* Find all the logs in the CONFIGS directory */
4494 rc = class_dentry_readdir(env, mgs, &log_list);
4498 out = data->ioc_bulk;
4499 remains = data->ioc_inllen1;
4500 list_for_each_entry_safe(dirent, n, &log_list, mde_list) {
4501 list_del_init(&dirent->mde_list);
4502 suffix = strrchr(dirent->mde_name, '-');
4503 if (suffix != NULL) {
4504 l = snprintf(out, remains, "config_log: %s\n",
4509 mgs_direntry_free(dirent);
4516 struct mgs_lcfg_fork_data {
4517 struct lustre_cfg_bufs mlfd_bufs;
4518 struct mgs_device *mlfd_mgs;
4519 struct llog_handle *mlfd_llh;
4520 const char *mlfd_oldname;
4521 const char *mlfd_newname;
4525 static bool contain_valid_fsname(char *buf, const char *fsname,
4526 int buflen, int namelen)
4528 if (buflen < namelen)
4531 if (memcmp(buf, fsname, namelen) != 0)
4534 if (buf[namelen] != '\0' && buf[namelen] != '-')
4540 static int mgs_lcfg_fork_handler(const struct lu_env *env,
4541 struct llog_handle *o_llh,
4542 struct llog_rec_hdr *o_rec, void *data)
4544 struct mgs_lcfg_fork_data *mlfd = data;
4545 struct lustre_cfg_bufs *n_bufs = &mlfd->mlfd_bufs;
4546 struct lustre_cfg *o_lcfg = (struct lustre_cfg *)(o_rec + 1);
4547 struct llog_cfg_rec *lcr;
4549 char *n_buf = mlfd->mlfd_data;
4551 int o_namelen = strlen(mlfd->mlfd_oldname);
4552 int n_namelen = strlen(mlfd->mlfd_newname);
4553 int diff = n_namelen - o_namelen;
4554 __u32 cmd = o_lcfg->lcfg_command;
4555 __u32 cnt = o_lcfg->lcfg_bufcount;
4561 o_buf = lustre_cfg_buf(o_lcfg, 0);
4562 o_buflen = o_lcfg->lcfg_buflens[0];
4563 if (contain_valid_fsname(o_buf, mlfd->mlfd_oldname, o_buflen,
4565 memcpy(n_buf, mlfd->mlfd_newname, n_namelen);
4566 memcpy(n_buf + n_namelen, o_buf + o_namelen,
4567 o_buflen - o_namelen);
4568 lustre_cfg_bufs_reset(n_bufs, n_buf);
4569 n_buf += cfs_size_round(o_buflen + diff);
4571 lustre_cfg_bufs_reset(n_bufs, o_buflen != 0 ? o_buf : NULL);
4576 struct cfg_marker *o_marker;
4577 struct cfg_marker *n_marker;
4581 CDEBUG(D_MGS, "Unknown cfg marker entry with %d "
4586 /* buf[1] is marker */
4587 o_buf = lustre_cfg_buf(o_lcfg, 1);
4588 o_buflen = o_lcfg->lcfg_buflens[1];
4589 o_marker = (struct cfg_marker *)o_buf;
4590 if (!contain_valid_fsname(o_marker->cm_tgtname,
4592 sizeof(o_marker->cm_tgtname),
4594 lustre_cfg_bufs_set(n_bufs, 1, o_marker,
4599 n_marker = (struct cfg_marker *)n_buf;
4600 *n_marker = *o_marker;
4601 memcpy(n_marker->cm_tgtname, mlfd->mlfd_newname, n_namelen);
4602 tgt_namelen = strlen(o_marker->cm_tgtname);
4603 if (tgt_namelen > o_namelen)
4604 memcpy(n_marker->cm_tgtname + n_namelen,
4605 o_marker->cm_tgtname + o_namelen,
4606 tgt_namelen - o_namelen);
4607 n_marker->cm_tgtname[tgt_namelen + diff] = '\0';
4608 lustre_cfg_bufs_set(n_bufs, 1, n_marker, sizeof(*n_marker));
4612 case LCFG_SET_PARAM: {
4613 for (i = 1; i < cnt; i++)
4614 /* buf[i] is the param value, reuse it directly */
4615 lustre_cfg_bufs_set(n_bufs, i,
4616 lustre_cfg_buf(o_lcfg, i),
4617 o_lcfg->lcfg_buflens[i]);
4623 case LCFG_POOL_DEL: {
4624 if (cnt < 3 || cnt > 4) {
4625 CDEBUG(D_MGS, "Unknown cfg pool (%x) entry with %d "
4626 "buffers\n", cmd, cnt);
4630 /* buf[1] is fsname */
4631 o_buf = lustre_cfg_buf(o_lcfg, 1);
4632 o_buflen = o_lcfg->lcfg_buflens[1];
4633 memcpy(n_buf, mlfd->mlfd_newname, n_namelen);
4634 memcpy(n_buf + n_namelen, o_buf + o_namelen,
4635 o_buflen - o_namelen);
4636 lustre_cfg_bufs_set(n_bufs, 1, n_buf, o_buflen + diff);
4637 n_buf += cfs_size_round(o_buflen + diff);
4639 /* buf[2] is the pool name, reuse it directly */
4640 lustre_cfg_bufs_set(n_bufs, 2, lustre_cfg_buf(o_lcfg, 2),
4641 o_lcfg->lcfg_buflens[2]);
4646 /* buf[3] is ostname */
4647 o_buf = lustre_cfg_buf(o_lcfg, 3);
4648 o_buflen = o_lcfg->lcfg_buflens[3];
4649 memcpy(n_buf, mlfd->mlfd_newname, n_namelen);
4650 memcpy(n_buf + n_namelen, o_buf + o_namelen,
4651 o_buflen - o_namelen);
4652 lustre_cfg_bufs_set(n_bufs, 3, n_buf, o_buflen + diff);
4657 o_buflen = o_lcfg->lcfg_buflens[1];
4658 if (o_buflen == sizeof(struct lov_desc) ||
4659 o_buflen == sizeof(struct lmv_desc)) {
4665 o_buf = lustre_cfg_buf(o_lcfg, 1);
4666 if (o_buflen == sizeof(struct lov_desc)) {
4667 struct lov_desc *o_desc =
4668 (struct lov_desc *)o_buf;
4669 struct lov_desc *n_desc =
4670 (struct lov_desc *)n_buf;
4673 o_uuid = o_desc->ld_uuid.uuid;
4674 n_uuid = n_desc->ld_uuid.uuid;
4675 uuid_len = sizeof(o_desc->ld_uuid.uuid);
4677 struct lmv_desc *o_desc =
4678 (struct lmv_desc *)o_buf;
4679 struct lmv_desc *n_desc =
4680 (struct lmv_desc *)n_buf;
4683 o_uuid = o_desc->ld_uuid.uuid;
4684 n_uuid = n_desc->ld_uuid.uuid;
4685 uuid_len = sizeof(o_desc->ld_uuid.uuid);
4688 if (unlikely(!contain_valid_fsname(o_uuid,
4689 mlfd->mlfd_oldname, uuid_len,
4691 lustre_cfg_bufs_set(n_bufs, 1, o_buf,
4696 memcpy(n_uuid, mlfd->mlfd_newname, n_namelen);
4697 uuid_len = strlen(o_uuid);
4698 if (uuid_len > o_namelen)
4699 memcpy(n_uuid + n_namelen,
4701 uuid_len - o_namelen);
4702 n_uuid[uuid_len + diff] = '\0';
4703 lustre_cfg_bufs_set(n_bufs, 1, n_buf, o_buflen);
4705 } /* else case fall through */
4706 } /* else case fall through */
4710 for (i = 1; i < cnt; i++) {
4711 o_buflen = o_lcfg->lcfg_buflens[i];
4715 o_buf = lustre_cfg_buf(o_lcfg, i);
4716 if (!contain_valid_fsname(o_buf, mlfd->mlfd_oldname,
4717 o_buflen, o_namelen)) {
4718 lustre_cfg_bufs_set(n_bufs, i, o_buf, o_buflen);
4722 memcpy(n_buf, mlfd->mlfd_newname, n_namelen);
4723 if (o_buflen == o_namelen) {
4724 lustre_cfg_bufs_set(n_bufs, i, n_buf,
4726 n_buf += cfs_size_round(n_namelen);
4730 memcpy(n_buf + n_namelen, o_buf + o_namelen,
4731 o_buflen - o_namelen);
4732 lustre_cfg_bufs_set(n_bufs, i, n_buf, o_buflen + diff);
4733 n_buf += cfs_size_round(o_buflen + diff);
4739 lcr = lustre_cfg_rec_new(cmd, n_bufs);
4743 lcr->lcr_cfg = *o_lcfg;
4744 rc = llog_write(env, mlfd->mlfd_llh, &lcr->lcr_hdr, LLOG_NEXT_IDX);
4745 lustre_cfg_rec_free(lcr);
4750 static int mgs_lcfg_fork_one(const struct lu_env *env, struct mgs_device *mgs,
4751 struct mgs_direntry *mde, const char *oldname,
4752 const char *newname)
4754 struct llog_handle *old_llh = NULL;
4755 struct llog_handle *new_llh = NULL;
4756 struct llog_ctxt *ctxt = NULL;
4757 struct mgs_lcfg_fork_data *mlfd = NULL;
4758 char *name_buf = NULL;
4760 int old_namelen = strlen(oldname);
4761 int new_namelen = strlen(newname);
4765 name_buflen = mde->mde_len + new_namelen - old_namelen;
4766 OBD_ALLOC(name_buf, name_buflen);
4770 memcpy(name_buf, newname, new_namelen);
4771 memcpy(name_buf + new_namelen, mde->mde_name + old_namelen,
4772 mde->mde_len - old_namelen);
4774 CDEBUG(D_MGS, "Fork the config-log from %s to %s\n",
4775 mde->mde_name, name_buf);
4777 ctxt = llog_get_context(mgs->mgs_obd, LLOG_CONFIG_ORIG_CTXT);
4780 rc = llog_open_create(env, ctxt, &new_llh, NULL, name_buf);
4784 rc = llog_init_handle(env, new_llh, LLOG_F_IS_PLAIN, NULL);
4788 if (unlikely(mgs_log_is_empty(env, mgs, mde->mde_name)))
4791 rc = llog_open(env, ctxt, &old_llh, NULL, mde->mde_name,
4796 rc = llog_init_handle(env, old_llh, LLOG_F_IS_PLAIN, NULL);
4800 new_llh->lgh_hdr->llh_tgtuuid = old_llh->lgh_hdr->llh_tgtuuid;
4802 OBD_ALLOC(mlfd, LLOG_MIN_CHUNK_SIZE);
4804 GOTO(out, rc = -ENOMEM);
4806 mlfd->mlfd_mgs = mgs;
4807 mlfd->mlfd_llh = new_llh;
4808 mlfd->mlfd_oldname = oldname;
4809 mlfd->mlfd_newname = newname;
4811 rc = llog_process(env, old_llh, mgs_lcfg_fork_handler, mlfd, NULL);
4812 OBD_FREE(mlfd, LLOG_MIN_CHUNK_SIZE);
4818 llog_close(env, old_llh);
4820 llog_close(env, new_llh);
4822 OBD_FREE(name_buf, name_buflen);
4824 llog_ctxt_put(ctxt);
4829 int mgs_lcfg_fork(const struct lu_env *env, struct mgs_device *mgs,
4830 const char *oldname, const char *newname)
4832 struct list_head log_list;
4833 struct mgs_direntry *dirent, *n;
4834 int olen = strlen(oldname);
4835 int nlen = strlen(newname);
4840 if (unlikely(!oldname || oldname[0] == '\0' ||
4841 !newname || newname[0] == '\0'))
4844 if (strcmp(oldname, newname) == 0)
4847 /* lock it to prevent fork/erase/register in parallel. */
4848 mutex_lock(&mgs->mgs_mutex);
4850 rc = class_dentry_readdir(env, mgs, &log_list);
4852 mutex_unlock(&mgs->mgs_mutex);
4856 if (list_empty(&log_list)) {
4857 mutex_unlock(&mgs->mgs_mutex);
4861 list_for_each_entry_safe(dirent, n, &log_list, mde_list) {
4864 ptr = strrchr(dirent->mde_name, '-');
4866 int tlen = ptr - dirent->mde_name;
4869 strncmp(newname, dirent->mde_name, tlen) == 0)
4870 GOTO(out, rc = -EEXIST);
4873 strncmp(oldname, dirent->mde_name, tlen) == 0)
4877 list_del_init(&dirent->mde_list);
4878 mgs_direntry_free(dirent);
4881 if (list_empty(&log_list)) {
4882 mutex_unlock(&mgs->mgs_mutex);
4886 list_for_each_entry(dirent, &log_list, mde_list) {
4887 rc = mgs_lcfg_fork_one(env, mgs, dirent, oldname, newname);
4895 mutex_unlock(&mgs->mgs_mutex);
4897 list_for_each_entry_safe(dirent, n, &log_list, mde_list) {
4898 list_del_init(&dirent->mde_list);
4899 mgs_direntry_free(dirent);
4902 if (rc && count > 0)
4903 mgs_erase_logs(env, mgs, newname);
4908 int mgs_lcfg_erase(const struct lu_env *env, struct mgs_device *mgs,
4914 if (unlikely(!fsname || fsname[0] == '\0'))
4917 rc = mgs_erase_logs(env, mgs, fsname);
4922 static int mgs_xattr_del(const struct lu_env *env, struct dt_object *obj)
4924 struct dt_device *dev;
4925 struct thandle *th = NULL;
4930 dev = container_of0(obj->do_lu.lo_dev, struct dt_device, dd_lu_dev);
4931 th = dt_trans_create(env, dev);
4933 RETURN(PTR_ERR(th));
4935 rc = dt_declare_xattr_del(env, obj, XATTR_TARGET_RENAME, th);
4939 rc = dt_trans_start_local(env, dev, th);
4943 dt_write_lock(env, obj, 0);
4944 rc = dt_xattr_del(env, obj, XATTR_TARGET_RENAME, th);
4949 dt_write_unlock(env, obj);
4952 dt_trans_stop(env, dev, th);
4957 int mgs_lcfg_rename(const struct lu_env *env, struct mgs_device *mgs)
4959 struct list_head log_list;
4960 struct mgs_direntry *dirent, *n;
4962 struct lu_buf buf = {
4964 .lb_len = sizeof(fsname)
4970 rc = class_dentry_readdir(env, mgs, &log_list);
4974 if (list_empty(&log_list))
4977 list_for_each_entry_safe(dirent, n, &log_list, mde_list) {
4978 struct dt_object *o = NULL;
4983 list_del_init(&dirent->mde_list);
4984 ptr = strrchr(dirent->mde_name, '-');
4988 len = ptr - dirent->mde_name;
4989 if (unlikely(len >= sizeof(oldname))) {
4990 CDEBUG(D_MGS, "Skip invalid configuration file %s\n",
4995 o = local_file_find(env, mgs->mgs_los, mgs->mgs_configs_dir,
4999 CDEBUG(D_MGS, "Fail to locate file %s: rc = %d\n",
5000 dirent->mde_name, rc);
5004 rc = dt_xattr_get(env, o, &buf, XATTR_TARGET_RENAME);
5010 "Fail to get EA for %s: rc = %d\n",
5011 dirent->mde_name, rc);
5015 if (unlikely(rc == len &&
5016 memcmp(fsname, dirent->mde_name, len) == 0)) {
5017 /* The new fsname is the same as the old one. */
5018 rc = mgs_xattr_del(env, o);
5022 memcpy(oldname, dirent->mde_name, len);
5023 oldname[len] = '\0';
5025 rc = mgs_lcfg_fork_one(env, mgs, dirent, oldname, fsname);
5026 if (rc && rc != -EEXIST) {
5027 CDEBUG(D_MGS, "Fail to fork %s: rc = %d\n",
5028 dirent->mde_name, rc);
5032 rc = mgs_erase_log(env, mgs, dirent->mde_name);
5034 CDEBUG(D_MGS, "Fail to erase old %s: rc = %d\n",
5035 dirent->mde_name, rc);
5036 /* keep it there if failed to remove it. */
5041 if (o && !IS_ERR(o))
5042 lu_object_put(env, &o->do_lu);
5044 mgs_direntry_free(dirent);
5049 list_for_each_entry_safe(dirent, n, &log_list, mde_list) {
5050 list_del_init(&dirent->mde_list);
5051 mgs_direntry_free(dirent);
5057 /* Setup _mgs fsdb and log
5059 int mgs__mgs_fsdb_setup(const struct lu_env *env, struct mgs_device *mgs)
5061 struct fs_db *fsdb = NULL;
5065 rc = mgs_find_or_make_fsdb(env, mgs, MGSSELF_NAME, &fsdb);
5067 mgs_put_fsdb(mgs, fsdb);
5072 /* Setup params fsdb and log
5074 int mgs_params_fsdb_setup(const struct lu_env *env, struct mgs_device *mgs)
5076 struct fs_db *fsdb = NULL;
5077 struct llog_handle *params_llh = NULL;
5081 rc = mgs_find_or_make_fsdb(env, mgs, PARAMS_FILENAME, &fsdb);
5083 mutex_lock(&fsdb->fsdb_mutex);
5084 rc = record_start_log(env, mgs, ¶ms_llh, PARAMS_FILENAME);
5086 rc = record_end_log(env, ¶ms_llh);
5087 mutex_unlock(&fsdb->fsdb_mutex);
5088 mgs_put_fsdb(mgs, fsdb);
5094 /* Cleanup params fsdb and log
5096 int mgs_params_fsdb_cleanup(const struct lu_env *env, struct mgs_device *mgs)
5100 rc = mgs_erase_logs(env, mgs, PARAMS_FILENAME);
5101 return rc == -ENOENT ? 0 : rc;
5105 * Fill in the mgs_target_info based on data devname and param provide.
5107 * @env thread context
5109 * @mti mgs target info. We want to set this based other paramters
5110 * passed to this function. Once setup we write it to the config
5112 * @devname optional OBD device name
5113 * @param string that contains both what tunable to set and the value to
5116 * RETURN 0 for success
5117 * negative error number on failure
5119 static int mgs_set_conf_param(const struct lu_env *env, struct mgs_device *mgs,
5120 struct mgs_target_info *mti, const char *devname,
5123 struct fs_db *fsdb = NULL;
5128 /* lustre, lustre-mdtlov, lustre-client, lustre-MDT0000 */
5132 /* We have two possible cases here:
5134 * 1) the device name embedded in the param:
5135 * lustre-OST0000.osc.max_dirty_mb=32
5137 * 2) the file system name is embedded in
5138 * the param: lustre.sys.at.min=0
5140 len = strcspn(param, ".=");
5141 if (!len || param[len] == '=')
5144 if (len >= sizeof(mti->mti_svname))
5147 snprintf(mti->mti_svname, sizeof(mti->mti_svname),
5148 "%.*s", (int)len, param);
5151 if (strlcpy(mti->mti_svname, devname, sizeof(mti->mti_svname)) >=
5152 sizeof(mti->mti_svname))
5156 if (!strlen(mti->mti_svname)) {
5157 LCONSOLE_ERROR_MSG(0x14d, "No target specified: %s\n", param);
5161 dev_type = mgs_parse_devname(mti->mti_svname, mti->mti_fsname,
5162 &mti->mti_stripe_index);
5164 /* For this case we have an invalid obd device name */
5166 CDEBUG(D_MGS, "%s don't contain an index\n", mti->mti_svname);
5167 strlcpy(mti->mti_fsname, mti->mti_svname, MTI_NAME_MAXLEN);
5170 /* Not an obd device, assume devname is the fsname.
5171 * User might of only provided fsname and not obd device
5174 CDEBUG(D_MGS, "%s is seen as a file system name\n", mti->mti_svname);
5175 strlcpy(mti->mti_fsname, mti->mti_svname, MTI_NAME_MAXLEN);
5180 GOTO(out, rc = dev_type);
5182 /* param related to llite isn't allowed to set by OST or MDT */
5183 if (dev_type & LDD_F_SV_TYPE_OST ||
5184 dev_type & LDD_F_SV_TYPE_MDT) {
5185 /* param related to llite isn't allowed to set by OST
5188 if (!strncmp(param, PARAM_LLITE,
5189 sizeof(PARAM_LLITE) - 1))
5190 GOTO(out, rc = -EINVAL);
5192 /* Strip -osc or -mdc suffix from svname */
5193 if (server_make_name(dev_type, mti->mti_stripe_index,
5194 mti->mti_fsname, mti->mti_svname,
5195 sizeof(mti->mti_svname)))
5196 GOTO(out, rc = -EINVAL);
5201 if (strlcpy(mti->mti_params, param, sizeof(mti->mti_params)) >=
5202 sizeof(mti->mti_params))
5203 GOTO(out, rc = -E2BIG);
5205 CDEBUG(D_MGS, "set_conf_param fs='%s' device='%s' param='%s'\n",
5206 mti->mti_fsname, mti->mti_svname, mti->mti_params);
5208 rc = mgs_find_or_make_fsdb(env, mgs, mti->mti_fsname, &fsdb);
5212 if (!test_bit(FSDB_MGS_SELF, &fsdb->fsdb_flags) &&
5213 test_bit(FSDB_LOG_EMPTY, &fsdb->fsdb_flags)) {
5214 CERROR("No filesystem targets for %s. cfg_device from lctl "
5215 "is '%s'\n", mti->mti_fsname, mti->mti_svname);
5216 mgs_unlink_fsdb(mgs, fsdb);
5217 GOTO(out, rc = -EINVAL);
5221 * Revoke lock so everyone updates. Should be alright if
5222 * someone was already reading while we were updating the logs,
5223 * so we don't really need to hold the lock while we're
5226 mti->mti_flags = dev_type | LDD_F_PARAM;
5227 mutex_lock(&fsdb->fsdb_mutex);
5228 rc = mgs_write_log_param(env, mgs, fsdb, mti, mti->mti_params);
5229 mutex_unlock(&fsdb->fsdb_mutex);
5230 mgs_revoke_lock(mgs, fsdb, CONFIG_T_CONFIG);
5234 mgs_put_fsdb(mgs, fsdb);
5239 static int mgs_set_param2(const struct lu_env *env, struct mgs_device *mgs,
5240 struct mgs_target_info *mti, const char *param)
5242 struct fs_db *fsdb = NULL;
5247 if (strlcpy(mti->mti_params, param, sizeof(mti->mti_params)) >=
5248 sizeof(mti->mti_params))
5249 GOTO(out, rc = -E2BIG);
5251 len = strcspn(param, ".=");
5252 if (len && param[len] != '=') {
5253 struct list_head *tmp;
5257 ptr = strchr(param, '.');
5259 len = strlen(param);
5262 if (len >= sizeof(mti->mti_svname))
5263 GOTO(out, rc = -E2BIG);
5265 snprintf(mti->mti_svname, sizeof(mti->mti_svname), "%.*s",
5268 mutex_lock(&mgs->mgs_mutex);
5269 if (unlikely(list_empty(&mgs->mgs_fs_db_list))) {
5270 mutex_unlock(&mgs->mgs_mutex);
5271 GOTO(out, rc = -ENODEV);
5274 list_for_each(tmp, &mgs->mgs_fs_db_list) {
5275 fsdb = list_entry(tmp, struct fs_db, fsdb_list);
5276 if (fsdb->fsdb_has_lproc_entry &&
5277 strcmp(fsdb->fsdb_name, "params") != 0 &&
5278 strstr(param, fsdb->fsdb_name)) {
5279 snprintf(mti->mti_svname,
5280 sizeof(mti->mti_svname), "%s",
5288 snprintf(mti->mti_svname, sizeof(mti->mti_svname),
5291 mutex_unlock(&mgs->mgs_mutex);
5293 snprintf(mti->mti_svname, sizeof(mti->mti_svname), "general");
5296 CDEBUG(D_MGS, "set_param2 fs='%s' device='%s' param='%s'\n",
5297 mti->mti_fsname, mti->mti_svname, mti->mti_params);
5299 /* The return value should be the device type i.e LDD_F_SV_TYPE_XXX.
5300 * A returned error tells us we don't have a target obd device.
5302 dev_type = server_name2index(mti->mti_svname, &mti->mti_stripe_index,
5307 /* the return value should be the device type i.e LDD_F_SV_TYPE_XXX.
5308 * Strip -osc or -mdc suffix from svname
5310 if ((dev_type & LDD_F_SV_TYPE_OST || dev_type & LDD_F_SV_TYPE_MDT) &&
5311 server_make_name(dev_type, mti->mti_stripe_index,
5312 mti->mti_fsname, mti->mti_svname,
5313 sizeof(mti->mti_svname)))
5314 GOTO(out, rc = -EINVAL);
5316 rc = mgs_find_or_make_fsdb(env, mgs, PARAMS_FILENAME, &fsdb);
5320 * Revoke lock so everyone updates. Should be alright if
5321 * someone was already reading while we were updating the logs,
5322 * so we don't really need to hold the lock while we're
5325 mti->mti_flags = dev_type | LDD_F_PARAM2;
5326 mutex_lock(&fsdb->fsdb_mutex);
5327 rc = mgs_write_log_param2(env, mgs, fsdb, mti, mti->mti_params);
5328 mutex_unlock(&fsdb->fsdb_mutex);
5329 mgs_revoke_lock(mgs, fsdb, CONFIG_T_PARAMS);
5330 mgs_put_fsdb(mgs, fsdb);
5335 /* Set a permanent (config log) param for a target or fs
5337 * @lcfg buf0 may contain the device (testfs-MDT0000) name
5338 * buf1 contains the single parameter
5340 int mgs_set_param(const struct lu_env *env, struct mgs_device *mgs,
5341 struct lustre_cfg *lcfg)
5343 const char *param = lustre_cfg_string(lcfg, 1);
5344 struct mgs_target_info *mti;
5347 /* Create a fake mti to hold everything */
5352 print_lustre_cfg(lcfg);
5354 if (lcfg->lcfg_command == LCFG_PARAM) {
5355 /* For the case of lctl conf_param devname can be
5356 * lustre, lustre-mdtlov, lustre-client, lustre-MDT0000
5358 const char *devname = lustre_cfg_string(lcfg, 0);
5360 rc = mgs_set_conf_param(env, mgs, mti, devname, param);
5362 /* In the case of lctl set_param -P lcfg[0] will always
5363 * be 'general'. At least for now.
5365 rc = mgs_set_param2(env, mgs, mti, param);
5373 static int mgs_write_log_pool(const struct lu_env *env,
5374 struct mgs_device *mgs, char *logname,
5375 struct fs_db *fsdb, char *tgtname,
5376 enum lcfg_command_type cmd,
5377 char *fsname, char *poolname,
5378 char *ostname, char *comment)
5380 struct llog_handle *llh = NULL;
5383 rc = record_start_log(env, mgs, &llh, logname);
5386 rc = record_marker(env, llh, fsdb, CM_START, tgtname, comment);
5389 rc = record_base(env, llh, tgtname, 0, cmd,
5390 fsname, poolname, ostname, NULL);
5393 rc = record_marker(env, llh, fsdb, CM_END, tgtname, comment);
5395 record_end_log(env, &llh);
5399 int mgs_nodemap_cmd(const struct lu_env *env, struct mgs_device *mgs,
5400 enum lcfg_command_type cmd, const char *nodemap_name,
5411 case LCFG_NODEMAP_ADD:
5412 rc = nodemap_add(nodemap_name);
5414 case LCFG_NODEMAP_DEL:
5415 rc = nodemap_del(nodemap_name);
5417 case LCFG_NODEMAP_ADD_RANGE:
5418 rc = nodemap_parse_range(param, nid);
5421 rc = nodemap_add_range(nodemap_name, nid);
5423 case LCFG_NODEMAP_DEL_RANGE:
5424 rc = nodemap_parse_range(param, nid);
5427 rc = nodemap_del_range(nodemap_name, nid);
5429 case LCFG_NODEMAP_ADMIN:
5430 rc = kstrtobool(param, &bool_switch);
5433 rc = nodemap_set_allow_root(nodemap_name, bool_switch);
5435 case LCFG_NODEMAP_DENY_UNKNOWN:
5436 rc = kstrtobool(param, &bool_switch);
5439 rc = nodemap_set_deny_unknown(nodemap_name, bool_switch);
5441 case LCFG_NODEMAP_AUDIT_MODE:
5442 rc = kstrtoul(param, 10, (unsigned long *)&bool_switch);
5444 rc = nodemap_set_audit_mode(nodemap_name, bool_switch);
5446 case LCFG_NODEMAP_MAP_MODE:
5447 if (strcmp("both", param) == 0)
5448 rc = nodemap_set_mapping_mode(nodemap_name,
5450 else if (strcmp("uid_only", param) == 0)
5451 rc = nodemap_set_mapping_mode(nodemap_name,
5452 NODEMAP_MAP_UID_ONLY);
5453 else if (strcmp("gid_only", param) == 0)
5454 rc = nodemap_set_mapping_mode(nodemap_name,
5455 NODEMAP_MAP_GID_ONLY);
5459 case LCFG_NODEMAP_TRUSTED:
5460 rc = kstrtobool(param, &bool_switch);
5463 rc = nodemap_set_trust_client_ids(nodemap_name, bool_switch);
5465 case LCFG_NODEMAP_SQUASH_UID:
5466 rc = kstrtouint(param, 10, &int_id);
5469 rc = nodemap_set_squash_uid(nodemap_name, int_id);
5471 case LCFG_NODEMAP_SQUASH_GID:
5472 rc = kstrtouint(param, 10, &int_id);
5475 rc = nodemap_set_squash_gid(nodemap_name, int_id);
5477 case LCFG_NODEMAP_ADD_UIDMAP:
5478 case LCFG_NODEMAP_ADD_GIDMAP:
5479 rc = nodemap_parse_idmap(param, idmap);
5482 if (cmd == LCFG_NODEMAP_ADD_UIDMAP)
5483 rc = nodemap_add_idmap(nodemap_name, NODEMAP_UID,
5486 rc = nodemap_add_idmap(nodemap_name, NODEMAP_GID,
5489 case LCFG_NODEMAP_DEL_UIDMAP:
5490 case LCFG_NODEMAP_DEL_GIDMAP:
5491 rc = nodemap_parse_idmap(param, idmap);
5494 if (cmd == LCFG_NODEMAP_DEL_UIDMAP)
5495 rc = nodemap_del_idmap(nodemap_name, NODEMAP_UID,
5498 rc = nodemap_del_idmap(nodemap_name, NODEMAP_GID,
5501 case LCFG_NODEMAP_SET_FILESET:
5502 rc = nodemap_set_fileset(nodemap_name, param);
5504 case LCFG_NODEMAP_SET_SEPOL:
5505 rc = nodemap_set_sepol(nodemap_name, param);
5514 int mgs_pool_cmd(const struct lu_env *env, struct mgs_device *mgs,
5515 enum lcfg_command_type cmd, char *fsname,
5516 char *poolname, char *ostname)
5521 char *label = NULL, *canceled_label = NULL;
5523 struct mgs_target_info *mti = NULL;
5524 bool checked = false;
5525 bool locked = false;
5530 rc = mgs_find_or_make_fsdb(env, mgs, fsname, &fsdb);
5532 CERROR("Can't get db for %s\n", fsname);
5535 if (test_bit(FSDB_LOG_EMPTY, &fsdb->fsdb_flags)) {
5536 CERROR("%s is not defined\n", fsname);
5538 GOTO(out_fsdb, rc = -EINVAL);
5541 label_sz = 10 + strlen(fsname) + strlen(poolname);
5543 /* check if ostname match fsname */
5544 if (ostname != NULL) {
5547 ptr = strrchr(ostname, '-');
5548 if ((ptr == NULL) ||
5549 (strncmp(fsname, ostname, ptr-ostname) != 0))
5551 label_sz += strlen(ostname);
5554 OBD_ALLOC(label, label_sz);
5556 GOTO(out_fsdb, rc = -ENOMEM);
5561 "new %s.%s", fsname, poolname);
5565 "add %s.%s.%s", fsname, poolname, ostname);
5568 OBD_ALLOC(canceled_label, label_sz);
5569 if (canceled_label == NULL)
5570 GOTO(out_label, rc = -ENOMEM);
5572 "rem %s.%s.%s", fsname, poolname, ostname);
5573 sprintf(canceled_label,
5574 "add %s.%s.%s", fsname, poolname, ostname);
5577 OBD_ALLOC(canceled_label, label_sz);
5578 if (canceled_label == NULL)
5579 GOTO(out_label, rc = -ENOMEM);
5581 "del %s.%s", fsname, poolname);
5582 sprintf(canceled_label,
5583 "new %s.%s", fsname, poolname);
5591 GOTO(out_cancel, rc = -ENOMEM);
5592 strncpy(mti->mti_svname, "lov pool", sizeof(mti->mti_svname));
5594 mutex_lock(&fsdb->fsdb_mutex);
5596 /* write pool def to all MDT logs */
5597 for (i = 0; i < INDEX_MAP_SIZE * 8; i++) {
5598 if (test_bit(i, fsdb->fsdb_mdt_index_map)) {
5599 rc = name_create_mdt_and_lov(&logname, &lovname,
5604 if (!checked && (canceled_label == NULL)) {
5605 rc = mgs_check_marker(env, mgs, fsdb, mti,
5606 logname, lovname, label);
5608 name_destroy(&logname);
5609 name_destroy(&lovname);
5611 rc = (rc == LLOG_PROC_BREAK ?
5616 if (canceled_label != NULL)
5617 rc = mgs_modify(env, mgs, fsdb, mti, logname,
5618 lovname, canceled_label,
5622 rc = mgs_write_log_pool(env, mgs, logname,
5626 name_destroy(&logname);
5627 name_destroy(&lovname);
5633 rc = name_create(&logname, fsname, "-client");
5637 if (!checked && (canceled_label == NULL)) {
5638 rc = mgs_check_marker(env, mgs, fsdb, mti, logname,
5639 fsdb->fsdb_clilov, label);
5641 name_destroy(&logname);
5642 GOTO(out_mti, rc = (rc == LLOG_PROC_BREAK ?
5646 if (canceled_label != NULL) {
5647 rc = mgs_modify(env, mgs, fsdb, mti, logname,
5648 fsdb->fsdb_clilov, canceled_label, CM_SKIP);
5650 name_destroy(&logname);
5655 rc = mgs_write_log_pool(env, mgs, logname, fsdb, fsdb->fsdb_clilov,
5656 cmd, fsname, poolname, ostname, label);
5657 mutex_unlock(&fsdb->fsdb_mutex);
5659 name_destroy(&logname);
5660 /* request for update */
5661 mgs_revoke_lock(mgs, fsdb, CONFIG_T_CONFIG);
5667 mutex_unlock(&fsdb->fsdb_mutex);
5671 if (canceled_label != NULL)
5672 OBD_FREE(canceled_label, label_sz);
5674 OBD_FREE(label, label_sz);
5677 mgs_unlink_fsdb(mgs, fsdb);
5678 mgs_put_fsdb(mgs, fsdb);