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 rc = name_create(&logname, fsname, "-client");
1600 rc = mgs_replace_nids_log(env, mgs_obd, logname, devname, nids);
1601 name_destroy(&logname);
1603 CERROR("%s: error while replacing NIDs for %s: rc = %d\n",
1604 fsname, devname, rc);
1608 /* Process MDT llogs */
1609 for (i = 0; i < INDEX_MAP_SIZE * 8; i++) {
1610 if (!test_bit(i, fsdb->fsdb_mdt_index_map))
1612 rc = name_create_mdt(&logname, fsname, i);
1615 rc = mgs_replace_nids_log(env, mgs_obd, logname, devname, nids);
1616 name_destroy(&logname);
1622 spin_lock(&mgs_obd->obd_dev_lock);
1623 mgs_obd->obd_no_conn = conn_state;
1624 spin_unlock(&mgs_obd->obd_dev_lock);
1627 mgs_put_fsdb(mgs, fsdb);
1633 * This is called for every record in llog. Some of records are
1634 * skipped, others are copied to new log as is.
1635 * Records to be skipped are
1636 * marker records marked SKIP
1637 * records enclosed between SKIP markers
1639 * \param[in] llh log to be processed
1640 * \param[in] rec current record
1641 * \param[in] data mgs_replace_data structure
1645 static int mgs_clear_config_handler(const struct lu_env *env,
1646 struct llog_handle *llh,
1647 struct llog_rec_hdr *rec, void *data)
1649 struct mgs_replace_data *mrd;
1650 struct lustre_cfg *lcfg = REC_DATA(rec);
1651 int cfg_len = REC_DATA_LEN(rec);
1656 mrd = (struct mgs_replace_data *)data;
1658 if (rec->lrh_type != OBD_CFG_REC) {
1659 CDEBUG(D_MGS, "Config llog Name=%s, Record Index=%u, "
1660 "Unhandled Record Type=%#x\n", llh->lgh_name,
1661 rec->lrh_index, rec->lrh_type);
1665 rc = lustre_cfg_sanity_check(lcfg, cfg_len);
1667 CDEBUG(D_MGS, "Config llog Name=%s, Invalid config file.",
1672 if (lcfg->lcfg_command == LCFG_MARKER) {
1673 struct cfg_marker *marker;
1675 marker = lustre_cfg_buf(lcfg, 1);
1676 if (marker->cm_flags & CM_SKIP) {
1677 if (marker->cm_flags & CM_START)
1678 mrd->state = REPLACE_SKIP;
1679 if (marker->cm_flags & CM_END)
1680 mrd->state = REPLACE_COPY;
1681 /* SKIP section started or finished */
1682 CDEBUG(D_MGS, "Skip idx=%d, rc=%d, len=%d, "
1683 "cmd %x %s %s\n", rec->lrh_index, rc,
1684 rec->lrh_len, lcfg->lcfg_command,
1685 lustre_cfg_string(lcfg, 0),
1686 lustre_cfg_string(lcfg, 1));
1690 if (mrd->state == REPLACE_SKIP) {
1691 /* record enclosed between SKIP markers, skip it */
1692 CDEBUG(D_MGS, "Skip idx=%d, rc=%d, len=%d, "
1693 "cmd %x %s %s\n", rec->lrh_index, rc,
1694 rec->lrh_len, lcfg->lcfg_command,
1695 lustre_cfg_string(lcfg, 0),
1696 lustre_cfg_string(lcfg, 1));
1701 /* Record is placed in temporary llog as is */
1702 rc = llog_write(env, mrd->temp_llh, rec, LLOG_NEXT_IDX);
1704 CDEBUG(D_MGS, "Copied idx=%d, rc=%d, len=%d, cmd %x %s %s\n",
1705 rec->lrh_index, rc, rec->lrh_len, lcfg->lcfg_command,
1706 lustre_cfg_string(lcfg, 0), lustre_cfg_string(lcfg, 1));
1711 * Directory CONFIGS/ may contain files which are not config logs to
1712 * be cleared. Skip any llogs with a non-alphanumeric character after
1713 * the last '-'. For example, fsname-MDT0000.sav, fsname-MDT0000.bak,
1714 * fsname-MDT0000.orig, fsname-MDT0000~, fsname-MDT0000.20150516, etc.
1716 static bool config_to_clear(const char *logname)
1721 str = strrchr(logname, '-');
1726 while (isalnum(str[++i]));
1727 return str[i] == '\0';
1731 * Clear config logs for \a name
1734 * \param mgs MGS device
1735 * \param name name of device or of filesystem
1736 * (ex. lustre-OST0000 or lustre) in later case all logs
1741 int mgs_clear_configs(const struct lu_env *env,
1742 struct mgs_device *mgs, const char *name)
1744 struct list_head dentry_list;
1745 struct mgs_direntry *dirent, *n;
1748 struct obd_device *mgs_obd = mgs->mgs_obd;
1753 /* Prevent clients and servers from connecting to mgs */
1754 spin_lock(&mgs_obd->obd_dev_lock);
1755 conn_state = mgs_obd->obd_no_conn;
1756 mgs_obd->obd_no_conn = 1;
1757 spin_unlock(&mgs_obd->obd_dev_lock);
1760 * config logs cannot be cleaned if anything other than
1763 if (!only_mgs_is_running(mgs_obd)) {
1764 CERROR("Only MGS is allowed to be started\n");
1765 GOTO(out, rc = -EBUSY);
1768 /* Find all the logs in the CONFIGS directory */
1769 rc = class_dentry_readdir(env, mgs, &dentry_list);
1771 CERROR("%s: cannot read config directory '%s': rc = %d\n",
1772 mgs_obd->obd_name, MOUNT_CONFIGS_DIR, rc);
1776 if (list_empty(&dentry_list)) {
1777 CERROR("%s: list empty reading config dir '%s': rc = %d\n",
1778 mgs_obd->obd_name, MOUNT_CONFIGS_DIR, -ENOENT);
1779 GOTO(out, rc = -ENOENT);
1782 OBD_ALLOC(namedash, strlen(name) + 2);
1783 if (namedash == NULL)
1784 GOTO(out, rc = -ENOMEM);
1785 snprintf(namedash, strlen(name) + 2, "%s-", name);
1787 list_for_each_entry(dirent, &dentry_list, mde_list) {
1788 if (strcmp(name, dirent->mde_name) &&
1789 strncmp(namedash, dirent->mde_name, strlen(namedash)))
1791 if (!config_to_clear(dirent->mde_name))
1793 CDEBUG(D_MGS, "%s: Clear config log %s\n",
1794 mgs_obd->obd_name, dirent->mde_name);
1795 rc = mgs_replace_log(env, mgs_obd, dirent->mde_name, NULL,
1796 mgs_clear_config_handler, NULL);
1801 list_for_each_entry_safe(dirent, n, &dentry_list, mde_list) {
1802 list_del_init(&dirent->mde_list);
1803 mgs_direntry_free(dirent);
1805 OBD_FREE(namedash, strlen(name) + 2);
1807 spin_lock(&mgs_obd->obd_dev_lock);
1808 mgs_obd->obd_no_conn = conn_state;
1809 spin_unlock(&mgs_obd->obd_dev_lock);
1814 static int record_lov_setup(const struct lu_env *env, struct llog_handle *llh,
1815 char *devname, struct lov_desc *desc)
1817 struct mgs_thread_info *mgi = mgs_env_info(env);
1818 struct llog_cfg_rec *lcr;
1821 lustre_cfg_bufs_reset(&mgi->mgi_bufs, devname);
1822 lustre_cfg_bufs_set(&mgi->mgi_bufs, 1, desc, sizeof(*desc));
1823 lcr = lustre_cfg_rec_new(LCFG_SETUP, &mgi->mgi_bufs);
1827 rc = llog_write(env, llh, &lcr->lcr_hdr, LLOG_NEXT_IDX);
1828 lustre_cfg_rec_free(lcr);
1832 static int record_lmv_setup(const struct lu_env *env, struct llog_handle *llh,
1833 char *devname, struct lmv_desc *desc)
1835 struct mgs_thread_info *mgi = mgs_env_info(env);
1836 struct llog_cfg_rec *lcr;
1839 lustre_cfg_bufs_reset(&mgi->mgi_bufs, devname);
1840 lustre_cfg_bufs_set(&mgi->mgi_bufs, 1, desc, sizeof(*desc));
1841 lcr = lustre_cfg_rec_new(LCFG_SETUP, &mgi->mgi_bufs);
1845 rc = llog_write(env, llh, &lcr->lcr_hdr, LLOG_NEXT_IDX);
1846 lustre_cfg_rec_free(lcr);
1850 static inline int record_mdc_add(const struct lu_env *env,
1851 struct llog_handle *llh,
1852 char *logname, char *mdcuuid,
1853 char *mdtuuid, char *index,
1856 return record_base(env,llh,logname,0,LCFG_ADD_MDC,
1857 mdtuuid,index,gen,mdcuuid);
1860 static inline int record_lov_add(const struct lu_env *env,
1861 struct llog_handle *llh,
1862 char *lov_name, char *ost_uuid,
1863 char *index, char *gen)
1865 return record_base(env, llh, lov_name, 0, LCFG_LOV_ADD_OBD,
1866 ost_uuid, index, gen, NULL);
1869 static inline int record_mount_opt(const struct lu_env *env,
1870 struct llog_handle *llh,
1871 char *profile, char *lov_name,
1874 return record_base(env, llh, NULL, 0, LCFG_MOUNTOPT,
1875 profile, lov_name, mdc_name, NULL);
1878 static int record_marker(const struct lu_env *env,
1879 struct llog_handle *llh,
1880 struct fs_db *fsdb, __u32 flags,
1881 char *tgtname, char *comment)
1883 struct mgs_thread_info *mgi = mgs_env_info(env);
1884 struct llog_cfg_rec *lcr;
1888 if (flags & CM_START)
1890 mgi->mgi_marker.cm_step = fsdb->fsdb_gen;
1891 mgi->mgi_marker.cm_flags = flags;
1892 mgi->mgi_marker.cm_vers = LUSTRE_VERSION_CODE;
1893 cplen = strlcpy(mgi->mgi_marker.cm_tgtname, tgtname,
1894 sizeof(mgi->mgi_marker.cm_tgtname));
1895 if (cplen >= sizeof(mgi->mgi_marker.cm_tgtname))
1897 cplen = strlcpy(mgi->mgi_marker.cm_comment, comment,
1898 sizeof(mgi->mgi_marker.cm_comment));
1899 if (cplen >= sizeof(mgi->mgi_marker.cm_comment))
1901 mgi->mgi_marker.cm_createtime = ktime_get_real_seconds();
1902 mgi->mgi_marker.cm_canceltime = 0;
1903 lustre_cfg_bufs_reset(&mgi->mgi_bufs, NULL);
1904 lustre_cfg_bufs_set(&mgi->mgi_bufs, 1, &mgi->mgi_marker,
1905 sizeof(mgi->mgi_marker));
1906 lcr = lustre_cfg_rec_new(LCFG_MARKER, &mgi->mgi_bufs);
1910 rc = llog_write(env, llh, &lcr->lcr_hdr, LLOG_NEXT_IDX);
1911 lustre_cfg_rec_free(lcr);
1915 static int record_start_log(const struct lu_env *env, struct mgs_device *mgs,
1916 struct llog_handle **llh, char *name)
1918 static struct obd_uuid cfg_uuid = { .uuid = "config_uuid" };
1919 struct llog_ctxt *ctxt;
1924 GOTO(out, rc = -EBUSY);
1926 ctxt = llog_get_context(mgs->mgs_obd, LLOG_CONFIG_ORIG_CTXT);
1928 GOTO(out, rc = -ENODEV);
1929 LASSERT(ctxt->loc_obd == mgs->mgs_obd);
1931 rc = llog_open_create(env, ctxt, llh, NULL, name);
1934 rc = llog_init_handle(env, *llh, LLOG_F_IS_PLAIN, &cfg_uuid);
1936 llog_close(env, *llh);
1938 llog_ctxt_put(ctxt);
1941 CERROR("%s: can't start log %s: rc = %d\n",
1942 mgs->mgs_obd->obd_name, name, rc);
1948 static int record_end_log(const struct lu_env *env, struct llog_handle **llh)
1952 rc = llog_close(env, *llh);
1958 /******************** config "macros" *********************/
1960 /* write an lcfg directly into a log (with markers) */
1961 static int mgs_write_log_direct(const struct lu_env *env,
1962 struct mgs_device *mgs, struct fs_db *fsdb,
1963 char *logname, struct llog_cfg_rec *lcr,
1964 char *devname, char *comment)
1966 struct llog_handle *llh = NULL;
1971 rc = record_start_log(env, mgs, &llh, logname);
1975 /* FIXME These should be a single journal transaction */
1976 rc = record_marker(env, llh, fsdb, CM_START, devname, comment);
1979 rc = llog_write(env, llh, &lcr->lcr_hdr, LLOG_NEXT_IDX);
1982 rc = record_marker(env, llh, fsdb, CM_END, devname, comment);
1986 record_end_log(env, &llh);
1990 /* write the lcfg in all logs for the given fs */
1991 static int mgs_write_log_direct_all(const struct lu_env *env,
1992 struct mgs_device *mgs,
1994 struct mgs_target_info *mti,
1995 struct llog_cfg_rec *lcr, char *devname,
1996 char *comment, int server_only)
1998 struct list_head log_list;
1999 struct mgs_direntry *dirent, *n;
2000 char *fsname = mti->mti_fsname;
2001 int rc = 0, len = strlen(fsname);
2004 /* Find all the logs in the CONFIGS directory */
2005 rc = class_dentry_readdir(env, mgs, &log_list);
2009 /* Could use fsdb index maps instead of directory listing */
2010 list_for_each_entry_safe(dirent, n, &log_list, mde_list) {
2011 list_del_init(&dirent->mde_list);
2012 /* don't write to sptlrpc rule log */
2013 if (strstr(dirent->mde_name, "-sptlrpc") != NULL)
2016 /* caller wants write server logs only */
2017 if (server_only && strstr(dirent->mde_name, "-client") != NULL)
2020 if (strlen(dirent->mde_name) <= len ||
2021 strncmp(fsname, dirent->mde_name, len) != 0 ||
2022 dirent->mde_name[len] != '-')
2025 CDEBUG(D_MGS, "Changing log %s\n", dirent->mde_name);
2026 /* Erase any old settings of this same parameter */
2027 rc = mgs_modify(env, mgs, fsdb, mti, dirent->mde_name,
2028 devname, comment, CM_SKIP);
2030 CERROR("%s: Can't modify llog %s: rc = %d\n",
2031 mgs->mgs_obd->obd_name, dirent->mde_name, rc);
2034 /* Write the new one */
2035 rc = mgs_write_log_direct(env, mgs, fsdb, dirent->mde_name,
2036 lcr, devname, comment);
2038 CERROR("%s: writing log %s: rc = %d\n",
2039 mgs->mgs_obd->obd_name, dirent->mde_name, rc);
2041 mgs_direntry_free(dirent);
2047 static int mgs_write_log_osp_to_mdt(const struct lu_env *env,
2048 struct mgs_device *mgs,
2050 struct mgs_target_info *mti,
2051 int index, char *logname);
2052 static int mgs_write_log_osc_to_lov(const struct lu_env *env,
2053 struct mgs_device *mgs,
2055 struct mgs_target_info *mti,
2056 char *logname, char *suffix, char *lovname,
2057 enum lustre_sec_part sec_part, int flags);
2058 static int name_create_mdt_and_lov(char **logname, char **lovname,
2059 struct fs_db *fsdb, int i);
2061 static int add_param(char *params, char *key, char *val)
2063 char *start = params + strlen(params);
2064 char *end = params + sizeof(((struct mgs_target_info *)0)->mti_params);
2068 keylen = strlen(key);
2069 if (start + 1 + keylen + strlen(val) >= end) {
2070 CERROR("params are too long: %s %s%s\n",
2071 params, key != NULL ? key : "", val);
2075 sprintf(start, " %s%s", key != NULL ? key : "", val);
2080 * Walk through client config log record and convert the related records
2083 static int mgs_steal_client_llog_handler(const struct lu_env *env,
2084 struct llog_handle *llh,
2085 struct llog_rec_hdr *rec, void *data)
2087 struct mgs_device *mgs;
2088 struct obd_device *obd;
2089 struct mgs_target_info *mti, *tmti;
2091 int cfg_len = rec->lrh_len;
2092 char *cfg_buf = (char*) (rec + 1);
2093 struct lustre_cfg *lcfg;
2095 struct llog_handle *mdt_llh = NULL;
2096 static int got_an_osc_or_mdc = 0;
2097 /* 0: not found any osc/mdc;
2101 static int last_step = -1;
2106 mti = ((struct temp_comp*)data)->comp_mti;
2107 tmti = ((struct temp_comp*)data)->comp_tmti;
2108 fsdb = ((struct temp_comp*)data)->comp_fsdb;
2109 obd = ((struct temp_comp *)data)->comp_obd;
2110 mgs = lu2mgs_dev(obd->obd_lu_dev);
2113 if (rec->lrh_type != OBD_CFG_REC) {
2114 CERROR("unhandled lrh_type: %#x\n", rec->lrh_type);
2118 rc = lustre_cfg_sanity_check(cfg_buf, cfg_len);
2120 CERROR("Insane cfg\n");
2124 lcfg = (struct lustre_cfg *)cfg_buf;
2126 if (lcfg->lcfg_command == LCFG_MARKER) {
2127 struct cfg_marker *marker;
2128 marker = lustre_cfg_buf(lcfg, 1);
2129 if (!strncmp(marker->cm_comment, "add osc", 7) &&
2130 (marker->cm_flags & CM_START) &&
2131 !(marker->cm_flags & CM_SKIP)) {
2132 got_an_osc_or_mdc = 1;
2133 cplen = strlcpy(tmti->mti_svname, marker->cm_tgtname,
2134 sizeof(tmti->mti_svname));
2135 if (cplen >= sizeof(tmti->mti_svname))
2137 rc = record_start_log(env, mgs, &mdt_llh,
2141 rc = record_marker(env, mdt_llh, fsdb, CM_START,
2142 mti->mti_svname, "add osc(copied)");
2143 record_end_log(env, &mdt_llh);
2144 last_step = marker->cm_step;
2147 if (!strncmp(marker->cm_comment, "add osc", 7) &&
2148 (marker->cm_flags & CM_END) &&
2149 !(marker->cm_flags & CM_SKIP)) {
2150 LASSERT(last_step == marker->cm_step);
2152 got_an_osc_or_mdc = 0;
2153 memset(tmti, 0, sizeof(*tmti));
2154 rc = record_start_log(env, mgs, &mdt_llh,
2158 rc = record_marker(env, mdt_llh, fsdb, CM_END,
2159 mti->mti_svname, "add osc(copied)");
2160 record_end_log(env, &mdt_llh);
2163 if (!strncmp(marker->cm_comment, "add mdc", 7) &&
2164 (marker->cm_flags & CM_START) &&
2165 !(marker->cm_flags & CM_SKIP)) {
2166 got_an_osc_or_mdc = 2;
2167 last_step = marker->cm_step;
2168 memcpy(tmti->mti_svname, marker->cm_tgtname,
2169 strlen(marker->cm_tgtname));
2173 if (!strncmp(marker->cm_comment, "add mdc", 7) &&
2174 (marker->cm_flags & CM_END) &&
2175 !(marker->cm_flags & CM_SKIP)) {
2176 LASSERT(last_step == marker->cm_step);
2178 got_an_osc_or_mdc = 0;
2179 memset(tmti, 0, sizeof(*tmti));
2184 if (got_an_osc_or_mdc == 0 || last_step < 0)
2187 if (lcfg->lcfg_command == LCFG_ADD_UUID) {
2188 __u64 nodenid = lcfg->lcfg_nid;
2190 if (strlen(tmti->mti_uuid) == 0) {
2191 /* target uuid not set, this config record is before
2192 * LCFG_SETUP, this nid is one of target node nid.
2194 tmti->mti_nids[tmti->mti_nid_count] = nodenid;
2195 tmti->mti_nid_count++;
2197 char nidstr[LNET_NIDSTR_SIZE];
2199 /* failover node nid */
2200 libcfs_nid2str_r(nodenid, nidstr, sizeof(nidstr));
2201 rc = add_param(tmti->mti_params, PARAM_FAILNODE,
2208 if (lcfg->lcfg_command == LCFG_SETUP) {
2211 target = lustre_cfg_string(lcfg, 1);
2212 memcpy(tmti->mti_uuid, target, strlen(target));
2216 /* ignore client side sptlrpc_conf_log */
2217 if (lcfg->lcfg_command == LCFG_SPTLRPC_CONF)
2220 if (lcfg->lcfg_command == LCFG_ADD_MDC &&
2221 strstr(lustre_cfg_string(lcfg, 0), "-clilmv") != NULL) {
2224 if (sscanf(lustre_cfg_buf(lcfg, 2), "%d", &index) != 1)
2227 memcpy(tmti->mti_fsname, mti->mti_fsname,
2228 strlen(mti->mti_fsname));
2229 tmti->mti_stripe_index = index;
2231 rc = mgs_write_log_osp_to_mdt(env, mgs, fsdb, tmti,
2232 mti->mti_stripe_index,
2234 memset(tmti, 0, sizeof(*tmti));
2238 if (lcfg->lcfg_command == LCFG_LOV_ADD_OBD) {
2241 char *logname, *lovname;
2243 rc = name_create_mdt_and_lov(&logname, &lovname, fsdb,
2244 mti->mti_stripe_index);
2247 sprintf(mdt_index, "-MDT%04x", mti->mti_stripe_index);
2249 if (sscanf(lustre_cfg_buf(lcfg, 2), "%d", &index) != 1) {
2250 name_destroy(&logname);
2251 name_destroy(&lovname);
2255 tmti->mti_stripe_index = index;
2256 rc = mgs_write_log_osc_to_lov(env, mgs, fsdb, tmti, logname,
2259 name_destroy(&logname);
2260 name_destroy(&lovname);
2266 /* fsdb->fsdb_mutex is already held in mgs_write_log_target*/
2267 /* stealed from mgs_get_fsdb_from_llog*/
2268 static int mgs_steal_llog_for_mdt_from_client(const struct lu_env *env,
2269 struct mgs_device *mgs,
2271 struct temp_comp* comp)
2273 struct llog_handle *loghandle;
2274 struct mgs_target_info *tmti;
2275 struct llog_ctxt *ctxt;
2280 ctxt = llog_get_context(mgs->mgs_obd, LLOG_CONFIG_ORIG_CTXT);
2281 LASSERT(ctxt != NULL);
2283 OBD_ALLOC_PTR(tmti);
2285 GOTO(out_ctxt, rc = -ENOMEM);
2287 comp->comp_tmti = tmti;
2288 comp->comp_obd = mgs->mgs_obd;
2290 rc = llog_open(env, ctxt, &loghandle, NULL, client_name,
2298 rc = llog_init_handle(env, loghandle, LLOG_F_IS_PLAIN, NULL);
2300 GOTO(out_close, rc);
2302 rc = llog_process_or_fork(env, loghandle, mgs_steal_client_llog_handler,
2303 (void *)comp, NULL, false);
2304 CDEBUG(D_MGS, "steal llog re = %d\n", rc);
2306 llog_close(env, loghandle);
2310 llog_ctxt_put(ctxt);
2314 /* lmv is the second thing for client logs */
2315 /* copied from mgs_write_log_lov. Please refer to that. */
2316 static int mgs_write_log_lmv(const struct lu_env *env,
2317 struct mgs_device *mgs,
2319 struct mgs_target_info *mti,
2320 char *logname, char *lmvname)
2322 struct llog_handle *llh = NULL;
2323 struct lmv_desc *lmvdesc;
2328 CDEBUG(D_MGS, "Writing lmv(%s) log for %s\n", lmvname,logname);
2330 OBD_ALLOC_PTR(lmvdesc);
2331 if (lmvdesc == NULL)
2333 lmvdesc->ld_active_tgt_count = 0;
2334 lmvdesc->ld_tgt_count = 0;
2335 sprintf((char*)lmvdesc->ld_uuid.uuid, "%s_UUID", lmvname);
2336 uuid = (char *)lmvdesc->ld_uuid.uuid;
2338 rc = record_start_log(env, mgs, &llh, logname);
2341 rc = record_marker(env, llh, fsdb, CM_START, lmvname, "lmv setup");
2344 rc = record_attach(env, llh, lmvname, "lmv", uuid);
2347 rc = record_lmv_setup(env, llh, lmvname, lmvdesc);
2350 rc = record_marker(env, llh, fsdb, CM_END, lmvname, "lmv setup");
2354 record_end_log(env, &llh);
2356 OBD_FREE_PTR(lmvdesc);
2360 /* lov is the first thing in the mdt and client logs */
2361 static int mgs_write_log_lov(const struct lu_env *env, struct mgs_device *mgs,
2362 struct fs_db *fsdb, struct mgs_target_info *mti,
2363 char *logname, char *lovname)
2365 struct llog_handle *llh = NULL;
2366 struct lov_desc *lovdesc;
2371 CDEBUG(D_MGS, "Writing lov(%s) log for %s\n", lovname, logname);
2374 #01 L attach 0:lov_mdsA 1:lov 2:71ccb_lov_mdsA_19f961a9e1
2375 #02 L lov_setup 0:lov_mdsA 1:(struct lov_desc)
2376 uuid=lov1_UUID, stripe count=1, size=1048576, offset=0, pattern=0
2379 /* FIXME just make lov_setup accept empty desc (put uuid in buf 2) */
2380 OBD_ALLOC_PTR(lovdesc);
2381 if (lovdesc == NULL)
2383 lovdesc->ld_magic = LOV_DESC_MAGIC;
2384 lovdesc->ld_tgt_count = 0;
2385 /* Defaults. Can be changed later by lcfg config_param */
2386 lovdesc->ld_default_stripe_count = 1;
2387 lovdesc->ld_pattern = LOV_PATTERN_RAID0;
2388 lovdesc->ld_default_stripe_size = LOV_DESC_STRIPE_SIZE_DEFAULT;
2389 lovdesc->ld_default_stripe_offset = -1;
2390 lovdesc->ld_qos_maxage = LOV_DESC_QOS_MAXAGE_DEFAULT;
2391 sprintf((char*)lovdesc->ld_uuid.uuid, "%s_UUID", lovname);
2392 /* can these be the same? */
2393 uuid = (char *)lovdesc->ld_uuid.uuid;
2395 /* This should always be the first entry in a log.
2396 rc = mgs_clear_log(obd, logname); */
2397 rc = record_start_log(env, mgs, &llh, logname);
2400 /* FIXME these should be a single journal transaction */
2401 rc = record_marker(env, llh, fsdb, CM_START, lovname, "lov setup");
2404 rc = record_attach(env, llh, lovname, "lov", uuid);
2407 rc = record_lov_setup(env, llh, lovname, lovdesc);
2410 rc = record_marker(env, llh, fsdb, CM_END, lovname, "lov setup");
2415 record_end_log(env, &llh);
2417 OBD_FREE_PTR(lovdesc);
2421 /* add failnids to open log */
2422 static int mgs_write_log_failnids(const struct lu_env *env,
2423 struct mgs_target_info *mti,
2424 struct llog_handle *llh,
2427 char *failnodeuuid = NULL;
2428 char *ptr = mti->mti_params;
2433 #03 L add_uuid nid=uml1@tcp(0x20000c0a80201) nal=90 0: 1:uml1_UUID
2434 #04 L add_uuid nid=1@elan(0x1000000000001) nal=90 0: 1:uml1_UUID
2435 #05 L setup 0:OSC_uml1_ost1_mdsA 1:ost1_UUID 2:uml1_UUID
2436 #06 L add_uuid nid=uml2@tcp(0x20000c0a80202) nal=90 0: 1:uml2_UUID
2437 #0x L add_uuid nid=2@elan(0x1000000000002) nal=90 0: 1:uml2_UUID
2438 #07 L add_conn 0:OSC_uml1_ost1_mdsA 1:uml2_UUID
2442 * Pull failnid info out of params string, which may contain something
2443 * like "<nid1>,<nid2>:<nid3>,<nid4>". class_parse_nid() does not
2444 * complain about abnormal inputs like ",:<nid1>", "<nid1>:,<nid2>",
2445 * etc. However, convert_hostnames() should have caught those.
2447 while (class_find_param(ptr, PARAM_FAILNODE, &ptr) == 0) {
2448 while (class_parse_nid(ptr, &nid, &ptr) == 0) {
2449 char nidstr[LNET_NIDSTR_SIZE];
2451 if (failnodeuuid == NULL) {
2452 /* We don't know the failover node name,
2453 * so just use the first nid as the uuid */
2454 libcfs_nid2str_r(nid, nidstr, sizeof(nidstr));
2455 rc = name_create(&failnodeuuid, nidstr, "");
2459 CDEBUG(D_MGS, "add nid %s for failover uuid %s, "
2461 libcfs_nid2str_r(nid, nidstr, sizeof(nidstr)),
2462 failnodeuuid, cliname);
2463 rc = record_add_uuid(env, llh, nid, failnodeuuid);
2465 * If *ptr is ':', we have added all NIDs for
2469 rc = record_add_conn(env, llh, cliname,
2471 name_destroy(&failnodeuuid);
2472 failnodeuuid = NULL;
2476 rc = record_add_conn(env, llh, cliname, failnodeuuid);
2477 name_destroy(&failnodeuuid);
2478 failnodeuuid = NULL;
2485 static int mgs_write_log_mdc_to_lmv(const struct lu_env *env,
2486 struct mgs_device *mgs,
2488 struct mgs_target_info *mti,
2489 char *logname, char *lmvname)
2491 struct llog_handle *llh = NULL;
2492 char *mdcname = NULL;
2493 char *nodeuuid = NULL;
2494 char *mdcuuid = NULL;
2495 char *lmvuuid = NULL;
2497 char nidstr[LNET_NIDSTR_SIZE];
2501 if (mgs_log_is_empty(env, mgs, logname)) {
2502 CERROR("log is empty! Logical error\n");
2506 CDEBUG(D_MGS, "adding mdc for %s to log %s:lmv(%s)\n",
2507 mti->mti_svname, logname, lmvname);
2509 libcfs_nid2str_r(mti->mti_nids[0], nidstr, sizeof(nidstr));
2510 rc = name_create(&nodeuuid, nidstr, "");
2513 rc = name_create(&mdcname, mti->mti_svname, "-mdc");
2516 rc = name_create(&mdcuuid, mdcname, "_UUID");
2519 rc = name_create(&lmvuuid, lmvname, "_UUID");
2523 rc = record_start_log(env, mgs, &llh, logname);
2526 rc = record_marker(env, llh, fsdb, CM_START, mti->mti_svname,
2530 for (i = 0; i < mti->mti_nid_count; i++) {
2531 CDEBUG(D_MGS, "add nid %s for mdt\n",
2532 libcfs_nid2str_r(mti->mti_nids[i],
2533 nidstr, sizeof(nidstr)));
2535 rc = record_add_uuid(env, llh, mti->mti_nids[i], nodeuuid);
2540 rc = record_attach(env, llh, mdcname, LUSTRE_MDC_NAME, lmvuuid);
2543 rc = record_setup(env, llh, mdcname, mti->mti_uuid, nodeuuid,
2547 rc = mgs_write_log_failnids(env, mti, llh, mdcname);
2550 snprintf(index, sizeof(index), "%d", mti->mti_stripe_index);
2551 rc = record_mdc_add(env, llh, lmvname, mdcuuid, mti->mti_uuid,
2555 rc = record_marker(env, llh, fsdb, CM_END, mti->mti_svname,
2560 record_end_log(env, &llh);
2562 name_destroy(&lmvuuid);
2563 name_destroy(&mdcuuid);
2564 name_destroy(&mdcname);
2565 name_destroy(&nodeuuid);
2569 static inline int name_create_lov(char **lovname, char *mdtname,
2570 struct fs_db *fsdb, int index)
2573 if (index == 0 && test_bit(FSDB_OSCNAME18, &fsdb->fsdb_flags))
2574 return name_create(lovname, fsdb->fsdb_name, "-mdtlov");
2576 return name_create(lovname, mdtname, "-mdtlov");
2579 static int name_create_mdt_and_lov(char **logname, char **lovname,
2580 struct fs_db *fsdb, int i)
2584 rc = name_create_mdt(logname, fsdb->fsdb_name, i);
2588 if (i == 0 && test_bit(FSDB_OSCNAME18, &fsdb->fsdb_flags))
2589 rc = name_create(lovname, fsdb->fsdb_name, "-mdtlov");
2591 rc = name_create(lovname, *logname, "-mdtlov");
2593 name_destroy(logname);
2599 static inline int name_create_mdt_osc(char **oscname, char *ostname,
2600 struct fs_db *fsdb, int i)
2604 if (i == 0 && test_bit(FSDB_OSCNAME18, &fsdb->fsdb_flags))
2605 sprintf(suffix, "-osc");
2607 sprintf(suffix, "-osc-MDT%04x", i);
2608 return name_create(oscname, ostname, suffix);
2611 /* add new mdc to already existent MDS */
2612 static int mgs_write_log_osp_to_mdt(const struct lu_env *env,
2613 struct mgs_device *mgs,
2615 struct mgs_target_info *mti,
2616 int mdt_index, char *logname)
2618 struct llog_handle *llh = NULL;
2619 char *nodeuuid = NULL;
2620 char *ospname = NULL;
2621 char *lovuuid = NULL;
2622 char *mdtuuid = NULL;
2623 char *svname = NULL;
2624 char *mdtname = NULL;
2625 char *lovname = NULL;
2627 char nidstr[LNET_NIDSTR_SIZE];
2631 if (mgs_log_is_empty(env, mgs, mti->mti_svname)) {
2632 CERROR("log is empty! Logical error\n");
2636 CDEBUG(D_MGS, "adding osp index %d to %s\n", mti->mti_stripe_index,
2639 rc = name_create_mdt(&mdtname, fsdb->fsdb_name, mti->mti_stripe_index);
2643 libcfs_nid2str_r(mti->mti_nids[0], nidstr, sizeof(nidstr));
2644 rc = name_create(&nodeuuid, nidstr, "");
2646 GOTO(out_destory, rc);
2648 rc = name_create(&svname, mdtname, "-osp");
2650 GOTO(out_destory, rc);
2652 sprintf(index_str, "-MDT%04x", mdt_index);
2653 rc = name_create(&ospname, svname, index_str);
2655 GOTO(out_destory, rc);
2657 rc = name_create_lov(&lovname, logname, fsdb, mdt_index);
2659 GOTO(out_destory, rc);
2661 rc = name_create(&lovuuid, lovname, "_UUID");
2663 GOTO(out_destory, rc);
2665 rc = name_create(&mdtuuid, mdtname, "_UUID");
2667 GOTO(out_destory, rc);
2669 rc = record_start_log(env, mgs, &llh, logname);
2671 GOTO(out_destory, rc);
2673 rc = record_marker(env, llh, fsdb, CM_START, mti->mti_svname,
2676 GOTO(out_destory, rc);
2678 for (i = 0; i < mti->mti_nid_count; i++) {
2679 CDEBUG(D_MGS, "add nid %s for mdt\n",
2680 libcfs_nid2str_r(mti->mti_nids[i],
2681 nidstr, sizeof(nidstr)));
2682 rc = record_add_uuid(env, llh, mti->mti_nids[i], nodeuuid);
2687 rc = record_attach(env, llh, ospname, LUSTRE_OSP_NAME, lovuuid);
2691 rc = record_setup(env, llh, ospname, mti->mti_uuid, nodeuuid,
2696 rc = mgs_write_log_failnids(env, mti, llh, ospname);
2700 /* Add mdc(osp) to lod */
2701 snprintf(index_str, sizeof(index_str), "%d", mti->mti_stripe_index);
2702 rc = record_base(env, llh, lovname, 0, LCFG_ADD_MDC, mti->mti_uuid,
2703 index_str, "1", NULL);
2707 rc = record_marker(env, llh, fsdb, CM_END, mti->mti_svname, "add osp");
2712 record_end_log(env, &llh);
2715 name_destroy(&mdtuuid);
2716 name_destroy(&lovuuid);
2717 name_destroy(&lovname);
2718 name_destroy(&ospname);
2719 name_destroy(&svname);
2720 name_destroy(&nodeuuid);
2721 name_destroy(&mdtname);
2725 static int mgs_write_log_mdt0(const struct lu_env *env,
2726 struct mgs_device *mgs,
2728 struct mgs_target_info *mti)
2730 char *log = mti->mti_svname;
2731 struct llog_handle *llh = NULL;
2732 struct obd_uuid *uuid;
2735 char *ptr = mti->mti_params;
2736 int rc = 0, failout = 0;
2739 OBD_ALLOC_PTR(uuid);
2743 if (class_find_param(ptr, PARAM_FAILMODE, &ptr) == 0)
2744 failout = (strncmp(ptr, "failout", 7) == 0);
2746 rc = name_create(&lovname, log, "-mdtlov");
2749 if (mgs_log_is_empty(env, mgs, log)) {
2750 rc = mgs_write_log_lov(env, mgs, fsdb, mti, log, lovname);
2755 sprintf(mdt_index, "%d", mti->mti_stripe_index);
2757 rc = record_start_log(env, mgs, &llh, log);
2761 /* add MDT itself */
2763 /* FIXME this whole fn should be a single journal transaction */
2764 sprintf(uuid->uuid, "%s_UUID", log);
2765 rc = record_marker(env, llh, fsdb, CM_START, log, "add mdt");
2768 rc = record_attach(env, llh, log, LUSTRE_MDT_NAME, uuid->uuid);
2771 rc = record_mount_opt(env, llh, log, lovname, NULL);
2774 rc = record_setup(env, llh, log, uuid->uuid, mdt_index, lovname,
2775 failout ? "n" : "f");
2778 rc = record_marker(env, llh, fsdb, CM_END, log, "add mdt");
2782 record_end_log(env, &llh);
2784 name_destroy(&lovname);
2790 /* envelope method for all layers log */
2791 static int mgs_write_log_mdt(const struct lu_env *env,
2792 struct mgs_device *mgs,
2794 struct mgs_target_info *mti)
2796 struct mgs_thread_info *mgi = mgs_env_info(env);
2797 struct llog_handle *llh = NULL;
2802 CDEBUG(D_MGS, "writing new mdt %s\n", mti->mti_svname);
2804 if (mti->mti_uuid[0] == '\0') {
2805 /* Make up our own uuid */
2806 snprintf(mti->mti_uuid, sizeof(mti->mti_uuid),
2807 "%s_UUID", mti->mti_svname);
2811 rc = mgs_write_log_mdt0(env, mgs, fsdb, mti);
2814 /* Append the mdt info to the client log */
2815 rc = name_create(&cliname, mti->mti_fsname, "-client");
2819 if (mgs_log_is_empty(env, mgs, cliname)) {
2820 /* Start client log */
2821 rc = mgs_write_log_lov(env, mgs, fsdb, mti, cliname,
2825 rc = mgs_write_log_lmv(env, mgs, fsdb, mti, cliname,
2832 #09 L add_uuid nid=uml1@tcp(0x20000c0a80201) 0: 1:uml1_UUID
2833 #10 L attach 0:MDC_uml1_mdsA_MNT_client 1:mdc 2:1d834_MNT_client_03f
2834 #11 L setup 0:MDC_uml1_mdsA_MNT_client 1:mdsA_UUID 2:uml1_UUID
2835 #12 L add_uuid nid=uml2@tcp(0x20000c0a80202) 0: 1:uml2_UUID
2836 #13 L add_conn 0:MDC_uml1_mdsA_MNT_client 1:uml2_UUID
2837 #14 L mount_option 0: 1:client 2:lov1 3:MDC_uml1_mdsA_MNT_client
2840 /* copy client info about lov/lmv */
2841 mgi->mgi_comp.comp_mti = mti;
2842 mgi->mgi_comp.comp_fsdb = fsdb;
2844 rc = mgs_steal_llog_for_mdt_from_client(env, mgs, cliname,
2848 rc = mgs_write_log_mdc_to_lmv(env, mgs, fsdb, mti, cliname,
2854 rc = record_start_log(env, mgs, &llh, cliname);
2858 rc = record_marker(env, llh, fsdb, CM_START, cliname, "mount opts");
2861 rc = record_mount_opt(env, llh, cliname, fsdb->fsdb_clilov,
2865 rc = record_marker(env, llh, fsdb, CM_END, cliname, "mount opts");
2869 /* for_all_existing_mdt except current one */
2870 for (i = 0; i < INDEX_MAP_SIZE * 8; i++) {
2871 if (i != mti->mti_stripe_index &&
2872 test_bit(i, fsdb->fsdb_mdt_index_map)) {
2875 rc = name_create_mdt(&logname, fsdb->fsdb_name, i);
2879 /* NB: If the log for the MDT is empty, it means
2880 * the MDT is only added to the index
2881 * map, and not being process yet, i.e. this
2882 * is an unregistered MDT, see mgs_write_log_target().
2883 * so we should skip it. Otherwise
2885 * 1. MGS get register request for MDT1 and MDT2.
2887 * 2. Then both MDT1 and MDT2 are added into
2888 * fsdb_mdt_index_map. (see mgs_set_index()).
2890 * 3. Then MDT1 get the lock of fsdb_mutex, then
2891 * generate the config log, here, it will regard MDT2
2892 * as an existent MDT, and generate "add osp" for
2893 * lustre-MDT0001-osp-MDT0002. Note: at the moment
2894 * MDT0002 config log is still empty, so it will
2895 * add "add osp" even before "lov setup", which
2896 * will definitly cause trouble.
2898 * 4. MDT1 registeration finished, fsdb_mutex is
2899 * released, then MDT2 get in, then in above
2900 * mgs_steal_llog_for_mdt_from_client(), it will
2901 * add another osp log for lustre-MDT0001-osp-MDT0002,
2902 * which will cause another trouble.*/
2903 if (!mgs_log_is_empty(env, mgs, logname))
2904 rc = mgs_write_log_osp_to_mdt(env, mgs, fsdb,
2907 name_destroy(&logname);
2913 record_end_log(env, &llh);
2915 name_destroy(&cliname);
2919 /* Add the ost info to the client/mdt lov */
2920 static int mgs_write_log_osc_to_lov(const struct lu_env *env,
2921 struct mgs_device *mgs, struct fs_db *fsdb,
2922 struct mgs_target_info *mti,
2923 char *logname, char *suffix, char *lovname,
2924 enum lustre_sec_part sec_part, int flags)
2926 struct llog_handle *llh = NULL;
2927 char *nodeuuid = NULL;
2928 char *oscname = NULL;
2929 char *oscuuid = NULL;
2930 char *lovuuid = NULL;
2931 char *svname = NULL;
2933 char nidstr[LNET_NIDSTR_SIZE];
2937 CDEBUG(D_INFO, "adding osc for %s to log %s\n",
2938 mti->mti_svname, logname);
2940 if (mgs_log_is_empty(env, mgs, logname)) {
2941 CERROR("log is empty! Logical error\n");
2945 libcfs_nid2str_r(mti->mti_nids[0], nidstr, sizeof(nidstr));
2946 rc = name_create(&nodeuuid, nidstr, "");
2949 rc = name_create(&svname, mti->mti_svname, "-osc");
2953 /* for the system upgraded from old 1.8, keep using the old osc naming
2954 * style for mdt, see name_create_mdt_osc(). LU-1257 */
2955 if (test_bit(FSDB_OSCNAME18, &fsdb->fsdb_flags))
2956 rc = name_create(&oscname, svname, "");
2958 rc = name_create(&oscname, svname, suffix);
2962 rc = name_create(&oscuuid, oscname, "_UUID");
2965 rc = name_create(&lovuuid, lovname, "_UUID");
2971 #03 L add_uuid nid=uml1@tcp(0x20000c0a80201) 0: 1:uml1_UUID
2973 #04 L add_uuid nid=1@elan(0x1000000000001) nal=90 0: 1:uml1_UUID
2974 #04 L attach 0:OSC_uml1_ost1_MNT_client 1:osc 2:89070_lov1_a41dff51a
2975 #05 L setup 0:OSC_uml1_ost1_MNT_client 1:ost1_UUID 2:uml1_UUID
2977 #06 L add_uuid nid=uml2@tcp(0x20000c0a80202) 0: 1:uml2_UUID
2978 #07 L add_conn 0:OSC_uml1_ost1_MNT_client 1:uml2_UUID
2979 #08 L lov_modify_tgts add 0:lov1 1:ost1_UUID 2(index):0 3(gen):1
2982 rc = record_start_log(env, mgs, &llh, logname);
2986 /* FIXME these should be a single journal transaction */
2987 rc = record_marker(env, llh, fsdb, CM_START | flags, mti->mti_svname,
2992 /* NB: don't change record order, because upon MDT steal OSC config
2993 * from client, it treats all nids before LCFG_SETUP as target nids
2994 * (multiple interfaces), while nids after as failover node nids.
2995 * See mgs_steal_client_llog_handler() LCFG_ADD_UUID.
2997 for (i = 0; i < mti->mti_nid_count; i++) {
2998 CDEBUG(D_MGS, "add nid %s\n",
2999 libcfs_nid2str_r(mti->mti_nids[i],
3000 nidstr, sizeof(nidstr)));
3001 rc = record_add_uuid(env, llh, mti->mti_nids[i], nodeuuid);
3005 rc = record_attach(env, llh, oscname, LUSTRE_OSC_NAME, lovuuid);
3008 rc = record_setup(env, llh, oscname, mti->mti_uuid, nodeuuid,
3012 rc = mgs_write_log_failnids(env, mti, llh, oscname);
3016 snprintf(index, sizeof(index), "%d", mti->mti_stripe_index);
3018 rc = record_lov_add(env, llh, lovname, mti->mti_uuid, index, "1");
3021 rc = record_marker(env, llh, fsdb, CM_END | flags, mti->mti_svname,
3026 record_end_log(env, &llh);
3028 name_destroy(&lovuuid);
3029 name_destroy(&oscuuid);
3030 name_destroy(&oscname);
3031 name_destroy(&svname);
3032 name_destroy(&nodeuuid);
3036 static int mgs_write_log_ost(const struct lu_env *env,
3037 struct mgs_device *mgs, struct fs_db *fsdb,
3038 struct mgs_target_info *mti)
3040 struct llog_handle *llh = NULL;
3041 char *logname, *lovname;
3042 char *ptr = mti->mti_params;
3043 int rc, flags = 0, failout = 0, i;
3046 CDEBUG(D_MGS, "writing new ost %s\n", mti->mti_svname);
3048 /* The ost startup log */
3050 /* If the ost log already exists, that means that someone reformatted
3051 the ost and it called target_add again. */
3052 if (!mgs_log_is_empty(env, mgs, mti->mti_svname)) {
3053 LCONSOLE_ERROR_MSG(0x141, "The config log for %s already "
3054 "exists, yet the server claims it never "
3055 "registered. It may have been reformatted, "
3056 "or the index changed. writeconf the MDT to "
3057 "regenerate all logs.\n", mti->mti_svname);
3062 attach obdfilter ost1 ost1_UUID
3063 setup /dev/loop2 ldiskfs f|n errors=remount-ro,user_xattr
3065 if (class_find_param(ptr, PARAM_FAILMODE, &ptr) == 0)
3066 failout = (strncmp(ptr, "failout", 7) == 0);
3067 rc = record_start_log(env, mgs, &llh, mti->mti_svname);
3070 /* FIXME these should be a single journal transaction */
3071 rc = record_marker(env, llh, fsdb, CM_START, mti->mti_svname,"add ost");
3074 if (*mti->mti_uuid == '\0')
3075 snprintf(mti->mti_uuid, sizeof(mti->mti_uuid),
3076 "%s_UUID", mti->mti_svname);
3077 rc = record_attach(env, llh, mti->mti_svname,
3078 "obdfilter"/*LUSTRE_OST_NAME*/, mti->mti_uuid);
3081 rc = record_setup(env, llh, mti->mti_svname,
3082 "dev"/*ignored*/, "type"/*ignored*/,
3083 failout ? "n" : "f", NULL/*options*/);
3086 rc = record_marker(env, llh, fsdb, CM_END, mti->mti_svname, "add ost");
3090 record_end_log(env, &llh);
3093 /* We also have to update the other logs where this osc is part of
3096 if (test_bit(FSDB_OLDLOG14, &fsdb->fsdb_flags)) {
3097 /* If we're upgrading, the old mdt log already has our
3098 entry. Let's do a fake one for fun. */
3099 /* Note that we can't add any new failnids, since we don't
3100 know the old osc names. */
3101 flags = CM_SKIP | CM_UPGRADE146;
3103 } else if ((mti->mti_flags & LDD_F_UPDATE) != LDD_F_UPDATE) {
3104 /* If the update flag isn't set, don't update client/mdt
3107 LCONSOLE_WARN("Client log for %s was not updated; writeconf "
3108 "the MDT first to regenerate it.\n",
3112 /* Add ost to all MDT lov defs */
3113 for (i = 0; i < INDEX_MAP_SIZE * 8; i++){
3114 if (test_bit(i, fsdb->fsdb_mdt_index_map)) {
3117 rc = name_create_mdt_and_lov(&logname, &lovname, fsdb,
3122 snprintf(mdt_index, sizeof(mdt_index), "-MDT%04x", i);
3123 rc = mgs_write_log_osc_to_lov(env, mgs, fsdb, mti,
3125 lovname, LUSTRE_SP_MDT,
3127 name_destroy(&logname);
3128 name_destroy(&lovname);
3134 /* Append ost info to the client log */
3135 rc = name_create(&logname, mti->mti_fsname, "-client");
3138 if (mgs_log_is_empty(env, mgs, logname)) {
3139 /* Start client log */
3140 rc = mgs_write_log_lov(env, mgs, fsdb, mti, logname,
3144 rc = mgs_write_log_lmv(env, mgs, fsdb, mti, logname,
3149 rc = mgs_write_log_osc_to_lov(env, mgs, fsdb, mti, logname, "",
3150 fsdb->fsdb_clilov, LUSTRE_SP_CLI, flags);
3152 name_destroy(&logname);
3156 static __inline__ int mgs_param_empty(char *ptr)
3160 if ((tmp = strchr(ptr, '=')) && (*(++tmp) == '\0'))
3165 static int mgs_write_log_failnid_internal(const struct lu_env *env,
3166 struct mgs_device *mgs,
3168 struct mgs_target_info *mti,
3169 char *logname, char *cliname)
3172 struct llog_handle *llh = NULL;
3174 if (mgs_param_empty(mti->mti_params)) {
3175 /* Remove _all_ failnids */
3176 rc = mgs_modify(env, mgs, fsdb, mti, logname,
3177 mti->mti_svname, "add failnid", CM_SKIP);
3178 return rc < 0 ? rc : 0;
3181 /* Otherwise failover nids are additive */
3182 rc = record_start_log(env, mgs, &llh, logname);
3185 /* FIXME this should be a single journal transaction */
3186 rc = record_marker(env, llh, fsdb, CM_START, mti->mti_svname,
3190 rc = mgs_write_log_failnids(env, mti, llh, cliname);
3193 rc = record_marker(env, llh, fsdb, CM_END,
3194 mti->mti_svname, "add failnid");
3196 record_end_log(env, &llh);
3201 /* Add additional failnids to an existing log.
3202 The mdc/osc must have been added to logs first */
3203 /* tcp nids must be in dotted-quad ascii -
3204 we can't resolve hostnames from the kernel. */
3205 static int mgs_write_log_add_failnid(const struct lu_env *env,
3206 struct mgs_device *mgs,
3208 struct mgs_target_info *mti)
3210 char *logname, *cliname;
3214 /* FIXME we currently can't erase the failnids
3215 * given when a target first registers, since they aren't part of
3216 * an "add uuid" stanza
3219 /* Verify that we know about this target */
3220 if (mgs_log_is_empty(env, mgs, mti->mti_svname)) {
3221 LCONSOLE_ERROR_MSG(0x142, "The target %s has not registered "
3222 "yet. It must be started before failnids "
3223 "can be added.\n", mti->mti_svname);
3227 /* Create mdc/osc client name (e.g. lustre-OST0001-osc) */
3228 if (mti->mti_flags & LDD_F_SV_TYPE_MDT) {
3229 rc = name_create(&cliname, mti->mti_svname, "-mdc");
3230 } else if (mti->mti_flags & LDD_F_SV_TYPE_OST) {
3231 rc = name_create(&cliname, mti->mti_svname, "-osc");
3238 /* Add failover nids to the client log */
3239 rc = name_create(&logname, mti->mti_fsname, "-client");
3241 name_destroy(&cliname);
3245 rc = mgs_write_log_failnid_internal(env, mgs, fsdb,mti,logname,cliname);
3246 name_destroy(&logname);
3247 name_destroy(&cliname);
3251 if (mti->mti_flags & LDD_F_SV_TYPE_OST) {
3252 /* Add OST failover nids to the MDT logs as well */
3255 for (i = 0; i < INDEX_MAP_SIZE * 8; i++) {
3256 if (!test_bit(i, fsdb->fsdb_mdt_index_map))
3258 rc = name_create_mdt(&logname, mti->mti_fsname, i);
3261 rc = name_create_mdt_osc(&cliname, mti->mti_svname,
3264 name_destroy(&logname);
3267 rc = mgs_write_log_failnid_internal(env, mgs, fsdb,
3270 name_destroy(&cliname);
3271 name_destroy(&logname);
3280 static int mgs_wlp_lcfg(const struct lu_env *env,
3281 struct mgs_device *mgs, struct fs_db *fsdb,
3282 struct mgs_target_info *mti,
3283 char *logname, struct lustre_cfg_bufs *bufs,
3284 char *tgtname, char *ptr)
3286 char comment[MTI_NAME_MAXLEN];
3288 struct llog_cfg_rec *lcr;
3291 /* Erase any old settings of this same parameter */
3292 strlcpy(comment, ptr, sizeof(comment));
3293 /* But don't try to match the value. */
3294 tmp = strchr(comment, '=');
3297 /* FIXME we should skip settings that are the same as old values */
3298 rc = mgs_modify(env, mgs, fsdb, mti, logname, tgtname, comment,CM_SKIP);
3301 del = mgs_param_empty(ptr);
3303 LCONSOLE_INFO("%s parameter %s.%s in log %s\n", del ? "Disabling" : rc ?
3304 "Setting" : "Modifying", tgtname, comment, logname);
3306 /* mgs_modify() will return 1 if nothing had to be done */
3312 lustre_cfg_bufs_reset(bufs, tgtname);
3313 lustre_cfg_bufs_set_string(bufs, 1, ptr);
3314 if (mti->mti_flags & LDD_F_PARAM2)
3315 lustre_cfg_bufs_set_string(bufs, 2, LCTL_UPCALL);
3317 lcr = lustre_cfg_rec_new((mti->mti_flags & LDD_F_PARAM2) ?
3318 LCFG_SET_PARAM : LCFG_PARAM, bufs);
3322 rc = mgs_write_log_direct(env, mgs, fsdb, logname, lcr, tgtname,
3324 lustre_cfg_rec_free(lcr);
3328 /* write global variable settings into log */
3329 static int mgs_write_log_sys(const struct lu_env *env,
3330 struct mgs_device *mgs, struct fs_db *fsdb,
3331 struct mgs_target_info *mti, char *sys, char *ptr)
3333 struct mgs_thread_info *mgi = mgs_env_info(env);
3334 struct lustre_cfg *lcfg;
3335 struct llog_cfg_rec *lcr;
3337 int rc, cmd, convert = 1;
3339 if (class_match_param(ptr, PARAM_TIMEOUT, &tmp) == 0) {
3340 cmd = LCFG_SET_TIMEOUT;
3341 } else if (class_match_param(ptr, PARAM_LDLM_TIMEOUT, &tmp) == 0) {
3342 cmd = LCFG_SET_LDLM_TIMEOUT;
3343 /* Check for known params here so we can return error to lctl */
3344 } else if ((class_match_param(ptr, PARAM_AT_MIN, &tmp) == 0) ||
3345 (class_match_param(ptr, PARAM_AT_MAX, &tmp) == 0) ||
3346 (class_match_param(ptr, PARAM_AT_EXTRA, &tmp) == 0) ||
3347 (class_match_param(ptr, PARAM_AT_EARLY_MARGIN, &tmp) == 0) ||
3348 (class_match_param(ptr, PARAM_AT_HISTORY, &tmp) == 0)) {
3350 } else if (class_match_param(ptr, PARAM_JOBID_VAR, &tmp) == 0) {
3351 convert = 0; /* Don't convert string value to integer */
3357 if (mgs_param_empty(ptr))
3358 CDEBUG(D_MGS, "global '%s' removed\n", sys);
3360 CDEBUG(D_MGS, "global '%s' val=%s\n", sys, tmp);
3362 lustre_cfg_bufs_reset(&mgi->mgi_bufs, NULL);
3363 lustre_cfg_bufs_set_string(&mgi->mgi_bufs, 1, sys);
3364 if (!convert && *tmp != '\0')
3365 lustre_cfg_bufs_set_string(&mgi->mgi_bufs, 2, tmp);
3366 lcr = lustre_cfg_rec_new(cmd, &mgi->mgi_bufs);
3370 lcfg = &lcr->lcr_cfg;
3372 rc = kstrtouint(tmp, 0, &lcfg->lcfg_num);
3374 GOTO(out_rec_free, rc);
3379 /* truncate the comment to the parameter name */
3383 /* modify all servers and clients */
3384 rc = mgs_write_log_direct_all(env, mgs, fsdb, mti,
3385 *tmp == '\0' ? NULL : lcr,
3386 mti->mti_fsname, sys, 0);
3387 if (rc == 0 && *tmp != '\0') {
3389 case LCFG_SET_TIMEOUT:
3390 if (!obd_timeout_set || lcfg->lcfg_num > obd_timeout)
3391 class_process_config(lcfg);
3393 case LCFG_SET_LDLM_TIMEOUT:
3394 if (!ldlm_timeout_set || lcfg->lcfg_num > ldlm_timeout)
3395 class_process_config(lcfg);
3403 lustre_cfg_rec_free(lcr);
3407 /* write quota settings into log */
3408 static int mgs_write_log_quota(const struct lu_env *env, struct mgs_device *mgs,
3409 struct fs_db *fsdb, struct mgs_target_info *mti,
3410 char *quota, char *ptr)
3412 struct mgs_thread_info *mgi = mgs_env_info(env);
3413 struct llog_cfg_rec *lcr;
3416 int rc, cmd = LCFG_PARAM;
3418 /* support only 'meta' and 'data' pools so far */
3419 if (class_match_param(ptr, QUOTA_METAPOOL_NAME, &tmp) != 0 &&
3420 class_match_param(ptr, QUOTA_DATAPOOL_NAME, &tmp) != 0) {
3421 CERROR("parameter quota.%s isn't supported (only quota.mdt "
3422 "& quota.ost are)\n", ptr);
3427 CDEBUG(D_MGS, "global '%s' removed\n", quota);
3429 CDEBUG(D_MGS, "global '%s'\n", quota);
3431 if (strchr(tmp, 'u') == NULL && strchr(tmp, 'g') == NULL &&
3432 strchr(tmp, 'p') == NULL &&
3433 strcmp(tmp, "none") != 0) {
3434 CERROR("enable option(%s) isn't supported\n", tmp);
3439 lustre_cfg_bufs_reset(&mgi->mgi_bufs, mti->mti_fsname);
3440 lustre_cfg_bufs_set_string(&mgi->mgi_bufs, 1, quota);
3441 lcr = lustre_cfg_rec_new(cmd, &mgi->mgi_bufs);
3445 /* truncate the comment to the parameter name */
3450 /* XXX we duplicated quota enable information in all server
3451 * config logs, it should be moved to a separate config
3452 * log once we cleanup the config log for global param. */
3453 /* modify all servers */
3454 rc = mgs_write_log_direct_all(env, mgs, fsdb, mti,
3455 *tmp == '\0' ? NULL : lcr,
3456 mti->mti_fsname, quota, 1);
3458 lustre_cfg_rec_free(lcr);
3459 return rc < 0 ? rc : 0;
3462 static int mgs_srpc_set_param_disk(const struct lu_env *env,
3463 struct mgs_device *mgs,
3465 struct mgs_target_info *mti,
3468 struct mgs_thread_info *mgi = mgs_env_info(env);
3469 struct llog_cfg_rec *lcr;
3470 struct llog_handle *llh = NULL;
3472 char *comment, *ptr;
3478 ptr = strchr(param, '=');
3479 LASSERT(ptr != NULL);
3482 OBD_ALLOC(comment, len + 1);
3483 if (comment == NULL)
3485 strncpy(comment, param, len);
3486 comment[len] = '\0';
3489 lustre_cfg_bufs_reset(&mgi->mgi_bufs, mti->mti_svname);
3490 lustre_cfg_bufs_set_string(&mgi->mgi_bufs, 1, param);
3491 lcr = lustre_cfg_rec_new(LCFG_SPTLRPC_CONF, &mgi->mgi_bufs);
3493 GOTO(out_comment, rc = -ENOMEM);
3495 /* construct log name */
3496 rc = name_create(&logname, mti->mti_fsname, "-sptlrpc");
3500 if (mgs_log_is_empty(env, mgs, logname)) {
3501 rc = record_start_log(env, mgs, &llh, logname);
3504 record_end_log(env, &llh);
3507 /* obsolete old one */
3508 rc = mgs_modify(env, mgs, fsdb, mti, logname, mti->mti_svname,
3512 /* write the new one */
3513 rc = mgs_write_log_direct(env, mgs, fsdb, logname, lcr,
3514 mti->mti_svname, comment);
3516 CERROR("%s: error writing log %s: rc = %d\n",
3517 mgs->mgs_obd->obd_name, logname, rc);
3519 name_destroy(&logname);
3521 lustre_cfg_rec_free(lcr);
3523 OBD_FREE(comment, len + 1);
3527 static int mgs_srpc_set_param_udesc_mem(struct fs_db *fsdb,
3532 /* disable the adjustable udesc parameter for now, i.e. use default
3533 * setting that client always ship udesc to MDT if possible. to enable
3534 * it simply remove the following line */
3537 ptr = strchr(param, '=');
3542 if (strcmp(param, PARAM_SRPC_UDESC))
3545 if (strcmp(ptr, "yes") == 0) {
3546 set_bit(FSDB_UDESC, &fsdb->fsdb_flags);
3547 CWARN("Enable user descriptor shipping from client to MDT\n");
3548 } else if (strcmp(ptr, "no") == 0) {
3549 clear_bit(FSDB_UDESC, &fsdb->fsdb_flags);
3550 CWARN("Disable user descriptor shipping from client to MDT\n");
3558 CERROR("Invalid param: %s\n", param);
3562 static int mgs_srpc_set_param_mem(struct fs_db *fsdb,
3566 struct sptlrpc_rule rule;
3567 struct sptlrpc_rule_set *rset;
3571 if (strncmp(param, PARAM_SRPC, sizeof(PARAM_SRPC) - 1) != 0) {
3572 CERROR("Invalid sptlrpc parameter: %s\n", param);
3576 if (strncmp(param, PARAM_SRPC_UDESC,
3577 sizeof(PARAM_SRPC_UDESC) - 1) == 0) {
3578 RETURN(mgs_srpc_set_param_udesc_mem(fsdb, param));
3581 if (strncmp(param, PARAM_SRPC_FLVR, sizeof(PARAM_SRPC_FLVR) - 1) != 0) {
3582 CERROR("Invalid sptlrpc flavor parameter: %s\n", param);
3586 param += sizeof(PARAM_SRPC_FLVR) - 1;
3588 rc = sptlrpc_parse_rule(param, &rule);
3592 /* mgs rules implies must be mgc->mgs */
3593 if (test_bit(FSDB_MGS_SELF, &fsdb->fsdb_flags)) {
3594 if ((rule.sr_from != LUSTRE_SP_MGC &&
3595 rule.sr_from != LUSTRE_SP_ANY) ||
3596 (rule.sr_to != LUSTRE_SP_MGS &&
3597 rule.sr_to != LUSTRE_SP_ANY))
3601 /* preapre room for this coming rule. svcname format should be:
3602 * - fsname: general rule
3603 * - fsname-tgtname: target-specific rule
3605 if (strchr(svname, '-')) {
3606 struct mgs_tgt_srpc_conf *tgtconf;
3609 for (tgtconf = fsdb->fsdb_srpc_tgt; tgtconf != NULL;
3610 tgtconf = tgtconf->mtsc_next) {
3611 if (!strcmp(tgtconf->mtsc_tgt, svname)) {
3620 OBD_ALLOC_PTR(tgtconf);
3621 if (tgtconf == NULL)
3624 name_len = strlen(svname);
3626 OBD_ALLOC(tgtconf->mtsc_tgt, name_len + 1);
3627 if (tgtconf->mtsc_tgt == NULL) {
3628 OBD_FREE_PTR(tgtconf);
3631 memcpy(tgtconf->mtsc_tgt, svname, name_len);
3633 tgtconf->mtsc_next = fsdb->fsdb_srpc_tgt;
3634 fsdb->fsdb_srpc_tgt = tgtconf;
3637 rset = &tgtconf->mtsc_rset;
3638 } else if (strcmp(svname, MGSSELF_NAME) == 0) {
3639 /* put _mgs related srpc rule directly in mgs ruleset */
3640 rset = &fsdb->fsdb_mgs->mgs_lut.lut_sptlrpc_rset;
3642 rset = &fsdb->fsdb_srpc_gen;
3645 rc = sptlrpc_rule_set_merge(rset, &rule);
3650 static int mgs_srpc_set_param(const struct lu_env *env,
3651 struct mgs_device *mgs,
3653 struct mgs_target_info *mti,
3663 /* keep a copy of original param, which could be destroied
3665 copy_size = strlen(param) + 1;
3666 OBD_ALLOC(copy, copy_size);
3669 memcpy(copy, param, copy_size);
3671 rc = mgs_srpc_set_param_mem(fsdb, mti->mti_svname, param);
3675 /* previous steps guaranteed the syntax is correct */
3676 rc = mgs_srpc_set_param_disk(env, mgs, fsdb, mti, copy);
3680 if (test_bit(FSDB_MGS_SELF, &fsdb->fsdb_flags)) {
3682 * for mgs rules, make them effective immediately.
3684 LASSERT(fsdb->fsdb_srpc_tgt == NULL);
3685 sptlrpc_target_update_exp_flavor(mgs->mgs_obd,
3686 &fsdb->fsdb_srpc_gen);
3690 OBD_FREE(copy, copy_size);
3694 struct mgs_srpc_read_data {
3695 struct fs_db *msrd_fsdb;
3699 static int mgs_srpc_read_handler(const struct lu_env *env,
3700 struct llog_handle *llh,
3701 struct llog_rec_hdr *rec, void *data)
3703 struct mgs_srpc_read_data *msrd = data;
3704 struct cfg_marker *marker;
3705 struct lustre_cfg *lcfg = REC_DATA(rec);
3706 char *svname, *param;
3710 if (rec->lrh_type != OBD_CFG_REC) {
3711 CERROR("unhandled lrh_type: %#x\n", rec->lrh_type);
3715 cfg_len = REC_DATA_LEN(rec);
3717 rc = lustre_cfg_sanity_check(lcfg, cfg_len);
3719 CERROR("Insane cfg\n");
3723 if (lcfg->lcfg_command == LCFG_MARKER) {
3724 marker = lustre_cfg_buf(lcfg, 1);
3726 if (marker->cm_flags & CM_START &&
3727 marker->cm_flags & CM_SKIP)
3728 msrd->msrd_skip = 1;
3729 if (marker->cm_flags & CM_END)
3730 msrd->msrd_skip = 0;
3735 if (msrd->msrd_skip)
3738 if (lcfg->lcfg_command != LCFG_SPTLRPC_CONF) {
3739 CERROR("invalid command (%x)\n", lcfg->lcfg_command);
3743 svname = lustre_cfg_string(lcfg, 0);
3744 if (svname == NULL) {
3745 CERROR("svname is empty\n");
3749 param = lustre_cfg_string(lcfg, 1);
3750 if (param == NULL) {
3751 CERROR("param is empty\n");
3755 rc = mgs_srpc_set_param_mem(msrd->msrd_fsdb, svname, param);
3757 CERROR("read sptlrpc record error (%d): %s\n", rc, param);
3762 int mgs_get_fsdb_srpc_from_llog(const struct lu_env *env,
3763 struct mgs_device *mgs,
3766 struct llog_handle *llh = NULL;
3767 struct llog_ctxt *ctxt;
3769 struct mgs_srpc_read_data msrd;
3773 /* construct log name */
3774 rc = name_create(&logname, fsdb->fsdb_name, "-sptlrpc");
3778 ctxt = llog_get_context(mgs->mgs_obd, LLOG_CONFIG_ORIG_CTXT);
3779 LASSERT(ctxt != NULL);
3781 if (mgs_log_is_empty(env, mgs, logname))
3784 rc = llog_open(env, ctxt, &llh, NULL, logname,
3792 rc = llog_init_handle(env, llh, LLOG_F_IS_PLAIN, NULL);
3794 GOTO(out_close, rc);
3796 if (llog_get_size(llh) <= 1)
3797 GOTO(out_close, rc = 0);
3799 msrd.msrd_fsdb = fsdb;
3802 rc = llog_process(env, llh, mgs_srpc_read_handler, (void *)&msrd,
3806 llog_close(env, llh);
3808 llog_ctxt_put(ctxt);
3809 name_destroy(&logname);
3812 CERROR("failed to read sptlrpc config database: %d\n", rc);
3816 static int mgs_write_log_param2(const struct lu_env *env,
3817 struct mgs_device *mgs,
3819 struct mgs_target_info *mti, char *ptr)
3821 struct lustre_cfg_bufs bufs;
3825 CDEBUG(D_MGS, "next param '%s'\n", ptr);
3827 /* PARAM_MGSNODE and PARAM_NETWORK are set only when formating
3828 * or during the inital mount. It can never change after that.
3830 if (!class_match_param(ptr, PARAM_MGSNODE, NULL) ||
3831 !class_match_param(ptr, PARAM_NETWORK, NULL)) {
3836 /* Processed in mgs_write_log_ost. Another value that can't
3837 * be changed by lctl set_param -P.
3839 if (!class_match_param(ptr, PARAM_FAILMODE, NULL)) {
3840 LCONSOLE_ERROR_MSG(0x169,
3841 "%s can only be changed with tunefs.lustre and --writeconf\n",
3847 /* FIXME !!! Support for sptlrpc is incomplete. Currently the change
3848 * doesn't transmit to the client. See LU-7183.
3850 if (!class_match_param(ptr, PARAM_SRPC, NULL)) {
3851 rc = mgs_srpc_set_param(env, mgs, fsdb, mti, ptr);
3855 /* Can't use class_match_param since ptr doesn't start with
3856 * PARAM_FAILNODE. So we look for PARAM_FAILNODE contained in ptr.
3858 if (strstr(ptr, PARAM_FAILNODE)) {
3859 /* Add a failover nidlist. We already processed failovers
3860 * params for new targets in mgs_write_log_target.
3864 /* can't use wildcards with failover.node */
3865 if (strchr(ptr, '*')) {
3870 param = strstr(ptr, PARAM_FAILNODE);
3871 if (strlcpy(mti->mti_params, param, sizeof(mti->mti_params)) >=
3872 sizeof(mti->mti_params)) {
3877 CDEBUG(D_MGS, "Adding failnode with param %s\n",
3879 rc = mgs_write_log_add_failnid(env, mgs, fsdb, mti);
3883 rc = mgs_wlp_lcfg(env, mgs, fsdb, mti, PARAMS_FILENAME, &bufs,
3884 mti->mti_svname, ptr);
3889 /* Permanent settings of all parameters by writing into the appropriate
3890 * configuration logs.
3891 * A parameter with null value ("<param>='\0'") means to erase it out of
3894 static int mgs_write_log_param(const struct lu_env *env,
3895 struct mgs_device *mgs, struct fs_db *fsdb,
3896 struct mgs_target_info *mti, char *ptr)
3898 struct mgs_thread_info *mgi = mgs_env_info(env);
3904 /* For various parameter settings, we have to figure out which logs
3905 care about them (e.g. both mdt and client for lov settings) */
3906 CDEBUG(D_MGS, "next param '%s'\n", ptr);
3908 /* The params are stored in MOUNT_DATA_FILE and modified via
3909 tunefs.lustre, or set using lctl conf_param */
3911 /* Processed in lustre_start_mgc */
3912 if (class_match_param(ptr, PARAM_MGSNODE, NULL) == 0)
3915 /* Processed in ost/mdt */
3916 if (class_match_param(ptr, PARAM_NETWORK, NULL) == 0)
3919 /* Processed in mgs_write_log_ost */
3920 if (class_match_param(ptr, PARAM_FAILMODE, NULL) == 0) {
3921 if (mti->mti_flags & LDD_F_PARAM) {
3922 LCONSOLE_ERROR_MSG(0x169,
3923 "%s can only be changed with tunefs.lustre and --writeconf\n",
3930 if (class_match_param(ptr, PARAM_SRPC, NULL) == 0) {
3931 rc = mgs_srpc_set_param(env, mgs, fsdb, mti, ptr);
3935 if (class_match_param(ptr, PARAM_FAILNODE, NULL) == 0) {
3936 /* Add a failover nidlist */
3938 /* We already processed failovers params for new
3939 targets in mgs_write_log_target */
3940 if (mti->mti_flags & LDD_F_PARAM) {
3941 CDEBUG(D_MGS, "Adding failnode\n");
3942 rc = mgs_write_log_add_failnid(env, mgs, fsdb, mti);
3947 if (class_match_param(ptr, PARAM_SYS, &tmp) == 0) {
3948 rc = mgs_write_log_sys(env, mgs, fsdb, mti, ptr, tmp);
3952 if (class_match_param(ptr, PARAM_QUOTA, &tmp) == 0) {
3953 rc = mgs_write_log_quota(env, mgs, fsdb, mti, ptr, tmp);
3957 if (class_match_param(ptr, PARAM_OSC PARAM_ACTIVE, &tmp) == 0 ||
3958 class_match_param(ptr, PARAM_MDC PARAM_ACTIVE, &tmp) == 0) {
3959 /* active=0 means off, anything else means on */
3960 int flag = (*tmp == '0') ? CM_EXCLUDE : 0;
3961 bool deactive_osc = memcmp(ptr, PARAM_OSC PARAM_ACTIVE,
3962 strlen(PARAM_OSC PARAM_ACTIVE)) == 0;
3965 if (!deactive_osc) {
3968 rc = server_name2index(mti->mti_svname, &index, NULL);
3973 LCONSOLE_ERROR_MSG(0x144, "%s: MDC0 can not be"
3974 " (de)activated.\n",
3976 GOTO(end, rc = -EPERM);
3980 LCONSOLE_WARN("Permanently %sactivating %s\n",
3981 flag ? "de" : "re", mti->mti_svname);
3983 rc = name_create(&logname, mti->mti_fsname, "-client");
3986 rc = mgs_modify(env, mgs, fsdb, mti, logname,
3988 deactive_osc ? "add osc" : "add mdc", flag);
3989 name_destroy(&logname);
3994 /* Add to all MDT logs for DNE */
3995 for (i = 0; i < INDEX_MAP_SIZE * 8; i++) {
3996 if (!test_bit(i, fsdb->fsdb_mdt_index_map))
3998 rc = name_create_mdt(&logname, mti->mti_fsname, i);
4001 rc = mgs_modify(env, mgs, fsdb, mti, logname,
4003 deactive_osc ? "add osc" : "add osp",
4005 name_destroy(&logname);
4011 LCONSOLE_ERROR_MSG(0x145,
4012 "Couldn't find %s in log (%d). No permanent changes were made to the config log.\n",
4013 mti->mti_svname, rc);
4014 if (test_bit(FSDB_OLDLOG14, &fsdb->fsdb_flags))
4015 LCONSOLE_ERROR_MSG(0x146,
4016 "This may be because the log is in the old 1.4 style. Consider --writeconf to update the logs.\n");
4019 /* Fall through to osc/mdc proc for deactivating live
4020 OSC/OSP on running MDT / clients. */
4022 /* Below here, let obd's XXX_process_config methods handle it */
4024 /* All lov. in proc */
4025 if (class_match_param(ptr, PARAM_LOV, NULL) == 0) {
4028 CDEBUG(D_MGS, "lov param %s\n", ptr);
4029 if (!(mti->mti_flags & LDD_F_SV_TYPE_MDT)) {
4030 LCONSOLE_ERROR_MSG(0x147, "LOV params must be "
4031 "set on the MDT, not %s. "
4038 if (mgs_log_is_empty(env, mgs, mti->mti_svname))
4039 GOTO(end, rc = -ENODEV);
4041 rc = name_create_mdt_and_lov(&logname, &mdtlovname, fsdb,
4042 mti->mti_stripe_index);
4045 rc = mgs_wlp_lcfg(env, mgs, fsdb, mti, mti->mti_svname,
4046 &mgi->mgi_bufs, mdtlovname, ptr);
4047 name_destroy(&logname);
4048 name_destroy(&mdtlovname);
4053 rc = name_create(&logname, mti->mti_fsname, "-client");
4056 rc = mgs_wlp_lcfg(env, mgs, fsdb, mti, logname, &mgi->mgi_bufs,
4057 fsdb->fsdb_clilov, ptr);
4058 name_destroy(&logname);
4062 /* All osc., mdc., llite. params in proc */
4063 if ((class_match_param(ptr, PARAM_OSC, NULL) == 0) ||
4064 (class_match_param(ptr, PARAM_MDC, NULL) == 0) ||
4065 (class_match_param(ptr, PARAM_LLITE, NULL) == 0)) {
4068 if (test_bit(FSDB_OLDLOG14, &fsdb->fsdb_flags)) {
4069 LCONSOLE_ERROR_MSG(0x148, "Upgraded client logs for %s"
4070 " cannot be modified. Consider"
4071 " updating the configuration with"
4074 GOTO(end, rc = -EINVAL);
4076 if (memcmp(ptr, PARAM_LLITE, strlen(PARAM_LLITE)) == 0) {
4077 rc = name_create(&cname, mti->mti_fsname, "-client");
4078 /* Add the client type to match the obdname in
4079 class_config_llog_handler */
4080 } else if (mti->mti_flags & LDD_F_SV_TYPE_MDT) {
4081 rc = name_create(&cname, mti->mti_svname, "-mdc");
4082 } else if (mti->mti_flags & LDD_F_SV_TYPE_OST) {
4083 rc = name_create(&cname, mti->mti_svname, "-osc");
4085 GOTO(end, rc = -EINVAL);
4090 /* Forbid direct update of llite root squash parameters.
4091 * These parameters are indirectly set via the MDT settings.
4093 if ((class_match_param(ptr, PARAM_LLITE, &tmp) == 0) &&
4094 ((memcmp(tmp, "root_squash=", 12) == 0) ||
4095 (memcmp(tmp, "nosquash_nids=", 14) == 0))) {
4096 LCONSOLE_ERROR("%s: root squash parameters can only "
4097 "be updated through MDT component\n",
4099 name_destroy(&cname);
4100 GOTO(end, rc = -EINVAL);
4103 CDEBUG(D_MGS, "%.3s param %s\n", ptr, ptr + 4);
4106 rc = name_create(&logname, mti->mti_fsname, "-client");
4108 name_destroy(&cname);
4111 rc = mgs_wlp_lcfg(env, mgs, fsdb, mti, logname, &mgi->mgi_bufs,
4114 /* osc params affect the MDT as well */
4115 if (!rc && (mti->mti_flags & LDD_F_SV_TYPE_OST)) {
4118 for (i = 0; i < INDEX_MAP_SIZE * 8; i++){
4119 if (!test_bit(i, fsdb->fsdb_mdt_index_map))
4121 name_destroy(&cname);
4122 rc = name_create_mdt_osc(&cname, mti->mti_svname,
4124 name_destroy(&logname);
4127 rc = name_create_mdt(&logname,
4128 mti->mti_fsname, i);
4131 if (!mgs_log_is_empty(env, mgs, logname)) {
4132 rc = mgs_wlp_lcfg(env, mgs, fsdb,
4142 /* For mdc activate/deactivate, it affects OSP on MDT as well */
4143 if (class_match_param(ptr, PARAM_MDC PARAM_ACTIVE, &tmp) == 0 &&
4146 char *lodname = NULL;
4147 char *param_str = NULL;
4151 /* replace mdc with osp */
4152 memcpy(ptr, PARAM_OSP, strlen(PARAM_OSP));
4153 rc = server_name2index(mti->mti_svname, &index, NULL);
4155 memcpy(ptr, PARAM_MDC, strlen(PARAM_MDC));
4159 for (i = 0; i < INDEX_MAP_SIZE * 8; i++) {
4160 if (!test_bit(i, fsdb->fsdb_mdt_index_map))
4166 name_destroy(&logname);
4167 rc = name_create_mdt(&logname, mti->mti_fsname,
4172 if (mgs_log_is_empty(env, mgs, logname))
4175 snprintf(suffix, sizeof(suffix), "-osp-MDT%04x",
4177 name_destroy(&cname);
4178 rc = name_create(&cname, mti->mti_svname,
4183 rc = mgs_wlp_lcfg(env, mgs, fsdb, mti, logname,
4184 &mgi->mgi_bufs, cname, ptr);
4188 /* Add configuration log for noitfying LOD
4189 * to active/deactive the OSP. */
4190 name_destroy(¶m_str);
4191 rc = name_create(¶m_str, cname,
4192 (*tmp == '0') ? ".active=0" :
4197 name_destroy(&lodname);
4198 rc = name_create(&lodname, logname, "-mdtlov");
4202 rc = mgs_wlp_lcfg(env, mgs, fsdb, mti, logname,
4203 &mgi->mgi_bufs, lodname,
4208 memcpy(ptr, PARAM_MDC, strlen(PARAM_MDC));
4209 name_destroy(&lodname);
4210 name_destroy(¶m_str);
4213 name_destroy(&logname);
4214 name_destroy(&cname);
4218 /* All mdt. params in proc */
4219 if (class_match_param(ptr, PARAM_MDT, &tmp) == 0) {
4223 CDEBUG(D_MGS, "%.3s param %s\n", ptr, ptr + 4);
4224 if (strncmp(mti->mti_svname, mti->mti_fsname,
4225 MTI_NAME_MAXLEN) == 0)
4226 /* device is unspecified completely? */
4227 rc = LDD_F_SV_TYPE_MDT | LDD_F_SV_ALL;
4229 rc = server_name2index(mti->mti_svname, &idx, NULL);
4232 if ((rc & LDD_F_SV_TYPE_MDT) == 0)
4234 if (rc & LDD_F_SV_ALL) {
4235 for (i = 0; i < INDEX_MAP_SIZE * 8; i++) {
4237 fsdb->fsdb_mdt_index_map))
4239 rc = name_create_mdt(&logname,
4240 mti->mti_fsname, i);
4243 rc = mgs_wlp_lcfg(env, mgs, fsdb, mti,
4244 logname, &mgi->mgi_bufs,
4246 name_destroy(&logname);
4251 if ((memcmp(tmp, "root_squash=", 12) == 0) ||
4252 (memcmp(tmp, "nosquash_nids=", 14) == 0)) {
4253 LCONSOLE_ERROR("%s: root squash parameters "
4254 "cannot be applied to a single MDT\n",
4256 GOTO(end, rc = -EINVAL);
4258 rc = mgs_wlp_lcfg(env, mgs, fsdb, mti,
4259 mti->mti_svname, &mgi->mgi_bufs,
4260 mti->mti_svname, ptr);
4265 /* root squash settings are also applied to llite
4266 * config log (see LU-1778) */
4268 ((memcmp(tmp, "root_squash=", 12) == 0) ||
4269 (memcmp(tmp, "nosquash_nids=", 14) == 0))) {
4273 rc = name_create(&cname, mti->mti_fsname, "-client");
4276 rc = name_create(&logname, mti->mti_fsname, "-client");
4278 name_destroy(&cname);
4281 rc = name_create(&ptr2, PARAM_LLITE, tmp);
4283 name_destroy(&cname);
4284 name_destroy(&logname);
4287 rc = mgs_wlp_lcfg(env, mgs, fsdb, mti, logname,
4288 &mgi->mgi_bufs, cname, ptr2);
4289 name_destroy(&ptr2);
4290 name_destroy(&logname);
4291 name_destroy(&cname);
4296 /* All mdd., ost. and osd. params in proc */
4297 if ((class_match_param(ptr, PARAM_MDD, NULL) == 0) ||
4298 (class_match_param(ptr, PARAM_LOD, NULL) == 0) ||
4299 (class_match_param(ptr, PARAM_OST, NULL) == 0) ||
4300 (class_match_param(ptr, PARAM_OSD, NULL) == 0)) {
4301 CDEBUG(D_MGS, "%.3s param %s\n", ptr, ptr + 4);
4302 if (mgs_log_is_empty(env, mgs, mti->mti_svname))
4303 GOTO(end, rc = -ENODEV);
4305 rc = mgs_wlp_lcfg(env, mgs, fsdb, mti, mti->mti_svname,
4306 &mgi->mgi_bufs, mti->mti_svname, ptr);
4310 LCONSOLE_WARN("Ignoring unrecognized param '%s'\n", ptr);
4314 CERROR("err %d on param '%s'\n", rc, ptr);
4319 int mgs_write_log_target(const struct lu_env *env, struct mgs_device *mgs,
4320 struct mgs_target_info *mti, struct fs_db *fsdb)
4327 /* set/check the new target index */
4328 rc = mgs_set_index(env, mgs, mti);
4332 if (rc == EALREADY) {
4333 LCONSOLE_WARN("Found index %d for %s, updating log\n",
4334 mti->mti_stripe_index, mti->mti_svname);
4335 /* We would like to mark old log sections as invalid
4336 and add new log sections in the client and mdt logs.
4337 But if we add new sections, then live clients will
4338 get repeat setup instructions for already running
4339 osc's. So don't update the client/mdt logs. */
4340 mti->mti_flags &= ~LDD_F_UPDATE;
4344 OBD_FAIL_TIMEOUT(OBD_FAIL_MGS_WRITE_TARGET_DELAY, cfs_fail_val > 0 ?
4347 mutex_lock(&fsdb->fsdb_mutex);
4349 if (mti->mti_flags & (LDD_F_VIRGIN | LDD_F_WRITECONF)) {
4350 /* Generate a log from scratch */
4351 if (mti->mti_flags & LDD_F_SV_TYPE_MDT) {
4352 rc = mgs_write_log_mdt(env, mgs, fsdb, mti);
4353 } else if (mti->mti_flags & LDD_F_SV_TYPE_OST) {
4354 rc = mgs_write_log_ost(env, mgs, fsdb, mti);
4356 CERROR("Unknown target type %#x, can't create log for %s\n",
4357 mti->mti_flags, mti->mti_svname);
4360 CERROR("Can't write logs for %s (%d)\n",
4361 mti->mti_svname, rc);
4365 /* Just update the params from tunefs in mgs_write_log_params */
4366 CDEBUG(D_MGS, "Update params for %s\n", mti->mti_svname);
4367 mti->mti_flags |= LDD_F_PARAM;
4370 /* allocate temporary buffer, where class_get_next_param will
4371 make copy of a current parameter */
4372 OBD_ALLOC(buf, strlen(mti->mti_params) + 1);
4374 GOTO(out_up, rc = -ENOMEM);
4375 params = mti->mti_params;
4376 while (params != NULL) {
4377 rc = class_get_next_param(¶ms, buf);
4380 /* there is no next parameter, that is
4385 CDEBUG(D_MGS, "remaining string: '%s', param: '%s'\n",
4387 rc = mgs_write_log_param(env, mgs, fsdb, mti, buf);
4392 OBD_FREE(buf, strlen(mti->mti_params) + 1);
4395 mutex_unlock(&fsdb->fsdb_mutex);
4399 int mgs_erase_log(const struct lu_env *env, struct mgs_device *mgs, char *name)
4401 struct llog_ctxt *ctxt;
4404 ctxt = llog_get_context(mgs->mgs_obd, LLOG_CONFIG_ORIG_CTXT);
4406 CERROR("%s: MGS config context doesn't exist\n",
4407 mgs->mgs_obd->obd_name);
4410 rc = llog_erase(env, ctxt, NULL, name);
4411 /* llog may not exist */
4414 llog_ctxt_put(ctxt);
4418 CERROR("%s: failed to clear log %s: %d\n",
4419 mgs->mgs_obd->obd_name, name, rc);
4424 /* erase all logs for the given fs */
4425 int mgs_erase_logs(const struct lu_env *env, struct mgs_device *mgs,
4428 struct list_head log_list;
4429 struct mgs_direntry *dirent, *n;
4430 char barrier_name[20] = {};
4433 int rc, len = strlen(fsname);
4436 mutex_lock(&mgs->mgs_mutex);
4438 /* Find all the logs in the CONFIGS directory */
4439 rc = class_dentry_readdir(env, mgs, &log_list);
4441 mutex_unlock(&mgs->mgs_mutex);
4445 if (list_empty(&log_list)) {
4446 mutex_unlock(&mgs->mgs_mutex);
4450 snprintf(barrier_name, sizeof(barrier_name) - 1, "%s-%s",
4451 fsname, BARRIER_FILENAME);
4452 /* Delete the barrier fsdb */
4453 mgs_remove_fsdb_by_name(mgs, barrier_name);
4454 /* Delete the fs db */
4455 mgs_remove_fsdb_by_name(mgs, fsname);
4456 mutex_unlock(&mgs->mgs_mutex);
4458 list_for_each_entry_safe(dirent, n, &log_list, mde_list) {
4459 list_del_init(&dirent->mde_list);
4460 suffix = strrchr(dirent->mde_name, '-');
4461 if (suffix != NULL) {
4462 if ((len == suffix - dirent->mde_name) &&
4463 (strncmp(fsname, dirent->mde_name, len) == 0)) {
4464 CDEBUG(D_MGS, "Removing log %s\n",
4466 mgs_erase_log(env, mgs, dirent->mde_name);
4470 mgs_direntry_free(dirent);
4479 /* list all logs for the given fs */
4480 int mgs_list_logs(const struct lu_env *env, struct mgs_device *mgs,
4481 struct obd_ioctl_data *data)
4483 struct list_head log_list;
4484 struct mgs_direntry *dirent, *n;
4490 /* Find all the logs in the CONFIGS directory */
4491 rc = class_dentry_readdir(env, mgs, &log_list);
4495 out = data->ioc_bulk;
4496 remains = data->ioc_inllen1;
4497 list_for_each_entry_safe(dirent, n, &log_list, mde_list) {
4498 list_del_init(&dirent->mde_list);
4499 suffix = strrchr(dirent->mde_name, '-');
4500 if (suffix != NULL) {
4501 l = scnprintf(out, remains, "config_log: %s\n",
4506 mgs_direntry_free(dirent);
4513 struct mgs_lcfg_fork_data {
4514 struct lustre_cfg_bufs mlfd_bufs;
4515 struct mgs_device *mlfd_mgs;
4516 struct llog_handle *mlfd_llh;
4517 const char *mlfd_oldname;
4518 const char *mlfd_newname;
4522 static bool contain_valid_fsname(char *buf, const char *fsname,
4523 int buflen, int namelen)
4525 if (buflen < namelen)
4528 if (memcmp(buf, fsname, namelen) != 0)
4531 if (buf[namelen] != '\0' && buf[namelen] != '-')
4537 static int mgs_lcfg_fork_handler(const struct lu_env *env,
4538 struct llog_handle *o_llh,
4539 struct llog_rec_hdr *o_rec, void *data)
4541 struct mgs_lcfg_fork_data *mlfd = data;
4542 struct lustre_cfg_bufs *n_bufs = &mlfd->mlfd_bufs;
4543 struct lustre_cfg *o_lcfg = (struct lustre_cfg *)(o_rec + 1);
4544 struct llog_cfg_rec *lcr;
4546 char *n_buf = mlfd->mlfd_data;
4548 int o_namelen = strlen(mlfd->mlfd_oldname);
4549 int n_namelen = strlen(mlfd->mlfd_newname);
4550 int diff = n_namelen - o_namelen;
4551 __u32 cmd = o_lcfg->lcfg_command;
4552 __u32 cnt = o_lcfg->lcfg_bufcount;
4558 o_buf = lustre_cfg_buf(o_lcfg, 0);
4559 o_buflen = o_lcfg->lcfg_buflens[0];
4560 if (contain_valid_fsname(o_buf, mlfd->mlfd_oldname, o_buflen,
4562 memcpy(n_buf, mlfd->mlfd_newname, n_namelen);
4563 memcpy(n_buf + n_namelen, o_buf + o_namelen,
4564 o_buflen - o_namelen);
4565 lustre_cfg_bufs_reset(n_bufs, n_buf);
4566 n_buf += cfs_size_round(o_buflen + diff);
4568 lustre_cfg_bufs_reset(n_bufs, o_buflen != 0 ? o_buf : NULL);
4573 struct cfg_marker *o_marker;
4574 struct cfg_marker *n_marker;
4578 CDEBUG(D_MGS, "Unknown cfg marker entry with %d "
4583 /* buf[1] is marker */
4584 o_buf = lustre_cfg_buf(o_lcfg, 1);
4585 o_buflen = o_lcfg->lcfg_buflens[1];
4586 o_marker = (struct cfg_marker *)o_buf;
4587 if (!contain_valid_fsname(o_marker->cm_tgtname,
4589 sizeof(o_marker->cm_tgtname),
4591 lustre_cfg_bufs_set(n_bufs, 1, o_marker,
4596 n_marker = (struct cfg_marker *)n_buf;
4597 *n_marker = *o_marker;
4598 memcpy(n_marker->cm_tgtname, mlfd->mlfd_newname, n_namelen);
4599 tgt_namelen = strlen(o_marker->cm_tgtname);
4600 if (tgt_namelen > o_namelen)
4601 memcpy(n_marker->cm_tgtname + n_namelen,
4602 o_marker->cm_tgtname + o_namelen,
4603 tgt_namelen - o_namelen);
4604 n_marker->cm_tgtname[tgt_namelen + diff] = '\0';
4605 lustre_cfg_bufs_set(n_bufs, 1, n_marker, sizeof(*n_marker));
4609 case LCFG_SET_PARAM: {
4610 for (i = 1; i < cnt; i++)
4611 /* buf[i] is the param value, reuse it directly */
4612 lustre_cfg_bufs_set(n_bufs, i,
4613 lustre_cfg_buf(o_lcfg, i),
4614 o_lcfg->lcfg_buflens[i]);
4620 case LCFG_POOL_DEL: {
4621 if (cnt < 3 || cnt > 4) {
4622 CDEBUG(D_MGS, "Unknown cfg pool (%x) entry with %d "
4623 "buffers\n", cmd, cnt);
4627 /* buf[1] is fsname */
4628 o_buf = lustre_cfg_buf(o_lcfg, 1);
4629 o_buflen = o_lcfg->lcfg_buflens[1];
4630 memcpy(n_buf, mlfd->mlfd_newname, n_namelen);
4631 memcpy(n_buf + n_namelen, o_buf + o_namelen,
4632 o_buflen - o_namelen);
4633 lustre_cfg_bufs_set(n_bufs, 1, n_buf, o_buflen + diff);
4634 n_buf += cfs_size_round(o_buflen + diff);
4636 /* buf[2] is the pool name, reuse it directly */
4637 lustre_cfg_bufs_set(n_bufs, 2, lustre_cfg_buf(o_lcfg, 2),
4638 o_lcfg->lcfg_buflens[2]);
4643 /* buf[3] is ostname */
4644 o_buf = lustre_cfg_buf(o_lcfg, 3);
4645 o_buflen = o_lcfg->lcfg_buflens[3];
4646 memcpy(n_buf, mlfd->mlfd_newname, n_namelen);
4647 memcpy(n_buf + n_namelen, o_buf + o_namelen,
4648 o_buflen - o_namelen);
4649 lustre_cfg_bufs_set(n_bufs, 3, n_buf, o_buflen + diff);
4654 o_buflen = o_lcfg->lcfg_buflens[1];
4655 if (o_buflen == sizeof(struct lov_desc) ||
4656 o_buflen == sizeof(struct lmv_desc)) {
4662 o_buf = lustre_cfg_buf(o_lcfg, 1);
4663 if (o_buflen == sizeof(struct lov_desc)) {
4664 struct lov_desc *o_desc =
4665 (struct lov_desc *)o_buf;
4666 struct lov_desc *n_desc =
4667 (struct lov_desc *)n_buf;
4670 o_uuid = o_desc->ld_uuid.uuid;
4671 n_uuid = n_desc->ld_uuid.uuid;
4672 uuid_len = sizeof(o_desc->ld_uuid.uuid);
4674 struct lmv_desc *o_desc =
4675 (struct lmv_desc *)o_buf;
4676 struct lmv_desc *n_desc =
4677 (struct lmv_desc *)n_buf;
4680 o_uuid = o_desc->ld_uuid.uuid;
4681 n_uuid = n_desc->ld_uuid.uuid;
4682 uuid_len = sizeof(o_desc->ld_uuid.uuid);
4685 if (unlikely(!contain_valid_fsname(o_uuid,
4686 mlfd->mlfd_oldname, uuid_len,
4688 lustre_cfg_bufs_set(n_bufs, 1, o_buf,
4693 memcpy(n_uuid, mlfd->mlfd_newname, n_namelen);
4694 uuid_len = strlen(o_uuid);
4695 if (uuid_len > o_namelen)
4696 memcpy(n_uuid + n_namelen,
4698 uuid_len - o_namelen);
4699 n_uuid[uuid_len + diff] = '\0';
4700 lustre_cfg_bufs_set(n_bufs, 1, n_buf, o_buflen);
4702 } /* else case fall through */
4703 } /* else case fall through */
4707 for (i = 1; i < cnt; i++) {
4708 o_buflen = o_lcfg->lcfg_buflens[i];
4712 o_buf = lustre_cfg_buf(o_lcfg, i);
4713 if (!contain_valid_fsname(o_buf, mlfd->mlfd_oldname,
4714 o_buflen, o_namelen)) {
4715 lustre_cfg_bufs_set(n_bufs, i, o_buf, o_buflen);
4719 memcpy(n_buf, mlfd->mlfd_newname, n_namelen);
4720 if (o_buflen == o_namelen) {
4721 lustre_cfg_bufs_set(n_bufs, i, n_buf,
4723 n_buf += cfs_size_round(n_namelen);
4727 memcpy(n_buf + n_namelen, o_buf + o_namelen,
4728 o_buflen - o_namelen);
4729 lustre_cfg_bufs_set(n_bufs, i, n_buf, o_buflen + diff);
4730 n_buf += cfs_size_round(o_buflen + diff);
4736 lcr = lustre_cfg_rec_new(cmd, n_bufs);
4740 lcr->lcr_cfg = *o_lcfg;
4741 rc = llog_write(env, mlfd->mlfd_llh, &lcr->lcr_hdr, LLOG_NEXT_IDX);
4742 lustre_cfg_rec_free(lcr);
4747 static int mgs_lcfg_fork_one(const struct lu_env *env, struct mgs_device *mgs,
4748 struct mgs_direntry *mde, const char *oldname,
4749 const char *newname)
4751 struct llog_handle *old_llh = NULL;
4752 struct llog_handle *new_llh = NULL;
4753 struct llog_ctxt *ctxt = NULL;
4754 struct mgs_lcfg_fork_data *mlfd = NULL;
4755 char *name_buf = NULL;
4757 int old_namelen = strlen(oldname);
4758 int new_namelen = strlen(newname);
4762 name_buflen = mde->mde_len + new_namelen - old_namelen;
4763 OBD_ALLOC(name_buf, name_buflen);
4767 memcpy(name_buf, newname, new_namelen);
4768 memcpy(name_buf + new_namelen, mde->mde_name + old_namelen,
4769 mde->mde_len - old_namelen);
4771 CDEBUG(D_MGS, "Fork the config-log from %s to %s\n",
4772 mde->mde_name, name_buf);
4774 ctxt = llog_get_context(mgs->mgs_obd, LLOG_CONFIG_ORIG_CTXT);
4777 rc = llog_open_create(env, ctxt, &new_llh, NULL, name_buf);
4781 rc = llog_init_handle(env, new_llh, LLOG_F_IS_PLAIN, NULL);
4785 if (unlikely(mgs_log_is_empty(env, mgs, mde->mde_name)))
4788 rc = llog_open(env, ctxt, &old_llh, NULL, mde->mde_name,
4793 rc = llog_init_handle(env, old_llh, LLOG_F_IS_PLAIN, NULL);
4797 new_llh->lgh_hdr->llh_tgtuuid = old_llh->lgh_hdr->llh_tgtuuid;
4799 OBD_ALLOC(mlfd, LLOG_MIN_CHUNK_SIZE);
4801 GOTO(out, rc = -ENOMEM);
4803 mlfd->mlfd_mgs = mgs;
4804 mlfd->mlfd_llh = new_llh;
4805 mlfd->mlfd_oldname = oldname;
4806 mlfd->mlfd_newname = newname;
4808 rc = llog_process(env, old_llh, mgs_lcfg_fork_handler, mlfd, NULL);
4809 OBD_FREE(mlfd, LLOG_MIN_CHUNK_SIZE);
4815 llog_close(env, old_llh);
4817 llog_close(env, new_llh);
4819 OBD_FREE(name_buf, name_buflen);
4821 llog_ctxt_put(ctxt);
4826 int mgs_lcfg_fork(const struct lu_env *env, struct mgs_device *mgs,
4827 const char *oldname, const char *newname)
4829 struct list_head log_list;
4830 struct mgs_direntry *dirent, *n;
4831 int olen = strlen(oldname);
4832 int nlen = strlen(newname);
4837 if (unlikely(!oldname || oldname[0] == '\0' ||
4838 !newname || newname[0] == '\0'))
4841 if (strcmp(oldname, newname) == 0)
4844 /* lock it to prevent fork/erase/register in parallel. */
4845 mutex_lock(&mgs->mgs_mutex);
4847 rc = class_dentry_readdir(env, mgs, &log_list);
4849 mutex_unlock(&mgs->mgs_mutex);
4853 if (list_empty(&log_list)) {
4854 mutex_unlock(&mgs->mgs_mutex);
4858 list_for_each_entry_safe(dirent, n, &log_list, mde_list) {
4861 ptr = strrchr(dirent->mde_name, '-');
4863 int tlen = ptr - dirent->mde_name;
4866 strncmp(newname, dirent->mde_name, tlen) == 0)
4867 GOTO(out, rc = -EEXIST);
4870 strncmp(oldname, dirent->mde_name, tlen) == 0)
4874 list_del_init(&dirent->mde_list);
4875 mgs_direntry_free(dirent);
4878 if (list_empty(&log_list)) {
4879 mutex_unlock(&mgs->mgs_mutex);
4883 list_for_each_entry(dirent, &log_list, mde_list) {
4884 rc = mgs_lcfg_fork_one(env, mgs, dirent, oldname, newname);
4892 mutex_unlock(&mgs->mgs_mutex);
4894 list_for_each_entry_safe(dirent, n, &log_list, mde_list) {
4895 list_del_init(&dirent->mde_list);
4896 mgs_direntry_free(dirent);
4899 if (rc && count > 0)
4900 mgs_erase_logs(env, mgs, newname);
4905 int mgs_lcfg_erase(const struct lu_env *env, struct mgs_device *mgs,
4911 if (unlikely(!fsname || fsname[0] == '\0'))
4914 rc = mgs_erase_logs(env, mgs, fsname);
4919 static int mgs_xattr_del(const struct lu_env *env, struct dt_object *obj)
4921 struct dt_device *dev;
4922 struct thandle *th = NULL;
4927 dev = container_of0(obj->do_lu.lo_dev, struct dt_device, dd_lu_dev);
4928 th = dt_trans_create(env, dev);
4930 RETURN(PTR_ERR(th));
4932 rc = dt_declare_xattr_del(env, obj, XATTR_TARGET_RENAME, th);
4936 rc = dt_trans_start_local(env, dev, th);
4940 dt_write_lock(env, obj, 0);
4941 rc = dt_xattr_del(env, obj, XATTR_TARGET_RENAME, th);
4946 dt_write_unlock(env, obj);
4949 dt_trans_stop(env, dev, th);
4954 int mgs_lcfg_rename(const struct lu_env *env, struct mgs_device *mgs)
4956 struct list_head log_list;
4957 struct mgs_direntry *dirent, *n;
4959 struct lu_buf buf = {
4961 .lb_len = sizeof(fsname)
4967 rc = class_dentry_readdir(env, mgs, &log_list);
4971 if (list_empty(&log_list))
4974 list_for_each_entry_safe(dirent, n, &log_list, mde_list) {
4975 struct dt_object *o = NULL;
4980 list_del_init(&dirent->mde_list);
4981 ptr = strrchr(dirent->mde_name, '-');
4985 len = ptr - dirent->mde_name;
4986 if (unlikely(len >= sizeof(oldname))) {
4987 CDEBUG(D_MGS, "Skip invalid configuration file %s\n",
4992 o = local_file_find(env, mgs->mgs_los, mgs->mgs_configs_dir,
4996 CDEBUG(D_MGS, "Fail to locate file %s: rc = %d\n",
4997 dirent->mde_name, rc);
5001 rc = dt_xattr_get(env, o, &buf, XATTR_TARGET_RENAME);
5007 "Fail to get EA for %s: rc = %d\n",
5008 dirent->mde_name, rc);
5012 if (unlikely(rc == len &&
5013 memcmp(fsname, dirent->mde_name, len) == 0)) {
5014 /* The new fsname is the same as the old one. */
5015 rc = mgs_xattr_del(env, o);
5019 memcpy(oldname, dirent->mde_name, len);
5020 oldname[len] = '\0';
5022 rc = mgs_lcfg_fork_one(env, mgs, dirent, oldname, fsname);
5023 if (rc && rc != -EEXIST) {
5024 CDEBUG(D_MGS, "Fail to fork %s: rc = %d\n",
5025 dirent->mde_name, rc);
5029 rc = mgs_erase_log(env, mgs, dirent->mde_name);
5031 CDEBUG(D_MGS, "Fail to erase old %s: rc = %d\n",
5032 dirent->mde_name, rc);
5033 /* keep it there if failed to remove it. */
5038 if (o && !IS_ERR(o))
5039 lu_object_put(env, &o->do_lu);
5041 mgs_direntry_free(dirent);
5046 list_for_each_entry_safe(dirent, n, &log_list, mde_list) {
5047 list_del_init(&dirent->mde_list);
5048 mgs_direntry_free(dirent);
5054 /* Setup _mgs fsdb and log
5056 int mgs__mgs_fsdb_setup(const struct lu_env *env, struct mgs_device *mgs)
5058 struct fs_db *fsdb = NULL;
5062 rc = mgs_find_or_make_fsdb(env, mgs, MGSSELF_NAME, &fsdb);
5064 mgs_put_fsdb(mgs, fsdb);
5069 /* Setup params fsdb and log
5071 int mgs_params_fsdb_setup(const struct lu_env *env, struct mgs_device *mgs)
5073 struct fs_db *fsdb = NULL;
5074 struct llog_handle *params_llh = NULL;
5078 rc = mgs_find_or_make_fsdb(env, mgs, PARAMS_FILENAME, &fsdb);
5080 mutex_lock(&fsdb->fsdb_mutex);
5081 rc = record_start_log(env, mgs, ¶ms_llh, PARAMS_FILENAME);
5083 rc = record_end_log(env, ¶ms_llh);
5084 mutex_unlock(&fsdb->fsdb_mutex);
5085 mgs_put_fsdb(mgs, fsdb);
5091 /* Cleanup params fsdb and log
5093 int mgs_params_fsdb_cleanup(const struct lu_env *env, struct mgs_device *mgs)
5097 rc = mgs_erase_logs(env, mgs, PARAMS_FILENAME);
5098 return rc == -ENOENT ? 0 : rc;
5102 * Fill in the mgs_target_info based on data devname and param provide.
5104 * @env thread context
5106 * @mti mgs target info. We want to set this based other paramters
5107 * passed to this function. Once setup we write it to the config
5109 * @devname optional OBD device name
5110 * @param string that contains both what tunable to set and the value to
5113 * RETURN 0 for success
5114 * negative error number on failure
5116 static int mgs_set_conf_param(const struct lu_env *env, struct mgs_device *mgs,
5117 struct mgs_target_info *mti, const char *devname,
5120 struct fs_db *fsdb = NULL;
5125 /* lustre, lustre-mdtlov, lustre-client, lustre-MDT0000 */
5129 /* We have two possible cases here:
5131 * 1) the device name embedded in the param:
5132 * lustre-OST0000.osc.max_dirty_mb=32
5134 * 2) the file system name is embedded in
5135 * the param: lustre.sys.at.min=0
5137 len = strcspn(param, ".=");
5138 if (!len || param[len] == '=')
5141 if (len >= sizeof(mti->mti_svname))
5144 snprintf(mti->mti_svname, sizeof(mti->mti_svname),
5145 "%.*s", (int)len, param);
5148 if (strlcpy(mti->mti_svname, devname, sizeof(mti->mti_svname)) >=
5149 sizeof(mti->mti_svname))
5153 if (!strlen(mti->mti_svname)) {
5154 LCONSOLE_ERROR_MSG(0x14d, "No target specified: %s\n", param);
5158 dev_type = mgs_parse_devname(mti->mti_svname, mti->mti_fsname,
5159 &mti->mti_stripe_index);
5161 /* For this case we have an invalid obd device name */
5163 CDEBUG(D_MGS, "%s don't contain an index\n", mti->mti_svname);
5164 strlcpy(mti->mti_fsname, mti->mti_svname, MTI_NAME_MAXLEN);
5167 /* Not an obd device, assume devname is the fsname.
5168 * User might of only provided fsname and not obd device
5171 CDEBUG(D_MGS, "%s is seen as a file system name\n", mti->mti_svname);
5172 strlcpy(mti->mti_fsname, mti->mti_svname, MTI_NAME_MAXLEN);
5177 GOTO(out, rc = dev_type);
5179 /* param related to llite isn't allowed to set by OST or MDT */
5180 if (dev_type & LDD_F_SV_TYPE_OST ||
5181 dev_type & LDD_F_SV_TYPE_MDT) {
5182 /* param related to llite isn't allowed to set by OST
5185 if (!strncmp(param, PARAM_LLITE,
5186 sizeof(PARAM_LLITE) - 1))
5187 GOTO(out, rc = -EINVAL);
5189 /* Strip -osc or -mdc suffix from svname */
5190 if (server_make_name(dev_type, mti->mti_stripe_index,
5191 mti->mti_fsname, mti->mti_svname,
5192 sizeof(mti->mti_svname)))
5193 GOTO(out, rc = -EINVAL);
5198 if (strlcpy(mti->mti_params, param, sizeof(mti->mti_params)) >=
5199 sizeof(mti->mti_params))
5200 GOTO(out, rc = -E2BIG);
5202 CDEBUG(D_MGS, "set_conf_param fs='%s' device='%s' param='%s'\n",
5203 mti->mti_fsname, mti->mti_svname, mti->mti_params);
5205 rc = mgs_find_or_make_fsdb(env, mgs, mti->mti_fsname, &fsdb);
5209 if (!test_bit(FSDB_MGS_SELF, &fsdb->fsdb_flags) &&
5210 test_bit(FSDB_LOG_EMPTY, &fsdb->fsdb_flags)) {
5211 CERROR("No filesystem targets for %s. cfg_device from lctl "
5212 "is '%s'\n", mti->mti_fsname, mti->mti_svname);
5213 mgs_unlink_fsdb(mgs, fsdb);
5214 GOTO(out, rc = -EINVAL);
5218 * Revoke lock so everyone updates. Should be alright if
5219 * someone was already reading while we were updating the logs,
5220 * so we don't really need to hold the lock while we're
5223 mti->mti_flags = dev_type | LDD_F_PARAM;
5224 mutex_lock(&fsdb->fsdb_mutex);
5225 rc = mgs_write_log_param(env, mgs, fsdb, mti, mti->mti_params);
5226 mutex_unlock(&fsdb->fsdb_mutex);
5227 mgs_revoke_lock(mgs, fsdb, CONFIG_T_CONFIG);
5231 mgs_put_fsdb(mgs, fsdb);
5236 static int mgs_set_param2(const struct lu_env *env, struct mgs_device *mgs,
5237 struct mgs_target_info *mti, const char *param)
5239 struct fs_db *fsdb = NULL;
5244 if (strlcpy(mti->mti_params, param, sizeof(mti->mti_params)) >=
5245 sizeof(mti->mti_params))
5246 GOTO(out, rc = -E2BIG);
5248 len = strcspn(param, ".=");
5249 if (len && param[len] != '=') {
5250 struct list_head *tmp;
5254 ptr = strchr(param, '.');
5256 len = strlen(param);
5259 if (len >= sizeof(mti->mti_svname))
5260 GOTO(out, rc = -E2BIG);
5262 snprintf(mti->mti_svname, sizeof(mti->mti_svname), "%.*s",
5265 mutex_lock(&mgs->mgs_mutex);
5266 if (unlikely(list_empty(&mgs->mgs_fs_db_list))) {
5267 mutex_unlock(&mgs->mgs_mutex);
5268 GOTO(out, rc = -ENODEV);
5271 list_for_each(tmp, &mgs->mgs_fs_db_list) {
5272 fsdb = list_entry(tmp, struct fs_db, fsdb_list);
5273 if (fsdb->fsdb_has_lproc_entry &&
5274 strcmp(fsdb->fsdb_name, "params") != 0 &&
5275 strstr(param, fsdb->fsdb_name)) {
5276 snprintf(mti->mti_svname,
5277 sizeof(mti->mti_svname), "%s",
5285 snprintf(mti->mti_svname, sizeof(mti->mti_svname),
5288 mutex_unlock(&mgs->mgs_mutex);
5290 snprintf(mti->mti_svname, sizeof(mti->mti_svname), "general");
5293 CDEBUG(D_MGS, "set_param2 fs='%s' device='%s' param='%s'\n",
5294 mti->mti_fsname, mti->mti_svname, mti->mti_params);
5296 /* The return value should be the device type i.e LDD_F_SV_TYPE_XXX.
5297 * A returned error tells us we don't have a target obd device.
5299 dev_type = server_name2index(mti->mti_svname, &mti->mti_stripe_index,
5304 /* the return value should be the device type i.e LDD_F_SV_TYPE_XXX.
5305 * Strip -osc or -mdc suffix from svname
5307 if ((dev_type & LDD_F_SV_TYPE_OST || dev_type & LDD_F_SV_TYPE_MDT) &&
5308 server_make_name(dev_type, mti->mti_stripe_index,
5309 mti->mti_fsname, mti->mti_svname,
5310 sizeof(mti->mti_svname)))
5311 GOTO(out, rc = -EINVAL);
5313 rc = mgs_find_or_make_fsdb(env, mgs, PARAMS_FILENAME, &fsdb);
5317 * Revoke lock so everyone updates. Should be alright if
5318 * someone was already reading while we were updating the logs,
5319 * so we don't really need to hold the lock while we're
5322 mti->mti_flags = dev_type | LDD_F_PARAM2;
5323 mutex_lock(&fsdb->fsdb_mutex);
5324 rc = mgs_write_log_param2(env, mgs, fsdb, mti, mti->mti_params);
5325 mutex_unlock(&fsdb->fsdb_mutex);
5326 mgs_revoke_lock(mgs, fsdb, CONFIG_T_PARAMS);
5327 mgs_put_fsdb(mgs, fsdb);
5332 /* Set a permanent (config log) param for a target or fs
5334 * @lcfg buf0 may contain the device (testfs-MDT0000) name
5335 * buf1 contains the single parameter
5337 int mgs_set_param(const struct lu_env *env, struct mgs_device *mgs,
5338 struct lustre_cfg *lcfg)
5340 const char *param = lustre_cfg_string(lcfg, 1);
5341 struct mgs_target_info *mti;
5344 /* Create a fake mti to hold everything */
5349 print_lustre_cfg(lcfg);
5351 if (lcfg->lcfg_command == LCFG_PARAM) {
5352 /* For the case of lctl conf_param devname can be
5353 * lustre, lustre-mdtlov, lustre-client, lustre-MDT0000
5355 const char *devname = lustre_cfg_string(lcfg, 0);
5357 rc = mgs_set_conf_param(env, mgs, mti, devname, param);
5359 /* In the case of lctl set_param -P lcfg[0] will always
5360 * be 'general'. At least for now.
5362 rc = mgs_set_param2(env, mgs, mti, param);
5370 static int mgs_write_log_pool(const struct lu_env *env,
5371 struct mgs_device *mgs, char *logname,
5372 struct fs_db *fsdb, char *tgtname,
5373 enum lcfg_command_type cmd,
5374 char *fsname, char *poolname,
5375 char *ostname, char *comment)
5377 struct llog_handle *llh = NULL;
5380 rc = record_start_log(env, mgs, &llh, logname);
5383 rc = record_marker(env, llh, fsdb, CM_START, tgtname, comment);
5386 rc = record_base(env, llh, tgtname, 0, cmd,
5387 fsname, poolname, ostname, NULL);
5390 rc = record_marker(env, llh, fsdb, CM_END, tgtname, comment);
5392 record_end_log(env, &llh);
5396 int mgs_nodemap_cmd(const struct lu_env *env, struct mgs_device *mgs,
5397 enum lcfg_command_type cmd, const char *nodemap_name,
5408 case LCFG_NODEMAP_ADD:
5409 rc = nodemap_add(nodemap_name);
5411 case LCFG_NODEMAP_DEL:
5412 rc = nodemap_del(nodemap_name);
5414 case LCFG_NODEMAP_ADD_RANGE:
5415 rc = nodemap_parse_range(param, nid);
5418 rc = nodemap_add_range(nodemap_name, nid);
5420 case LCFG_NODEMAP_DEL_RANGE:
5421 rc = nodemap_parse_range(param, nid);
5424 rc = nodemap_del_range(nodemap_name, nid);
5426 case LCFG_NODEMAP_ADMIN:
5427 rc = kstrtobool(param, &bool_switch);
5430 rc = nodemap_set_allow_root(nodemap_name, bool_switch);
5432 case LCFG_NODEMAP_DENY_UNKNOWN:
5433 rc = kstrtobool(param, &bool_switch);
5436 rc = nodemap_set_deny_unknown(nodemap_name, bool_switch);
5438 case LCFG_NODEMAP_AUDIT_MODE:
5439 rc = kstrtoul(param, 10, (unsigned long *)&bool_switch);
5441 rc = nodemap_set_audit_mode(nodemap_name, bool_switch);
5443 case LCFG_NODEMAP_MAP_MODE:
5444 if (strcmp("both", param) == 0)
5445 rc = nodemap_set_mapping_mode(nodemap_name,
5447 else if (strcmp("uid_only", param) == 0)
5448 rc = nodemap_set_mapping_mode(nodemap_name,
5449 NODEMAP_MAP_UID_ONLY);
5450 else if (strcmp("gid_only", param) == 0)
5451 rc = nodemap_set_mapping_mode(nodemap_name,
5452 NODEMAP_MAP_GID_ONLY);
5456 case LCFG_NODEMAP_TRUSTED:
5457 rc = kstrtobool(param, &bool_switch);
5460 rc = nodemap_set_trust_client_ids(nodemap_name, bool_switch);
5462 case LCFG_NODEMAP_SQUASH_UID:
5463 rc = kstrtouint(param, 10, &int_id);
5466 rc = nodemap_set_squash_uid(nodemap_name, int_id);
5468 case LCFG_NODEMAP_SQUASH_GID:
5469 rc = kstrtouint(param, 10, &int_id);
5472 rc = nodemap_set_squash_gid(nodemap_name, int_id);
5474 case LCFG_NODEMAP_ADD_UIDMAP:
5475 case LCFG_NODEMAP_ADD_GIDMAP:
5476 rc = nodemap_parse_idmap(param, idmap);
5479 if (cmd == LCFG_NODEMAP_ADD_UIDMAP)
5480 rc = nodemap_add_idmap(nodemap_name, NODEMAP_UID,
5483 rc = nodemap_add_idmap(nodemap_name, NODEMAP_GID,
5486 case LCFG_NODEMAP_DEL_UIDMAP:
5487 case LCFG_NODEMAP_DEL_GIDMAP:
5488 rc = nodemap_parse_idmap(param, idmap);
5491 if (cmd == LCFG_NODEMAP_DEL_UIDMAP)
5492 rc = nodemap_del_idmap(nodemap_name, NODEMAP_UID,
5495 rc = nodemap_del_idmap(nodemap_name, NODEMAP_GID,
5498 case LCFG_NODEMAP_SET_FILESET:
5499 rc = nodemap_set_fileset(nodemap_name, param);
5501 case LCFG_NODEMAP_SET_SEPOL:
5502 rc = nodemap_set_sepol(nodemap_name, param);
5511 int mgs_pool_cmd(const struct lu_env *env, struct mgs_device *mgs,
5512 enum lcfg_command_type cmd, char *fsname,
5513 char *poolname, char *ostname)
5518 char *label = NULL, *canceled_label = NULL;
5520 struct mgs_target_info *mti = NULL;
5521 bool checked = false;
5522 bool locked = false;
5527 rc = mgs_find_or_make_fsdb(env, mgs, fsname, &fsdb);
5529 CERROR("Can't get db for %s\n", fsname);
5532 if (test_bit(FSDB_LOG_EMPTY, &fsdb->fsdb_flags)) {
5533 CERROR("%s is not defined\n", fsname);
5535 GOTO(out_fsdb, rc = -EINVAL);
5538 label_sz = 10 + strlen(fsname) + strlen(poolname);
5540 /* check if ostname match fsname */
5541 if (ostname != NULL) {
5544 ptr = strrchr(ostname, '-');
5545 if ((ptr == NULL) ||
5546 (strncmp(fsname, ostname, ptr-ostname) != 0))
5548 label_sz += strlen(ostname);
5551 OBD_ALLOC(label, label_sz);
5553 GOTO(out_fsdb, rc = -ENOMEM);
5558 "new %s.%s", fsname, poolname);
5562 "add %s.%s.%s", fsname, poolname, ostname);
5565 OBD_ALLOC(canceled_label, label_sz);
5566 if (canceled_label == NULL)
5567 GOTO(out_label, rc = -ENOMEM);
5569 "rem %s.%s.%s", fsname, poolname, ostname);
5570 sprintf(canceled_label,
5571 "add %s.%s.%s", fsname, poolname, ostname);
5574 OBD_ALLOC(canceled_label, label_sz);
5575 if (canceled_label == NULL)
5576 GOTO(out_label, rc = -ENOMEM);
5578 "del %s.%s", fsname, poolname);
5579 sprintf(canceled_label,
5580 "new %s.%s", fsname, poolname);
5588 GOTO(out_cancel, rc = -ENOMEM);
5589 strncpy(mti->mti_svname, "lov pool", sizeof(mti->mti_svname));
5591 mutex_lock(&fsdb->fsdb_mutex);
5593 /* write pool def to all MDT logs */
5594 for (i = 0; i < INDEX_MAP_SIZE * 8; i++) {
5595 if (test_bit(i, fsdb->fsdb_mdt_index_map)) {
5596 rc = name_create_mdt_and_lov(&logname, &lovname,
5601 if (!checked && (canceled_label == NULL)) {
5602 rc = mgs_check_marker(env, mgs, fsdb, mti,
5603 logname, lovname, label);
5605 name_destroy(&logname);
5606 name_destroy(&lovname);
5608 rc = (rc == LLOG_PROC_BREAK ?
5613 if (canceled_label != NULL)
5614 rc = mgs_modify(env, mgs, fsdb, mti, logname,
5615 lovname, canceled_label,
5619 rc = mgs_write_log_pool(env, mgs, logname,
5623 name_destroy(&logname);
5624 name_destroy(&lovname);
5630 rc = name_create(&logname, fsname, "-client");
5634 if (!checked && (canceled_label == NULL)) {
5635 rc = mgs_check_marker(env, mgs, fsdb, mti, logname,
5636 fsdb->fsdb_clilov, label);
5638 name_destroy(&logname);
5639 GOTO(out_mti, rc = (rc == LLOG_PROC_BREAK ?
5643 if (canceled_label != NULL) {
5644 rc = mgs_modify(env, mgs, fsdb, mti, logname,
5645 fsdb->fsdb_clilov, canceled_label, CM_SKIP);
5647 name_destroy(&logname);
5652 rc = mgs_write_log_pool(env, mgs, logname, fsdb, fsdb->fsdb_clilov,
5653 cmd, fsname, poolname, ostname, label);
5654 mutex_unlock(&fsdb->fsdb_mutex);
5656 name_destroy(&logname);
5657 /* request for update */
5658 mgs_revoke_lock(mgs, fsdb, CONFIG_T_CONFIG);
5664 mutex_unlock(&fsdb->fsdb_mutex);
5668 if (canceled_label != NULL)
5669 OBD_FREE(canceled_label, label_sz);
5671 OBD_FREE(label, label_sz);
5674 mgs_unlink_fsdb(mgs, fsdb);
5675 mgs_put_fsdb(mgs, fsdb);