4 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License version 2 only,
8 * as published by the Free Software Foundation.
10 * This program is distributed in the hope that it will be useful, but
11 * WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * General Public License version 2 for more details (a copy is included
14 * in the LICENSE file that accompanied this code).
16 * You should have received a copy of the GNU General Public License
17 * version 2 along with this program; If not, see
18 * http://www.gnu.org/licenses/gpl-2.0.html
23 * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved.
24 * Use is subject to license terms.
26 * Copyright (c) 2011, 2017, Intel Corporation.
29 * This file is part of Lustre, http://www.lustre.org/
30 * Lustre is a trademark of Sun Microsystems, Inc.
32 * lustre/mgs/mgs_llog.c
34 * Lustre Management Server (mgs) config llog creation
36 * Author: Nathan Rutman <nathan@clusterfs.com>
37 * Author: Alex Zhuravlev <bzzz@whamcloud.com>
38 * Author: Mikhail Pershin <tappro@whamcloud.com>
41 #define DEBUG_SUBSYSTEM S_MGS
42 #define D_MGS D_CONFIG
45 #include <uapi/linux/lustre/lustre_ioctl.h>
46 #include <uapi/linux/lustre/lustre_param.h>
47 #include <lustre_sec.h>
48 #include <lustre_quota.h>
49 #include <lustre_sec.h>
51 #include "mgs_internal.h"
53 /********************** Class functions ********************/
56 * Find all logs in CONFIG directory and link then into list.
58 * \param[in] env pointer to the thread context
59 * \param[in] mgs pointer to the mgs device
60 * \param[out] log_list the list to hold the found llog name entry
62 * \retval 0 for success
63 * \retval negative error number on failure
65 int class_dentry_readdir(const struct lu_env *env, struct mgs_device *mgs,
66 struct list_head *log_list)
68 struct dt_object *dir = mgs->mgs_configs_dir;
69 const struct dt_it_ops *iops;
71 struct mgs_direntry *de;
74 size_t suffix_len = sizeof(".bak") - 1;
76 INIT_LIST_HEAD(log_list);
79 LASSERT(dir->do_index_ops);
81 iops = &dir->do_index_ops->dio_it;
82 it = iops->init(env, dir, LUDA_64BITHASH);
86 rc = iops->load(env, it, 0);
92 key = (void *)iops->key(env, it);
94 CERROR("%s: key failed when listing %s: rc = %d\n",
95 mgs->mgs_obd->obd_name, MOUNT_CONFIGS_DIR,
99 key_sz = iops->key_size(env, it);
102 /* filter out "." and ".." entries */
106 if (key_sz == 2 && key[1] == '.')
110 /* filter out ".bak" files */
111 if (key_sz >= suffix_len &&
112 !memcmp(".bak", key + key_sz - suffix_len, suffix_len)) {
113 CDEBUG(D_MGS, "Skipping backup file %.*s\n",
118 de = mgs_direntry_alloc(key_sz + 1);
124 memcpy(de->mde_name, key, key_sz);
125 de->mde_name[key_sz] = 0;
127 list_add(&de->mde_list, log_list);
130 rc = iops->next(env, it);
140 struct mgs_direntry *n;
142 CERROR("%s: key failed when listing %s: rc = %d\n",
143 mgs->mgs_obd->obd_name, MOUNT_CONFIGS_DIR, rc);
145 list_for_each_entry_safe(de, n, log_list, mde_list) {
146 list_del_init(&de->mde_list);
147 mgs_direntry_free(de);
154 /******************** DB functions *********************/
156 static inline int name_create(char **newname, char *prefix, char *suffix)
159 OBD_ALLOC(*newname, strlen(prefix) + strlen(suffix) + 1);
162 sprintf(*newname, "%s%s", prefix, suffix);
166 static inline void name_destroy(char **name)
169 OBD_FREE(*name, strlen(*name) + 1);
173 struct mgs_fsdb_handler_data
179 /* from the (client) config log, figure out:
180 1. which ost's/mdt's are configured (by index)
181 2. what the last config step is
182 3. COMPAT_18 osc name
184 /* It might be better to have a separate db file, instead of parsing the info
185 out of the client log. This is slow and potentially error-prone. */
186 static int mgs_fsdb_handler(const struct lu_env *env, struct llog_handle *llh,
187 struct llog_rec_hdr *rec, void *data)
189 struct mgs_fsdb_handler_data *d = data;
190 struct fs_db *fsdb = d->fsdb;
191 int cfg_len = rec->lrh_len;
192 char *cfg_buf = (char*) (rec + 1);
193 struct lustre_cfg *lcfg;
198 if (rec->lrh_type != OBD_CFG_REC) {
199 CERROR("unhandled lrh_type: %#x\n", rec->lrh_type);
203 rc = lustre_cfg_sanity_check(cfg_buf, cfg_len);
205 CERROR("Insane cfg\n");
209 lcfg = (struct lustre_cfg *)cfg_buf;
211 CDEBUG(D_INFO, "cmd %x %s %s\n", lcfg->lcfg_command,
212 lustre_cfg_string(lcfg, 0), lustre_cfg_string(lcfg, 1));
214 /* Figure out ost indicies */
215 /* lov_modify_tgts add 0:lov1 1:ost1_UUID 2(index):0 3(gen):1 */
216 if (lcfg->lcfg_command == LCFG_LOV_ADD_OBD ||
217 lcfg->lcfg_command == LCFG_LOV_DEL_OBD) {
218 rc = kstrtouint(lustre_cfg_string(lcfg, 2), 10, &index);
222 CDEBUG(D_MGS, "OST index for %s is %u (%s)\n",
223 lustre_cfg_string(lcfg, 1), index,
224 lustre_cfg_string(lcfg, 2));
225 set_bit(index, fsdb->fsdb_ost_index_map);
228 /* Figure out mdt indicies */
229 /* attach 0:MDC_uml1_mdsA_MNT_client 1:mdc 2:1d834_MNT_client_03f */
230 if ((lcfg->lcfg_command == LCFG_ATTACH) &&
231 (strcmp(lustre_cfg_string(lcfg, 1), LUSTRE_MDC_NAME) == 0)) {
232 rc = server_name2index(lustre_cfg_string(lcfg, 0),
234 if (rc != LDD_F_SV_TYPE_MDT) {
235 CWARN("Unparsable MDC name %s, assuming index 0\n",
236 lustre_cfg_string(lcfg, 0));
240 CDEBUG(D_MGS, "MDT index is %u\n", index);
241 if (!test_bit(index, fsdb->fsdb_mdt_index_map)) {
242 set_bit(index, fsdb->fsdb_mdt_index_map);
243 fsdb->fsdb_mdt_count++;
248 * figure out the old config. fsdb_gen = 0 means old log
249 * It is obsoleted and not supported anymore
251 if (fsdb->fsdb_gen == 0) {
252 CERROR("Old config format is not supported\n");
257 * compat to 1.8, check osc name used by MDT0 to OSTs, bz18548.
259 if (!test_bit(FSDB_OSCNAME18, &fsdb->fsdb_flags) &&
260 lcfg->lcfg_command == LCFG_ATTACH &&
261 strcmp(lustre_cfg_string(lcfg, 1), LUSTRE_OSC_NAME) == 0) {
262 if (OBD_OCD_VERSION_MAJOR(d->ver) == 1 &&
263 OBD_OCD_VERSION_MINOR(d->ver) <= 8) {
264 CWARN("MDT using 1.8 OSC name scheme\n");
265 set_bit(FSDB_OSCNAME18, &fsdb->fsdb_flags);
269 if (lcfg->lcfg_command == LCFG_MARKER) {
270 struct cfg_marker *marker;
271 marker = lustre_cfg_buf(lcfg, 1);
273 d->ver = marker->cm_vers;
275 /* Keep track of the latest marker step */
276 fsdb->fsdb_gen = max(fsdb->fsdb_gen, marker->cm_step);
282 /* fsdb->fsdb_mutex is already held in mgs_find_or_make_fsdb*/
283 static int mgs_get_fsdb_from_llog(const struct lu_env *env,
284 struct mgs_device *mgs,
288 struct llog_handle *loghandle;
289 struct llog_ctxt *ctxt;
290 struct mgs_fsdb_handler_data d = {
297 ctxt = llog_get_context(mgs->mgs_obd, LLOG_CONFIG_ORIG_CTXT);
298 LASSERT(ctxt != NULL);
299 rc = name_create(&logname, fsdb->fsdb_name, "-client");
302 rc = llog_open_create(env, ctxt, &loghandle, NULL, logname);
306 rc = llog_init_handle(env, loghandle, LLOG_F_IS_PLAIN, NULL);
310 if (llog_get_size(loghandle) <= 1)
311 set_bit(FSDB_LOG_EMPTY, &fsdb->fsdb_flags);
313 rc = llog_process(env, loghandle, mgs_fsdb_handler, (void *)&d, NULL);
314 CDEBUG(D_INFO, "get_db = %d\n", rc);
316 llog_close(env, loghandle);
318 name_destroy(&logname);
325 static void mgs_free_fsdb_srpc(struct fs_db *fsdb)
327 struct mgs_tgt_srpc_conf *tgtconf;
329 /* free target-specific rules */
330 while (fsdb->fsdb_srpc_tgt) {
331 tgtconf = fsdb->fsdb_srpc_tgt;
332 fsdb->fsdb_srpc_tgt = tgtconf->mtsc_next;
334 LASSERT(tgtconf->mtsc_tgt);
336 sptlrpc_rule_set_free(&tgtconf->mtsc_rset);
337 OBD_FREE(tgtconf->mtsc_tgt, strlen(tgtconf->mtsc_tgt) + 1);
338 OBD_FREE_PTR(tgtconf);
341 /* free general rules */
342 sptlrpc_rule_set_free(&fsdb->fsdb_srpc_gen);
345 static void mgs_unlink_fsdb(struct mgs_device *mgs, struct fs_db *fsdb)
347 mutex_lock(&mgs->mgs_mutex);
348 if (likely(!list_empty(&fsdb->fsdb_list))) {
349 LASSERTF(atomic_read(&fsdb->fsdb_ref) >= 2,
350 "Invalid ref %d on %s\n",
351 atomic_read(&fsdb->fsdb_ref),
354 list_del_init(&fsdb->fsdb_list);
355 /* Drop the reference on the list.*/
356 mgs_put_fsdb(mgs, fsdb);
358 mutex_unlock(&mgs->mgs_mutex);
361 /* The caller must hold mgs->mgs_mutex. */
362 static inline struct fs_db *
363 mgs_find_fsdb_noref(struct mgs_device *mgs, const char *fsname)
366 struct list_head *tmp;
368 list_for_each(tmp, &mgs->mgs_fs_db_list) {
369 fsdb = list_entry(tmp, struct fs_db, fsdb_list);
370 if (strcmp(fsdb->fsdb_name, fsname) == 0)
377 /* The caller must hold mgs->mgs_mutex. */
378 static void mgs_remove_fsdb_by_name(struct mgs_device *mgs, const char *name)
382 fsdb = mgs_find_fsdb_noref(mgs, name);
384 list_del_init(&fsdb->fsdb_list);
385 /* Drop the reference on the list.*/
386 mgs_put_fsdb(mgs, fsdb);
390 /* The caller must hold mgs->mgs_mutex. */
391 struct fs_db *mgs_find_fsdb(struct mgs_device *mgs, const char *fsname)
395 fsdb = mgs_find_fsdb_noref(mgs, fsname);
397 atomic_inc(&fsdb->fsdb_ref);
402 /* The caller must hold mgs->mgs_mutex. */
403 static struct fs_db *mgs_new_fsdb(const struct lu_env *env,
404 struct mgs_device *mgs, char *fsname)
410 if (strlen(fsname) >= sizeof(fsdb->fsdb_name)) {
411 CERROR("fsname %s is too long\n", fsname);
413 RETURN(ERR_PTR(-EINVAL));
418 RETURN(ERR_PTR(-ENOMEM));
420 strncpy(fsdb->fsdb_name, fsname, sizeof(fsdb->fsdb_name));
421 mutex_init(&fsdb->fsdb_mutex);
422 INIT_LIST_HEAD(&fsdb->fsdb_list);
423 set_bit(FSDB_UDESC, &fsdb->fsdb_flags);
425 INIT_LIST_HEAD(&fsdb->fsdb_clients);
426 atomic_set(&fsdb->fsdb_notify_phase, 0);
427 init_waitqueue_head(&fsdb->fsdb_notify_waitq);
428 init_completion(&fsdb->fsdb_notify_comp);
430 if (strcmp(fsname, MGSSELF_NAME) == 0) {
431 set_bit(FSDB_MGS_SELF, &fsdb->fsdb_flags);
432 fsdb->fsdb_mgs = mgs;
433 if (logname_is_barrier(fsname))
436 OBD_ALLOC(fsdb->fsdb_mdt_index_map, INDEX_MAP_SIZE);
437 if (!fsdb->fsdb_mdt_index_map) {
438 CERROR("No memory for MDT index maps\n");
440 GOTO(err, rc = -ENOMEM);
443 OBD_ALLOC(fsdb->fsdb_ost_index_map, INDEX_MAP_SIZE);
444 if (!fsdb->fsdb_ost_index_map) {
445 CERROR("No memory for OST index maps\n");
447 GOTO(err, rc = -ENOMEM);
450 if (logname_is_barrier(fsname))
453 rc = name_create(&fsdb->fsdb_clilov, fsname, "-clilov");
457 rc = name_create(&fsdb->fsdb_clilmv, fsname, "-clilmv");
461 /* initialise data for NID table */
462 mgs_ir_init_fs(env, mgs, fsdb);
463 lproc_mgs_add_live(mgs, fsdb);
466 if (!test_bit(FSDB_MGS_SELF, &fsdb->fsdb_flags) &&
467 strcmp(PARAMS_FILENAME, fsname) != 0) {
468 /* populate the db from the client llog */
469 rc = mgs_get_fsdb_from_llog(env, mgs, fsdb);
471 CERROR("Can't get db from client log %d\n", rc);
477 /* populate srpc rules from params llog */
478 rc = mgs_get_fsdb_srpc_from_llog(env, mgs, fsdb);
480 CERROR("Can't get db from params log %d\n", rc);
486 /* One ref is for the fsdb on the list.
487 * The other ref is for the caller. */
488 atomic_set(&fsdb->fsdb_ref, 2);
489 list_add(&fsdb->fsdb_list, &mgs->mgs_fs_db_list);
494 atomic_set(&fsdb->fsdb_ref, 1);
495 mgs_put_fsdb(mgs, fsdb);
500 static void mgs_free_fsdb(struct mgs_device *mgs, struct fs_db *fsdb)
502 LASSERT(list_empty(&fsdb->fsdb_list));
504 lproc_mgs_del_live(mgs, fsdb);
506 /* deinitialize fsr */
508 mgs_ir_fini_fs(mgs, fsdb);
510 if (fsdb->fsdb_ost_index_map)
511 OBD_FREE(fsdb->fsdb_ost_index_map, INDEX_MAP_SIZE);
512 if (fsdb->fsdb_mdt_index_map)
513 OBD_FREE(fsdb->fsdb_mdt_index_map, INDEX_MAP_SIZE);
514 name_destroy(&fsdb->fsdb_clilov);
515 name_destroy(&fsdb->fsdb_clilmv);
516 mgs_free_fsdb_srpc(fsdb);
520 void mgs_put_fsdb(struct mgs_device *mgs, struct fs_db *fsdb)
522 if (atomic_dec_and_test(&fsdb->fsdb_ref))
523 mgs_free_fsdb(mgs, fsdb);
526 int mgs_init_fsdb_list(struct mgs_device *mgs)
528 INIT_LIST_HEAD(&mgs->mgs_fs_db_list);
532 int mgs_cleanup_fsdb_list(struct mgs_device *mgs)
535 struct list_head *tmp, *tmp2;
537 mutex_lock(&mgs->mgs_mutex);
538 list_for_each_safe(tmp, tmp2, &mgs->mgs_fs_db_list) {
539 fsdb = list_entry(tmp, struct fs_db, fsdb_list);
540 list_del_init(&fsdb->fsdb_list);
541 mgs_put_fsdb(mgs, fsdb);
543 mutex_unlock(&mgs->mgs_mutex);
547 /* The caller must hold mgs->mgs_mutex. */
548 int mgs_find_or_make_fsdb_nolock(const struct lu_env *env,
549 struct mgs_device *mgs,
550 char *name, struct fs_db **dbh)
556 fsdb = mgs_find_fsdb(mgs, name);
558 fsdb = mgs_new_fsdb(env, mgs, name);
562 CDEBUG(D_MGS, "Created new db: rc = %d\n", rc);
571 int mgs_find_or_make_fsdb(const struct lu_env *env, struct mgs_device *mgs,
572 char *name, struct fs_db **dbh)
577 mutex_lock(&mgs->mgs_mutex);
578 rc = mgs_find_or_make_fsdb_nolock(env, mgs, name, dbh);
579 mutex_unlock(&mgs->mgs_mutex);
586 -1= empty client log */
587 int mgs_check_index(const struct lu_env *env,
588 struct mgs_device *mgs,
589 struct mgs_target_info *mti)
596 LASSERT(!(mti->mti_flags & LDD_F_NEED_INDEX));
598 rc = mgs_find_or_make_fsdb(env, mgs, mti->mti_fsname, &fsdb);
600 CERROR("Can't get db for %s\n", mti->mti_fsname);
604 if (test_bit(FSDB_LOG_EMPTY, &fsdb->fsdb_flags))
607 if (mti->mti_flags & LDD_F_SV_TYPE_OST)
608 imap = fsdb->fsdb_ost_index_map;
609 else if (mti->mti_flags & LDD_F_SV_TYPE_MDT)
610 imap = fsdb->fsdb_mdt_index_map;
612 GOTO(out, rc = -EINVAL);
614 if (test_bit(mti->mti_stripe_index, imap))
620 mgs_put_fsdb(mgs, fsdb);
624 static __inline__ int next_index(void *index_map, int map_len)
627 for (i = 0; i < map_len * 8; i++)
628 if (!test_bit(i, index_map)) {
631 CERROR("max index %d exceeded.\n", i);
635 /* Make the mdt/ost server obd name based on the filesystem name */
636 static bool server_make_name(u32 flags, u16 index, const char *fs,
637 char *name_buf, size_t name_buf_size)
639 bool invalid_flag = false;
641 if (flags & (LDD_F_SV_TYPE_MDT | LDD_F_SV_TYPE_OST)) {
642 if (!(flags & LDD_F_SV_ALL))
643 snprintf(name_buf, name_buf_size, "%.8s%c%s%04x", fs,
644 (flags & LDD_F_VIRGIN) ? ':' :
645 ((flags & LDD_F_WRITECONF) ? '=' : '-'),
646 (flags & LDD_F_SV_TYPE_MDT) ? "MDT" : "OST",
648 } else if (flags & LDD_F_SV_TYPE_MGS) {
649 snprintf(name_buf, name_buf_size, "MGS");
651 CERROR("unknown server type %#x\n", flags);
658 0 newly marked as in use
660 +EALREADY for update of an old index */
661 static int mgs_set_index(const struct lu_env *env,
662 struct mgs_device *mgs,
663 struct mgs_target_info *mti)
670 rc = mgs_find_or_make_fsdb(env, mgs, mti->mti_fsname, &fsdb);
672 CERROR("Can't get db for %s\n", mti->mti_fsname);
676 mutex_lock(&fsdb->fsdb_mutex);
677 if (mti->mti_flags & LDD_F_SV_TYPE_OST) {
678 imap = fsdb->fsdb_ost_index_map;
679 } else if (mti->mti_flags & LDD_F_SV_TYPE_MDT) {
680 imap = fsdb->fsdb_mdt_index_map;
682 GOTO(out_up, rc = -EINVAL);
685 if (mti->mti_flags & LDD_F_NEED_INDEX) {
686 rc = next_index(imap, INDEX_MAP_SIZE);
688 GOTO(out_up, rc = -ERANGE);
689 mti->mti_stripe_index = rc;
692 /* the last index(0xffff) is reserved for default value. */
693 if (mti->mti_stripe_index >= INDEX_MAP_SIZE * 8 - 1) {
694 LCONSOLE_ERROR_MSG(0x13f, "Server %s requested index %u, "
695 "but index must be less than %u.\n",
696 mti->mti_svname, mti->mti_stripe_index,
697 INDEX_MAP_SIZE * 8 - 1);
698 GOTO(out_up, rc = -ERANGE);
701 if (test_bit(mti->mti_stripe_index, imap)) {
702 if ((mti->mti_flags & LDD_F_VIRGIN) &&
703 !(mti->mti_flags & LDD_F_WRITECONF)) {
704 LCONSOLE_ERROR_MSG(0x140, "Server %s requested index "
705 "%d, but that index is already in "
706 "use. Use --writeconf to force\n",
708 mti->mti_stripe_index);
709 GOTO(out_up, rc = -EADDRINUSE);
711 CDEBUG(D_MGS, "Server %s updating index %d\n",
712 mti->mti_svname, mti->mti_stripe_index);
713 GOTO(out_up, rc = EALREADY);
716 set_bit(mti->mti_stripe_index, imap);
717 if (mti->mti_flags & LDD_F_SV_TYPE_MDT)
718 fsdb->fsdb_mdt_count++;
721 set_bit(mti->mti_stripe_index, imap);
722 clear_bit(FSDB_LOG_EMPTY, &fsdb->fsdb_flags);
723 if (server_make_name(mti->mti_flags & ~(LDD_F_VIRGIN | LDD_F_WRITECONF),
724 mti->mti_stripe_index, mti->mti_fsname,
725 mti->mti_svname, sizeof(mti->mti_svname))) {
726 CERROR("unknown server type %#x\n", mti->mti_flags);
727 GOTO(out_up, rc = -EINVAL);
730 CDEBUG(D_MGS, "Set index for %s to %d\n", mti->mti_svname,
731 mti->mti_stripe_index);
733 GOTO(out_up, rc = 0);
736 mutex_unlock(&fsdb->fsdb_mutex);
737 mgs_put_fsdb(mgs, fsdb);
741 struct mgs_modify_lookup {
742 struct cfg_marker mml_marker;
746 static int mgs_check_record_match(const struct lu_env *env,
747 struct llog_handle *llh,
748 struct llog_rec_hdr *rec, void *data)
750 struct cfg_marker *mc_marker = data;
751 struct cfg_marker *marker;
752 struct lustre_cfg *lcfg = REC_DATA(rec);
753 int cfg_len = REC_DATA_LEN(rec);
758 if (rec->lrh_type != OBD_CFG_REC) {
759 CDEBUG(D_ERROR, "Unhandled lrh_type: %#x\n", rec->lrh_type);
763 rc = lustre_cfg_sanity_check(lcfg, cfg_len);
765 CDEBUG(D_ERROR, "Insane cfg\n");
769 /* We only care about markers */
770 if (lcfg->lcfg_command != LCFG_MARKER)
773 marker = lustre_cfg_buf(lcfg, 1);
775 if (marker->cm_flags & CM_SKIP)
778 if ((strcmp(mc_marker->cm_comment, marker->cm_comment) == 0) &&
779 (strcmp(mc_marker->cm_tgtname, marker->cm_tgtname) == 0)) {
780 /* Found a non-skipped marker match */
781 CDEBUG(D_MGS, "Matched rec %u marker %d flag %x %s %s\n",
782 rec->lrh_index, marker->cm_step,
783 marker->cm_flags, marker->cm_tgtname,
785 rc = LLOG_PROC_BREAK;
792 * Check an existing config log record with matching comment and device
794 * 0 - checked successfully,
795 * LLOG_PROC_BREAK - record matches
798 static int mgs_check_marker(const struct lu_env *env, struct mgs_device *mgs,
799 struct fs_db *fsdb, struct mgs_target_info *mti,
800 char *logname, char *devname, char *comment)
802 struct llog_handle *loghandle;
803 struct llog_ctxt *ctxt;
804 struct cfg_marker *mc_marker;
809 LASSERT(mutex_is_locked(&fsdb->fsdb_mutex));
810 CDEBUG(D_MGS, "mgs check %s/%s/%s\n", logname, devname, comment);
812 ctxt = llog_get_context(mgs->mgs_obd, LLOG_CONFIG_ORIG_CTXT);
813 LASSERT(ctxt != NULL);
814 rc = llog_open(env, ctxt, &loghandle, NULL, logname, LLOG_OPEN_EXISTS);
821 rc = llog_init_handle(env, loghandle, LLOG_F_IS_PLAIN, NULL);
825 if (llog_get_size(loghandle) <= 1)
826 GOTO(out_close, rc = 0);
828 OBD_ALLOC_PTR(mc_marker);
830 GOTO(out_close, rc = -ENOMEM);
831 if (strlcpy(mc_marker->cm_comment, comment,
832 sizeof(mc_marker->cm_comment)) >=
833 sizeof(mc_marker->cm_comment))
834 GOTO(out_free, rc = -E2BIG);
835 if (strlcpy(mc_marker->cm_tgtname, devname,
836 sizeof(mc_marker->cm_tgtname)) >=
837 sizeof(mc_marker->cm_tgtname))
838 GOTO(out_free, rc = -E2BIG);
840 rc = llog_process(env, loghandle, mgs_check_record_match,
841 (void *)mc_marker, NULL);
844 OBD_FREE_PTR(mc_marker);
847 llog_close(env, loghandle);
849 if (rc && rc != LLOG_PROC_BREAK)
850 CDEBUG(D_ERROR, "%s: mgs check %s/%s failed: rc = %d\n",
851 mgs->mgs_obd->obd_name, mti->mti_svname, comment, rc);
856 static int mgs_modify_handler(const struct lu_env *env,
857 struct llog_handle *llh,
858 struct llog_rec_hdr *rec, void *data)
860 struct mgs_modify_lookup *mml = data;
861 struct cfg_marker *marker;
862 struct lustre_cfg *lcfg = REC_DATA(rec);
863 int cfg_len = REC_DATA_LEN(rec);
867 if (rec->lrh_type != OBD_CFG_REC) {
868 CERROR("unhandled lrh_type: %#x\n", rec->lrh_type);
872 rc = lustre_cfg_sanity_check(lcfg, cfg_len);
874 CERROR("Insane cfg\n");
878 /* We only care about markers */
879 if (lcfg->lcfg_command != LCFG_MARKER)
882 marker = lustre_cfg_buf(lcfg, 1);
883 if ((strcmp(mml->mml_marker.cm_comment, marker->cm_comment) == 0) &&
884 (strcmp(mml->mml_marker.cm_tgtname, marker->cm_tgtname) == 0) &&
885 !(marker->cm_flags & CM_SKIP)) {
886 /* Found a non-skipped marker match */
887 CDEBUG(D_MGS, "Changing rec %u marker %d %x->%x: %s %s\n",
888 rec->lrh_index, marker->cm_step,
889 marker->cm_flags, mml->mml_marker.cm_flags,
890 marker->cm_tgtname, marker->cm_comment);
891 /* Overwrite the old marker llog entry */
892 marker->cm_flags &= ~CM_EXCLUDE; /* in case we're unexcluding */
893 marker->cm_flags |= mml->mml_marker.cm_flags;
894 marker->cm_canceltime = mml->mml_marker.cm_canceltime;
895 rc = llog_write(env, llh, rec, rec->lrh_index);
904 * Modify an existing config log record (for CM_SKIP or CM_EXCLUDE)
906 * 0 - modified successfully,
907 * 1 - no modification was done
910 static int mgs_modify(const struct lu_env *env, struct mgs_device *mgs,
911 struct fs_db *fsdb, struct mgs_target_info *mti,
912 char *logname, char *devname, char *comment, int flags)
914 struct llog_handle *loghandle;
915 struct llog_ctxt *ctxt;
916 struct mgs_modify_lookup *mml;
921 LASSERT(mutex_is_locked(&fsdb->fsdb_mutex));
922 CDEBUG(D_MGS, "modify %s/%s/%s fl=%x\n", logname, devname, comment,
925 ctxt = llog_get_context(mgs->mgs_obd, LLOG_CONFIG_ORIG_CTXT);
926 LASSERT(ctxt != NULL);
927 rc = llog_open(env, ctxt, &loghandle, NULL, logname, LLOG_OPEN_EXISTS);
934 rc = llog_init_handle(env, loghandle, LLOG_F_IS_PLAIN, NULL);
938 if (llog_get_size(loghandle) <= 1)
939 GOTO(out_close, rc = 0);
943 GOTO(out_close, rc = -ENOMEM);
944 if (strlcpy(mml->mml_marker.cm_comment, comment,
945 sizeof(mml->mml_marker.cm_comment)) >=
946 sizeof(mml->mml_marker.cm_comment))
947 GOTO(out_free, rc = -E2BIG);
948 if (strlcpy(mml->mml_marker.cm_tgtname, devname,
949 sizeof(mml->mml_marker.cm_tgtname)) >=
950 sizeof(mml->mml_marker.cm_tgtname))
951 GOTO(out_free, rc = -E2BIG);
952 /* Modify mostly means cancel */
953 mml->mml_marker.cm_flags = flags;
954 mml->mml_marker.cm_canceltime = flags ? ktime_get_real_seconds() : 0;
955 mml->mml_modified = 0;
956 rc = llog_process(env, loghandle, mgs_modify_handler, (void *)mml,
958 if (!rc && !mml->mml_modified)
965 llog_close(env, loghandle);
968 CERROR("%s: modify %s/%s failed: rc = %d\n",
969 mgs->mgs_obd->obd_name, mti->mti_svname, comment, rc);
982 /** This structure is passed to mgs_replace_handler */
983 struct mgs_replace_data {
984 /* Nids are replaced for this target device */
985 struct mgs_target_info target;
986 /* Temporary modified llog */
987 struct llog_handle *temp_llh;
988 enum replace_state state;
994 * Check: a) if block should be skipped
995 * b) is it target block
1000 * \retval 0 should not to be skipped
1001 * \retval 1 should to be skipped
1003 static int check_markers(struct lustre_cfg *lcfg,
1004 struct mgs_replace_data *mrd)
1006 struct cfg_marker *marker;
1008 /* Track markers. Find given device */
1009 if (lcfg->lcfg_command == LCFG_MARKER) {
1010 marker = lustre_cfg_buf(lcfg, 1);
1011 /* Clean llog from records marked as CM_SKIP.
1012 CM_EXCLUDE records are used for "active" command
1013 and can be restored if needed */
1014 if ((marker->cm_flags & (CM_SKIP | CM_START)) ==
1015 (CM_SKIP | CM_START)) {
1016 mrd->state = REPLACE_SKIP;
1020 if ((marker->cm_flags & (CM_SKIP | CM_END)) ==
1021 (CM_SKIP | CM_END)) {
1022 mrd->state = REPLACE_COPY;
1026 if (strcmp(mrd->target.mti_svname, marker->cm_tgtname) == 0) {
1027 LASSERT(!(marker->cm_flags & CM_START) ||
1028 !(marker->cm_flags & CM_END));
1029 if (marker->cm_flags & CM_START) {
1030 mrd->state = REPLACE_UUID;
1031 mrd->failover = NULL;
1032 } else if (marker->cm_flags & CM_END)
1033 mrd->state = REPLACE_COPY;
1040 static int record_base(const struct lu_env *env, struct llog_handle *llh,
1041 char *cfgname, lnet_nid_t nid, int cmd,
1042 char *s1, char *s2, char *s3, char *s4)
1044 struct mgs_thread_info *mgi = mgs_env_info(env);
1045 struct llog_cfg_rec *lcr;
1048 CDEBUG(D_MGS, "lcfg %s %#x %s %s %s %s\n", cfgname,
1049 cmd, s1, s2, s3, s4);
1051 lustre_cfg_bufs_reset(&mgi->mgi_bufs, cfgname);
1053 lustre_cfg_bufs_set_string(&mgi->mgi_bufs, 1, s1);
1055 lustre_cfg_bufs_set_string(&mgi->mgi_bufs, 2, s2);
1057 lustre_cfg_bufs_set_string(&mgi->mgi_bufs, 3, s3);
1059 lustre_cfg_bufs_set_string(&mgi->mgi_bufs, 4, s4);
1061 lcr = lustre_cfg_rec_new(cmd, &mgi->mgi_bufs);
1065 lcr->lcr_cfg.lcfg_nid = nid;
1066 rc = llog_write(env, llh, &lcr->lcr_hdr, LLOG_NEXT_IDX);
1068 lustre_cfg_rec_free(lcr);
1072 "failed to write lcfg %s %#x %s %s %s %s: rc = %d\n",
1073 cfgname, cmd, s1, s2, s3, s4, rc);
1077 static inline int record_add_uuid(const struct lu_env *env,
1078 struct llog_handle *llh,
1079 uint64_t nid, char *uuid)
1081 return record_base(env, llh, NULL, nid, LCFG_ADD_UUID, uuid,
1085 static inline int record_add_conn(const struct lu_env *env,
1086 struct llog_handle *llh,
1087 char *devname, char *uuid)
1089 return record_base(env, llh, devname, 0, LCFG_ADD_CONN, uuid,
1093 static inline int record_attach(const struct lu_env *env,
1094 struct llog_handle *llh, char *devname,
1095 char *type, char *uuid)
1097 return record_base(env, llh, devname, 0, LCFG_ATTACH, type, uuid,
1101 static inline int record_setup(const struct lu_env *env,
1102 struct llog_handle *llh, char *devname,
1103 char *s1, char *s2, char *s3, char *s4)
1105 return record_base(env, llh, devname, 0, LCFG_SETUP, s1, s2, s3, s4);
1109 * \retval <0 record processing error
1110 * \retval n record is processed. No need copy original one.
1111 * \retval 0 record is not processed.
1113 static int process_command(const struct lu_env *env, struct lustre_cfg *lcfg,
1114 struct mgs_replace_data *mrd)
1121 if (mrd->state == REPLACE_UUID &&
1122 lcfg->lcfg_command == LCFG_ADD_UUID) {
1123 /* LCFG_ADD_UUID command found. Let's skip original command
1124 and add passed nids */
1125 ptr = mrd->target.mti_params;
1126 while (class_parse_nid(ptr, &nid, &ptr) == 0) {
1127 if (!mrd->nodeuuid) {
1128 rc = name_create(&mrd->nodeuuid,
1129 libcfs_nid2str(nid), "");
1131 CERROR("Can't create uuid for "
1132 "nid %s, device %s\n",
1133 libcfs_nid2str(nid),
1134 mrd->target.mti_svname);
1138 CDEBUG(D_MGS, "add nid %s with uuid %s, "
1139 "device %s\n", libcfs_nid2str(nid),
1140 mrd->target.mti_params,
1142 rc = record_add_uuid(env,
1149 mrd->failover = ptr;
1154 if (nids_added == 0) {
1155 CERROR("No new nids were added, nid %s with uuid %s, "
1156 "device %s\n", libcfs_nid2str(nid),
1157 mrd->nodeuuid ? mrd->nodeuuid : "NULL",
1158 mrd->target.mti_svname);
1159 name_destroy(&mrd->nodeuuid);
1162 mrd->state = REPLACE_SETUP;
1168 if (mrd->state == REPLACE_SETUP && lcfg->lcfg_command == LCFG_SETUP) {
1169 /* LCFG_SETUP command found. UUID should be changed */
1170 rc = record_setup(env,
1172 /* devname the same */
1173 lustre_cfg_string(lcfg, 0),
1174 /* s1 is not changed */
1175 lustre_cfg_string(lcfg, 1),
1177 /* s3 is not changed */
1178 lustre_cfg_string(lcfg, 3),
1179 /* s4 is not changed */
1180 lustre_cfg_string(lcfg, 4));
1182 name_destroy(&mrd->nodeuuid);
1186 if (mrd->failover) {
1187 ptr = mrd->failover;
1188 while (class_parse_nid(ptr, &nid, &ptr) == 0) {
1189 if (mrd->nodeuuid == NULL) {
1190 rc = name_create(&mrd->nodeuuid,
1191 libcfs_nid2str(nid),
1197 CDEBUG(D_MGS, "add nid %s for failover %s\n",
1198 libcfs_nid2str(nid), mrd->nodeuuid);
1199 rc = record_add_uuid(env, mrd->temp_llh, nid,
1202 name_destroy(&mrd->nodeuuid);
1206 rc = record_add_conn(env,
1208 lustre_cfg_string(lcfg, 0),
1210 name_destroy(&mrd->nodeuuid);
1215 if (mrd->nodeuuid) {
1216 rc = record_add_conn(env, mrd->temp_llh,
1217 lustre_cfg_string(lcfg, 0),
1219 name_destroy(&mrd->nodeuuid);
1224 mrd->state = REPLACE_DONE;
1228 /* Another commands in target device block */
1233 * Handler that called for every record in llog.
1234 * Records are processed in order they placed in llog.
1236 * \param[in] llh log to be processed
1237 * \param[in] rec current record
1238 * \param[in] data mgs_replace_data structure
1242 static int mgs_replace_nids_handler(const struct lu_env *env,
1243 struct llog_handle *llh,
1244 struct llog_rec_hdr *rec,
1247 struct mgs_replace_data *mrd;
1248 struct lustre_cfg *lcfg = REC_DATA(rec);
1249 int cfg_len = REC_DATA_LEN(rec);
1253 mrd = (struct mgs_replace_data *)data;
1255 if (rec->lrh_type != OBD_CFG_REC) {
1256 CERROR("unhandled lrh_type: %#x, cmd %x %s %s\n",
1257 rec->lrh_type, lcfg->lcfg_command,
1258 lustre_cfg_string(lcfg, 0),
1259 lustre_cfg_string(lcfg, 1));
1263 rc = lustre_cfg_sanity_check(lcfg, cfg_len);
1265 /* Do not copy any invalidated records */
1266 GOTO(skip_out, rc = 0);
1269 rc = check_markers(lcfg, mrd);
1270 if (rc || mrd->state == REPLACE_SKIP)
1271 GOTO(skip_out, rc = 0);
1273 /* Write to new log all commands outside target device block */
1274 if (mrd->state == REPLACE_COPY)
1275 GOTO(copy_out, rc = 0);
1277 if (mrd->state == REPLACE_DONE &&
1278 (lcfg->lcfg_command == LCFG_ADD_UUID ||
1279 lcfg->lcfg_command == LCFG_ADD_CONN)) {
1281 CWARN("Previous failover is deleted, but new one is "
1282 "not set. This means you configure system "
1283 "without failover or passed wrong replace_nids "
1284 "command parameters. Device %s, passed nids %s\n",
1285 mrd->target.mti_svname, mrd->target.mti_params);
1286 GOTO(skip_out, rc = 0);
1289 rc = process_command(env, lcfg, mrd);
1296 /* Record is placed in temporary llog as is */
1297 rc = llog_write(env, mrd->temp_llh, rec, LLOG_NEXT_IDX);
1299 CDEBUG(D_MGS, "Copied idx=%d, rc=%d, len=%d, cmd %x %s %s\n",
1300 rec->lrh_index, rc, rec->lrh_len, lcfg->lcfg_command,
1301 lustre_cfg_string(lcfg, 0), lustre_cfg_string(lcfg, 1));
1305 CDEBUG(D_MGS, "Skipped idx=%d, rc=%d, len=%d, cmd %x %s %s\n",
1306 rec->lrh_index, rc, rec->lrh_len, lcfg->lcfg_command,
1307 lustre_cfg_string(lcfg, 0), lustre_cfg_string(lcfg, 1));
1311 static int mgs_log_is_empty(const struct lu_env *env,
1312 struct mgs_device *mgs, char *name)
1314 struct llog_ctxt *ctxt;
1317 ctxt = llog_get_context(mgs->mgs_obd, LLOG_CONFIG_ORIG_CTXT);
1318 LASSERT(ctxt != NULL);
1320 rc = llog_is_empty(env, ctxt, name);
1321 llog_ctxt_put(ctxt);
1325 static int mgs_replace_log(const struct lu_env *env,
1326 struct obd_device *mgs,
1327 char *logname, char *devname,
1328 llog_cb_t replace_handler, void *data)
1330 struct llog_handle *orig_llh, *backup_llh;
1331 struct llog_ctxt *ctxt;
1332 struct mgs_replace_data *mrd;
1333 struct mgs_device *mgs_dev = lu2mgs_dev(mgs->obd_lu_dev);
1334 static struct obd_uuid cfg_uuid = { .uuid = "config_uuid" };
1336 int rc, rc2, buf_size;
1340 ctxt = llog_get_context(mgs, LLOG_CONFIG_ORIG_CTXT);
1341 LASSERT(ctxt != NULL);
1343 if (mgs_log_is_empty(env, mgs_dev, logname)) {
1344 /* Log is empty. Nothing to replace */
1345 GOTO(out_put, rc = 0);
1348 now = ktime_get_real_seconds();
1350 /* max time64_t in decimal fits into 20 bytes long string */
1351 buf_size = strlen(logname) + 1 + 20 + 1 + strlen(".bak") + 1;
1352 OBD_ALLOC(backup, buf_size);
1354 GOTO(out_put, rc = -ENOMEM);
1356 snprintf(backup, buf_size, "%s.%llu.bak", logname, now);
1358 rc = llog_backup(env, mgs, ctxt, ctxt, logname, backup);
1360 /* Now erase original log file. Connections are not allowed.
1361 Backup is already saved */
1362 rc = llog_erase(env, ctxt, NULL, logname);
1365 } else if (rc != -ENOENT) {
1366 CERROR("%s: can't make backup for %s: rc = %d\n",
1367 mgs->obd_name, logname, rc);
1371 /* open local log */
1372 rc = llog_open_create(env, ctxt, &orig_llh, NULL, logname);
1374 GOTO(out_restore, rc);
1376 rc = llog_init_handle(env, orig_llh, LLOG_F_IS_PLAIN, &cfg_uuid);
1378 GOTO(out_closel, rc);
1380 /* open backup llog */
1381 rc = llog_open(env, ctxt, &backup_llh, NULL, backup,
1384 GOTO(out_closel, rc);
1386 rc = llog_init_handle(env, backup_llh, LLOG_F_IS_PLAIN, NULL);
1388 GOTO(out_close, rc);
1390 if (llog_get_size(backup_llh) <= 1)
1391 GOTO(out_close, rc = 0);
1395 GOTO(out_close, rc = -ENOMEM);
1396 /* devname is only needed information to replace UUID records */
1398 strlcpy(mrd->target.mti_svname, devname,
1399 sizeof(mrd->target.mti_svname));
1400 /* data is parsed in llog callback */
1402 strlcpy(mrd->target.mti_params, data,
1403 sizeof(mrd->target.mti_params));
1404 /* Copy records to this temporary llog */
1405 mrd->temp_llh = orig_llh;
1407 rc = llog_process(env, backup_llh, replace_handler,
1411 rc2 = llog_close(NULL, backup_llh);
1415 rc2 = llog_close(NULL, orig_llh);
1421 CERROR("%s: llog should be restored: rc = %d\n",
1423 rc2 = llog_backup(env, mgs, ctxt, ctxt, backup,
1426 CERROR("%s: can't restore backup %s: rc = %d\n",
1427 mgs->obd_name, logname, rc2);
1431 OBD_FREE(backup, buf_size);
1434 llog_ctxt_put(ctxt);
1437 CERROR("%s: failed to replace log %s: rc = %d\n",
1438 mgs->obd_name, logname, rc);
1443 static int mgs_replace_nids_log(const struct lu_env *env,
1444 struct obd_device *obd,
1445 char *logname, char *devname, char *nids)
1447 CDEBUG(D_MGS, "Replace NIDs for %s in %s\n", devname, logname);
1448 return mgs_replace_log(env, obd, logname, devname,
1449 mgs_replace_nids_handler, nids);
1453 * Parse device name and get file system name and/or device index
1455 * @devname device name (ex. lustre-MDT0000)
1456 * @fsname file system name extracted from @devname and returned
1457 * to the caller (optional)
1458 * @index device index extracted from @devname and returned to
1459 * the caller (optional)
1461 * RETURN 0 success if we are only interested in
1462 * extracting fsname from devname.
1465 * LDD_F_SV_TYPE_* Besides extracting the fsname the
1466 * user also wants the index. Report to
1467 * the user the type of obd device the
1468 * returned index belongs too.
1470 * -EINVAL The obd device name is improper so
1471 * fsname could not be extracted.
1473 * -ENXIO Failed to extract the index out of
1474 * the obd device name. Most likely an
1475 * invalid obd device name
1477 static int mgs_parse_devname(char *devname, char *fsname, u32 *index)
1482 /* Extract fsname */
1484 rc = server_name2fsname(devname, fsname, NULL);
1486 CDEBUG(D_MGS, "Device name %s without fsname\n",
1493 rc = server_name2index(devname, index, NULL);
1495 CDEBUG(D_MGS, "Device name %s with wrong index\n",
1501 /* server_name2index can return LDD_F_SV_TYPE_* so always return rc */
1505 /* This is only called during replace_nids */
1506 static int only_mgs_is_running(struct obd_device *mgs_obd)
1508 /* TDB: Is global variable with devices count exists? */
1509 int num_devices = get_devices_count();
1510 int num_exports = 0;
1511 struct obd_export *exp;
1513 spin_lock(&mgs_obd->obd_dev_lock);
1514 list_for_each_entry(exp, &mgs_obd->obd_exports, exp_obd_chain) {
1515 /* skip self export */
1516 if (exp == mgs_obd->obd_self_export)
1518 if (exp_connect_flags(exp) & OBD_CONNECT_MDS_MDS)
1523 CERROR("%s: node %s still connected during replace_nids "
1524 "connect_flags:%llx\n",
1526 libcfs_nid2str(exp->exp_nid_stats->nid),
1527 exp_connect_flags(exp));
1530 spin_unlock(&mgs_obd->obd_dev_lock);
1532 /* osd, MGS and MGC + self_export
1533 (wc -l /proc/fs/lustre/devices <= 2) && (non self exports == 0) */
1534 return (num_devices <= 3) && (num_exports == 0);
1537 static int name_create_mdt(char **logname, char *fsname, int mdt_idx)
1541 if (mdt_idx > INDEX_MAP_MAX_VALUE)
1544 snprintf(postfix, sizeof(postfix), "-MDT%04x", mdt_idx);
1545 return name_create(logname, fsname, postfix);
1549 * Replace nids for \a device to \a nids values
1551 * \param obd MGS obd device
1552 * \param devname nids need to be replaced for this device
1553 * (ex. lustre-OST0000)
1554 * \param nids nids list (ex. nid1,nid2,nid3)
1558 int mgs_replace_nids(const struct lu_env *env,
1559 struct mgs_device *mgs,
1560 char *devname, char *nids)
1562 /* Assume fsname is part of device name */
1563 char fsname[MTI_NAME_MAXLEN];
1567 struct fs_db *fsdb = NULL;
1570 struct obd_device *mgs_obd = mgs->mgs_obd;
1573 /* We can only change NIDs if no other nodes are connected */
1574 spin_lock(&mgs_obd->obd_dev_lock);
1575 conn_state = mgs_obd->obd_no_conn;
1576 mgs_obd->obd_no_conn = 1;
1577 spin_unlock(&mgs_obd->obd_dev_lock);
1579 /* We can not change nids if not only MGS is started */
1580 if (!only_mgs_is_running(mgs_obd)) {
1581 CERROR("Only MGS is allowed to be started\n");
1582 GOTO(out, rc = -EINPROGRESS);
1585 /* Get fsname and index */
1586 rc = mgs_parse_devname(devname, fsname, &index);
1590 rc = mgs_find_or_make_fsdb(env, mgs, fsname, &fsdb);
1592 CERROR("%s: can't find fsdb: rc = %d\n", fsname, rc);
1596 /* Process client llogs */
1597 name_create(&logname, fsname, "-client");
1598 rc = mgs_replace_nids_log(env, mgs_obd, logname, devname, nids);
1599 name_destroy(&logname);
1601 CERROR("%s: error while replacing NIDs for %s: rc = %d\n",
1602 fsname, devname, rc);
1606 /* Process MDT llogs */
1607 for (i = 0; i < INDEX_MAP_SIZE * 8; i++) {
1608 if (!test_bit(i, fsdb->fsdb_mdt_index_map))
1610 name_create_mdt(&logname, fsname, i);
1611 rc = mgs_replace_nids_log(env, mgs_obd, logname, devname, nids);
1612 name_destroy(&logname);
1618 spin_lock(&mgs_obd->obd_dev_lock);
1619 mgs_obd->obd_no_conn = conn_state;
1620 spin_unlock(&mgs_obd->obd_dev_lock);
1623 mgs_put_fsdb(mgs, fsdb);
1629 * This is called for every record in llog. Some of records are
1630 * skipped, others are copied to new log as is.
1631 * Records to be skipped are
1632 * marker records marked SKIP
1633 * records enclosed between SKIP markers
1635 * \param[in] llh log to be processed
1636 * \param[in] rec current record
1637 * \param[in] data mgs_replace_data structure
1641 static int mgs_clear_config_handler(const struct lu_env *env,
1642 struct llog_handle *llh,
1643 struct llog_rec_hdr *rec, void *data)
1645 struct mgs_replace_data *mrd;
1646 struct lustre_cfg *lcfg = REC_DATA(rec);
1647 int cfg_len = REC_DATA_LEN(rec);
1652 mrd = (struct mgs_replace_data *)data;
1654 if (rec->lrh_type != OBD_CFG_REC) {
1655 CDEBUG(D_MGS, "Config llog Name=%s, Record Index=%u, "
1656 "Unhandled Record Type=%#x\n", llh->lgh_name,
1657 rec->lrh_index, rec->lrh_type);
1661 rc = lustre_cfg_sanity_check(lcfg, cfg_len);
1663 CDEBUG(D_MGS, "Config llog Name=%s, Invalid config file.",
1668 if (lcfg->lcfg_command == LCFG_MARKER) {
1669 struct cfg_marker *marker;
1671 marker = lustre_cfg_buf(lcfg, 1);
1672 if (marker->cm_flags & CM_SKIP) {
1673 if (marker->cm_flags & CM_START)
1674 mrd->state = REPLACE_SKIP;
1675 if (marker->cm_flags & CM_END)
1676 mrd->state = REPLACE_COPY;
1677 /* SKIP section started or finished */
1678 CDEBUG(D_MGS, "Skip idx=%d, rc=%d, len=%d, "
1679 "cmd %x %s %s\n", rec->lrh_index, rc,
1680 rec->lrh_len, lcfg->lcfg_command,
1681 lustre_cfg_string(lcfg, 0),
1682 lustre_cfg_string(lcfg, 1));
1686 if (mrd->state == REPLACE_SKIP) {
1687 /* record enclosed between SKIP markers, skip it */
1688 CDEBUG(D_MGS, "Skip idx=%d, rc=%d, len=%d, "
1689 "cmd %x %s %s\n", rec->lrh_index, rc,
1690 rec->lrh_len, lcfg->lcfg_command,
1691 lustre_cfg_string(lcfg, 0),
1692 lustre_cfg_string(lcfg, 1));
1697 /* Record is placed in temporary llog as is */
1698 rc = llog_write(env, mrd->temp_llh, rec, LLOG_NEXT_IDX);
1700 CDEBUG(D_MGS, "Copied idx=%d, rc=%d, len=%d, cmd %x %s %s\n",
1701 rec->lrh_index, rc, rec->lrh_len, lcfg->lcfg_command,
1702 lustre_cfg_string(lcfg, 0), lustre_cfg_string(lcfg, 1));
1707 * Directory CONFIGS/ may contain files which are not config logs to
1708 * be cleared. Skip any llogs with a non-alphanumeric character after
1709 * the last '-'. For example, fsname-MDT0000.sav, fsname-MDT0000.bak,
1710 * fsname-MDT0000.orig, fsname-MDT0000~, fsname-MDT0000.20150516, etc.
1712 static bool config_to_clear(const char *logname)
1717 str = strrchr(logname, '-');
1722 while (isalnum(str[++i]));
1723 return str[i] == '\0';
1727 * Clear config logs for \a name
1730 * \param mgs MGS device
1731 * \param name name of device or of filesystem
1732 * (ex. lustre-OST0000 or lustre) in later case all logs
1737 int mgs_clear_configs(const struct lu_env *env,
1738 struct mgs_device *mgs, const char *name)
1740 struct list_head dentry_list;
1741 struct mgs_direntry *dirent, *n;
1744 struct obd_device *mgs_obd = mgs->mgs_obd;
1749 /* Prevent clients and servers from connecting to mgs */
1750 spin_lock(&mgs_obd->obd_dev_lock);
1751 conn_state = mgs_obd->obd_no_conn;
1752 mgs_obd->obd_no_conn = 1;
1753 spin_unlock(&mgs_obd->obd_dev_lock);
1756 * config logs cannot be cleaned if anything other than
1759 if (!only_mgs_is_running(mgs_obd)) {
1760 CERROR("Only MGS is allowed to be started\n");
1761 GOTO(out, rc = -EBUSY);
1764 /* Find all the logs in the CONFIGS directory */
1765 rc = class_dentry_readdir(env, mgs, &dentry_list);
1767 CERROR("%s: cannot read config directory '%s': rc = %d\n",
1768 mgs_obd->obd_name, MOUNT_CONFIGS_DIR, rc);
1772 if (list_empty(&dentry_list)) {
1773 CERROR("%s: list empty reading config dir '%s': rc = %d\n",
1774 mgs_obd->obd_name, MOUNT_CONFIGS_DIR, -ENOENT);
1775 GOTO(out, rc = -ENOENT);
1778 OBD_ALLOC(namedash, strlen(name) + 2);
1779 if (namedash == NULL)
1780 GOTO(out, rc = -ENOMEM);
1781 snprintf(namedash, strlen(name) + 2, "%s-", name);
1783 list_for_each_entry(dirent, &dentry_list, mde_list) {
1784 if (strcmp(name, dirent->mde_name) &&
1785 strncmp(namedash, dirent->mde_name, strlen(namedash)))
1787 if (!config_to_clear(dirent->mde_name))
1789 CDEBUG(D_MGS, "%s: Clear config log %s\n",
1790 mgs_obd->obd_name, dirent->mde_name);
1791 rc = mgs_replace_log(env, mgs_obd, dirent->mde_name, NULL,
1792 mgs_clear_config_handler, NULL);
1797 list_for_each_entry_safe(dirent, n, &dentry_list, mde_list) {
1798 list_del_init(&dirent->mde_list);
1799 mgs_direntry_free(dirent);
1801 OBD_FREE(namedash, strlen(name) + 2);
1803 spin_lock(&mgs_obd->obd_dev_lock);
1804 mgs_obd->obd_no_conn = conn_state;
1805 spin_unlock(&mgs_obd->obd_dev_lock);
1810 static int record_lov_setup(const struct lu_env *env, struct llog_handle *llh,
1811 char *devname, struct lov_desc *desc)
1813 struct mgs_thread_info *mgi = mgs_env_info(env);
1814 struct llog_cfg_rec *lcr;
1817 lustre_cfg_bufs_reset(&mgi->mgi_bufs, devname);
1818 lustre_cfg_bufs_set(&mgi->mgi_bufs, 1, desc, sizeof(*desc));
1819 lcr = lustre_cfg_rec_new(LCFG_SETUP, &mgi->mgi_bufs);
1823 rc = llog_write(env, llh, &lcr->lcr_hdr, LLOG_NEXT_IDX);
1824 lustre_cfg_rec_free(lcr);
1828 static int record_lmv_setup(const struct lu_env *env, struct llog_handle *llh,
1829 char *devname, struct lmv_desc *desc)
1831 struct mgs_thread_info *mgi = mgs_env_info(env);
1832 struct llog_cfg_rec *lcr;
1835 lustre_cfg_bufs_reset(&mgi->mgi_bufs, devname);
1836 lustre_cfg_bufs_set(&mgi->mgi_bufs, 1, desc, sizeof(*desc));
1837 lcr = lustre_cfg_rec_new(LCFG_SETUP, &mgi->mgi_bufs);
1841 rc = llog_write(env, llh, &lcr->lcr_hdr, LLOG_NEXT_IDX);
1842 lustre_cfg_rec_free(lcr);
1846 static inline int record_mdc_add(const struct lu_env *env,
1847 struct llog_handle *llh,
1848 char *logname, char *mdcuuid,
1849 char *mdtuuid, char *index,
1852 return record_base(env,llh,logname,0,LCFG_ADD_MDC,
1853 mdtuuid,index,gen,mdcuuid);
1856 static inline int record_lov_add(const struct lu_env *env,
1857 struct llog_handle *llh,
1858 char *lov_name, char *ost_uuid,
1859 char *index, char *gen)
1861 return record_base(env, llh, lov_name, 0, LCFG_LOV_ADD_OBD,
1862 ost_uuid, index, gen, NULL);
1865 static inline int record_mount_opt(const struct lu_env *env,
1866 struct llog_handle *llh,
1867 char *profile, char *lov_name,
1870 return record_base(env, llh, NULL, 0, LCFG_MOUNTOPT,
1871 profile, lov_name, mdc_name, NULL);
1874 static int record_marker(const struct lu_env *env,
1875 struct llog_handle *llh,
1876 struct fs_db *fsdb, __u32 flags,
1877 char *tgtname, char *comment)
1879 struct mgs_thread_info *mgi = mgs_env_info(env);
1880 struct llog_cfg_rec *lcr;
1884 if (flags & CM_START)
1886 mgi->mgi_marker.cm_step = fsdb->fsdb_gen;
1887 mgi->mgi_marker.cm_flags = flags;
1888 mgi->mgi_marker.cm_vers = LUSTRE_VERSION_CODE;
1889 cplen = strlcpy(mgi->mgi_marker.cm_tgtname, tgtname,
1890 sizeof(mgi->mgi_marker.cm_tgtname));
1891 if (cplen >= sizeof(mgi->mgi_marker.cm_tgtname))
1893 cplen = strlcpy(mgi->mgi_marker.cm_comment, comment,
1894 sizeof(mgi->mgi_marker.cm_comment));
1895 if (cplen >= sizeof(mgi->mgi_marker.cm_comment))
1897 mgi->mgi_marker.cm_createtime = ktime_get_real_seconds();
1898 mgi->mgi_marker.cm_canceltime = 0;
1899 lustre_cfg_bufs_reset(&mgi->mgi_bufs, NULL);
1900 lustre_cfg_bufs_set(&mgi->mgi_bufs, 1, &mgi->mgi_marker,
1901 sizeof(mgi->mgi_marker));
1902 lcr = lustre_cfg_rec_new(LCFG_MARKER, &mgi->mgi_bufs);
1906 rc = llog_write(env, llh, &lcr->lcr_hdr, LLOG_NEXT_IDX);
1907 lustre_cfg_rec_free(lcr);
1911 static int record_start_log(const struct lu_env *env, struct mgs_device *mgs,
1912 struct llog_handle **llh, char *name)
1914 static struct obd_uuid cfg_uuid = { .uuid = "config_uuid" };
1915 struct llog_ctxt *ctxt;
1920 GOTO(out, rc = -EBUSY);
1922 ctxt = llog_get_context(mgs->mgs_obd, LLOG_CONFIG_ORIG_CTXT);
1924 GOTO(out, rc = -ENODEV);
1925 LASSERT(ctxt->loc_obd == mgs->mgs_obd);
1927 rc = llog_open_create(env, ctxt, llh, NULL, name);
1930 rc = llog_init_handle(env, *llh, LLOG_F_IS_PLAIN, &cfg_uuid);
1932 llog_close(env, *llh);
1934 llog_ctxt_put(ctxt);
1937 CERROR("%s: can't start log %s: rc = %d\n",
1938 mgs->mgs_obd->obd_name, name, rc);
1944 static int record_end_log(const struct lu_env *env, struct llog_handle **llh)
1948 rc = llog_close(env, *llh);
1954 /******************** config "macros" *********************/
1956 /* write an lcfg directly into a log (with markers) */
1957 static int mgs_write_log_direct(const struct lu_env *env,
1958 struct mgs_device *mgs, struct fs_db *fsdb,
1959 char *logname, struct llog_cfg_rec *lcr,
1960 char *devname, char *comment)
1962 struct llog_handle *llh = NULL;
1967 rc = record_start_log(env, mgs, &llh, logname);
1971 /* FIXME These should be a single journal transaction */
1972 rc = record_marker(env, llh, fsdb, CM_START, devname, comment);
1975 rc = llog_write(env, llh, &lcr->lcr_hdr, LLOG_NEXT_IDX);
1978 rc = record_marker(env, llh, fsdb, CM_END, devname, comment);
1982 record_end_log(env, &llh);
1986 /* write the lcfg in all logs for the given fs */
1987 static int mgs_write_log_direct_all(const struct lu_env *env,
1988 struct mgs_device *mgs,
1990 struct mgs_target_info *mti,
1991 struct llog_cfg_rec *lcr, char *devname,
1992 char *comment, int server_only)
1994 struct list_head log_list;
1995 struct mgs_direntry *dirent, *n;
1996 char *fsname = mti->mti_fsname;
1997 int rc = 0, len = strlen(fsname);
2000 /* Find all the logs in the CONFIGS directory */
2001 rc = class_dentry_readdir(env, mgs, &log_list);
2005 /* Could use fsdb index maps instead of directory listing */
2006 list_for_each_entry_safe(dirent, n, &log_list, mde_list) {
2007 list_del_init(&dirent->mde_list);
2008 /* don't write to sptlrpc rule log */
2009 if (strstr(dirent->mde_name, "-sptlrpc") != NULL)
2012 /* caller wants write server logs only */
2013 if (server_only && strstr(dirent->mde_name, "-client") != NULL)
2016 if (strlen(dirent->mde_name) <= len ||
2017 strncmp(fsname, dirent->mde_name, len) != 0 ||
2018 dirent->mde_name[len] != '-')
2021 CDEBUG(D_MGS, "Changing log %s\n", dirent->mde_name);
2022 /* Erase any old settings of this same parameter */
2023 rc = mgs_modify(env, mgs, fsdb, mti, dirent->mde_name,
2024 devname, comment, CM_SKIP);
2026 CERROR("%s: Can't modify llog %s: rc = %d\n",
2027 mgs->mgs_obd->obd_name, dirent->mde_name, rc);
2030 /* Write the new one */
2031 rc = mgs_write_log_direct(env, mgs, fsdb, dirent->mde_name,
2032 lcr, devname, comment);
2034 CERROR("%s: writing log %s: rc = %d\n",
2035 mgs->mgs_obd->obd_name, dirent->mde_name, rc);
2037 mgs_direntry_free(dirent);
2043 static int mgs_write_log_osp_to_mdt(const struct lu_env *env,
2044 struct mgs_device *mgs,
2046 struct mgs_target_info *mti,
2047 int index, char *logname);
2048 static int mgs_write_log_osc_to_lov(const struct lu_env *env,
2049 struct mgs_device *mgs,
2051 struct mgs_target_info *mti,
2052 char *logname, char *suffix, char *lovname,
2053 enum lustre_sec_part sec_part, int flags);
2054 static int name_create_mdt_and_lov(char **logname, char **lovname,
2055 struct fs_db *fsdb, int i);
2057 static int add_param(char *params, char *key, char *val)
2059 char *start = params + strlen(params);
2060 char *end = params + sizeof(((struct mgs_target_info *)0)->mti_params);
2064 keylen = strlen(key);
2065 if (start + 1 + keylen + strlen(val) >= end) {
2066 CERROR("params are too long: %s %s%s\n",
2067 params, key != NULL ? key : "", val);
2071 sprintf(start, " %s%s", key != NULL ? key : "", val);
2076 * Walk through client config log record and convert the related records
2079 static int mgs_steal_client_llog_handler(const struct lu_env *env,
2080 struct llog_handle *llh,
2081 struct llog_rec_hdr *rec, void *data)
2083 struct mgs_device *mgs;
2084 struct obd_device *obd;
2085 struct mgs_target_info *mti, *tmti;
2087 int cfg_len = rec->lrh_len;
2088 char *cfg_buf = (char*) (rec + 1);
2089 struct lustre_cfg *lcfg;
2091 struct llog_handle *mdt_llh = NULL;
2092 static int got_an_osc_or_mdc = 0;
2093 /* 0: not found any osc/mdc;
2097 static int last_step = -1;
2102 mti = ((struct temp_comp*)data)->comp_mti;
2103 tmti = ((struct temp_comp*)data)->comp_tmti;
2104 fsdb = ((struct temp_comp*)data)->comp_fsdb;
2105 obd = ((struct temp_comp *)data)->comp_obd;
2106 mgs = lu2mgs_dev(obd->obd_lu_dev);
2109 if (rec->lrh_type != OBD_CFG_REC) {
2110 CERROR("unhandled lrh_type: %#x\n", rec->lrh_type);
2114 rc = lustre_cfg_sanity_check(cfg_buf, cfg_len);
2116 CERROR("Insane cfg\n");
2120 lcfg = (struct lustre_cfg *)cfg_buf;
2122 if (lcfg->lcfg_command == LCFG_MARKER) {
2123 struct cfg_marker *marker;
2124 marker = lustre_cfg_buf(lcfg, 1);
2125 if (!strncmp(marker->cm_comment, "add osc", 7) &&
2126 (marker->cm_flags & CM_START) &&
2127 !(marker->cm_flags & CM_SKIP)) {
2128 got_an_osc_or_mdc = 1;
2129 cplen = strlcpy(tmti->mti_svname, marker->cm_tgtname,
2130 sizeof(tmti->mti_svname));
2131 if (cplen >= sizeof(tmti->mti_svname))
2133 rc = record_start_log(env, mgs, &mdt_llh,
2137 rc = record_marker(env, mdt_llh, fsdb, CM_START,
2138 mti->mti_svname, "add osc(copied)");
2139 record_end_log(env, &mdt_llh);
2140 last_step = marker->cm_step;
2143 if (!strncmp(marker->cm_comment, "add osc", 7) &&
2144 (marker->cm_flags & CM_END) &&
2145 !(marker->cm_flags & CM_SKIP)) {
2146 LASSERT(last_step == marker->cm_step);
2148 got_an_osc_or_mdc = 0;
2149 memset(tmti, 0, sizeof(*tmti));
2150 rc = record_start_log(env, mgs, &mdt_llh,
2154 rc = record_marker(env, mdt_llh, fsdb, CM_END,
2155 mti->mti_svname, "add osc(copied)");
2156 record_end_log(env, &mdt_llh);
2159 if (!strncmp(marker->cm_comment, "add mdc", 7) &&
2160 (marker->cm_flags & CM_START) &&
2161 !(marker->cm_flags & CM_SKIP)) {
2162 got_an_osc_or_mdc = 2;
2163 last_step = marker->cm_step;
2164 memcpy(tmti->mti_svname, marker->cm_tgtname,
2165 strlen(marker->cm_tgtname));
2169 if (!strncmp(marker->cm_comment, "add mdc", 7) &&
2170 (marker->cm_flags & CM_END) &&
2171 !(marker->cm_flags & CM_SKIP)) {
2172 LASSERT(last_step == marker->cm_step);
2174 got_an_osc_or_mdc = 0;
2175 memset(tmti, 0, sizeof(*tmti));
2180 if (got_an_osc_or_mdc == 0 || last_step < 0)
2183 if (lcfg->lcfg_command == LCFG_ADD_UUID) {
2184 __u64 nodenid = lcfg->lcfg_nid;
2186 if (strlen(tmti->mti_uuid) == 0) {
2187 /* target uuid not set, this config record is before
2188 * LCFG_SETUP, this nid is one of target node nid.
2190 tmti->mti_nids[tmti->mti_nid_count] = nodenid;
2191 tmti->mti_nid_count++;
2193 char nidstr[LNET_NIDSTR_SIZE];
2195 /* failover node nid */
2196 libcfs_nid2str_r(nodenid, nidstr, sizeof(nidstr));
2197 rc = add_param(tmti->mti_params, PARAM_FAILNODE,
2204 if (lcfg->lcfg_command == LCFG_SETUP) {
2207 target = lustre_cfg_string(lcfg, 1);
2208 memcpy(tmti->mti_uuid, target, strlen(target));
2212 /* ignore client side sptlrpc_conf_log */
2213 if (lcfg->lcfg_command == LCFG_SPTLRPC_CONF)
2216 if (lcfg->lcfg_command == LCFG_ADD_MDC &&
2217 strstr(lustre_cfg_string(lcfg, 0), "-clilmv") != NULL) {
2220 if (sscanf(lustre_cfg_buf(lcfg, 2), "%d", &index) != 1)
2223 memcpy(tmti->mti_fsname, mti->mti_fsname,
2224 strlen(mti->mti_fsname));
2225 tmti->mti_stripe_index = index;
2227 rc = mgs_write_log_osp_to_mdt(env, mgs, fsdb, tmti,
2228 mti->mti_stripe_index,
2230 memset(tmti, 0, sizeof(*tmti));
2234 if (lcfg->lcfg_command == LCFG_LOV_ADD_OBD) {
2237 char *logname, *lovname;
2239 rc = name_create_mdt_and_lov(&logname, &lovname, fsdb,
2240 mti->mti_stripe_index);
2243 sprintf(mdt_index, "-MDT%04x", mti->mti_stripe_index);
2245 if (sscanf(lustre_cfg_buf(lcfg, 2), "%d", &index) != 1) {
2246 name_destroy(&logname);
2247 name_destroy(&lovname);
2251 tmti->mti_stripe_index = index;
2252 rc = mgs_write_log_osc_to_lov(env, mgs, fsdb, tmti, logname,
2255 name_destroy(&logname);
2256 name_destroy(&lovname);
2262 /* fsdb->fsdb_mutex is already held in mgs_write_log_target*/
2263 /* stealed from mgs_get_fsdb_from_llog*/
2264 static int mgs_steal_llog_for_mdt_from_client(const struct lu_env *env,
2265 struct mgs_device *mgs,
2267 struct temp_comp* comp)
2269 struct llog_handle *loghandle;
2270 struct mgs_target_info *tmti;
2271 struct llog_ctxt *ctxt;
2276 ctxt = llog_get_context(mgs->mgs_obd, LLOG_CONFIG_ORIG_CTXT);
2277 LASSERT(ctxt != NULL);
2279 OBD_ALLOC_PTR(tmti);
2281 GOTO(out_ctxt, rc = -ENOMEM);
2283 comp->comp_tmti = tmti;
2284 comp->comp_obd = mgs->mgs_obd;
2286 rc = llog_open(env, ctxt, &loghandle, NULL, client_name,
2294 rc = llog_init_handle(env, loghandle, LLOG_F_IS_PLAIN, NULL);
2296 GOTO(out_close, rc);
2298 rc = llog_process_or_fork(env, loghandle, mgs_steal_client_llog_handler,
2299 (void *)comp, NULL, false);
2300 CDEBUG(D_MGS, "steal llog re = %d\n", rc);
2302 llog_close(env, loghandle);
2306 llog_ctxt_put(ctxt);
2310 /* lmv is the second thing for client logs */
2311 /* copied from mgs_write_log_lov. Please refer to that. */
2312 static int mgs_write_log_lmv(const struct lu_env *env,
2313 struct mgs_device *mgs,
2315 struct mgs_target_info *mti,
2316 char *logname, char *lmvname)
2318 struct llog_handle *llh = NULL;
2319 struct lmv_desc *lmvdesc;
2324 CDEBUG(D_MGS, "Writing lmv(%s) log for %s\n", lmvname,logname);
2326 OBD_ALLOC_PTR(lmvdesc);
2327 if (lmvdesc == NULL)
2329 lmvdesc->ld_active_tgt_count = 0;
2330 lmvdesc->ld_tgt_count = 0;
2331 sprintf((char*)lmvdesc->ld_uuid.uuid, "%s_UUID", lmvname);
2332 uuid = (char *)lmvdesc->ld_uuid.uuid;
2334 rc = record_start_log(env, mgs, &llh, logname);
2337 rc = record_marker(env, llh, fsdb, CM_START, lmvname, "lmv setup");
2340 rc = record_attach(env, llh, lmvname, "lmv", uuid);
2343 rc = record_lmv_setup(env, llh, lmvname, lmvdesc);
2346 rc = record_marker(env, llh, fsdb, CM_END, lmvname, "lmv setup");
2350 record_end_log(env, &llh);
2352 OBD_FREE_PTR(lmvdesc);
2356 /* lov is the first thing in the mdt and client logs */
2357 static int mgs_write_log_lov(const struct lu_env *env, struct mgs_device *mgs,
2358 struct fs_db *fsdb, struct mgs_target_info *mti,
2359 char *logname, char *lovname)
2361 struct llog_handle *llh = NULL;
2362 struct lov_desc *lovdesc;
2367 CDEBUG(D_MGS, "Writing lov(%s) log for %s\n", lovname, logname);
2370 #01 L attach 0:lov_mdsA 1:lov 2:71ccb_lov_mdsA_19f961a9e1
2371 #02 L lov_setup 0:lov_mdsA 1:(struct lov_desc)
2372 uuid=lov1_UUID, stripe count=1, size=1048576, offset=0, pattern=0
2375 /* FIXME just make lov_setup accept empty desc (put uuid in buf 2) */
2376 OBD_ALLOC_PTR(lovdesc);
2377 if (lovdesc == NULL)
2379 lovdesc->ld_magic = LOV_DESC_MAGIC;
2380 lovdesc->ld_tgt_count = 0;
2381 /* Defaults. Can be changed later by lcfg config_param */
2382 lovdesc->ld_default_stripe_count = 1;
2383 lovdesc->ld_pattern = LOV_PATTERN_RAID0;
2384 lovdesc->ld_default_stripe_size = LOV_DESC_STRIPE_SIZE_DEFAULT;
2385 lovdesc->ld_default_stripe_offset = -1;
2386 lovdesc->ld_qos_maxage = LOV_DESC_QOS_MAXAGE_DEFAULT;
2387 sprintf((char*)lovdesc->ld_uuid.uuid, "%s_UUID", lovname);
2388 /* can these be the same? */
2389 uuid = (char *)lovdesc->ld_uuid.uuid;
2391 /* This should always be the first entry in a log.
2392 rc = mgs_clear_log(obd, logname); */
2393 rc = record_start_log(env, mgs, &llh, logname);
2396 /* FIXME these should be a single journal transaction */
2397 rc = record_marker(env, llh, fsdb, CM_START, lovname, "lov setup");
2400 rc = record_attach(env, llh, lovname, "lov", uuid);
2403 rc = record_lov_setup(env, llh, lovname, lovdesc);
2406 rc = record_marker(env, llh, fsdb, CM_END, lovname, "lov setup");
2411 record_end_log(env, &llh);
2413 OBD_FREE_PTR(lovdesc);
2417 /* add failnids to open log */
2418 static int mgs_write_log_failnids(const struct lu_env *env,
2419 struct mgs_target_info *mti,
2420 struct llog_handle *llh,
2423 char *failnodeuuid = NULL;
2424 char *ptr = mti->mti_params;
2429 #03 L add_uuid nid=uml1@tcp(0x20000c0a80201) nal=90 0: 1:uml1_UUID
2430 #04 L add_uuid nid=1@elan(0x1000000000001) nal=90 0: 1:uml1_UUID
2431 #05 L setup 0:OSC_uml1_ost1_mdsA 1:ost1_UUID 2:uml1_UUID
2432 #06 L add_uuid nid=uml2@tcp(0x20000c0a80202) nal=90 0: 1:uml2_UUID
2433 #0x L add_uuid nid=2@elan(0x1000000000002) nal=90 0: 1:uml2_UUID
2434 #07 L add_conn 0:OSC_uml1_ost1_mdsA 1:uml2_UUID
2438 * Pull failnid info out of params string, which may contain something
2439 * like "<nid1>,<nid2>:<nid3>,<nid4>". class_parse_nid() does not
2440 * complain about abnormal inputs like ",:<nid1>", "<nid1>:,<nid2>",
2441 * etc. However, convert_hostnames() should have caught those.
2443 while (class_find_param(ptr, PARAM_FAILNODE, &ptr) == 0) {
2444 while (class_parse_nid(ptr, &nid, &ptr) == 0) {
2445 char nidstr[LNET_NIDSTR_SIZE];
2447 if (failnodeuuid == NULL) {
2448 /* We don't know the failover node name,
2449 * so just use the first nid as the uuid */
2450 libcfs_nid2str_r(nid, nidstr, sizeof(nidstr));
2451 rc = name_create(&failnodeuuid, nidstr, "");
2455 CDEBUG(D_MGS, "add nid %s for failover uuid %s, "
2457 libcfs_nid2str_r(nid, nidstr, sizeof(nidstr)),
2458 failnodeuuid, cliname);
2459 rc = record_add_uuid(env, llh, nid, failnodeuuid);
2461 * If *ptr is ':', we have added all NIDs for
2465 rc = record_add_conn(env, llh, cliname,
2467 name_destroy(&failnodeuuid);
2468 failnodeuuid = NULL;
2472 rc = record_add_conn(env, llh, cliname, failnodeuuid);
2473 name_destroy(&failnodeuuid);
2474 failnodeuuid = NULL;
2481 static int mgs_write_log_mdc_to_lmv(const struct lu_env *env,
2482 struct mgs_device *mgs,
2484 struct mgs_target_info *mti,
2485 char *logname, char *lmvname)
2487 struct llog_handle *llh = NULL;
2488 char *mdcname = NULL;
2489 char *nodeuuid = NULL;
2490 char *mdcuuid = NULL;
2491 char *lmvuuid = NULL;
2493 char nidstr[LNET_NIDSTR_SIZE];
2497 if (mgs_log_is_empty(env, mgs, logname)) {
2498 CERROR("log is empty! Logical error\n");
2502 CDEBUG(D_MGS, "adding mdc for %s to log %s:lmv(%s)\n",
2503 mti->mti_svname, logname, lmvname);
2505 libcfs_nid2str_r(mti->mti_nids[0], nidstr, sizeof(nidstr));
2506 rc = name_create(&nodeuuid, nidstr, "");
2509 rc = name_create(&mdcname, mti->mti_svname, "-mdc");
2512 rc = name_create(&mdcuuid, mdcname, "_UUID");
2515 rc = name_create(&lmvuuid, lmvname, "_UUID");
2519 rc = record_start_log(env, mgs, &llh, logname);
2522 rc = record_marker(env, llh, fsdb, CM_START, mti->mti_svname,
2526 for (i = 0; i < mti->mti_nid_count; i++) {
2527 CDEBUG(D_MGS, "add nid %s for mdt\n",
2528 libcfs_nid2str_r(mti->mti_nids[i],
2529 nidstr, sizeof(nidstr)));
2531 rc = record_add_uuid(env, llh, mti->mti_nids[i], nodeuuid);
2536 rc = record_attach(env, llh, mdcname, LUSTRE_MDC_NAME, lmvuuid);
2539 rc = record_setup(env, llh, mdcname, mti->mti_uuid, nodeuuid,
2543 rc = mgs_write_log_failnids(env, mti, llh, mdcname);
2546 snprintf(index, sizeof(index), "%d", mti->mti_stripe_index);
2547 rc = record_mdc_add(env, llh, lmvname, mdcuuid, mti->mti_uuid,
2551 rc = record_marker(env, llh, fsdb, CM_END, mti->mti_svname,
2556 record_end_log(env, &llh);
2558 name_destroy(&lmvuuid);
2559 name_destroy(&mdcuuid);
2560 name_destroy(&mdcname);
2561 name_destroy(&nodeuuid);
2565 static inline int name_create_lov(char **lovname, char *mdtname,
2566 struct fs_db *fsdb, int index)
2569 if (index == 0 && test_bit(FSDB_OSCNAME18, &fsdb->fsdb_flags))
2570 return name_create(lovname, fsdb->fsdb_name, "-mdtlov");
2572 return name_create(lovname, mdtname, "-mdtlov");
2575 static int name_create_mdt_and_lov(char **logname, char **lovname,
2576 struct fs_db *fsdb, int i)
2580 rc = name_create_mdt(logname, fsdb->fsdb_name, i);
2584 if (i == 0 && test_bit(FSDB_OSCNAME18, &fsdb->fsdb_flags))
2585 rc = name_create(lovname, fsdb->fsdb_name, "-mdtlov");
2587 rc = name_create(lovname, *logname, "-mdtlov");
2589 name_destroy(logname);
2595 static inline int name_create_mdt_osc(char **oscname, char *ostname,
2596 struct fs_db *fsdb, int i)
2600 if (i == 0 && test_bit(FSDB_OSCNAME18, &fsdb->fsdb_flags))
2601 sprintf(suffix, "-osc");
2603 sprintf(suffix, "-osc-MDT%04x", i);
2604 return name_create(oscname, ostname, suffix);
2607 /* add new mdc to already existent MDS */
2608 static int mgs_write_log_osp_to_mdt(const struct lu_env *env,
2609 struct mgs_device *mgs,
2611 struct mgs_target_info *mti,
2612 int mdt_index, char *logname)
2614 struct llog_handle *llh = NULL;
2615 char *nodeuuid = NULL;
2616 char *ospname = NULL;
2617 char *lovuuid = NULL;
2618 char *mdtuuid = NULL;
2619 char *svname = NULL;
2620 char *mdtname = NULL;
2621 char *lovname = NULL;
2623 char nidstr[LNET_NIDSTR_SIZE];
2627 if (mgs_log_is_empty(env, mgs, mti->mti_svname)) {
2628 CERROR("log is empty! Logical error\n");
2632 CDEBUG(D_MGS, "adding osp index %d to %s\n", mti->mti_stripe_index,
2635 rc = name_create_mdt(&mdtname, fsdb->fsdb_name, mti->mti_stripe_index);
2639 libcfs_nid2str_r(mti->mti_nids[0], nidstr, sizeof(nidstr));
2640 rc = name_create(&nodeuuid, nidstr, "");
2642 GOTO(out_destory, rc);
2644 rc = name_create(&svname, mdtname, "-osp");
2646 GOTO(out_destory, rc);
2648 sprintf(index_str, "-MDT%04x", mdt_index);
2649 rc = name_create(&ospname, svname, index_str);
2651 GOTO(out_destory, rc);
2653 rc = name_create_lov(&lovname, logname, fsdb, mdt_index);
2655 GOTO(out_destory, rc);
2657 rc = name_create(&lovuuid, lovname, "_UUID");
2659 GOTO(out_destory, rc);
2661 rc = name_create(&mdtuuid, mdtname, "_UUID");
2663 GOTO(out_destory, rc);
2665 rc = record_start_log(env, mgs, &llh, logname);
2667 GOTO(out_destory, rc);
2669 rc = record_marker(env, llh, fsdb, CM_START, mti->mti_svname,
2672 GOTO(out_destory, rc);
2674 for (i = 0; i < mti->mti_nid_count; i++) {
2675 CDEBUG(D_MGS, "add nid %s for mdt\n",
2676 libcfs_nid2str_r(mti->mti_nids[i],
2677 nidstr, sizeof(nidstr)));
2678 rc = record_add_uuid(env, llh, mti->mti_nids[i], nodeuuid);
2683 rc = record_attach(env, llh, ospname, LUSTRE_OSP_NAME, lovuuid);
2687 rc = record_setup(env, llh, ospname, mti->mti_uuid, nodeuuid,
2692 rc = mgs_write_log_failnids(env, mti, llh, ospname);
2696 /* Add mdc(osp) to lod */
2697 snprintf(index_str, sizeof(index_str), "%d", mti->mti_stripe_index);
2698 rc = record_base(env, llh, lovname, 0, LCFG_ADD_MDC, mti->mti_uuid,
2699 index_str, "1", NULL);
2703 rc = record_marker(env, llh, fsdb, CM_END, mti->mti_svname, "add osp");
2708 record_end_log(env, &llh);
2711 name_destroy(&mdtuuid);
2712 name_destroy(&lovuuid);
2713 name_destroy(&lovname);
2714 name_destroy(&ospname);
2715 name_destroy(&svname);
2716 name_destroy(&nodeuuid);
2717 name_destroy(&mdtname);
2721 static int mgs_write_log_mdt0(const struct lu_env *env,
2722 struct mgs_device *mgs,
2724 struct mgs_target_info *mti)
2726 char *log = mti->mti_svname;
2727 struct llog_handle *llh = NULL;
2728 struct obd_uuid *uuid;
2731 char *ptr = mti->mti_params;
2732 int rc = 0, failout = 0;
2735 OBD_ALLOC_PTR(uuid);
2739 if (class_find_param(ptr, PARAM_FAILMODE, &ptr) == 0)
2740 failout = (strncmp(ptr, "failout", 7) == 0);
2742 rc = name_create(&lovname, log, "-mdtlov");
2745 if (mgs_log_is_empty(env, mgs, log)) {
2746 rc = mgs_write_log_lov(env, mgs, fsdb, mti, log, lovname);
2751 sprintf(mdt_index, "%d", mti->mti_stripe_index);
2753 rc = record_start_log(env, mgs, &llh, log);
2757 /* add MDT itself */
2759 /* FIXME this whole fn should be a single journal transaction */
2760 sprintf(uuid->uuid, "%s_UUID", log);
2761 rc = record_marker(env, llh, fsdb, CM_START, log, "add mdt");
2764 rc = record_attach(env, llh, log, LUSTRE_MDT_NAME, uuid->uuid);
2767 rc = record_mount_opt(env, llh, log, lovname, NULL);
2770 rc = record_setup(env, llh, log, uuid->uuid, mdt_index, lovname,
2771 failout ? "n" : "f");
2774 rc = record_marker(env, llh, fsdb, CM_END, log, "add mdt");
2778 record_end_log(env, &llh);
2780 name_destroy(&lovname);
2786 /* envelope method for all layers log */
2787 static int mgs_write_log_mdt(const struct lu_env *env,
2788 struct mgs_device *mgs,
2790 struct mgs_target_info *mti)
2792 struct mgs_thread_info *mgi = mgs_env_info(env);
2793 struct llog_handle *llh = NULL;
2798 CDEBUG(D_MGS, "writing new mdt %s\n", mti->mti_svname);
2800 if (mti->mti_uuid[0] == '\0') {
2801 /* Make up our own uuid */
2802 snprintf(mti->mti_uuid, sizeof(mti->mti_uuid),
2803 "%s_UUID", mti->mti_svname);
2807 rc = mgs_write_log_mdt0(env, mgs, fsdb, mti);
2810 /* Append the mdt info to the client log */
2811 rc = name_create(&cliname, mti->mti_fsname, "-client");
2815 if (mgs_log_is_empty(env, mgs, cliname)) {
2816 /* Start client log */
2817 rc = mgs_write_log_lov(env, mgs, fsdb, mti, cliname,
2821 rc = mgs_write_log_lmv(env, mgs, fsdb, mti, cliname,
2828 #09 L add_uuid nid=uml1@tcp(0x20000c0a80201) 0: 1:uml1_UUID
2829 #10 L attach 0:MDC_uml1_mdsA_MNT_client 1:mdc 2:1d834_MNT_client_03f
2830 #11 L setup 0:MDC_uml1_mdsA_MNT_client 1:mdsA_UUID 2:uml1_UUID
2831 #12 L add_uuid nid=uml2@tcp(0x20000c0a80202) 0: 1:uml2_UUID
2832 #13 L add_conn 0:MDC_uml1_mdsA_MNT_client 1:uml2_UUID
2833 #14 L mount_option 0: 1:client 2:lov1 3:MDC_uml1_mdsA_MNT_client
2836 /* copy client info about lov/lmv */
2837 mgi->mgi_comp.comp_mti = mti;
2838 mgi->mgi_comp.comp_fsdb = fsdb;
2840 rc = mgs_steal_llog_for_mdt_from_client(env, mgs, cliname,
2844 rc = mgs_write_log_mdc_to_lmv(env, mgs, fsdb, mti, cliname,
2850 rc = record_start_log(env, mgs, &llh, cliname);
2854 rc = record_marker(env, llh, fsdb, CM_START, cliname, "mount opts");
2857 rc = record_mount_opt(env, llh, cliname, fsdb->fsdb_clilov,
2861 rc = record_marker(env, llh, fsdb, CM_END, cliname, "mount opts");
2865 /* for_all_existing_mdt except current one */
2866 for (i = 0; i < INDEX_MAP_SIZE * 8; i++) {
2867 if (i != mti->mti_stripe_index &&
2868 test_bit(i, fsdb->fsdb_mdt_index_map)) {
2871 rc = name_create_mdt(&logname, fsdb->fsdb_name, i);
2875 /* NB: If the log for the MDT is empty, it means
2876 * the MDT is only added to the index
2877 * map, and not being process yet, i.e. this
2878 * is an unregistered MDT, see mgs_write_log_target().
2879 * so we should skip it. Otherwise
2881 * 1. MGS get register request for MDT1 and MDT2.
2883 * 2. Then both MDT1 and MDT2 are added into
2884 * fsdb_mdt_index_map. (see mgs_set_index()).
2886 * 3. Then MDT1 get the lock of fsdb_mutex, then
2887 * generate the config log, here, it will regard MDT2
2888 * as an existent MDT, and generate "add osp" for
2889 * lustre-MDT0001-osp-MDT0002. Note: at the moment
2890 * MDT0002 config log is still empty, so it will
2891 * add "add osp" even before "lov setup", which
2892 * will definitly cause trouble.
2894 * 4. MDT1 registeration finished, fsdb_mutex is
2895 * released, then MDT2 get in, then in above
2896 * mgs_steal_llog_for_mdt_from_client(), it will
2897 * add another osp log for lustre-MDT0001-osp-MDT0002,
2898 * which will cause another trouble.*/
2899 if (!mgs_log_is_empty(env, mgs, logname))
2900 rc = mgs_write_log_osp_to_mdt(env, mgs, fsdb,
2903 name_destroy(&logname);
2909 record_end_log(env, &llh);
2911 name_destroy(&cliname);
2915 /* Add the ost info to the client/mdt lov */
2916 static int mgs_write_log_osc_to_lov(const struct lu_env *env,
2917 struct mgs_device *mgs, struct fs_db *fsdb,
2918 struct mgs_target_info *mti,
2919 char *logname, char *suffix, char *lovname,
2920 enum lustre_sec_part sec_part, int flags)
2922 struct llog_handle *llh = NULL;
2923 char *nodeuuid = NULL;
2924 char *oscname = NULL;
2925 char *oscuuid = NULL;
2926 char *lovuuid = NULL;
2927 char *svname = NULL;
2929 char nidstr[LNET_NIDSTR_SIZE];
2933 CDEBUG(D_INFO, "adding osc for %s to log %s\n",
2934 mti->mti_svname, logname);
2936 if (mgs_log_is_empty(env, mgs, logname)) {
2937 CERROR("log is empty! Logical error\n");
2941 libcfs_nid2str_r(mti->mti_nids[0], nidstr, sizeof(nidstr));
2942 rc = name_create(&nodeuuid, nidstr, "");
2945 rc = name_create(&svname, mti->mti_svname, "-osc");
2949 /* for the system upgraded from old 1.8, keep using the old osc naming
2950 * style for mdt, see name_create_mdt_osc(). LU-1257 */
2951 if (test_bit(FSDB_OSCNAME18, &fsdb->fsdb_flags))
2952 rc = name_create(&oscname, svname, "");
2954 rc = name_create(&oscname, svname, suffix);
2958 rc = name_create(&oscuuid, oscname, "_UUID");
2961 rc = name_create(&lovuuid, lovname, "_UUID");
2967 #03 L add_uuid nid=uml1@tcp(0x20000c0a80201) 0: 1:uml1_UUID
2969 #04 L add_uuid nid=1@elan(0x1000000000001) nal=90 0: 1:uml1_UUID
2970 #04 L attach 0:OSC_uml1_ost1_MNT_client 1:osc 2:89070_lov1_a41dff51a
2971 #05 L setup 0:OSC_uml1_ost1_MNT_client 1:ost1_UUID 2:uml1_UUID
2973 #06 L add_uuid nid=uml2@tcp(0x20000c0a80202) 0: 1:uml2_UUID
2974 #07 L add_conn 0:OSC_uml1_ost1_MNT_client 1:uml2_UUID
2975 #08 L lov_modify_tgts add 0:lov1 1:ost1_UUID 2(index):0 3(gen):1
2978 rc = record_start_log(env, mgs, &llh, logname);
2982 /* FIXME these should be a single journal transaction */
2983 rc = record_marker(env, llh, fsdb, CM_START | flags, mti->mti_svname,
2988 /* NB: don't change record order, because upon MDT steal OSC config
2989 * from client, it treats all nids before LCFG_SETUP as target nids
2990 * (multiple interfaces), while nids after as failover node nids.
2991 * See mgs_steal_client_llog_handler() LCFG_ADD_UUID.
2993 for (i = 0; i < mti->mti_nid_count; i++) {
2994 CDEBUG(D_MGS, "add nid %s\n",
2995 libcfs_nid2str_r(mti->mti_nids[i],
2996 nidstr, sizeof(nidstr)));
2997 rc = record_add_uuid(env, llh, mti->mti_nids[i], nodeuuid);
3001 rc = record_attach(env, llh, oscname, LUSTRE_OSC_NAME, lovuuid);
3004 rc = record_setup(env, llh, oscname, mti->mti_uuid, nodeuuid,
3008 rc = mgs_write_log_failnids(env, mti, llh, oscname);
3012 snprintf(index, sizeof(index), "%d", mti->mti_stripe_index);
3014 rc = record_lov_add(env, llh, lovname, mti->mti_uuid, index, "1");
3017 rc = record_marker(env, llh, fsdb, CM_END | flags, mti->mti_svname,
3022 record_end_log(env, &llh);
3024 name_destroy(&lovuuid);
3025 name_destroy(&oscuuid);
3026 name_destroy(&oscname);
3027 name_destroy(&svname);
3028 name_destroy(&nodeuuid);
3032 static int mgs_write_log_ost(const struct lu_env *env,
3033 struct mgs_device *mgs, struct fs_db *fsdb,
3034 struct mgs_target_info *mti)
3036 struct llog_handle *llh = NULL;
3037 char *logname, *lovname;
3038 char *ptr = mti->mti_params;
3039 int rc, flags = 0, failout = 0, i;
3042 CDEBUG(D_MGS, "writing new ost %s\n", mti->mti_svname);
3044 /* The ost startup log */
3046 /* If the ost log already exists, that means that someone reformatted
3047 the ost and it called target_add again. */
3048 if (!mgs_log_is_empty(env, mgs, mti->mti_svname)) {
3049 LCONSOLE_ERROR_MSG(0x141, "The config log for %s already "
3050 "exists, yet the server claims it never "
3051 "registered. It may have been reformatted, "
3052 "or the index changed. writeconf the MDT to "
3053 "regenerate all logs.\n", mti->mti_svname);
3058 attach obdfilter ost1 ost1_UUID
3059 setup /dev/loop2 ldiskfs f|n errors=remount-ro,user_xattr
3061 if (class_find_param(ptr, PARAM_FAILMODE, &ptr) == 0)
3062 failout = (strncmp(ptr, "failout", 7) == 0);
3063 rc = record_start_log(env, mgs, &llh, mti->mti_svname);
3066 /* FIXME these should be a single journal transaction */
3067 rc = record_marker(env, llh, fsdb, CM_START, mti->mti_svname,"add ost");
3070 if (*mti->mti_uuid == '\0')
3071 snprintf(mti->mti_uuid, sizeof(mti->mti_uuid),
3072 "%s_UUID", mti->mti_svname);
3073 rc = record_attach(env, llh, mti->mti_svname,
3074 "obdfilter"/*LUSTRE_OST_NAME*/, mti->mti_uuid);
3077 rc = record_setup(env, llh, mti->mti_svname,
3078 "dev"/*ignored*/, "type"/*ignored*/,
3079 failout ? "n" : "f", NULL/*options*/);
3082 rc = record_marker(env, llh, fsdb, CM_END, mti->mti_svname, "add ost");
3086 record_end_log(env, &llh);
3089 /* We also have to update the other logs where this osc is part of
3092 if (test_bit(FSDB_OLDLOG14, &fsdb->fsdb_flags)) {
3093 /* If we're upgrading, the old mdt log already has our
3094 entry. Let's do a fake one for fun. */
3095 /* Note that we can't add any new failnids, since we don't
3096 know the old osc names. */
3097 flags = CM_SKIP | CM_UPGRADE146;
3099 } else if ((mti->mti_flags & LDD_F_UPDATE) != LDD_F_UPDATE) {
3100 /* If the update flag isn't set, don't update client/mdt
3103 LCONSOLE_WARN("Client log for %s was not updated; writeconf "
3104 "the MDT first to regenerate it.\n",
3108 /* Add ost to all MDT lov defs */
3109 for (i = 0; i < INDEX_MAP_SIZE * 8; i++){
3110 if (test_bit(i, fsdb->fsdb_mdt_index_map)) {
3113 rc = name_create_mdt_and_lov(&logname, &lovname, fsdb,
3118 snprintf(mdt_index, sizeof(mdt_index), "-MDT%04x", i);
3119 rc = mgs_write_log_osc_to_lov(env, mgs, fsdb, mti,
3121 lovname, LUSTRE_SP_MDT,
3123 name_destroy(&logname);
3124 name_destroy(&lovname);
3130 /* Append ost info to the client log */
3131 rc = name_create(&logname, mti->mti_fsname, "-client");
3134 if (mgs_log_is_empty(env, mgs, logname)) {
3135 /* Start client log */
3136 rc = mgs_write_log_lov(env, mgs, fsdb, mti, logname,
3140 rc = mgs_write_log_lmv(env, mgs, fsdb, mti, logname,
3145 rc = mgs_write_log_osc_to_lov(env, mgs, fsdb, mti, logname, "",
3146 fsdb->fsdb_clilov, LUSTRE_SP_CLI, flags);
3148 name_destroy(&logname);
3152 static __inline__ int mgs_param_empty(char *ptr)
3156 if ((tmp = strchr(ptr, '=')) && (*(++tmp) == '\0'))
3161 static int mgs_write_log_failnid_internal(const struct lu_env *env,
3162 struct mgs_device *mgs,
3164 struct mgs_target_info *mti,
3165 char *logname, char *cliname)
3168 struct llog_handle *llh = NULL;
3170 if (mgs_param_empty(mti->mti_params)) {
3171 /* Remove _all_ failnids */
3172 rc = mgs_modify(env, mgs, fsdb, mti, logname,
3173 mti->mti_svname, "add failnid", CM_SKIP);
3174 return rc < 0 ? rc : 0;
3177 /* Otherwise failover nids are additive */
3178 rc = record_start_log(env, mgs, &llh, logname);
3181 /* FIXME this should be a single journal transaction */
3182 rc = record_marker(env, llh, fsdb, CM_START, mti->mti_svname,
3186 rc = mgs_write_log_failnids(env, mti, llh, cliname);
3189 rc = record_marker(env, llh, fsdb, CM_END,
3190 mti->mti_svname, "add failnid");
3192 record_end_log(env, &llh);
3197 /* Add additional failnids to an existing log.
3198 The mdc/osc must have been added to logs first */
3199 /* tcp nids must be in dotted-quad ascii -
3200 we can't resolve hostnames from the kernel. */
3201 static int mgs_write_log_add_failnid(const struct lu_env *env,
3202 struct mgs_device *mgs,
3204 struct mgs_target_info *mti)
3206 char *logname, *cliname;
3210 /* FIXME we currently can't erase the failnids
3211 * given when a target first registers, since they aren't part of
3212 * an "add uuid" stanza
3215 /* Verify that we know about this target */
3216 if (mgs_log_is_empty(env, mgs, mti->mti_svname)) {
3217 LCONSOLE_ERROR_MSG(0x142, "The target %s has not registered "
3218 "yet. It must be started before failnids "
3219 "can be added.\n", mti->mti_svname);
3223 /* Create mdc/osc client name (e.g. lustre-OST0001-osc) */
3224 if (mti->mti_flags & LDD_F_SV_TYPE_MDT) {
3225 rc = name_create(&cliname, mti->mti_svname, "-mdc");
3226 } else if (mti->mti_flags & LDD_F_SV_TYPE_OST) {
3227 rc = name_create(&cliname, mti->mti_svname, "-osc");
3234 /* Add failover nids to the client log */
3235 rc = name_create(&logname, mti->mti_fsname, "-client");
3237 name_destroy(&cliname);