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 i)
1541 sprintf(mdt_index, "-MDT%04x", i);
1542 return name_create(logname, fsname, mdt_index);
1546 * Replace nids for \a device to \a nids values
1548 * \param obd MGS obd device
1549 * \param devname nids need to be replaced for this device
1550 * (ex. lustre-OST0000)
1551 * \param nids nids list (ex. nid1,nid2,nid3)
1555 int mgs_replace_nids(const struct lu_env *env,
1556 struct mgs_device *mgs,
1557 char *devname, char *nids)
1559 /* Assume fsname is part of device name */
1560 char fsname[MTI_NAME_MAXLEN];
1564 struct fs_db *fsdb = NULL;
1567 struct obd_device *mgs_obd = mgs->mgs_obd;
1570 /* We can only change NIDs if no other nodes are connected */
1571 spin_lock(&mgs_obd->obd_dev_lock);
1572 conn_state = mgs_obd->obd_no_conn;
1573 mgs_obd->obd_no_conn = 1;
1574 spin_unlock(&mgs_obd->obd_dev_lock);
1576 /* We can not change nids if not only MGS is started */
1577 if (!only_mgs_is_running(mgs_obd)) {
1578 CERROR("Only MGS is allowed to be started\n");
1579 GOTO(out, rc = -EINPROGRESS);
1582 /* Get fsname and index */
1583 rc = mgs_parse_devname(devname, fsname, &index);
1587 rc = mgs_find_or_make_fsdb(env, mgs, fsname, &fsdb);
1589 CERROR("%s: can't find fsdb: rc = %d\n", fsname, rc);
1593 /* Process client llogs */
1594 name_create(&logname, fsname, "-client");
1595 rc = mgs_replace_nids_log(env, mgs_obd, logname, devname, nids);
1596 name_destroy(&logname);
1598 CERROR("%s: error while replacing NIDs for %s: rc = %d\n",
1599 fsname, devname, rc);
1603 /* Process MDT llogs */
1604 for (i = 0; i < INDEX_MAP_SIZE * 8; i++) {
1605 if (!test_bit(i, fsdb->fsdb_mdt_index_map))
1607 name_create_mdt(&logname, fsname, i);
1608 rc = mgs_replace_nids_log(env, mgs_obd, logname, devname, nids);
1609 name_destroy(&logname);
1615 spin_lock(&mgs_obd->obd_dev_lock);
1616 mgs_obd->obd_no_conn = conn_state;
1617 spin_unlock(&mgs_obd->obd_dev_lock);
1620 mgs_put_fsdb(mgs, fsdb);
1626 * This is called for every record in llog. Some of records are
1627 * skipped, others are copied to new log as is.
1628 * Records to be skipped are
1629 * marker records marked SKIP
1630 * records enclosed between SKIP markers
1632 * \param[in] llh log to be processed
1633 * \param[in] rec current record
1634 * \param[in] data mgs_replace_data structure
1638 static int mgs_clear_config_handler(const struct lu_env *env,
1639 struct llog_handle *llh,
1640 struct llog_rec_hdr *rec, void *data)
1642 struct mgs_replace_data *mrd;
1643 struct lustre_cfg *lcfg = REC_DATA(rec);
1644 int cfg_len = REC_DATA_LEN(rec);
1649 mrd = (struct mgs_replace_data *)data;
1651 if (rec->lrh_type != OBD_CFG_REC) {
1652 CDEBUG(D_MGS, "Config llog Name=%s, Record Index=%u, "
1653 "Unhandled Record Type=%#x\n", llh->lgh_name,
1654 rec->lrh_index, rec->lrh_type);
1658 rc = lustre_cfg_sanity_check(lcfg, cfg_len);
1660 CDEBUG(D_MGS, "Config llog Name=%s, Invalid config file.",
1665 if (lcfg->lcfg_command == LCFG_MARKER) {
1666 struct cfg_marker *marker;
1668 marker = lustre_cfg_buf(lcfg, 1);
1669 if (marker->cm_flags & CM_SKIP) {
1670 if (marker->cm_flags & CM_START)
1671 mrd->state = REPLACE_SKIP;
1672 if (marker->cm_flags & CM_END)
1673 mrd->state = REPLACE_COPY;
1674 /* SKIP section started or finished */
1675 CDEBUG(D_MGS, "Skip idx=%d, rc=%d, len=%d, "
1676 "cmd %x %s %s\n", rec->lrh_index, rc,
1677 rec->lrh_len, lcfg->lcfg_command,
1678 lustre_cfg_string(lcfg, 0),
1679 lustre_cfg_string(lcfg, 1));
1683 if (mrd->state == REPLACE_SKIP) {
1684 /* record enclosed between SKIP markers, skip it */
1685 CDEBUG(D_MGS, "Skip idx=%d, rc=%d, len=%d, "
1686 "cmd %x %s %s\n", rec->lrh_index, rc,
1687 rec->lrh_len, lcfg->lcfg_command,
1688 lustre_cfg_string(lcfg, 0),
1689 lustre_cfg_string(lcfg, 1));
1694 /* Record is placed in temporary llog as is */
1695 rc = llog_write(env, mrd->temp_llh, rec, LLOG_NEXT_IDX);
1697 CDEBUG(D_MGS, "Copied idx=%d, rc=%d, len=%d, cmd %x %s %s\n",
1698 rec->lrh_index, rc, rec->lrh_len, lcfg->lcfg_command,
1699 lustre_cfg_string(lcfg, 0), lustre_cfg_string(lcfg, 1));
1704 * Directory CONFIGS/ may contain files which are not config logs to
1705 * be cleared. Skip any llogs with a non-alphanumeric character after
1706 * the last '-'. For example, fsname-MDT0000.sav, fsname-MDT0000.bak,
1707 * fsname-MDT0000.orig, fsname-MDT0000~, fsname-MDT0000.20150516, etc.
1709 static bool config_to_clear(const char *logname)
1714 str = strrchr(logname, '-');
1719 while (isalnum(str[++i]));
1720 return str[i] == '\0';
1724 * Clear config logs for \a name
1727 * \param mgs MGS device
1728 * \param name name of device or of filesystem
1729 * (ex. lustre-OST0000 or lustre) in later case all logs
1734 int mgs_clear_configs(const struct lu_env *env,
1735 struct mgs_device *mgs, const char *name)
1737 struct list_head dentry_list;
1738 struct mgs_direntry *dirent, *n;
1741 struct obd_device *mgs_obd = mgs->mgs_obd;
1746 /* Prevent clients and servers from connecting to mgs */
1747 spin_lock(&mgs_obd->obd_dev_lock);
1748 conn_state = mgs_obd->obd_no_conn;
1749 mgs_obd->obd_no_conn = 1;
1750 spin_unlock(&mgs_obd->obd_dev_lock);
1753 * config logs cannot be cleaned if anything other than
1756 if (!only_mgs_is_running(mgs_obd)) {
1757 CERROR("Only MGS is allowed to be started\n");
1758 GOTO(out, rc = -EBUSY);
1761 /* Find all the logs in the CONFIGS directory */
1762 rc = class_dentry_readdir(env, mgs, &dentry_list);
1764 CERROR("%s: cannot read config directory '%s': rc = %d\n",
1765 mgs_obd->obd_name, MOUNT_CONFIGS_DIR, rc);
1769 if (list_empty(&dentry_list)) {
1770 CERROR("%s: list empty reading config dir '%s': rc = %d\n",
1771 mgs_obd->obd_name, MOUNT_CONFIGS_DIR, -ENOENT);
1772 GOTO(out, rc = -ENOENT);
1775 OBD_ALLOC(namedash, strlen(name) + 2);
1776 if (namedash == NULL)
1777 GOTO(out, rc = -ENOMEM);
1778 snprintf(namedash, strlen(name) + 2, "%s-", name);
1780 list_for_each_entry(dirent, &dentry_list, mde_list) {
1781 if (strcmp(name, dirent->mde_name) &&
1782 strncmp(namedash, dirent->mde_name, strlen(namedash)))
1784 if (!config_to_clear(dirent->mde_name))
1786 CDEBUG(D_MGS, "%s: Clear config log %s\n",
1787 mgs_obd->obd_name, dirent->mde_name);
1788 rc = mgs_replace_log(env, mgs_obd, dirent->mde_name, NULL,
1789 mgs_clear_config_handler, NULL);
1794 list_for_each_entry_safe(dirent, n, &dentry_list, mde_list) {
1795 list_del_init(&dirent->mde_list);
1796 mgs_direntry_free(dirent);
1798 OBD_FREE(namedash, strlen(name) + 2);
1800 spin_lock(&mgs_obd->obd_dev_lock);
1801 mgs_obd->obd_no_conn = conn_state;
1802 spin_unlock(&mgs_obd->obd_dev_lock);
1807 static int record_lov_setup(const struct lu_env *env, struct llog_handle *llh,
1808 char *devname, struct lov_desc *desc)
1810 struct mgs_thread_info *mgi = mgs_env_info(env);
1811 struct llog_cfg_rec *lcr;
1814 lustre_cfg_bufs_reset(&mgi->mgi_bufs, devname);
1815 lustre_cfg_bufs_set(&mgi->mgi_bufs, 1, desc, sizeof(*desc));
1816 lcr = lustre_cfg_rec_new(LCFG_SETUP, &mgi->mgi_bufs);
1820 rc = llog_write(env, llh, &lcr->lcr_hdr, LLOG_NEXT_IDX);
1821 lustre_cfg_rec_free(lcr);
1825 static int record_lmv_setup(const struct lu_env *env, struct llog_handle *llh,
1826 char *devname, struct lmv_desc *desc)
1828 struct mgs_thread_info *mgi = mgs_env_info(env);
1829 struct llog_cfg_rec *lcr;
1832 lustre_cfg_bufs_reset(&mgi->mgi_bufs, devname);
1833 lustre_cfg_bufs_set(&mgi->mgi_bufs, 1, desc, sizeof(*desc));
1834 lcr = lustre_cfg_rec_new(LCFG_SETUP, &mgi->mgi_bufs);
1838 rc = llog_write(env, llh, &lcr->lcr_hdr, LLOG_NEXT_IDX);
1839 lustre_cfg_rec_free(lcr);
1843 static inline int record_mdc_add(const struct lu_env *env,
1844 struct llog_handle *llh,
1845 char *logname, char *mdcuuid,
1846 char *mdtuuid, char *index,
1849 return record_base(env,llh,logname,0,LCFG_ADD_MDC,
1850 mdtuuid,index,gen,mdcuuid);
1853 static inline int record_lov_add(const struct lu_env *env,
1854 struct llog_handle *llh,
1855 char *lov_name, char *ost_uuid,
1856 char *index, char *gen)
1858 return record_base(env, llh, lov_name, 0, LCFG_LOV_ADD_OBD,
1859 ost_uuid, index, gen, NULL);
1862 static inline int record_mount_opt(const struct lu_env *env,
1863 struct llog_handle *llh,
1864 char *profile, char *lov_name,
1867 return record_base(env, llh, NULL, 0, LCFG_MOUNTOPT,
1868 profile, lov_name, mdc_name, NULL);
1871 static int record_marker(const struct lu_env *env,
1872 struct llog_handle *llh,
1873 struct fs_db *fsdb, __u32 flags,
1874 char *tgtname, char *comment)
1876 struct mgs_thread_info *mgi = mgs_env_info(env);
1877 struct llog_cfg_rec *lcr;
1881 if (flags & CM_START)
1883 mgi->mgi_marker.cm_step = fsdb->fsdb_gen;
1884 mgi->mgi_marker.cm_flags = flags;
1885 mgi->mgi_marker.cm_vers = LUSTRE_VERSION_CODE;
1886 cplen = strlcpy(mgi->mgi_marker.cm_tgtname, tgtname,
1887 sizeof(mgi->mgi_marker.cm_tgtname));
1888 if (cplen >= sizeof(mgi->mgi_marker.cm_tgtname))
1890 cplen = strlcpy(mgi->mgi_marker.cm_comment, comment,
1891 sizeof(mgi->mgi_marker.cm_comment));
1892 if (cplen >= sizeof(mgi->mgi_marker.cm_comment))
1894 mgi->mgi_marker.cm_createtime = ktime_get_real_seconds();
1895 mgi->mgi_marker.cm_canceltime = 0;
1896 lustre_cfg_bufs_reset(&mgi->mgi_bufs, NULL);
1897 lustre_cfg_bufs_set(&mgi->mgi_bufs, 1, &mgi->mgi_marker,
1898 sizeof(mgi->mgi_marker));
1899 lcr = lustre_cfg_rec_new(LCFG_MARKER, &mgi->mgi_bufs);
1903 rc = llog_write(env, llh, &lcr->lcr_hdr, LLOG_NEXT_IDX);
1904 lustre_cfg_rec_free(lcr);
1908 static int record_start_log(const struct lu_env *env, struct mgs_device *mgs,
1909 struct llog_handle **llh, char *name)
1911 static struct obd_uuid cfg_uuid = { .uuid = "config_uuid" };
1912 struct llog_ctxt *ctxt;
1917 GOTO(out, rc = -EBUSY);
1919 ctxt = llog_get_context(mgs->mgs_obd, LLOG_CONFIG_ORIG_CTXT);
1921 GOTO(out, rc = -ENODEV);
1922 LASSERT(ctxt->loc_obd == mgs->mgs_obd);
1924 rc = llog_open_create(env, ctxt, llh, NULL, name);
1927 rc = llog_init_handle(env, *llh, LLOG_F_IS_PLAIN, &cfg_uuid);
1929 llog_close(env, *llh);
1931 llog_ctxt_put(ctxt);
1934 CERROR("%s: can't start log %s: rc = %d\n",
1935 mgs->mgs_obd->obd_name, name, rc);
1941 static int record_end_log(const struct lu_env *env, struct llog_handle **llh)
1945 rc = llog_close(env, *llh);
1951 /******************** config "macros" *********************/
1953 /* write an lcfg directly into a log (with markers) */
1954 static int mgs_write_log_direct(const struct lu_env *env,
1955 struct mgs_device *mgs, struct fs_db *fsdb,
1956 char *logname, struct llog_cfg_rec *lcr,
1957 char *devname, char *comment)
1959 struct llog_handle *llh = NULL;
1964 rc = record_start_log(env, mgs, &llh, logname);
1968 /* FIXME These should be a single journal transaction */
1969 rc = record_marker(env, llh, fsdb, CM_START, devname, comment);
1972 rc = llog_write(env, llh, &lcr->lcr_hdr, LLOG_NEXT_IDX);
1975 rc = record_marker(env, llh, fsdb, CM_END, devname, comment);
1979 record_end_log(env, &llh);
1983 /* write the lcfg in all logs for the given fs */
1984 static int mgs_write_log_direct_all(const struct lu_env *env,
1985 struct mgs_device *mgs,
1987 struct mgs_target_info *mti,
1988 struct llog_cfg_rec *lcr, char *devname,
1989 char *comment, int server_only)
1991 struct list_head log_list;
1992 struct mgs_direntry *dirent, *n;
1993 char *fsname = mti->mti_fsname;
1994 int rc = 0, len = strlen(fsname);
1997 /* Find all the logs in the CONFIGS directory */
1998 rc = class_dentry_readdir(env, mgs, &log_list);
2002 /* Could use fsdb index maps instead of directory listing */
2003 list_for_each_entry_safe(dirent, n, &log_list, mde_list) {
2004 list_del_init(&dirent->mde_list);
2005 /* don't write to sptlrpc rule log */
2006 if (strstr(dirent->mde_name, "-sptlrpc") != NULL)
2009 /* caller wants write server logs only */
2010 if (server_only && strstr(dirent->mde_name, "-client") != NULL)
2013 if (strlen(dirent->mde_name) <= len ||
2014 strncmp(fsname, dirent->mde_name, len) != 0 ||
2015 dirent->mde_name[len] != '-')
2018 CDEBUG(D_MGS, "Changing log %s\n", dirent->mde_name);
2019 /* Erase any old settings of this same parameter */
2020 rc = mgs_modify(env, mgs, fsdb, mti, dirent->mde_name,
2021 devname, comment, CM_SKIP);
2023 CERROR("%s: Can't modify llog %s: rc = %d\n",
2024 mgs->mgs_obd->obd_name, dirent->mde_name, rc);
2027 /* Write the new one */
2028 rc = mgs_write_log_direct(env, mgs, fsdb, dirent->mde_name,
2029 lcr, devname, comment);
2031 CERROR("%s: writing log %s: rc = %d\n",
2032 mgs->mgs_obd->obd_name, dirent->mde_name, rc);
2034 mgs_direntry_free(dirent);
2040 static int mgs_write_log_osp_to_mdt(const struct lu_env *env,
2041 struct mgs_device *mgs,
2043 struct mgs_target_info *mti,
2044 int index, char *logname);
2045 static int mgs_write_log_osc_to_lov(const struct lu_env *env,
2046 struct mgs_device *mgs,
2048 struct mgs_target_info *mti,
2049 char *logname, char *suffix, char *lovname,
2050 enum lustre_sec_part sec_part, int flags);
2051 static int name_create_mdt_and_lov(char **logname, char **lovname,
2052 struct fs_db *fsdb, int i);
2054 static int add_param(char *params, char *key, char *val)
2056 char *start = params + strlen(params);
2057 char *end = params + sizeof(((struct mgs_target_info *)0)->mti_params);
2061 keylen = strlen(key);
2062 if (start + 1 + keylen + strlen(val) >= end) {
2063 CERROR("params are too long: %s %s%s\n",
2064 params, key != NULL ? key : "", val);
2068 sprintf(start, " %s%s", key != NULL ? key : "", val);
2073 * Walk through client config log record and convert the related records
2076 static int mgs_steal_client_llog_handler(const struct lu_env *env,
2077 struct llog_handle *llh,
2078 struct llog_rec_hdr *rec, void *data)
2080 struct mgs_device *mgs;
2081 struct obd_device *obd;
2082 struct mgs_target_info *mti, *tmti;
2084 int cfg_len = rec->lrh_len;
2085 char *cfg_buf = (char*) (rec + 1);
2086 struct lustre_cfg *lcfg;
2088 struct llog_handle *mdt_llh = NULL;
2089 static int got_an_osc_or_mdc = 0;
2090 /* 0: not found any osc/mdc;
2094 static int last_step = -1;
2099 mti = ((struct temp_comp*)data)->comp_mti;
2100 tmti = ((struct temp_comp*)data)->comp_tmti;
2101 fsdb = ((struct temp_comp*)data)->comp_fsdb;
2102 obd = ((struct temp_comp *)data)->comp_obd;
2103 mgs = lu2mgs_dev(obd->obd_lu_dev);
2106 if (rec->lrh_type != OBD_CFG_REC) {
2107 CERROR("unhandled lrh_type: %#x\n", rec->lrh_type);
2111 rc = lustre_cfg_sanity_check(cfg_buf, cfg_len);
2113 CERROR("Insane cfg\n");
2117 lcfg = (struct lustre_cfg *)cfg_buf;
2119 if (lcfg->lcfg_command == LCFG_MARKER) {
2120 struct cfg_marker *marker;
2121 marker = lustre_cfg_buf(lcfg, 1);
2122 if (!strncmp(marker->cm_comment, "add osc", 7) &&
2123 (marker->cm_flags & CM_START) &&
2124 !(marker->cm_flags & CM_SKIP)) {
2125 got_an_osc_or_mdc = 1;
2126 cplen = strlcpy(tmti->mti_svname, marker->cm_tgtname,
2127 sizeof(tmti->mti_svname));
2128 if (cplen >= sizeof(tmti->mti_svname))
2130 rc = record_start_log(env, mgs, &mdt_llh,
2134 rc = record_marker(env, mdt_llh, fsdb, CM_START,
2135 mti->mti_svname, "add osc(copied)");
2136 record_end_log(env, &mdt_llh);
2137 last_step = marker->cm_step;
2140 if (!strncmp(marker->cm_comment, "add osc", 7) &&
2141 (marker->cm_flags & CM_END) &&
2142 !(marker->cm_flags & CM_SKIP)) {
2143 LASSERT(last_step == marker->cm_step);
2145 got_an_osc_or_mdc = 0;
2146 memset(tmti, 0, sizeof(*tmti));
2147 rc = record_start_log(env, mgs, &mdt_llh,
2151 rc = record_marker(env, mdt_llh, fsdb, CM_END,
2152 mti->mti_svname, "add osc(copied)");
2153 record_end_log(env, &mdt_llh);
2156 if (!strncmp(marker->cm_comment, "add mdc", 7) &&
2157 (marker->cm_flags & CM_START) &&
2158 !(marker->cm_flags & CM_SKIP)) {
2159 got_an_osc_or_mdc = 2;
2160 last_step = marker->cm_step;
2161 memcpy(tmti->mti_svname, marker->cm_tgtname,
2162 strlen(marker->cm_tgtname));
2166 if (!strncmp(marker->cm_comment, "add mdc", 7) &&
2167 (marker->cm_flags & CM_END) &&
2168 !(marker->cm_flags & CM_SKIP)) {
2169 LASSERT(last_step == marker->cm_step);
2171 got_an_osc_or_mdc = 0;
2172 memset(tmti, 0, sizeof(*tmti));
2177 if (got_an_osc_or_mdc == 0 || last_step < 0)
2180 if (lcfg->lcfg_command == LCFG_ADD_UUID) {
2181 __u64 nodenid = lcfg->lcfg_nid;
2183 if (strlen(tmti->mti_uuid) == 0) {
2184 /* target uuid not set, this config record is before
2185 * LCFG_SETUP, this nid is one of target node nid.
2187 tmti->mti_nids[tmti->mti_nid_count] = nodenid;
2188 tmti->mti_nid_count++;
2190 char nidstr[LNET_NIDSTR_SIZE];
2192 /* failover node nid */
2193 libcfs_nid2str_r(nodenid, nidstr, sizeof(nidstr));
2194 rc = add_param(tmti->mti_params, PARAM_FAILNODE,
2201 if (lcfg->lcfg_command == LCFG_SETUP) {
2204 target = lustre_cfg_string(lcfg, 1);
2205 memcpy(tmti->mti_uuid, target, strlen(target));
2209 /* ignore client side sptlrpc_conf_log */
2210 if (lcfg->lcfg_command == LCFG_SPTLRPC_CONF)
2213 if (lcfg->lcfg_command == LCFG_ADD_MDC &&
2214 strstr(lustre_cfg_string(lcfg, 0), "-clilmv") != NULL) {
2217 if (sscanf(lustre_cfg_buf(lcfg, 2), "%d", &index) != 1)
2220 memcpy(tmti->mti_fsname, mti->mti_fsname,
2221 strlen(mti->mti_fsname));
2222 tmti->mti_stripe_index = index;
2224 rc = mgs_write_log_osp_to_mdt(env, mgs, fsdb, tmti,
2225 mti->mti_stripe_index,
2227 memset(tmti, 0, sizeof(*tmti));
2231 if (lcfg->lcfg_command == LCFG_LOV_ADD_OBD) {
2234 char *logname, *lovname;
2236 rc = name_create_mdt_and_lov(&logname, &lovname, fsdb,
2237 mti->mti_stripe_index);
2240 sprintf(mdt_index, "-MDT%04x", mti->mti_stripe_index);
2242 if (sscanf(lustre_cfg_buf(lcfg, 2), "%d", &index) != 1) {
2243 name_destroy(&logname);
2244 name_destroy(&lovname);
2248 tmti->mti_stripe_index = index;
2249 rc = mgs_write_log_osc_to_lov(env, mgs, fsdb, tmti, logname,
2252 name_destroy(&logname);
2253 name_destroy(&lovname);
2259 /* fsdb->fsdb_mutex is already held in mgs_write_log_target*/
2260 /* stealed from mgs_get_fsdb_from_llog*/
2261 static int mgs_steal_llog_for_mdt_from_client(const struct lu_env *env,
2262 struct mgs_device *mgs,
2264 struct temp_comp* comp)
2266 struct llog_handle *loghandle;
2267 struct mgs_target_info *tmti;
2268 struct llog_ctxt *ctxt;
2273 ctxt = llog_get_context(mgs->mgs_obd, LLOG_CONFIG_ORIG_CTXT);
2274 LASSERT(ctxt != NULL);
2276 OBD_ALLOC_PTR(tmti);
2278 GOTO(out_ctxt, rc = -ENOMEM);
2280 comp->comp_tmti = tmti;
2281 comp->comp_obd = mgs->mgs_obd;
2283 rc = llog_open(env, ctxt, &loghandle, NULL, client_name,
2291 rc = llog_init_handle(env, loghandle, LLOG_F_IS_PLAIN, NULL);
2293 GOTO(out_close, rc);
2295 rc = llog_process_or_fork(env, loghandle, mgs_steal_client_llog_handler,
2296 (void *)comp, NULL, false);
2297 CDEBUG(D_MGS, "steal llog re = %d\n", rc);
2299 llog_close(env, loghandle);
2303 llog_ctxt_put(ctxt);
2307 /* lmv is the second thing for client logs */
2308 /* copied from mgs_write_log_lov. Please refer to that. */
2309 static int mgs_write_log_lmv(const struct lu_env *env,
2310 struct mgs_device *mgs,
2312 struct mgs_target_info *mti,
2313 char *logname, char *lmvname)
2315 struct llog_handle *llh = NULL;
2316 struct lmv_desc *lmvdesc;
2321 CDEBUG(D_MGS, "Writing lmv(%s) log for %s\n", lmvname,logname);
2323 OBD_ALLOC_PTR(lmvdesc);
2324 if (lmvdesc == NULL)
2326 lmvdesc->ld_active_tgt_count = 0;
2327 lmvdesc->ld_tgt_count = 0;
2328 sprintf((char*)lmvdesc->ld_uuid.uuid, "%s_UUID", lmvname);
2329 uuid = (char *)lmvdesc->ld_uuid.uuid;
2331 rc = record_start_log(env, mgs, &llh, logname);
2334 rc = record_marker(env, llh, fsdb, CM_START, lmvname, "lmv setup");
2337 rc = record_attach(env, llh, lmvname, "lmv", uuid);
2340 rc = record_lmv_setup(env, llh, lmvname, lmvdesc);
2343 rc = record_marker(env, llh, fsdb, CM_END, lmvname, "lmv setup");
2347 record_end_log(env, &llh);
2349 OBD_FREE_PTR(lmvdesc);
2353 /* lov is the first thing in the mdt and client logs */
2354 static int mgs_write_log_lov(const struct lu_env *env, struct mgs_device *mgs,
2355 struct fs_db *fsdb, struct mgs_target_info *mti,
2356 char *logname, char *lovname)
2358 struct llog_handle *llh = NULL;
2359 struct lov_desc *lovdesc;
2364 CDEBUG(D_MGS, "Writing lov(%s) log for %s\n", lovname, logname);
2367 #01 L attach 0:lov_mdsA 1:lov 2:71ccb_lov_mdsA_19f961a9e1
2368 #02 L lov_setup 0:lov_mdsA 1:(struct lov_desc)
2369 uuid=lov1_UUID, stripe count=1, size=1048576, offset=0, pattern=0
2372 /* FIXME just make lov_setup accept empty desc (put uuid in buf 2) */
2373 OBD_ALLOC_PTR(lovdesc);
2374 if (lovdesc == NULL)
2376 lovdesc->ld_magic = LOV_DESC_MAGIC;
2377 lovdesc->ld_tgt_count = 0;
2378 /* Defaults. Can be changed later by lcfg config_param */
2379 lovdesc->ld_default_stripe_count = 1;
2380 lovdesc->ld_pattern = LOV_PATTERN_RAID0;
2381 lovdesc->ld_default_stripe_size = LOV_DESC_STRIPE_SIZE_DEFAULT;
2382 lovdesc->ld_default_stripe_offset = -1;
2383 lovdesc->ld_qos_maxage = LOV_DESC_QOS_MAXAGE_DEFAULT;
2384 sprintf((char*)lovdesc->ld_uuid.uuid, "%s_UUID", lovname);
2385 /* can these be the same? */
2386 uuid = (char *)lovdesc->ld_uuid.uuid;
2388 /* This should always be the first entry in a log.
2389 rc = mgs_clear_log(obd, logname); */
2390 rc = record_start_log(env, mgs, &llh, logname);
2393 /* FIXME these should be a single journal transaction */
2394 rc = record_marker(env, llh, fsdb, CM_START, lovname, "lov setup");
2397 rc = record_attach(env, llh, lovname, "lov", uuid);
2400 rc = record_lov_setup(env, llh, lovname, lovdesc);
2403 rc = record_marker(env, llh, fsdb, CM_END, lovname, "lov setup");
2408 record_end_log(env, &llh);
2410 OBD_FREE_PTR(lovdesc);
2414 /* add failnids to open log */
2415 static int mgs_write_log_failnids(const struct lu_env *env,
2416 struct mgs_target_info *mti,
2417 struct llog_handle *llh,
2420 char *failnodeuuid = NULL;
2421 char *ptr = mti->mti_params;
2426 #03 L add_uuid nid=uml1@tcp(0x20000c0a80201) nal=90 0: 1:uml1_UUID
2427 #04 L add_uuid nid=1@elan(0x1000000000001) nal=90 0: 1:uml1_UUID
2428 #05 L setup 0:OSC_uml1_ost1_mdsA 1:ost1_UUID 2:uml1_UUID
2429 #06 L add_uuid nid=uml2@tcp(0x20000c0a80202) nal=90 0: 1:uml2_UUID
2430 #0x L add_uuid nid=2@elan(0x1000000000002) nal=90 0: 1:uml2_UUID
2431 #07 L add_conn 0:OSC_uml1_ost1_mdsA 1:uml2_UUID
2435 * Pull failnid info out of params string, which may contain something
2436 * like "<nid1>,<nid2>:<nid3>,<nid4>". class_parse_nid() does not
2437 * complain about abnormal inputs like ",:<nid1>", "<nid1>:,<nid2>",
2438 * etc. However, convert_hostnames() should have caught those.
2440 while (class_find_param(ptr, PARAM_FAILNODE, &ptr) == 0) {
2441 while (class_parse_nid(ptr, &nid, &ptr) == 0) {
2442 char nidstr[LNET_NIDSTR_SIZE];
2444 if (failnodeuuid == NULL) {
2445 /* We don't know the failover node name,
2446 * so just use the first nid as the uuid */
2447 libcfs_nid2str_r(nid, nidstr, sizeof(nidstr));
2448 rc = name_create(&failnodeuuid, nidstr, "");
2452 CDEBUG(D_MGS, "add nid %s for failover uuid %s, "
2454 libcfs_nid2str_r(nid, nidstr, sizeof(nidstr)),
2455 failnodeuuid, cliname);
2456 rc = record_add_uuid(env, llh, nid, failnodeuuid);
2458 * If *ptr is ':', we have added all NIDs for
2462 rc = record_add_conn(env, llh, cliname,
2464 name_destroy(&failnodeuuid);
2465 failnodeuuid = NULL;
2469 rc = record_add_conn(env, llh, cliname, failnodeuuid);
2470 name_destroy(&failnodeuuid);
2471 failnodeuuid = NULL;
2478 static int mgs_write_log_mdc_to_lmv(const struct lu_env *env,
2479 struct mgs_device *mgs,
2481 struct mgs_target_info *mti,
2482 char *logname, char *lmvname)
2484 struct llog_handle *llh = NULL;
2485 char *mdcname = NULL;
2486 char *nodeuuid = NULL;
2487 char *mdcuuid = NULL;
2488 char *lmvuuid = NULL;
2490 char nidstr[LNET_NIDSTR_SIZE];
2494 if (mgs_log_is_empty(env, mgs, logname)) {
2495 CERROR("log is empty! Logical error\n");
2499 CDEBUG(D_MGS, "adding mdc for %s to log %s:lmv(%s)\n",
2500 mti->mti_svname, logname, lmvname);
2502 libcfs_nid2str_r(mti->mti_nids[0], nidstr, sizeof(nidstr));
2503 rc = name_create(&nodeuuid, nidstr, "");
2506 rc = name_create(&mdcname, mti->mti_svname, "-mdc");
2509 rc = name_create(&mdcuuid, mdcname, "_UUID");
2512 rc = name_create(&lmvuuid, lmvname, "_UUID");
2516 rc = record_start_log(env, mgs, &llh, logname);
2519 rc = record_marker(env, llh, fsdb, CM_START, mti->mti_svname,
2523 for (i = 0; i < mti->mti_nid_count; i++) {
2524 CDEBUG(D_MGS, "add nid %s for mdt\n",
2525 libcfs_nid2str_r(mti->mti_nids[i],
2526 nidstr, sizeof(nidstr)));
2528 rc = record_add_uuid(env, llh, mti->mti_nids[i], nodeuuid);
2533 rc = record_attach(env, llh, mdcname, LUSTRE_MDC_NAME, lmvuuid);
2536 rc = record_setup(env, llh, mdcname, mti->mti_uuid, nodeuuid,
2540 rc = mgs_write_log_failnids(env, mti, llh, mdcname);
2543 snprintf(index, sizeof(index), "%d", mti->mti_stripe_index);
2544 rc = record_mdc_add(env, llh, lmvname, mdcuuid, mti->mti_uuid,
2548 rc = record_marker(env, llh, fsdb, CM_END, mti->mti_svname,
2553 record_end_log(env, &llh);
2555 name_destroy(&lmvuuid);
2556 name_destroy(&mdcuuid);
2557 name_destroy(&mdcname);
2558 name_destroy(&nodeuuid);
2562 static inline int name_create_lov(char **lovname, char *mdtname,
2563 struct fs_db *fsdb, int index)
2566 if (index == 0 && test_bit(FSDB_OSCNAME18, &fsdb->fsdb_flags))
2567 return name_create(lovname, fsdb->fsdb_name, "-mdtlov");
2569 return name_create(lovname, mdtname, "-mdtlov");
2572 static int name_create_mdt_and_lov(char **logname, char **lovname,
2573 struct fs_db *fsdb, int i)
2577 rc = name_create_mdt(logname, fsdb->fsdb_name, i);
2581 if (i == 0 && test_bit(FSDB_OSCNAME18, &fsdb->fsdb_flags))
2582 rc = name_create(lovname, fsdb->fsdb_name, "-mdtlov");
2584 rc = name_create(lovname, *logname, "-mdtlov");
2586 name_destroy(logname);
2592 static inline int name_create_mdt_osc(char **oscname, char *ostname,
2593 struct fs_db *fsdb, int i)
2597 if (i == 0 && test_bit(FSDB_OSCNAME18, &fsdb->fsdb_flags))
2598 sprintf(suffix, "-osc");
2600 sprintf(suffix, "-osc-MDT%04x", i);
2601 return name_create(oscname, ostname, suffix);
2604 /* add new mdc to already existent MDS */
2605 static int mgs_write_log_osp_to_mdt(const struct lu_env *env,
2606 struct mgs_device *mgs,
2608 struct mgs_target_info *mti,
2609 int mdt_index, char *logname)
2611 struct llog_handle *llh = NULL;
2612 char *nodeuuid = NULL;
2613 char *ospname = NULL;
2614 char *lovuuid = NULL;
2615 char *mdtuuid = NULL;
2616 char *svname = NULL;
2617 char *mdtname = NULL;
2618 char *lovname = NULL;
2620 char nidstr[LNET_NIDSTR_SIZE];
2624 if (mgs_log_is_empty(env, mgs, mti->mti_svname)) {
2625 CERROR("log is empty! Logical error\n");
2629 CDEBUG(D_MGS, "adding osp index %d to %s\n", mti->mti_stripe_index,
2632 rc = name_create_mdt(&mdtname, fsdb->fsdb_name, mti->mti_stripe_index);
2636 libcfs_nid2str_r(mti->mti_nids[0], nidstr, sizeof(nidstr));
2637 rc = name_create(&nodeuuid, nidstr, "");
2639 GOTO(out_destory, rc);
2641 rc = name_create(&svname, mdtname, "-osp");
2643 GOTO(out_destory, rc);
2645 sprintf(index_str, "-MDT%04x", mdt_index);
2646 rc = name_create(&ospname, svname, index_str);
2648 GOTO(out_destory, rc);
2650 rc = name_create_lov(&lovname, logname, fsdb, mdt_index);
2652 GOTO(out_destory, rc);
2654 rc = name_create(&lovuuid, lovname, "_UUID");
2656 GOTO(out_destory, rc);
2658 rc = name_create(&mdtuuid, mdtname, "_UUID");
2660 GOTO(out_destory, rc);
2662 rc = record_start_log(env, mgs, &llh, logname);
2664 GOTO(out_destory, rc);
2666 rc = record_marker(env, llh, fsdb, CM_START, mti->mti_svname,
2669 GOTO(out_destory, rc);
2671 for (i = 0; i < mti->mti_nid_count; i++) {
2672 CDEBUG(D_MGS, "add nid %s for mdt\n",
2673 libcfs_nid2str_r(mti->mti_nids[i],
2674 nidstr, sizeof(nidstr)));
2675 rc = record_add_uuid(env, llh, mti->mti_nids[i], nodeuuid);
2680 rc = record_attach(env, llh, ospname, LUSTRE_OSP_NAME, lovuuid);
2684 rc = record_setup(env, llh, ospname, mti->mti_uuid, nodeuuid,
2689 rc = mgs_write_log_failnids(env, mti, llh, ospname);
2693 /* Add mdc(osp) to lod */
2694 snprintf(index_str, sizeof(index_str), "%d", mti->mti_stripe_index);
2695 rc = record_base(env, llh, lovname, 0, LCFG_ADD_MDC, mti->mti_uuid,
2696 index_str, "1", NULL);
2700 rc = record_marker(env, llh, fsdb, CM_END, mti->mti_svname, "add osp");
2705 record_end_log(env, &llh);
2708 name_destroy(&mdtuuid);
2709 name_destroy(&lovuuid);
2710 name_destroy(&lovname);
2711 name_destroy(&ospname);
2712 name_destroy(&svname);
2713 name_destroy(&nodeuuid);
2714 name_destroy(&mdtname);
2718 static int mgs_write_log_mdt0(const struct lu_env *env,
2719 struct mgs_device *mgs,
2721 struct mgs_target_info *mti)
2723 char *log = mti->mti_svname;
2724 struct llog_handle *llh = NULL;
2725 char *uuid, *lovname;
2727 char *ptr = mti->mti_params;
2728 int rc = 0, failout = 0;
2731 OBD_ALLOC(uuid, sizeof(struct obd_uuid));
2735 if (class_find_param(ptr, PARAM_FAILMODE, &ptr) == 0)
2736 failout = (strncmp(ptr, "failout", 7) == 0);
2738 rc = name_create(&lovname, log, "-mdtlov");
2741 if (mgs_log_is_empty(env, mgs, log)) {
2742 rc = mgs_write_log_lov(env, mgs, fsdb, mti, log, lovname);
2747 sprintf(mdt_index, "%d", mti->mti_stripe_index);
2749 rc = record_start_log(env, mgs, &llh, log);
2753 /* add MDT itself */
2755 /* FIXME this whole fn should be a single journal transaction */
2756 sprintf(uuid, "%s_UUID", log);
2757 rc = record_marker(env, llh, fsdb, CM_START, log, "add mdt");
2760 rc = record_attach(env, llh, log, LUSTRE_MDT_NAME, uuid);
2763 rc = record_mount_opt(env, llh, log, lovname, NULL);
2766 rc = record_setup(env, llh, log, uuid, mdt_index, lovname,
2767 failout ? "n" : "f");
2770 rc = record_marker(env, llh, fsdb, CM_END, log, "add mdt");
2774 record_end_log(env, &llh);
2776 name_destroy(&lovname);
2778 OBD_FREE(uuid, sizeof(struct obd_uuid));
2782 /* envelope method for all layers log */
2783 static int mgs_write_log_mdt(const struct lu_env *env,
2784 struct mgs_device *mgs,
2786 struct mgs_target_info *mti)
2788 struct mgs_thread_info *mgi = mgs_env_info(env);
2789 struct llog_handle *llh = NULL;
2794 CDEBUG(D_MGS, "writing new mdt %s\n", mti->mti_svname);
2796 if (mti->mti_uuid[0] == '\0') {
2797 /* Make up our own uuid */
2798 snprintf(mti->mti_uuid, sizeof(mti->mti_uuid),
2799 "%s_UUID", mti->mti_svname);
2803 rc = mgs_write_log_mdt0(env, mgs, fsdb, mti);
2806 /* Append the mdt info to the client log */
2807 rc = name_create(&cliname, mti->mti_fsname, "-client");
2811 if (mgs_log_is_empty(env, mgs, cliname)) {
2812 /* Start client log */
2813 rc = mgs_write_log_lov(env, mgs, fsdb, mti, cliname,
2817 rc = mgs_write_log_lmv(env, mgs, fsdb, mti, cliname,
2824 #09 L add_uuid nid=uml1@tcp(0x20000c0a80201) 0: 1:uml1_UUID
2825 #10 L attach 0:MDC_uml1_mdsA_MNT_client 1:mdc 2:1d834_MNT_client_03f
2826 #11 L setup 0:MDC_uml1_mdsA_MNT_client 1:mdsA_UUID 2:uml1_UUID
2827 #12 L add_uuid nid=uml2@tcp(0x20000c0a80202) 0: 1:uml2_UUID
2828 #13 L add_conn 0:MDC_uml1_mdsA_MNT_client 1:uml2_UUID
2829 #14 L mount_option 0: 1:client 2:lov1 3:MDC_uml1_mdsA_MNT_client
2832 /* copy client info about lov/lmv */
2833 mgi->mgi_comp.comp_mti = mti;
2834 mgi->mgi_comp.comp_fsdb = fsdb;
2836 rc = mgs_steal_llog_for_mdt_from_client(env, mgs, cliname,
2840 rc = mgs_write_log_mdc_to_lmv(env, mgs, fsdb, mti, cliname,
2846 rc = record_start_log(env, mgs, &llh, cliname);
2850 rc = record_marker(env, llh, fsdb, CM_START, cliname, "mount opts");
2853 rc = record_mount_opt(env, llh, cliname, fsdb->fsdb_clilov,
2857 rc = record_marker(env, llh, fsdb, CM_END, cliname, "mount opts");
2861 /* for_all_existing_mdt except current one */
2862 for (i = 0; i < INDEX_MAP_SIZE * 8; i++) {
2863 if (i != mti->mti_stripe_index &&
2864 test_bit(i, fsdb->fsdb_mdt_index_map)) {
2867 rc = name_create_mdt(&logname, fsdb->fsdb_name, i);
2871 /* NB: If the log for the MDT is empty, it means
2872 * the MDT is only added to the index
2873 * map, and not being process yet, i.e. this
2874 * is an unregistered MDT, see mgs_write_log_target().
2875 * so we should skip it. Otherwise
2877 * 1. MGS get register request for MDT1 and MDT2.
2879 * 2. Then both MDT1 and MDT2 are added into
2880 * fsdb_mdt_index_map. (see mgs_set_index()).
2882 * 3. Then MDT1 get the lock of fsdb_mutex, then
2883 * generate the config log, here, it will regard MDT2
2884 * as an existent MDT, and generate "add osp" for
2885 * lustre-MDT0001-osp-MDT0002. Note: at the moment
2886 * MDT0002 config log is still empty, so it will
2887 * add "add osp" even before "lov setup", which
2888 * will definitly cause trouble.
2890 * 4. MDT1 registeration finished, fsdb_mutex is
2891 * released, then MDT2 get in, then in above
2892 * mgs_steal_llog_for_mdt_from_client(), it will
2893 * add another osp log for lustre-MDT0001-osp-MDT0002,
2894 * which will cause another trouble.*/
2895 if (!mgs_log_is_empty(env, mgs, logname))
2896 rc = mgs_write_log_osp_to_mdt(env, mgs, fsdb,
2899 name_destroy(&logname);
2905 record_end_log(env, &llh);
2907 name_destroy(&cliname);
2911 /* Add the ost info to the client/mdt lov */
2912 static int mgs_write_log_osc_to_lov(const struct lu_env *env,
2913 struct mgs_device *mgs, struct fs_db *fsdb,
2914 struct mgs_target_info *mti,
2915 char *logname, char *suffix, char *lovname,
2916 enum lustre_sec_part sec_part, int flags)
2918 struct llog_handle *llh = NULL;
2919 char *nodeuuid = NULL;
2920 char *oscname = NULL;
2921 char *oscuuid = NULL;
2922 char *lovuuid = NULL;
2923 char *svname = NULL;
2925 char nidstr[LNET_NIDSTR_SIZE];
2929 CDEBUG(D_INFO, "adding osc for %s to log %s\n",
2930 mti->mti_svname, logname);
2932 if (mgs_log_is_empty(env, mgs, logname)) {
2933 CERROR("log is empty! Logical error\n");
2937 libcfs_nid2str_r(mti->mti_nids[0], nidstr, sizeof(nidstr));
2938 rc = name_create(&nodeuuid, nidstr, "");
2941 rc = name_create(&svname, mti->mti_svname, "-osc");
2945 /* for the system upgraded from old 1.8, keep using the old osc naming
2946 * style for mdt, see name_create_mdt_osc(). LU-1257 */
2947 if (test_bit(FSDB_OSCNAME18, &fsdb->fsdb_flags))
2948 rc = name_create(&oscname, svname, "");
2950 rc = name_create(&oscname, svname, suffix);
2954 rc = name_create(&oscuuid, oscname, "_UUID");
2957 rc = name_create(&lovuuid, lovname, "_UUID");
2963 #03 L add_uuid nid=uml1@tcp(0x20000c0a80201) 0: 1:uml1_UUID
2965 #04 L add_uuid nid=1@elan(0x1000000000001) nal=90 0: 1:uml1_UUID
2966 #04 L attach 0:OSC_uml1_ost1_MNT_client 1:osc 2:89070_lov1_a41dff51a
2967 #05 L setup 0:OSC_uml1_ost1_MNT_client 1:ost1_UUID 2:uml1_UUID
2969 #06 L add_uuid nid=uml2@tcp(0x20000c0a80202) 0: 1:uml2_UUID
2970 #07 L add_conn 0:OSC_uml1_ost1_MNT_client 1:uml2_UUID
2971 #08 L lov_modify_tgts add 0:lov1 1:ost1_UUID 2(index):0 3(gen):1
2974 rc = record_start_log(env, mgs, &llh, logname);
2978 /* FIXME these should be a single journal transaction */
2979 rc = record_marker(env, llh, fsdb, CM_START | flags, mti->mti_svname,
2984 /* NB: don't change record order, because upon MDT steal OSC config
2985 * from client, it treats all nids before LCFG_SETUP as target nids
2986 * (multiple interfaces), while nids after as failover node nids.
2987 * See mgs_steal_client_llog_handler() LCFG_ADD_UUID.
2989 for (i = 0; i < mti->mti_nid_count; i++) {
2990 CDEBUG(D_MGS, "add nid %s\n",
2991 libcfs_nid2str_r(mti->mti_nids[i],
2992 nidstr, sizeof(nidstr)));
2993 rc = record_add_uuid(env, llh, mti->mti_nids[i], nodeuuid);
2997 rc = record_attach(env, llh, oscname, LUSTRE_OSC_NAME, lovuuid);
3000 rc = record_setup(env, llh, oscname, mti->mti_uuid, nodeuuid,
3004 rc = mgs_write_log_failnids(env, mti, llh, oscname);
3008 snprintf(index, sizeof(index), "%d", mti->mti_stripe_index);
3010 rc = record_lov_add(env, llh, lovname, mti->mti_uuid, index, "1");
3013 rc = record_marker(env, llh, fsdb, CM_END | flags, mti->mti_svname,
3018 record_end_log(env, &llh);
3020 name_destroy(&lovuuid);
3021 name_destroy(&oscuuid);
3022 name_destroy(&oscname);
3023 name_destroy(&svname);
3024 name_destroy(&nodeuuid);
3028 static int mgs_write_log_ost(const struct lu_env *env,
3029 struct mgs_device *mgs, struct fs_db *fsdb,
3030 struct mgs_target_info *mti)
3032 struct llog_handle *llh = NULL;
3033 char *logname, *lovname;
3034 char *ptr = mti->mti_params;
3035 int rc, flags = 0, failout = 0, i;
3038 CDEBUG(D_MGS, "writing new ost %s\n", mti->mti_svname);
3040 /* The ost startup log */
3042 /* If the ost log already exists, that means that someone reformatted
3043 the ost and it called target_add again. */
3044 if (!mgs_log_is_empty(env, mgs, mti->mti_svname)) {
3045 LCONSOLE_ERROR_MSG(0x141, "The config log for %s already "
3046 "exists, yet the server claims it never "
3047 "registered. It may have been reformatted, "
3048 "or the index changed. writeconf the MDT to "
3049 "regenerate all logs.\n", mti->mti_svname);
3054 attach obdfilter ost1 ost1_UUID
3055 setup /dev/loop2 ldiskfs f|n errors=remount-ro,user_xattr
3057 if (class_find_param(ptr, PARAM_FAILMODE, &ptr) == 0)
3058 failout = (strncmp(ptr, "failout", 7) == 0);
3059 rc = record_start_log(env, mgs, &llh, mti->mti_svname);
3062 /* FIXME these should be a single journal transaction */
3063 rc = record_marker(env, llh, fsdb, CM_START, mti->mti_svname,"add ost");
3066 if (*mti->mti_uuid == '\0')
3067 snprintf(mti->mti_uuid, sizeof(mti->mti_uuid),
3068 "%s_UUID", mti->mti_svname);
3069 rc = record_attach(env, llh, mti->mti_svname,
3070 "obdfilter"/*LUSTRE_OST_NAME*/, mti->mti_uuid);
3073 rc = record_setup(env, llh, mti->mti_svname,
3074 "dev"/*ignored*/, "type"/*ignored*/,
3075 failout ? "n" : "f", NULL/*options*/);
3078 rc = record_marker(env, llh, fsdb, CM_END, mti->mti_svname, "add ost");
3082 record_end_log(env, &llh);
3085 /* We also have to update the other logs where this osc is part of
3088 if (test_bit(FSDB_OLDLOG14, &fsdb->fsdb_flags)) {
3089 /* If we're upgrading, the old mdt log already has our
3090 entry. Let's do a fake one for fun. */
3091 /* Note that we can't add any new failnids, since we don't
3092 know the old osc names. */
3093 flags = CM_SKIP | CM_UPGRADE146;
3095 } else if ((mti->mti_flags & LDD_F_UPDATE) != LDD_F_UPDATE) {
3096 /* If the update flag isn't set, don't update client/mdt
3099 LCONSOLE_WARN("Client log for %s was not updated; writeconf "
3100 "the MDT first to regenerate it.\n",
3104 /* Add ost to all MDT lov defs */
3105 for (i = 0; i < INDEX_MAP_SIZE * 8; i++){
3106 if (test_bit(i, fsdb->fsdb_mdt_index_map)) {
3109 rc = name_create_mdt_and_lov(&logname, &lovname, fsdb,
3114 snprintf(mdt_index, sizeof(mdt_index), "-MDT%04x", i);
3115 rc = mgs_write_log_osc_to_lov(env, mgs, fsdb, mti,
3117 lovname, LUSTRE_SP_MDT,
3119 name_destroy(&logname);
3120 name_destroy(&lovname);
3126 /* Append ost info to the client log */
3127 rc = name_create(&logname, mti->mti_fsname, "-client");
3130 if (mgs_log_is_empty(env, mgs, logname)) {
3131 /* Start client log */
3132 rc = mgs_write_log_lov(env, mgs, fsdb, mti, logname,
3136 rc = mgs_write_log_lmv(env, mgs, fsdb, mti, logname,
3141 rc = mgs_write_log_osc_to_lov(env, mgs, fsdb, mti, logname, "",
3142 fsdb->fsdb_clilov, LUSTRE_SP_CLI, flags);
3144 name_destroy(&logname);
3148 static __inline__ int mgs_param_empty(char *ptr)
3152 if ((tmp = strchr(ptr, '=')) && (*(++tmp) == '\0'))
3157 static int mgs_write_log_failnid_internal(const struct lu_env *env,
3158 struct mgs_device *mgs,
3160 struct mgs_target_info *mti,
3161 char *logname, char *cliname)
3164 struct llog_handle *llh = NULL;
3166 if (mgs_param_empty(mti->mti_params)) {
3167 /* Remove _all_ failnids */
3168 rc = mgs_modify(env, mgs, fsdb, mti, logname,
3169 mti->mti_svname, "add failnid", CM_SKIP);
3170 return rc < 0 ? rc : 0;
3173 /* Otherwise failover nids are additive */
3174 rc = record_start_log(env, mgs, &llh, logname);
3177 /* FIXME this should be a single journal transaction */
3178 rc = record_marker(env, llh, fsdb, CM_START, mti->mti_svname,
3182 rc = mgs_write_log_failnids(env, mti, llh, cliname);
3185 rc = record_marker(env, llh, fsdb, CM_END,
3186 mti->mti_svname, "add failnid");
3188 record_end_log(env, &llh);
3193 /* Add additional failnids to an existing log.
3194 The mdc/osc must have been added to logs first */
3195 /* tcp nids must be in dotted-quad ascii -
3196 we can't resolve hostnames from the kernel. */
3197 static int mgs_write_log_add_failnid(const struct lu_env *env,
3198 struct mgs_device *mgs,
3200 struct mgs_target_info *mti)
3202 char *logname, *cliname;
3206 /* FIXME we currently can't erase the failnids
3207 * given when a target first registers, since they aren't part of
3208 * an "add uuid" stanza
3211 /* Verify that we know about this target */
3212 if (mgs_log_is_empty(env, mgs, mti->mti_svname)) {
3213 LCONSOLE_ERROR_MSG(0x142, "The target %s has not registered "
3214 "yet. It must be started before failnids "
3215 "can be added.\n", mti->mti_svname);
3219 /* Create mdc/osc client name (e.g. lustre-OST0001-osc) */
3220 if (mti->mti_flags & LDD_F_SV_TYPE_MDT) {
3221 rc = name_create(&cliname, mti->mti_svname, "-mdc");
3222 } else if (mti->mti_flags & LDD_F_SV_TYPE_OST) {
3223 rc = name_create(&cliname, mti->mti_svname, "-osc");
3230 /* Add failover nids to the client log */
3231 rc = name_create(&logname, mti->mti_fsname, "-client");
3233 name_destroy(&cliname);
3237 rc = mgs_write_log_failnid_internal(env, mgs, fsdb,mti,logname,cliname);
3238 name_destroy(&logname);
3239 name_destroy(&cliname);
3243 if (mti->mti_flags & LDD_F_SV_TYPE_OST) {
3244 /* Add OST failover nids to the MDT logs as well */
3247 for (i = 0; i < INDEX_MAP_SIZE * 8; i++) {
3248 if (!test_bit(i, fsdb->fsdb_mdt_index_map))
3250 rc = name_create_mdt(&logname, mti->mti_fsname, i);
3253 rc = name_create_mdt_osc(&cliname, mti->mti_svname,
3256 name_destroy(&logname);
3259 rc = mgs_write_log_failnid_internal(env, mgs, fsdb,
3262 name_destroy(&cliname);
3263 name_destroy(&logname);
3272 static int mgs_wlp_lcfg(const struct lu_env *env,
3273 struct mgs_device *mgs, struct fs_db *fsdb,
3274 struct mgs_target_info *mti,
3275 char *logname, struct lustre_cfg_bufs *bufs,
3276 char *tgtname, char *ptr)
3278 char comment[MTI_NAME_MAXLEN];
3280 struct llog_cfg_rec *lcr;
3283 /* Erase any old settings of this same parameter */
3284 memcpy(comment, ptr, MTI_NAME_MAXLEN);
3285 comment[MTI_NAME_MAXLEN - 1] = 0;
3286 /* But don't try to match the value. */
3287 tmp = strchr(comment, '=');
3290 /* FIXME we should skip settings that are the same as old values */
3291 rc = mgs_modify(env, mgs, fsdb, mti, logname, tgtname, comment,CM_SKIP);
3294 del = mgs_param_empty(ptr);
3296 LCONSOLE_INFO("%s parameter %s.%s in log %s\n", del ? "Disabling" : rc ?
3297 "Setting" : "Modifying", tgtname, comment, logname);
3299 /* mgs_modify() will return 1 if nothing had to be done */
3305 lustre_cfg_bufs_reset(bufs, tgtname);
3306 lustre_cfg_bufs_set_string(bufs, 1, ptr);
3307 if (mti->mti_flags & LDD_F_PARAM2)
3308 lustre_cfg_bufs_set_string(bufs, 2, LCTL_UPCALL);
3310 lcr = lustre_cfg_rec_new((mti->mti_flags & LDD_F_PARAM2) ?
3311 LCFG_SET_PARAM : LCFG_PARAM, bufs);
3315 rc = mgs_write_log_direct(env, mgs, fsdb, logname, lcr, tgtname,
3317 lustre_cfg_rec_free(lcr);
3321 /* write global variable settings into log */
3322 static int mgs_write_log_sys(const struct lu_env *env,
3323 struct mgs_device *mgs, struct fs_db *fsdb,
3324 struct mgs_target_info *mti, char *sys, char *ptr)
3326 struct mgs_thread_info *mgi = mgs_env_info(env);
3327 struct lustre_cfg *lcfg;
3328 struct llog_cfg_rec *lcr;
3330 int rc, cmd, convert = 1;
3332 if (class_match_param(ptr, PARAM_TIMEOUT, &tmp) == 0) {
3333 cmd = LCFG_SET_TIMEOUT;
3334 } else if (class_match_param(ptr, PARAM_LDLM_TIMEOUT, &tmp) == 0) {
3335 cmd = LCFG_SET_LDLM_TIMEOUT;
3336 /* Check for known params here so we can return error to lctl */
3337 } else if ((class_match_param(ptr, PARAM_AT_MIN, &tmp) == 0) ||
3338 (class_match_param(ptr, PARAM_AT_MAX, &tmp) == 0) ||
3339 (class_match_param(ptr, PARAM_AT_EXTRA, &tmp) == 0) ||
3340 (class_match_param(ptr, PARAM_AT_EARLY_MARGIN, &tmp) == 0) ||
3341 (class_match_param(ptr, PARAM_AT_HISTORY, &tmp) == 0)) {
3343 } else if (class_match_param(ptr, PARAM_JOBID_VAR, &tmp) == 0) {
3344 convert = 0; /* Don't convert string value to integer */
3350 if (mgs_param_empty(ptr))
3351 CDEBUG(D_MGS, "global '%s' removed\n", sys);
3353 CDEBUG(D_MGS, "global '%s' val=%s\n", sys, tmp);
3355 lustre_cfg_bufs_reset(&mgi->mgi_bufs, NULL);
3356 lustre_cfg_bufs_set_string(&mgi->mgi_bufs, 1, sys);
3357 if (!convert && *tmp != '\0')
3358 lustre_cfg_bufs_set_string(&mgi->mgi_bufs, 2, tmp);
3359 lcr = lustre_cfg_rec_new(cmd, &mgi->mgi_bufs);
3363 lcfg = &lcr->lcr_cfg;
3365 rc = kstrtouint(tmp, 0, &lcfg->lcfg_num);
3367 GOTO(out_rec_free, rc);
3372 /* truncate the comment to the parameter name */
3376 /* modify all servers and clients */
3377 rc = mgs_write_log_direct_all(env, mgs, fsdb, mti,
3378 *tmp == '\0' ? NULL : lcr,
3379 mti->mti_fsname, sys, 0);
3380 if (rc == 0 && *tmp != '\0') {
3382 case LCFG_SET_TIMEOUT:
3383 if (!obd_timeout_set || lcfg->lcfg_num > obd_timeout)
3384 class_process_config(lcfg);
3386 case LCFG_SET_LDLM_TIMEOUT:
3387 if (!ldlm_timeout_set || lcfg->lcfg_num > ldlm_timeout)
3388 class_process_config(lcfg);
3396 lustre_cfg_rec_free(lcr);
3400 /* write quota settings into log */
3401 static int mgs_write_log_quota(const struct lu_env *env, struct mgs_device *mgs,
3402 struct fs_db *fsdb, struct mgs_target_info *mti,
3403 char *quota, char *ptr)
3405 struct mgs_thread_info *mgi = mgs_env_info(env);
3406 struct llog_cfg_rec *lcr;
3409 int rc, cmd = LCFG_PARAM;
3411 /* support only 'meta' and 'data' pools so far */
3412 if (class_match_param(ptr, QUOTA_METAPOOL_NAME, &tmp) != 0 &&
3413 class_match_param(ptr, QUOTA_DATAPOOL_NAME, &tmp) != 0) {
3414 CERROR("parameter quota.%s isn't supported (only quota.mdt "
3415 "& quota.ost are)\n", ptr);
3420 CDEBUG(D_MGS, "global '%s' removed\n", quota);
3422 CDEBUG(D_MGS, "global '%s'\n", quota);
3424 if (strchr(tmp, 'u') == NULL && strchr(tmp, 'g') == NULL &&
3425 strchr(tmp, 'p') == NULL &&
3426 strcmp(tmp, "none") != 0) {
3427 CERROR("enable option(%s) isn't supported\n", tmp);
3432 lustre_cfg_bufs_reset(&mgi->mgi_bufs, mti->mti_fsname);
3433 lustre_cfg_bufs_set_string(&mgi->mgi_bufs, 1, quota);
3434 lcr = lustre_cfg_rec_new(cmd, &mgi->mgi_bufs);
3438 /* truncate the comment to the parameter name */
3443 /* XXX we duplicated quota enable information in all server
3444 * config logs, it should be moved to a separate config
3445 * log once we cleanup the config log for global param. */
3446 /* modify all servers */
3447 rc = mgs_write_log_direct_all(env, mgs, fsdb, mti,
3448 *tmp == '\0' ? NULL : lcr,
3449 mti->mti_fsname, quota, 1);
3451 lustre_cfg_rec_free(lcr);
3452 return rc < 0 ? rc : 0;
3455 static int mgs_srpc_set_param_disk(const struct lu_env *env,
3456 struct mgs_device *mgs,
3458 struct mgs_target_info *mti,
3461 struct mgs_thread_info *mgi = mgs_env_info(env);
3462 struct llog_cfg_rec *lcr;
3463 struct llog_handle *llh = NULL;
3465 char *comment, *ptr;
3471 ptr = strchr(param, '=');
3472 LASSERT(ptr != NULL);
3475 OBD_ALLOC(comment, len + 1);
3476 if (comment == NULL)
3478 strncpy(comment, param, len);
3479 comment[len] = '\0';
3482 lustre_cfg_bufs_reset(&mgi->mgi_bufs, mti->mti_svname);
3483 lustre_cfg_bufs_set_string(&mgi->mgi_bufs, 1, param);
3484 lcr = lustre_cfg_rec_new(LCFG_SPTLRPC_CONF, &mgi->mgi_bufs);
3486 GOTO(out_comment, rc = -ENOMEM);
3488 /* construct log name */
3489 rc = name_create(&logname, mti->mti_fsname, "-sptlrpc");
3493 if (mgs_log_is_empty(env, mgs, logname)) {
3494 rc = record_start_log(env, mgs, &llh, logname);
3497 record_end_log(env, &llh);
3500 /* obsolete old one */
3501 rc = mgs_modify(env, mgs, fsdb, mti, logname, mti->mti_svname,
3505 /* write the new one */
3506 rc = mgs_write_log_direct(env, mgs, fsdb, logname, lcr,
3507 mti->mti_svname, comment);
3509 CERROR("%s: error writing log %s: rc = %d\n",
3510 mgs->mgs_obd->obd_name, logname, rc);
3512 name_destroy(&logname);
3514 lustre_cfg_rec_free(lcr);
3516 OBD_FREE(comment, len + 1);
3520 static int mgs_srpc_set_param_udesc_mem(struct fs_db *fsdb,
3525 /* disable the adjustable udesc parameter for now, i.e. use default
3526 * setting that client always ship udesc to MDT if possible. to enable
3527 * it simply remove the following line */
3530 ptr = strchr(param, '=');
3535 if (strcmp(param, PARAM_SRPC_UDESC))
3538 if (strcmp(ptr, "yes") == 0) {
3539 set_bit(FSDB_UDESC, &fsdb->fsdb_flags);
3540 CWARN("Enable user descriptor shipping from client to MDT\n");
3541 } else if (strcmp(ptr, "no") == 0) {
3542 clear_bit(FSDB_UDESC, &fsdb->fsdb_flags);
3543 CWARN("Disable user descriptor shipping from client to MDT\n");
3551 CERROR("Invalid param: %s\n", param);
3555 static int mgs_srpc_set_param_mem(struct fs_db *fsdb,
3559 struct sptlrpc_rule rule;
3560 struct sptlrpc_rule_set *rset;
3564 if (strncmp(param, PARAM_SRPC, sizeof(PARAM_SRPC) - 1) != 0) {
3565 CERROR("Invalid sptlrpc parameter: %s\n", param);
3569 if (strncmp(param, PARAM_SRPC_UDESC,
3570 sizeof(PARAM_SRPC_UDESC) - 1) == 0) {
3571 RETURN(mgs_srpc_set_param_udesc_mem(fsdb, param));
3574 if (strncmp(param, PARAM_SRPC_FLVR, sizeof(PARAM_SRPC_FLVR) - 1) != 0) {
3575 CERROR("Invalid sptlrpc flavor parameter: %s\n", param);
3579 param += sizeof(PARAM_SRPC_FLVR) - 1;
3581 rc = sptlrpc_parse_rule(param, &rule);
3585 /* mgs rules implies must be mgc->mgs */
3586 if (test_bit(FSDB_MGS_SELF, &fsdb->fsdb_flags)) {
3587 if ((rule.sr_from != LUSTRE_SP_MGC &&
3588 rule.sr_from != LUSTRE_SP_ANY) ||
3589 (rule.sr_to != LUSTRE_SP_MGS &&
3590 rule.sr_to != LUSTRE_SP_ANY))
3594 /* preapre room for this coming rule. svcname format should be:
3595 * - fsname: general rule
3596 * - fsname-tgtname: target-specific rule
3598 if (strchr(svname, '-')) {
3599 struct mgs_tgt_srpc_conf *tgtconf;
3602 for (tgtconf = fsdb->fsdb_srpc_tgt; tgtconf != NULL;
3603 tgtconf = tgtconf->mtsc_next) {
3604 if (!strcmp(tgtconf->mtsc_tgt, svname)) {
3613 OBD_ALLOC_PTR(tgtconf);
3614 if (tgtconf == NULL)
3617 name_len = strlen(svname);
3619 OBD_ALLOC(tgtconf->mtsc_tgt, name_len + 1);
3620 if (tgtconf->mtsc_tgt == NULL) {
3621 OBD_FREE_PTR(tgtconf);
3624 memcpy(tgtconf->mtsc_tgt, svname, name_len);
3626 tgtconf->mtsc_next = fsdb->fsdb_srpc_tgt;
3627 fsdb->fsdb_srpc_tgt = tgtconf;
3630 rset = &tgtconf->mtsc_rset;
3631 } else if (strcmp(svname, MGSSELF_NAME) == 0) {
3632 /* put _mgs related srpc rule directly in mgs ruleset */
3633 rset = &fsdb->fsdb_mgs->mgs_lut.lut_sptlrpc_rset;
3635 rset = &fsdb->fsdb_srpc_gen;
3638 rc = sptlrpc_rule_set_merge(rset, &rule);
3643 static int mgs_srpc_set_param(const struct lu_env *env,
3644 struct mgs_device *mgs,
3646 struct mgs_target_info *mti,
3656 /* keep a copy of original param, which could be destroied
3658 copy_size = strlen(param) + 1;
3659 OBD_ALLOC(copy, copy_size);
3662 memcpy(copy, param, copy_size);
3664 rc = mgs_srpc_set_param_mem(fsdb, mti->mti_svname, param);
3668 /* previous steps guaranteed the syntax is correct */
3669 rc = mgs_srpc_set_param_disk(env, mgs, fsdb, mti, copy);
3673 if (test_bit(FSDB_MGS_SELF, &fsdb->fsdb_flags)) {
3675 * for mgs rules, make them effective immediately.
3677 LASSERT(fsdb->fsdb_srpc_tgt == NULL);
3678 sptlrpc_target_update_exp_flavor(mgs->mgs_obd,
3679 &fsdb->fsdb_srpc_gen);
3683 OBD_FREE(copy, copy_size);
3687 struct mgs_srpc_read_data {
3688 struct fs_db *msrd_fsdb;
3692 static int mgs_srpc_read_handler(const struct lu_env *env,
3693 struct llog_handle *llh,
3694 struct llog_rec_hdr *rec, void *data)
3696 struct mgs_srpc_read_data *msrd = data;
3697 struct cfg_marker *marker;
3698 struct lustre_cfg *lcfg = REC_DATA(rec);
3699 char *svname, *param;
3703 if (rec->lrh_type != OBD_CFG_REC) {
3704 CERROR("unhandled lrh_type: %#x\n", rec->lrh_type);
3708 cfg_len = REC_DATA_LEN(rec);
3710 rc = lustre_cfg_sanity_check(lcfg, cfg_len);
3712 CERROR("Insane cfg\n");
3716 if (lcfg->lcfg_command == LCFG_MARKER) {
3717 marker = lustre_cfg_buf(lcfg, 1);
3719 if (marker->cm_flags & CM_START &&
3720 marker->cm_flags & CM_SKIP)
3721 msrd->msrd_skip = 1;
3722 if (marker->cm_flags & CM_END)
3723 msrd->msrd_skip = 0;
3728 if (msrd->msrd_skip)
3731 if (lcfg->lcfg_command != LCFG_SPTLRPC_CONF) {
3732 CERROR("invalid command (%x)\n", lcfg->lcfg_command);
3736 svname = lustre_cfg_string(lcfg, 0);
3737 if (svname == NULL) {
3738 CERROR("svname is empty\n");
3742 param = lustre_cfg_string(lcfg, 1);
3743 if (param == NULL) {
3744 CERROR("param is empty\n");
3748 rc = mgs_srpc_set_param_mem(msrd->msrd_fsdb, svname, param);
3750 CERROR("read sptlrpc record error (%d): %s\n", rc, param);
3755 int mgs_get_fsdb_srpc_from_llog(const struct lu_env *env,
3756 struct mgs_device *mgs,
3759 struct llog_handle *llh = NULL;
3760 struct llog_ctxt *ctxt;
3762 struct mgs_srpc_read_data msrd;
3766 /* construct log name */
3767 rc = name_create(&logname, fsdb->fsdb_name, "-sptlrpc");
3771 ctxt = llog_get_context(mgs->mgs_obd, LLOG_CONFIG_ORIG_CTXT);
3772 LASSERT(ctxt != NULL);
3774 if (mgs_log_is_empty(env, mgs, logname))
3777 rc = llog_open(env, ctxt, &llh, NULL, logname,
3785 rc = llog_init_handle(env, llh, LLOG_F_IS_PLAIN, NULL);
3787 GOTO(out_close, rc);
3789 if (llog_get_size(llh) <= 1)
3790 GOTO(out_close, rc = 0);
3792 msrd.msrd_fsdb = fsdb;
3795 rc = llog_process(env, llh, mgs_srpc_read_handler, (void *)&msrd,
3799 llog_close(env, llh);
3801 llog_ctxt_put(ctxt);
3802 name_destroy(&logname);
3805 CERROR("failed to read sptlrpc config database: %d\n", rc);
3809 static int mgs_write_log_param2(const struct lu_env *env,
3810 struct mgs_device *mgs,
3812 struct mgs_target_info *mti, char *ptr)
3814 struct lustre_cfg_bufs bufs;
3818 CDEBUG(D_MGS, "next param '%s'\n", ptr);
3820 /* PARAM_MGSNODE and PARAM_NETWORK are set only when formating
3821 * or during the inital mount. It can never change after that.
3823 if (!class_match_param(ptr, PARAM_MGSNODE, NULL) ||
3824 !class_match_param(ptr, PARAM_NETWORK, NULL)) {
3829 /* Processed in mgs_write_log_ost. Another value that can't
3830 * be changed by lctl set_param -P.
3832 if (!class_match_param(ptr, PARAM_FAILMODE, NULL)) {
3833 LCONSOLE_ERROR_MSG(0x169,
3834 "%s can only be changed with tunefs.lustre and --writeconf\n",
3840 /* FIXME !!! Support for sptlrpc is incomplete. Currently the change
3841 * doesn't transmit to the client. See LU-7183.
3843 if (!class_match_param(ptr, PARAM_SRPC, NULL)) {
3844 rc = mgs_srpc_set_param(env, mgs, fsdb, mti, ptr);
3848 /* Can't use class_match_param since ptr doesn't start with
3849 * PARAM_FAILNODE. So we look for PARAM_FAILNODE contained in ptr.
3851 if (strstr(ptr, PARAM_FAILNODE)) {
3852 /* Add a failover nidlist. We already processed failovers
3853 * params for new targets in mgs_write_log_target.
3857 /* can't use wildcards with failover.node */
3858 if (strchr(ptr, '*')) {
3863 param = strstr(ptr, PARAM_FAILNODE);
3864 if (strlcpy(mti->mti_params, param, sizeof(mti->mti_params)) >=
3865 sizeof(mti->mti_params)) {
3870 CDEBUG(D_MGS, "Adding failnode with param %s\n",
3872 rc = mgs_write_log_add_failnid(env, mgs, fsdb, mti);
3876 rc = mgs_wlp_lcfg(env, mgs, fsdb, mti, PARAMS_FILENAME, &bufs,
3877 mti->mti_svname, ptr);
3882 /* Permanent settings of all parameters by writing into the appropriate
3883 * configuration logs.
3884 * A parameter with null value ("<param>='\0'") means to erase it out of
3887 static int mgs_write_log_param(const struct lu_env *env,
3888 struct mgs_device *mgs, struct fs_db *fsdb,
3889 struct mgs_target_info *mti, char *ptr)
3891 struct mgs_thread_info *mgi = mgs_env_info(env);
3897 /* For various parameter settings, we have to figure out which logs
3898 care about them (e.g. both mdt and client for lov settings) */
3899 CDEBUG(D_MGS, "next param '%s'\n", ptr);
3901 /* The params are stored in MOUNT_DATA_FILE and modified via
3902 tunefs.lustre, or set using lctl conf_param */
3904 /* Processed in lustre_start_mgc */
3905 if (class_match_param(ptr, PARAM_MGSNODE, NULL) == 0)
3908 /* Processed in ost/mdt */
3909 if (class_match_param(ptr, PARAM_NETWORK, NULL) == 0)
3912 /* Processed in mgs_write_log_ost */
3913 if (class_match_param(ptr, PARAM_FAILMODE, NULL) == 0) {
3914 if (mti->mti_flags & LDD_F_PARAM) {
3915 LCONSOLE_ERROR_MSG(0x169, "%s can only be "
3916 "changed with tunefs.lustre"
3917 "and --writeconf\n", ptr);
3923 if (class_match_param(ptr, PARAM_SRPC, NULL) == 0) {
3924 rc = mgs_srpc_set_param(env, mgs, fsdb, mti, ptr);
3928 if (class_match_param(ptr, PARAM_FAILNODE, NULL) == 0) {
3929 /* Add a failover nidlist */
3931 /* We already processed failovers params for new
3932 targets in mgs_write_log_target */
3933 if (mti->mti_flags & LDD_F_PARAM) {
3934 CDEBUG(D_MGS, "Adding failnode\n");
3935 rc = mgs_write_log_add_failnid(env, mgs, fsdb, mti);
3940 if (class_match_param(ptr, PARAM_SYS, &tmp) == 0) {
3941 rc = mgs_write_log_sys(env, mgs, fsdb, mti, ptr, tmp);
3945 if (class_match_param(ptr, PARAM_QUOTA, &tmp) == 0) {
3946 rc = mgs_write_log_quota(env, mgs, fsdb, mti, ptr, tmp);
3950 if (class_match_param(ptr, PARAM_OSC PARAM_ACTIVE, &tmp) == 0 ||
3951 class_match_param(ptr, PARAM_MDC PARAM_ACTIVE, &tmp) == 0) {
3952 /* active=0 means off, anything else means on */
3953 int flag = (*tmp == '0') ? CM_EXCLUDE : 0;
3954 bool deactive_osc = memcmp(ptr, PARAM_OSC PARAM_ACTIVE,
3955 strlen(PARAM_OSC PARAM_ACTIVE)) == 0;
3958 if (!deactive_osc) {
3961 rc = server_name2index(mti->mti_svname, &index, NULL);
3966 LCONSOLE_ERROR_MSG(0x144, "%s: MDC0 can not be"
3967 " (de)activated.\n",
3969 GOTO(end, rc = -EPERM);
3973 LCONSOLE_WARN("Permanently %sactivating %s\n",
3974 flag ? "de" : "re", mti->mti_svname);
3976 rc = name_create(&logname, mti->mti_fsname, "-client");
3979 rc = mgs_modify(env, mgs, fsdb, mti, logname,
3981 deactive_osc ? "add osc" : "add mdc", flag);
3982 name_destroy(&logname);
3987 /* Add to all MDT logs for DNE */
3988 for (i = 0; i < INDEX_MAP_SIZE * 8; i++) {
3989 if (!test_bit(i, fsdb->fsdb_mdt_index_map))
3991 rc = name_create_mdt(&logname, mti->mti_fsname, i);
3994 rc = mgs_modify(env, mgs, fsdb, mti, logname,
3996 deactive_osc ? "add osc" : "add osp",
3998 name_destroy(&logname);
4004 LCONSOLE_ERROR_MSG(0x145, "Couldn't find %s in"
4005 "log (%d). No permanent "
4006 "changes were made to the "
4008 mti->mti_svname, rc);
4009 if (test_bit(FSDB_OLDLOG14, &fsdb->fsdb_flags))
4010 LCONSOLE_ERROR_MSG(0x146, "This may be"
4015 "update the logs.\n");
4018 /* Fall through to osc/mdc proc for deactivating live
4019 OSC/OSP on running MDT / clients. */
4021 /* Below here, let obd's XXX_process_config methods handle it */
4023 /* All lov. in proc */
4024 if (class_match_param(ptr, PARAM_LOV, NULL) == 0) {
4027 CDEBUG(D_MGS, "lov param %s\n", ptr);
4028 if (!(mti->mti_flags & LDD_F_SV_TYPE_MDT)) {
4029 LCONSOLE_ERROR_MSG(0x147, "LOV params must be "
4030 "set on the MDT, not %s. "
4037 if (mgs_log_is_empty(env, mgs, mti->mti_svname))
4038 GOTO(end, rc = -ENODEV);
4040 rc = name_create_mdt_and_lov(&logname, &mdtlovname, fsdb,
4041 mti->mti_stripe_index);
4044 rc = mgs_wlp_lcfg(env, mgs, fsdb, mti, mti->mti_svname,
4045 &mgi->mgi_bufs, mdtlovname, ptr);
4046 name_destroy(&logname);
4047 name_destroy(&mdtlovname);
4052 rc = name_create(&logname, mti->mti_fsname, "-client");
4055 rc = mgs_wlp_lcfg(env, mgs, fsdb, mti, logname, &mgi->mgi_bufs,
4056 fsdb->fsdb_clilov, ptr);
4057 name_destroy(&logname);
4061 /* All osc., mdc., llite. params in proc */
4062 if ((class_match_param(ptr, PARAM_OSC, NULL) == 0) ||
4063 (class_match_param(ptr, PARAM_MDC, NULL) == 0) ||
4064 (class_match_param(ptr, PARAM_LLITE, NULL) == 0)) {
4067 if (test_bit(FSDB_OLDLOG14, &fsdb->fsdb_flags)) {
4068 LCONSOLE_ERROR_MSG(0x148, "Upgraded client logs for %s"
4069 " cannot be modified. Consider"
4070 " updating the configuration with"
4073 GOTO(end, rc = -EINVAL);
4075 if (memcmp(ptr, PARAM_LLITE, strlen(PARAM_LLITE)) == 0) {
4076 rc = name_create(&cname, mti->mti_fsname, "-client");
4077 /* Add the client type to match the obdname in
4078 class_config_llog_handler */
4079 } else if (mti->mti_flags & LDD_F_SV_TYPE_MDT) {
4080 rc = name_create(&cname, mti->mti_svname, "-mdc");
4081 } else if (mti->mti_flags & LDD_F_SV_TYPE_OST) {
4082 rc = name_create(&cname, mti->mti_svname, "-osc");
4084 GOTO(end, rc = -EINVAL);
4089 /* Forbid direct update of llite root squash parameters.
4090 * These parameters are indirectly set via the MDT settings.
4092 if ((class_match_param(ptr, PARAM_LLITE, &tmp) == 0) &&
4093 ((memcmp(tmp, "root_squash=", 12) == 0) ||
4094 (memcmp(tmp, "nosquash_nids=", 14) == 0))) {
4095 LCONSOLE_ERROR("%s: root squash parameters can only "
4096 "be updated through MDT component\n",
4098 name_destroy(&cname);
4099 GOTO(end, rc = -EINVAL);
4102 CDEBUG(D_MGS, "%.3s param %s\n", ptr, ptr + 4);
4105 rc = name_create(&logname, mti->mti_fsname, "-client");
4107 name_destroy(&cname);
4110 rc = mgs_wlp_lcfg(env, mgs, fsdb, mti, logname, &mgi->mgi_bufs,
4113 /* osc params affect the MDT as well */
4114 if (!rc && (mti->mti_flags & LDD_F_SV_TYPE_OST)) {
4117 for (i = 0; i < INDEX_MAP_SIZE * 8; i++){
4118 if (!test_bit(i, fsdb->fsdb_mdt_index_map))
4120 name_destroy(&cname);
4121 rc = name_create_mdt_osc(&cname, mti->mti_svname,
4123 name_destroy(&logname);
4126 rc = name_create_mdt(&logname,
4127 mti->mti_fsname, i);
4130 if (!mgs_log_is_empty(env, mgs, logname)) {
4131 rc = mgs_wlp_lcfg(env, mgs, fsdb,
4141 /* For mdc activate/deactivate, it affects OSP on MDT as well */
4142 if (class_match_param(ptr, PARAM_MDC PARAM_ACTIVE, &tmp) == 0 &&
4145 char *lodname = NULL;
4146 char *param_str = NULL;
4150 /* replace mdc with osp */
4151 memcpy(ptr, PARAM_OSP, strlen(PARAM_OSP));
4152 rc = server_name2index(mti->mti_svname, &index, NULL);
4154 memcpy(ptr, PARAM_MDC, strlen(PARAM_MDC));
4158 for (i = 0; i < INDEX_MAP_SIZE * 8; i++) {
4159 if (!test_bit(i, fsdb->fsdb_mdt_index_map))
4165 name_destroy(&logname);
4166 rc = name_create_mdt(&logname, mti->mti_fsname,
4171 if (mgs_log_is_empty(env, mgs, logname))
4174 snprintf(suffix, sizeof(suffix), "-osp-MDT%04x",
4176 name_destroy(&cname);
4177 rc = name_create(&cname, mti->mti_svname,
4182 rc = mgs_wlp_lcfg(env, mgs, fsdb, mti, logname,
4183 &mgi->mgi_bufs, cname, ptr);
4187 /* Add configuration log for noitfying LOD
4188 * to active/deactive the OSP. */
4189 name_destroy(¶m_str);
4190 rc = name_create(¶m_str, cname,
4191 (*tmp == '0') ? ".active=0" :
4196 name_destroy(&lodname);
4197 rc = name_create(&lodname, logname, "-mdtlov");
4201 rc = mgs_wlp_lcfg(env, mgs, fsdb, mti, logname,
4202 &mgi->mgi_bufs, lodname,
4207 memcpy(ptr, PARAM_MDC, strlen(PARAM_MDC));
4208 name_destroy(&lodname);
4209 name_destroy(¶m_str);
4212 name_destroy(&logname);
4213 name_destroy(&cname);
4217 /* All mdt. params in proc */
4218 if (class_match_param(ptr, PARAM_MDT, &tmp) == 0) {
4222 CDEBUG(D_MGS, "%.3s param %s\n", ptr, ptr + 4);
4223 if (strncmp(mti->mti_svname, mti->mti_fsname,
4224 MTI_NAME_MAXLEN) == 0)
4225 /* device is unspecified completely? */
4226 rc = LDD_F_SV_TYPE_MDT | LDD_F_SV_ALL;
4228 rc = server_name2index(mti->mti_svname, &idx, NULL);
4231 if ((rc & LDD_F_SV_TYPE_MDT) == 0)
4233 if (rc & LDD_F_SV_ALL) {
4234 for (i = 0; i < INDEX_MAP_SIZE * 8; i++) {
4236 fsdb->fsdb_mdt_index_map))
4238 rc = name_create_mdt(&logname,
4239 mti->mti_fsname, i);
4242 rc = mgs_wlp_lcfg(env, mgs, fsdb, mti,
4243 logname, &mgi->mgi_bufs,
4245 name_destroy(&logname);
4250 if ((memcmp(tmp, "root_squash=", 12) == 0) ||
4251 (memcmp(tmp, "nosquash_nids=", 14) == 0)) {
4252 LCONSOLE_ERROR("%s: root squash parameters "
4253 "cannot be applied to a single MDT\n",
4255 GOTO(end, rc = -EINVAL);
4257 rc = mgs_wlp_lcfg(env, mgs, fsdb, mti,
4258 mti->mti_svname, &mgi->mgi_bufs,
4259 mti->mti_svname, ptr);
4264 /* root squash settings are also applied to llite
4265 * config log (see LU-1778) */
4267 ((memcmp(tmp, "root_squash=", 12) == 0) ||
4268 (memcmp(tmp, "nosquash_nids=", 14) == 0))) {
4272 rc = name_create(&cname, mti->mti_fsname, "-client");
4275 rc = name_create(&logname, mti->mti_fsname, "-client");
4277 name_destroy(&cname);
4280 rc = name_create(&ptr2, PARAM_LLITE, tmp);
4282 name_destroy(&cname);
4283 name_destroy(&logname);
4286 rc = mgs_wlp_lcfg(env, mgs, fsdb, mti, logname,
4287 &mgi->mgi_bufs, cname, ptr2);
4288 name_destroy(&ptr2);
4289 name_destroy(&logname);
4290 name_destroy(&cname);
4295 /* All mdd., ost. and osd. params in proc */
4296 if ((class_match_param(ptr, PARAM_MDD, NULL) == 0) ||
4297 (class_match_param(ptr, PARAM_LOD, NULL) == 0) ||
4298 (class_match_param(ptr, PARAM_OST, NULL) == 0) ||
4299 (class_match_param(ptr, PARAM_OSD, NULL) == 0)) {
4300 CDEBUG(D_MGS, "%.3s param %s\n", ptr, ptr + 4);
4301 if (mgs_log_is_empty(env, mgs, mti->mti_svname))
4302 GOTO(end, rc = -ENODEV);
4304 rc = mgs_wlp_lcfg(env, mgs, fsdb, mti, mti->mti_svname,
4305 &mgi->mgi_bufs, mti->mti_svname, ptr);
4309 LCONSOLE_WARN("Ignoring unrecognized param '%s'\n", ptr);
4313 CERROR("err %d on param '%s'\n", rc, ptr);
4318 int mgs_write_log_target(const struct lu_env *env, struct mgs_device *mgs,
4319 struct mgs_target_info *mti, struct fs_db *fsdb)
4326 /* set/check the new target index */
4327 rc = mgs_set_index(env, mgs, mti);
4331 if (rc == EALREADY) {
4332 LCONSOLE_WARN("Found index %d for %s, updating log\n",
4333 mti->mti_stripe_index, mti->mti_svname);
4334 /* We would like to mark old log sections as invalid
4335 and add new log sections in the client and mdt logs.
4336 But if we add new sections, then live clients will
4337 get repeat setup instructions for already running
4338 osc's. So don't update the client/mdt logs. */
4339 mti->mti_flags &= ~LDD_F_UPDATE;
4343 OBD_FAIL_TIMEOUT(OBD_FAIL_MGS_WRITE_TARGET_DELAY, cfs_fail_val > 0 ?
4346 mutex_lock(&fsdb->fsdb_mutex);
4348 if (mti->mti_flags & (LDD_F_VIRGIN | LDD_F_WRITECONF)) {
4349 /* Generate a log from scratch */
4350 if (mti->mti_flags & LDD_F_SV_TYPE_MDT) {
4351 rc = mgs_write_log_mdt(env, mgs, fsdb, mti);
4352 } else if (mti->mti_flags & LDD_F_SV_TYPE_OST) {
4353 rc = mgs_write_log_ost(env, mgs, fsdb, mti);
4355 CERROR("Unknown target type %#x, can't create log for %s\n",
4356 mti->mti_flags, mti->mti_svname);
4359 CERROR("Can't write logs for %s (%d)\n",
4360 mti->mti_svname, rc);
4364 /* Just update the params from tunefs in mgs_write_log_params */
4365 CDEBUG(D_MGS, "Update params for %s\n", mti->mti_svname);
4366 mti->mti_flags |= LDD_F_PARAM;
4369 /* allocate temporary buffer, where class_get_next_param will
4370 make copy of a current parameter */
4371 OBD_ALLOC(buf, strlen(mti->mti_params) + 1);
4373 GOTO(out_up, rc = -ENOMEM);
4374 params = mti->mti_params;
4375 while (params != NULL) {
4376 rc = class_get_next_param(¶ms, buf);
4379 /* there is no next parameter, that is
4384 CDEBUG(D_MGS, "remaining string: '%s', param: '%s'\n",
4386 rc = mgs_write_log_param(env, mgs, fsdb, mti, buf);
4391 OBD_FREE(buf, strlen(mti->mti_params) + 1);
4394 mutex_unlock(&fsdb->fsdb_mutex);
4398 int mgs_erase_log(const struct lu_env *env, struct mgs_device *mgs, char *name)
4400 struct llog_ctxt *ctxt;
4403 ctxt = llog_get_context(mgs->mgs_obd, LLOG_CONFIG_ORIG_CTXT);
4405 CERROR("%s: MGS config context doesn't exist\n",
4406 mgs->mgs_obd->obd_name);
4409 rc = llog_erase(env, ctxt, NULL, name);
4410 /* llog may not exist */
4413 llog_ctxt_put(ctxt);
4417 CERROR("%s: failed to clear log %s: %d\n",
4418 mgs->mgs_obd->obd_name, name, rc);
4423 /* erase all logs for the given fs */
4424 int mgs_erase_logs(const struct lu_env *env, struct mgs_device *mgs,
4427 struct list_head log_list;
4428 struct mgs_direntry *dirent, *n;
4429 char barrier_name[20] = {};
4432 int rc, len = strlen(fsname);
4435 mutex_lock(&mgs->mgs_mutex);
4437 /* Find all the logs in the CONFIGS directory */
4438 rc = class_dentry_readdir(env, mgs, &log_list);
4440 mutex_unlock(&mgs->mgs_mutex);
4444 if (list_empty(&log_list)) {
4445 mutex_unlock(&mgs->mgs_mutex);
4449 snprintf(barrier_name, sizeof(barrier_name) - 1, "%s-%s",
4450 fsname, BARRIER_FILENAME);
4451 /* Delete the barrier fsdb */
4452 mgs_remove_fsdb_by_name(mgs, barrier_name);
4453 /* Delete the fs db */
4454 mgs_remove_fsdb_by_name(mgs, fsname);
4455 mutex_unlock(&mgs->mgs_mutex);
4457 list_for_each_entry_safe(dirent, n, &log_list, mde_list) {
4458 list_del_init(&dirent->mde_list);
4459 suffix = strrchr(dirent->mde_name, '-');
4460 if (suffix != NULL) {
4461 if ((len == suffix - dirent->mde_name) &&
4462 (strncmp(fsname, dirent->mde_name, len) == 0)) {
4463 CDEBUG(D_MGS, "Removing log %s\n",
4465 mgs_erase_log(env, mgs, dirent->mde_name);
4469 mgs_direntry_free(dirent);
4478 /* list all logs for the given fs */
4479 int mgs_list_logs(const struct lu_env *env, struct mgs_device *mgs,
4480 struct obd_ioctl_data *data)
4482 struct list_head log_list;
4483 struct mgs_direntry *dirent, *n;
4489 /* Find all the logs in the CONFIGS directory */
4490 rc = class_dentry_readdir(env, mgs, &log_list);
4494 out = data->ioc_bulk;
4495 remains = data->ioc_inllen1;
4496 list_for_each_entry_safe(dirent, n, &log_list, mde_list) {
4497 list_del_init(&dirent->mde_list);
4498 suffix = strrchr(dirent->mde_name, '-');
4499 if (suffix != NULL) {
4500 l = snprintf(out, remains, "config_log: %s\n",
4505 mgs_direntry_free(dirent);
4512 struct mgs_lcfg_fork_data {
4513 struct lustre_cfg_bufs mlfd_bufs;
4514 struct mgs_device *mlfd_mgs;
4515 struct llog_handle *mlfd_llh;
4516 const char *mlfd_oldname;
4517 const char *mlfd_newname;
4521 static bool contain_valid_fsname(char *buf, const char *fsname,
4522 int buflen, int namelen)
4524 if (buflen < namelen)
4527 if (memcmp(buf, fsname, namelen) != 0)
4530 if (buf[namelen] != '\0' && buf[namelen] != '-')
4536 static int mgs_lcfg_fork_handler(const struct lu_env *env,
4537 struct llog_handle *o_llh,
4538 struct llog_rec_hdr *o_rec, void *data)
4540 struct mgs_lcfg_fork_data *mlfd = data;
4541 struct lustre_cfg_bufs *n_bufs = &mlfd->mlfd_bufs;
4542 struct lustre_cfg *o_lcfg = (struct lustre_cfg *)(o_rec + 1);
4543 struct llog_cfg_rec *lcr;
4545 char *n_buf = mlfd->mlfd_data;
4547 int o_namelen = strlen(mlfd->mlfd_oldname);
4548 int n_namelen = strlen(mlfd->mlfd_newname);
4549 int diff = n_namelen - o_namelen;
4550 __u32 cmd = o_lcfg->lcfg_command;
4551 __u32 cnt = o_lcfg->lcfg_bufcount;
4557 o_buf = lustre_cfg_buf(o_lcfg, 0);
4558 o_buflen = o_lcfg->lcfg_buflens[0];
4559 if (contain_valid_fsname(o_buf, mlfd->mlfd_oldname, o_buflen,
4561 memcpy(n_buf, mlfd->mlfd_newname, n_namelen);
4562 memcpy(n_buf + n_namelen, o_buf + o_namelen,
4563 o_buflen - o_namelen);
4564 lustre_cfg_bufs_reset(n_bufs, n_buf);
4565 n_buf += cfs_size_round(o_buflen + diff);
4567 lustre_cfg_bufs_reset(n_bufs, o_buflen != 0 ? o_buf : NULL);
4572 struct cfg_marker *o_marker;
4573 struct cfg_marker *n_marker;
4577 CDEBUG(D_MGS, "Unknown cfg marker entry with %d "
4582 /* buf[1] is marker */
4583 o_buf = lustre_cfg_buf(o_lcfg, 1);
4584 o_buflen = o_lcfg->lcfg_buflens[1];
4585 o_marker = (struct cfg_marker *)o_buf;
4586 if (!contain_valid_fsname(o_marker->cm_tgtname,
4588 sizeof(o_marker->cm_tgtname),
4590 lustre_cfg_bufs_set(n_bufs, 1, o_marker,
4595 n_marker = (struct cfg_marker *)n_buf;
4596 *n_marker = *o_marker;
4597 memcpy(n_marker->cm_tgtname, mlfd->mlfd_newname, n_namelen);
4598 tgt_namelen = strlen(o_marker->cm_tgtname);
4599 if (tgt_namelen > o_namelen)
4600 memcpy(n_marker->cm_tgtname + n_namelen,
4601 o_marker->cm_tgtname + o_namelen,
4602 tgt_namelen - o_namelen);
4603 n_marker->cm_tgtname[tgt_namelen + diff] = '\0';
4604 lustre_cfg_bufs_set(n_bufs, 1, n_marker, sizeof(*n_marker));
4608 case LCFG_SET_PARAM: {
4609 for (i = 1; i < cnt; i++)
4610 /* buf[i] is the param value, reuse it directly */
4611 lustre_cfg_bufs_set(n_bufs, i,
4612 lustre_cfg_buf(o_lcfg, i),
4613 o_lcfg->lcfg_buflens[i]);
4619 case LCFG_POOL_DEL: {
4620 if (cnt < 3 || cnt > 4) {
4621 CDEBUG(D_MGS, "Unknown cfg pool (%x) entry with %d "
4622 "buffers\n", cmd, cnt);
4626 /* buf[1] is fsname */
4627 o_buf = lustre_cfg_buf(o_lcfg, 1);
4628 o_buflen = o_lcfg->lcfg_buflens[1];
4629 memcpy(n_buf, mlfd->mlfd_newname, n_namelen);
4630 memcpy(n_buf + n_namelen, o_buf + o_namelen,
4631 o_buflen - o_namelen);
4632 lustre_cfg_bufs_set(n_bufs, 1, n_buf, o_buflen + diff);
4633 n_buf += cfs_size_round(o_buflen + diff);
4635 /* buf[2] is the pool name, reuse it directly */
4636 lustre_cfg_bufs_set(n_bufs, 2, lustre_cfg_buf(o_lcfg, 2),
4637 o_lcfg->lcfg_buflens[2]);
4642 /* buf[3] is ostname */
4643 o_buf = lustre_cfg_buf(o_lcfg, 3);
4644 o_buflen = o_lcfg->lcfg_buflens[3];
4645 memcpy(n_buf, mlfd->mlfd_newname, n_namelen);
4646 memcpy(n_buf + n_namelen, o_buf + o_namelen,
4647 o_buflen - o_namelen);
4648 lustre_cfg_bufs_set(n_bufs, 3, n_buf, o_buflen + diff);
4653 o_buflen = o_lcfg->lcfg_buflens[1];
4654 if (o_buflen == sizeof(struct lov_desc) ||
4655 o_buflen == sizeof(struct lmv_desc)) {
4661 o_buf = lustre_cfg_buf(o_lcfg, 1);
4662 if (o_buflen == sizeof(struct lov_desc)) {
4663 struct lov_desc *o_desc =
4664 (struct lov_desc *)o_buf;
4665 struct lov_desc *n_desc =
4666 (struct lov_desc *)n_buf;
4669 o_uuid = o_desc->ld_uuid.uuid;
4670 n_uuid = n_desc->ld_uuid.uuid;
4671 uuid_len = sizeof(o_desc->ld_uuid.uuid);
4673 struct lmv_desc *o_desc =
4674 (struct lmv_desc *)o_buf;
4675 struct lmv_desc *n_desc =
4676 (struct lmv_desc *)n_buf;
4679 o_uuid = o_desc->ld_uuid.uuid;
4680 n_uuid = n_desc->ld_uuid.uuid;
4681 uuid_len = sizeof(o_desc->ld_uuid.uuid);
4684 if (unlikely(!contain_valid_fsname(o_uuid,
4685 mlfd->mlfd_oldname, uuid_len,
4687 lustre_cfg_bufs_set(n_bufs, 1, o_buf,
4692 memcpy(n_uuid, mlfd->mlfd_newname, n_namelen);
4693 uuid_len = strlen(o_uuid);
4694 if (uuid_len > o_namelen)
4695 memcpy(n_uuid + n_namelen,
4697 uuid_len - o_namelen);
4698 n_uuid[uuid_len + diff] = '\0';
4699 lustre_cfg_bufs_set(n_bufs, 1, n_buf, o_buflen);
4701 } /* else case fall through */
4702 } /* else case fall through */
4705 for (i = 1; i < cnt; i++) {
4706 o_buflen = o_lcfg->lcfg_buflens[i];
4710 o_buf = lustre_cfg_buf(o_lcfg, i);
4711 if (!contain_valid_fsname(o_buf, mlfd->mlfd_oldname,
4712 o_buflen, o_namelen)) {
4713 lustre_cfg_bufs_set(n_bufs, i, o_buf, o_buflen);
4717 memcpy(n_buf, mlfd->mlfd_newname, n_namelen);
4718 if (o_buflen == o_namelen) {
4719 lustre_cfg_bufs_set(n_bufs, i, n_buf,
4721 n_buf += cfs_size_round(n_namelen);
4725 memcpy(n_buf + n_namelen, o_buf + o_namelen,
4726 o_buflen - o_namelen);
4727 lustre_cfg_bufs_set(n_bufs, i, n_buf, o_buflen + diff);
4728 n_buf += cfs_size_round(o_buflen + diff);
4734 lcr = lustre_cfg_rec_new(cmd, n_bufs);
4738 lcr->lcr_cfg = *o_lcfg;
4739 rc = llog_write(env, mlfd->mlfd_llh, &lcr->lcr_hdr, LLOG_NEXT_IDX);
4740 lustre_cfg_rec_free(lcr);
4745 static int mgs_lcfg_fork_one(const struct lu_env *env, struct mgs_device *mgs,
4746 struct mgs_direntry *mde, const char *oldname,
4747 const char *newname)
4749 struct llog_handle *old_llh = NULL;
4750 struct llog_handle *new_llh = NULL;
4751 struct llog_ctxt *ctxt = NULL;
4752 struct mgs_lcfg_fork_data *mlfd = NULL;
4753 char *name_buf = NULL;
4755 int old_namelen = strlen(oldname);
4756 int new_namelen = strlen(newname);
4760 name_buflen = mde->mde_len + new_namelen - old_namelen;
4761 OBD_ALLOC(name_buf, name_buflen);
4765 memcpy(name_buf, newname, new_namelen);
4766 memcpy(name_buf + new_namelen, mde->mde_name + old_namelen,
4767 mde->mde_len - old_namelen);
4769 CDEBUG(D_MGS, "Fork the config-log from %s to %s\n",
4770 mde->mde_name, name_buf);
4772 ctxt = llog_get_context(mgs->mgs_obd, LLOG_CONFIG_ORIG_CTXT);
4775 rc = llog_open_create(env, ctxt, &new_llh, NULL, name_buf);
4779 rc = llog_init_handle(env, new_llh, LLOG_F_IS_PLAIN, NULL);
4783 if (unlikely(mgs_log_is_empty(env, mgs, mde->mde_name)))
4786 rc = llog_open(env, ctxt, &old_llh, NULL, mde->mde_name,
4791 rc = llog_init_handle(env, old_llh, LLOG_F_IS_PLAIN, NULL);
4795 new_llh->lgh_hdr->llh_tgtuuid = old_llh->lgh_hdr->llh_tgtuuid;
4797 OBD_ALLOC(mlfd, LLOG_MIN_CHUNK_SIZE);
4799 GOTO(out, rc = -ENOMEM);
4801 mlfd->mlfd_mgs = mgs;
4802 mlfd->mlfd_llh = new_llh;
4803 mlfd->mlfd_oldname = oldname;
4804 mlfd->mlfd_newname = newname;
4806 rc = llog_process(env, old_llh, mgs_lcfg_fork_handler, mlfd, NULL);
4807 OBD_FREE(mlfd, LLOG_MIN_CHUNK_SIZE);
4813 llog_close(env, old_llh);
4815 llog_close(env, new_llh);
4817 OBD_FREE(name_buf, name_buflen);
4819 llog_ctxt_put(ctxt);
4824 int mgs_lcfg_fork(const struct lu_env *env, struct mgs_device *mgs,
4825 const char *oldname, const char *newname)
4827 struct list_head log_list;
4828 struct mgs_direntry *dirent, *n;
4829 int olen = strlen(oldname);
4830 int nlen = strlen(newname);
4835 if (unlikely(!oldname || oldname[0] == '\0' ||
4836 !newname || newname[0] == '\0'))
4839 if (strcmp(oldname, newname) == 0)
4842 /* lock it to prevent fork/erase/register in parallel. */
4843 mutex_lock(&mgs->mgs_mutex);
4845 rc = class_dentry_readdir(env, mgs, &log_list);
4847 mutex_unlock(&mgs->mgs_mutex);
4851 if (list_empty(&log_list)) {
4852 mutex_unlock(&mgs->mgs_mutex);
4856 list_for_each_entry_safe(dirent, n, &log_list, mde_list) {
4859 ptr = strrchr(dirent->mde_name, '-');
4861 int tlen = ptr - dirent->mde_name;
4864 strncmp(newname, dirent->mde_name, tlen) == 0)
4865 GOTO(out, rc = -EEXIST);
4868 strncmp(oldname, dirent->mde_name, tlen) == 0)
4872 list_del_init(&dirent->mde_list);
4873 mgs_direntry_free(dirent);
4876 if (list_empty(&log_list)) {
4877 mutex_unlock(&mgs->mgs_mutex);
4881 list_for_each_entry(dirent, &log_list, mde_list) {
4882 rc = mgs_lcfg_fork_one(env, mgs, dirent, oldname, newname);
4890 mutex_unlock(&mgs->mgs_mutex);
4892 list_for_each_entry_safe(dirent, n, &log_list, mde_list) {
4893 list_del_init(&dirent->mde_list);
4894 mgs_direntry_free(dirent);
4897 if (rc && count > 0)
4898 mgs_erase_logs(env, mgs, newname);
4903 int mgs_lcfg_erase(const struct lu_env *env, struct mgs_device *mgs,
4909 if (unlikely(!fsname || fsname[0] == '\0'))
4912 rc = mgs_erase_logs(env, mgs, fsname);
4917 static int mgs_xattr_del(const struct lu_env *env, struct dt_object *obj)
4919 struct dt_device *dev;
4920 struct thandle *th = NULL;
4925 dev = container_of0(obj->do_lu.lo_dev, struct dt_device, dd_lu_dev);
4926 th = dt_trans_create(env, dev);
4928 RETURN(PTR_ERR(th));
4930 rc = dt_declare_xattr_del(env, obj, XATTR_TARGET_RENAME, th);
4934 rc = dt_trans_start_local(env, dev, th);
4938 dt_write_lock(env, obj, 0);
4939 rc = dt_xattr_del(env, obj, XATTR_TARGET_RENAME, th);
4944 dt_write_unlock(env, obj);
4947 dt_trans_stop(env, dev, th);
4952 int mgs_lcfg_rename(const struct lu_env *env, struct mgs_device *mgs)
4954 struct list_head log_list;
4955 struct mgs_direntry *dirent, *n;
4957 struct lu_buf buf = {
4959 .lb_len = sizeof(fsname)
4965 rc = class_dentry_readdir(env, mgs, &log_list);
4969 if (list_empty(&log_list))
4972 list_for_each_entry_safe(dirent, n, &log_list, mde_list) {
4973 struct dt_object *o = NULL;
4978 list_del_init(&dirent->mde_list);
4979 ptr = strrchr(dirent->mde_name, '-');
4983 len = ptr - dirent->mde_name;
4984 if (unlikely(len >= sizeof(oldname))) {
4985 CDEBUG(D_MGS, "Skip invalid configuration file %s\n",
4990 o = local_file_find(env, mgs->mgs_los, mgs->mgs_configs_dir,
4994 CDEBUG(D_MGS, "Fail to locate file %s: rc = %d\n",
4995 dirent->mde_name, rc);
4999 rc = dt_xattr_get(env, o, &buf, XATTR_TARGET_RENAME);
5005 "Fail to get EA for %s: rc = %d\n",
5006 dirent->mde_name, rc);
5010 if (unlikely(rc == len &&
5011 memcmp(fsname, dirent->mde_name, len) == 0)) {
5012 /* The new fsname is the same as the old one. */
5013 rc = mgs_xattr_del(env, o);
5017 memcpy(oldname, dirent->mde_name, len);
5018 oldname[len] = '\0';
5020 rc = mgs_lcfg_fork_one(env, mgs, dirent, oldname, fsname);
5021 if (rc && rc != -EEXIST) {
5022 CDEBUG(D_MGS, "Fail to fork %s: rc = %d\n",
5023 dirent->mde_name, rc);
5027 rc = mgs_erase_log(env, mgs, dirent->mde_name);
5029 CDEBUG(D_MGS, "Fail to erase old %s: rc = %d\n",
5030 dirent->mde_name, rc);
5031 /* keep it there if failed to remove it. */
5036 if (o && !IS_ERR(o))
5037 lu_object_put(env, &o->do_lu);
5039 mgs_direntry_free(dirent);
5044 list_for_each_entry_safe(dirent, n, &log_list, mde_list) {
5045 list_del_init(&dirent->mde_list);
5046 mgs_direntry_free(dirent);
5052 /* Setup _mgs fsdb and log
5054 int mgs__mgs_fsdb_setup(const struct lu_env *env, struct mgs_device *mgs)
5056 struct fs_db *fsdb = NULL;
5060 rc = mgs_find_or_make_fsdb(env, mgs, MGSSELF_NAME, &fsdb);
5062 mgs_put_fsdb(mgs, fsdb);
5067 /* Setup params fsdb and log
5069 int mgs_params_fsdb_setup(const struct lu_env *env, struct mgs_device *mgs)
5071 struct fs_db *fsdb = NULL;
5072 struct llog_handle *params_llh = NULL;
5076 rc = mgs_find_or_make_fsdb(env, mgs, PARAMS_FILENAME, &fsdb);
5078 mutex_lock(&fsdb->fsdb_mutex);
5079 rc = record_start_log(env, mgs, ¶ms_llh, PARAMS_FILENAME);
5081 rc = record_end_log(env, ¶ms_llh);
5082 mutex_unlock(&fsdb->fsdb_mutex);
5083 mgs_put_fsdb(mgs, fsdb);
5089 /* Cleanup params fsdb and log
5091 int mgs_params_fsdb_cleanup(const struct lu_env *env, struct mgs_device *mgs)
5095 rc = mgs_erase_logs(env, mgs, PARAMS_FILENAME);
5096 return rc == -ENOENT ? 0 : rc;
5100 * Fill in the mgs_target_info based on data devname and param provide.
5102 * @env thread context
5104 * @mti mgs target info. We want to set this based other paramters
5105 * passed to this function. Once setup we write it to the config
5107 * @devname optional OBD device name
5108 * @param string that contains both what tunable to set and the value to
5111 * RETURN 0 for success
5112 * negative error number on failure
5114 static int mgs_set_conf_param(const struct lu_env *env, struct mgs_device *mgs,
5115 struct mgs_target_info *mti, const char *devname,
5118 struct fs_db *fsdb = NULL;
5123 /* lustre, lustre-mdtlov, lustre-client, lustre-MDT0000 */
5127 /* We have two possible cases here:
5129 * 1) the device name embedded in the param:
5130 * lustre-OST0000.osc.max_dirty_mb=32
5132 * 2) the file system name is embedded in
5133 * the param: lustre.sys.at.min=0
5135 len = strcspn(param, ".=");
5136 if (!len || param[len] == '=')
5139 if (len >= sizeof(mti->mti_svname))
5142 snprintf(mti->mti_svname, sizeof(mti->mti_svname),
5143 "%.*s", (int)len, param);
5146 if (strlcpy(mti->mti_svname, devname, sizeof(mti->mti_svname)) >=
5147 sizeof(mti->mti_svname))
5151 if (!strlen(mti->mti_svname)) {
5152 LCONSOLE_ERROR_MSG(0x14d, "No target specified: %s\n", param);
5156 dev_type = mgs_parse_devname(mti->mti_svname, mti->mti_fsname,
5157 &mti->mti_stripe_index);
5159 /* For this case we have an invalid obd device name */
5161 CDEBUG(D_MGS, "%s don't contain an index\n", mti->mti_svname);
5162 strlcpy(mti->mti_fsname, mti->mti_svname, MTI_NAME_MAXLEN);
5165 /* Not an obd device, assume devname is the fsname.
5166 * User might of only provided fsname and not obd device
5169 CDEBUG(D_MGS, "%s is seen as a file system name\n", mti->mti_svname);
5170 strlcpy(mti->mti_fsname, mti->mti_svname, MTI_NAME_MAXLEN);
5175 GOTO(out, rc = dev_type);
5177 /* param related to llite isn't allowed to set by OST or MDT */
5178 if (dev_type & LDD_F_SV_TYPE_OST ||
5179 dev_type & LDD_F_SV_TYPE_MDT) {
5180 /* param related to llite isn't allowed to set by OST
5183 if (!strncmp(param, PARAM_LLITE,
5184 sizeof(PARAM_LLITE) - 1))
5185 GOTO(out, rc = -EINVAL);
5187 /* Strip -osc or -mdc suffix from svname */
5188 if (server_make_name(dev_type, mti->mti_stripe_index,
5189 mti->mti_fsname, mti->mti_svname,
5190 sizeof(mti->mti_svname)))
5191 GOTO(out, rc = -EINVAL);
5196 if (strlcpy(mti->mti_params, param, sizeof(mti->mti_params)) >=
5197 sizeof(mti->mti_params))
5198 GOTO(out, rc = -E2BIG);
5200 CDEBUG(D_MGS, "set_conf_param fs='%s' device='%s' param='%s'\n",
5201 mti->mti_fsname, mti->mti_svname, mti->mti_params);
5203 rc = mgs_find_or_make_fsdb(env, mgs, mti->mti_fsname, &fsdb);
5207 if (!test_bit(FSDB_MGS_SELF, &fsdb->fsdb_flags) &&
5208 test_bit(FSDB_LOG_EMPTY, &fsdb->fsdb_flags)) {
5209 CERROR("No filesystem targets for %s. cfg_device from lctl "
5210 "is '%s'\n", mti->mti_fsname, mti->mti_svname);
5211 mgs_unlink_fsdb(mgs, fsdb);
5212 GOTO(out, rc = -EINVAL);
5216 * Revoke lock so everyone updates. Should be alright if
5217 * someone was already reading while we were updating the logs,
5218 * so we don't really need to hold the lock while we're
5221 mti->mti_flags = dev_type | LDD_F_PARAM;
5222 mutex_lock(&fsdb->fsdb_mutex);
5223 rc = mgs_write_log_param(env, mgs, fsdb, mti, mti->mti_params);
5224 mutex_unlock(&fsdb->fsdb_mutex);
5225 mgs_revoke_lock(mgs, fsdb, CONFIG_T_CONFIG);
5229 mgs_put_fsdb(mgs, fsdb);
5234 static int mgs_set_param2(const struct lu_env *env, struct mgs_device *mgs,
5235 struct mgs_target_info *mti, const char *param)
5237 struct fs_db *fsdb = NULL;
5242 if (strlcpy(mti->mti_params, param, sizeof(mti->mti_params)) >=
5243 sizeof(mti->mti_params))
5244 GOTO(out, rc = -E2BIG);
5246 len = strcspn(param, ".=");
5247 if (len && param[len] != '=') {
5248 struct list_head *tmp;
5252 ptr = strchr(param, '.');
5254 len = strlen(param);
5257 if (len >= sizeof(mti->mti_svname))
5258 GOTO(out, rc = -E2BIG);
5260 snprintf(mti->mti_svname, sizeof(mti->mti_svname), "%.*s",
5263 mutex_lock(&mgs->mgs_mutex);
5264 if (unlikely(list_empty(&mgs->mgs_fs_db_list))) {
5265 mutex_unlock(&mgs->mgs_mutex);
5266 GOTO(out, rc = -ENODEV);
5269 list_for_each(tmp, &mgs->mgs_fs_db_list) {
5270 fsdb = list_entry(tmp, struct fs_db, fsdb_list);
5271 if (fsdb->fsdb_has_lproc_entry &&
5272 strcmp(fsdb->fsdb_name, "params") != 0 &&
5273 strstr(param, fsdb->fsdb_name)) {
5274 snprintf(mti->mti_svname,
5275 sizeof(mti->mti_svname), "%s",
5283 snprintf(mti->mti_svname, sizeof(mti->mti_svname),
5286 mutex_unlock(&mgs->mgs_mutex);
5288 snprintf(mti->mti_svname, sizeof(mti->mti_svname), "general");
5291 CDEBUG(D_MGS, "set_param2 fs='%s' device='%s' param='%s'\n",
5292 mti->mti_fsname, mti->mti_svname, mti->mti_params);
5294 /* The return value should be the device type i.e LDD_F_SV_TYPE_XXX.
5295 * A returned error tells us we don't have a target obd device.
5297 dev_type = server_name2index(mti->mti_svname, &mti->mti_stripe_index,
5302 /* the return value should be the device type i.e LDD_F_SV_TYPE_XXX.
5303 * Strip -osc or -mdc suffix from svname
5305 if ((dev_type & LDD_F_SV_TYPE_OST || dev_type & LDD_F_SV_TYPE_MDT) &&
5306 server_make_name(dev_type, mti->mti_stripe_index,
5307 mti->mti_fsname, mti->mti_svname,
5308 sizeof(mti->mti_svname)))
5309 GOTO(out, rc = -EINVAL);
5311 rc = mgs_find_or_make_fsdb(env, mgs, PARAMS_FILENAME, &fsdb);
5315 * Revoke lock so everyone updates. Should be alright if
5316 * someone was already reading while we were updating the logs,
5317 * so we don't really need to hold the lock while we're
5320 mti->mti_flags = dev_type | LDD_F_PARAM2;
5321 mutex_lock(&fsdb->fsdb_mutex);
5322 rc = mgs_write_log_param2(env, mgs, fsdb, mti, mti->mti_params);
5323 mutex_unlock(&fsdb->fsdb_mutex);
5324 mgs_revoke_lock(mgs, fsdb, CONFIG_T_PARAMS);
5325 mgs_put_fsdb(mgs, fsdb);
5330 /* Set a permanent (config log) param for a target or fs
5332 * @lcfg buf0 may contain the device (testfs-MDT0000) name
5333 * buf1 contains the single parameter
5335 int mgs_set_param(const struct lu_env *env, struct mgs_device *mgs,
5336 struct lustre_cfg *lcfg)
5338 const char *param = lustre_cfg_string(lcfg, 1);
5339 struct mgs_target_info *mti;
5342 /* Create a fake mti to hold everything */
5347 print_lustre_cfg(lcfg);
5349 if (lcfg->lcfg_command == LCFG_PARAM) {
5350 /* For the case of lctl conf_param devname can be
5351 * lustre, lustre-mdtlov, lustre-client, lustre-MDT0000
5353 const char *devname = lustre_cfg_string(lcfg, 0);
5355 rc = mgs_set_conf_param(env, mgs, mti, devname, param);
5357 /* In the case of lctl set_param -P lcfg[0] will always
5358 * be 'general'. At least for now.
5360 rc = mgs_set_param2(env, mgs, mti, param);
5368 static int mgs_write_log_pool(const struct lu_env *env,
5369 struct mgs_device *mgs, char *logname,
5370 struct fs_db *fsdb, char *tgtname,
5371 enum lcfg_command_type cmd,
5372 char *fsname, char *poolname,
5373 char *ostname, char *comment)
5375 struct llog_handle *llh = NULL;
5378 rc = record_start_log(env, mgs, &llh, logname);
5381 rc = record_marker(env, llh, fsdb, CM_START, tgtname, comment);
5384 rc = record_base(env, llh, tgtname, 0, cmd,
5385 fsname, poolname, ostname, NULL);
5388 rc = record_marker(env, llh, fsdb, CM_END, tgtname, comment);
5390 record_end_log(env, &llh);
5394 int mgs_nodemap_cmd(const struct lu_env *env, struct mgs_device *mgs,
5395 enum lcfg_command_type cmd, const char *nodemap_name,
5406 case LCFG_NODEMAP_ADD:
5407 rc = nodemap_add(nodemap_name);
5409 case LCFG_NODEMAP_DEL:
5410 rc = nodemap_del(nodemap_name);
5412 case LCFG_NODEMAP_ADD_RANGE:
5413 rc = nodemap_parse_range(param, nid);
5416 rc = nodemap_add_range(nodemap_name, nid);
5418 case LCFG_NODEMAP_DEL_RANGE:
5419 rc = nodemap_parse_range(param, nid);
5422 rc = nodemap_del_range(nodemap_name, nid);
5424 case LCFG_NODEMAP_ADMIN:
5425 rc = kstrtobool(param, &bool_switch);
5428 rc = nodemap_set_allow_root(nodemap_name, bool_switch);
5430 case LCFG_NODEMAP_DENY_UNKNOWN:
5431 rc = kstrtobool(param, &bool_switch);
5434 rc = nodemap_set_deny_unknown(nodemap_name, bool_switch);
5436 case LCFG_NODEMAP_AUDIT_MODE:
5437 rc = kstrtoul(param, 10, (unsigned long *)&bool_switch);
5439 rc = nodemap_set_audit_mode(nodemap_name, bool_switch);
5441 case LCFG_NODEMAP_MAP_MODE:
5442 if (strcmp("both", param) == 0)
5443 rc = nodemap_set_mapping_mode(nodemap_name,
5445 else if (strcmp("uid_only", param) == 0)
5446 rc = nodemap_set_mapping_mode(nodemap_name,
5447 NODEMAP_MAP_UID_ONLY);
5448 else if (strcmp("gid_only", param) == 0)
5449 rc = nodemap_set_mapping_mode(nodemap_name,
5450 NODEMAP_MAP_GID_ONLY);
5454 case LCFG_NODEMAP_TRUSTED:
5455 rc = kstrtobool(param, &bool_switch);
5458 rc = nodemap_set_trust_client_ids(nodemap_name, bool_switch);
5460 case LCFG_NODEMAP_SQUASH_UID:
5461 rc = kstrtouint(param, 10, &int_id);
5464 rc = nodemap_set_squash_uid(nodemap_name, int_id);
5466 case LCFG_NODEMAP_SQUASH_GID:
5467 rc = kstrtouint(param, 10, &int_id);
5470 rc = nodemap_set_squash_gid(nodemap_name, int_id);
5472 case LCFG_NODEMAP_ADD_UIDMAP:
5473 case LCFG_NODEMAP_ADD_GIDMAP:
5474 rc = nodemap_parse_idmap(param, idmap);
5477 if (cmd == LCFG_NODEMAP_ADD_UIDMAP)
5478 rc = nodemap_add_idmap(nodemap_name, NODEMAP_UID,
5481 rc = nodemap_add_idmap(nodemap_name, NODEMAP_GID,
5484 case LCFG_NODEMAP_DEL_UIDMAP:
5485 case LCFG_NODEMAP_DEL_GIDMAP:
5486 rc = nodemap_parse_idmap(param, idmap);
5489 if (cmd == LCFG_NODEMAP_DEL_UIDMAP)
5490 rc = nodemap_del_idmap(nodemap_name, NODEMAP_UID,
5493 rc = nodemap_del_idmap(nodemap_name, NODEMAP_GID,
5496 case LCFG_NODEMAP_SET_FILESET:
5497 rc = nodemap_set_fileset(nodemap_name, param);
5499 case LCFG_NODEMAP_SET_SEPOL:
5500 rc = nodemap_set_sepol(nodemap_name, param);
5509 int mgs_pool_cmd(const struct lu_env *env, struct mgs_device *mgs,
5510 enum lcfg_command_type cmd, char *fsname,
5511 char *poolname, char *ostname)
5516 char *label = NULL, *canceled_label = NULL;
5518 struct mgs_target_info *mti = NULL;
5519 bool checked = false;
5520 bool locked = false;
5525 rc = mgs_find_or_make_fsdb(env, mgs, fsname, &fsdb);
5527 CERROR("Can't get db for %s\n", fsname);
5530 if (test_bit(FSDB_LOG_EMPTY, &fsdb->fsdb_flags)) {
5531 CERROR("%s is not defined\n", fsname);
5533 GOTO(out_fsdb, rc = -EINVAL);
5536 label_sz = 10 + strlen(fsname) + strlen(poolname);
5538 /* check if ostname match fsname */
5539 if (ostname != NULL) {
5542 ptr = strrchr(ostname, '-');
5543 if ((ptr == NULL) ||
5544 (strncmp(fsname, ostname, ptr-ostname) != 0))
5546 label_sz += strlen(ostname);
5549 OBD_ALLOC(label, label_sz);
5551 GOTO(out_fsdb, rc = -ENOMEM);
5556 "new %s.%s", fsname, poolname);
5560 "add %s.%s.%s", fsname, poolname, ostname);
5563 OBD_ALLOC(canceled_label, label_sz);
5564 if (canceled_label == NULL)
5565 GOTO(out_label, rc = -ENOMEM);
5567 "rem %s.%s.%s", fsname, poolname, ostname);
5568 sprintf(canceled_label,
5569 "add %s.%s.%s", fsname, poolname, ostname);
5572 OBD_ALLOC(canceled_label, label_sz);
5573 if (canceled_label == NULL)
5574 GOTO(out_label, rc = -ENOMEM);
5576 "del %s.%s", fsname, poolname);
5577 sprintf(canceled_label,
5578 "new %s.%s", fsname, poolname);
5586 GOTO(out_cancel, rc = -ENOMEM);
5587 strncpy(mti->mti_svname, "lov pool", sizeof(mti->mti_svname));
5589 mutex_lock(&fsdb->fsdb_mutex);
5591 /* write pool def to all MDT logs */
5592 for (i = 0; i < INDEX_MAP_SIZE * 8; i++) {
5593 if (test_bit(i, fsdb->fsdb_mdt_index_map)) {
5594 rc = name_create_mdt_and_lov(&logname, &lovname,
5599 if (!checked && (canceled_label == NULL)) {
5600 rc = mgs_check_marker(env, mgs, fsdb, mti,
5601 logname, lovname, label);
5603 name_destroy(&logname);
5604 name_destroy(&lovname);
5606 rc = (rc == LLOG_PROC_BREAK ?
5611 if (canceled_label != NULL)
5612 rc = mgs_modify(env, mgs, fsdb, mti, logname,
5613 lovname, canceled_label,
5617 rc = mgs_write_log_pool(env, mgs, logname,
5621 name_destroy(&logname);
5622 name_destroy(&lovname);
5628 rc = name_create(&logname, fsname, "-client");
5632 if (!checked && (canceled_label == NULL)) {
5633 rc = mgs_check_marker(env, mgs, fsdb, mti, logname,
5634 fsdb->fsdb_clilov, label);
5636 name_destroy(&logname);
5637 GOTO(out_mti, rc = (rc == LLOG_PROC_BREAK ?
5641 if (canceled_label != NULL) {
5642 rc = mgs_modify(env, mgs, fsdb, mti, logname,
5643 fsdb->fsdb_clilov, canceled_label, CM_SKIP);
5645 name_destroy(&logname);
5650 rc = mgs_write_log_pool(env, mgs, logname, fsdb, fsdb->fsdb_clilov,
5651 cmd, fsname, poolname, ostname, label);
5652 mutex_unlock(&fsdb->fsdb_mutex);
5654 name_destroy(&logname);
5655 /* request for update */
5656 mgs_revoke_lock(mgs, fsdb, CONFIG_T_CONFIG);
5662 mutex_unlock(&fsdb->fsdb_mutex);
5666 if (canceled_label != NULL)
5667 OBD_FREE(canceled_label, label_sz);
5669 OBD_FREE(label, label_sz);
5672 mgs_unlink_fsdb(mgs, fsdb);
5673 mgs_put_fsdb(mgs, fsdb);