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;
75 INIT_LIST_HEAD(log_list);
78 LASSERT(dir->do_index_ops);
80 iops = &dir->do_index_ops->dio_it;
81 it = iops->init(env, dir, LUDA_64BITHASH);
85 rc = iops->load(env, it, 0);
91 key = (void *)iops->key(env, it);
93 CERROR("%s: key failed when listing %s: rc = %d\n",
94 mgs->mgs_obd->obd_name, MOUNT_CONFIGS_DIR,
98 key_sz = iops->key_size(env, it);
101 /* filter out "." and ".." entries */
105 if (key_sz == 2 && key[1] == '.')
109 /* filter out ".bak" files */
110 /* sizeof(".bak") - 1 == 3 */
112 !memcmp(".bak", key + key_sz - 3, 3)) {
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 index = simple_strtoul(lustre_cfg_string(lcfg, 2),
220 CDEBUG(D_MGS, "OST index for %s is %u (%s)\n",
221 lustre_cfg_string(lcfg, 1), index,
222 lustre_cfg_string(lcfg, 2));
223 set_bit(index, fsdb->fsdb_ost_index_map);
226 /* Figure out mdt indicies */
227 /* attach 0:MDC_uml1_mdsA_MNT_client 1:mdc 2:1d834_MNT_client_03f */
228 if ((lcfg->lcfg_command == LCFG_ATTACH) &&
229 (strcmp(lustre_cfg_string(lcfg, 1), LUSTRE_MDC_NAME) == 0)) {
230 rc = server_name2index(lustre_cfg_string(lcfg, 0),
232 if (rc != LDD_F_SV_TYPE_MDT) {
233 CWARN("Unparsable MDC name %s, assuming index 0\n",
234 lustre_cfg_string(lcfg, 0));
238 CDEBUG(D_MGS, "MDT index is %u\n", index);
239 if (!test_bit(index, fsdb->fsdb_mdt_index_map)) {
240 set_bit(index, fsdb->fsdb_mdt_index_map);
241 fsdb->fsdb_mdt_count++;
246 * figure out the old config. fsdb_gen = 0 means old log
247 * It is obsoleted and not supported anymore
249 if (fsdb->fsdb_gen == 0) {
250 CERROR("Old config format is not supported\n");
255 * compat to 1.8, check osc name used by MDT0 to OSTs, bz18548.
257 if (!test_bit(FSDB_OSCNAME18, &fsdb->fsdb_flags) &&
258 lcfg->lcfg_command == LCFG_ATTACH &&
259 strcmp(lustre_cfg_string(lcfg, 1), LUSTRE_OSC_NAME) == 0) {
260 if (OBD_OCD_VERSION_MAJOR(d->ver) == 1 &&
261 OBD_OCD_VERSION_MINOR(d->ver) <= 8) {
262 CWARN("MDT using 1.8 OSC name scheme\n");
263 set_bit(FSDB_OSCNAME18, &fsdb->fsdb_flags);
267 if (lcfg->lcfg_command == LCFG_MARKER) {
268 struct cfg_marker *marker;
269 marker = lustre_cfg_buf(lcfg, 1);
271 d->ver = marker->cm_vers;
273 /* Keep track of the latest marker step */
274 fsdb->fsdb_gen = max(fsdb->fsdb_gen, marker->cm_step);
280 /* fsdb->fsdb_mutex is already held in mgs_find_or_make_fsdb*/
281 static int mgs_get_fsdb_from_llog(const struct lu_env *env,
282 struct mgs_device *mgs,
286 struct llog_handle *loghandle;
287 struct llog_ctxt *ctxt;
288 struct mgs_fsdb_handler_data d = {
295 ctxt = llog_get_context(mgs->mgs_obd, LLOG_CONFIG_ORIG_CTXT);
296 LASSERT(ctxt != NULL);
297 rc = name_create(&logname, fsdb->fsdb_name, "-client");
300 rc = llog_open_create(env, ctxt, &loghandle, NULL, logname);
304 rc = llog_init_handle(env, loghandle, LLOG_F_IS_PLAIN, NULL);
308 if (llog_get_size(loghandle) <= 1)
309 set_bit(FSDB_LOG_EMPTY, &fsdb->fsdb_flags);
311 rc = llog_process(env, loghandle, mgs_fsdb_handler, (void *)&d, NULL);
312 CDEBUG(D_INFO, "get_db = %d\n", rc);
314 llog_close(env, loghandle);
316 name_destroy(&logname);
323 static void mgs_free_fsdb_srpc(struct fs_db *fsdb)
325 struct mgs_tgt_srpc_conf *tgtconf;
327 /* free target-specific rules */
328 while (fsdb->fsdb_srpc_tgt) {
329 tgtconf = fsdb->fsdb_srpc_tgt;
330 fsdb->fsdb_srpc_tgt = tgtconf->mtsc_next;
332 LASSERT(tgtconf->mtsc_tgt);
334 sptlrpc_rule_set_free(&tgtconf->mtsc_rset);
335 OBD_FREE(tgtconf->mtsc_tgt, strlen(tgtconf->mtsc_tgt) + 1);
336 OBD_FREE_PTR(tgtconf);
339 /* free general rules */
340 sptlrpc_rule_set_free(&fsdb->fsdb_srpc_gen);
343 static void mgs_unlink_fsdb(struct mgs_device *mgs, struct fs_db *fsdb)
345 mutex_lock(&mgs->mgs_mutex);
346 if (likely(!list_empty(&fsdb->fsdb_list))) {
347 LASSERTF(atomic_read(&fsdb->fsdb_ref) >= 2,
348 "Invalid ref %d on %s\n",
349 atomic_read(&fsdb->fsdb_ref),
352 list_del_init(&fsdb->fsdb_list);
353 /* Drop the reference on the list.*/
354 mgs_put_fsdb(mgs, fsdb);
356 mutex_unlock(&mgs->mgs_mutex);
359 /* The caller must hold mgs->mgs_mutex. */
360 static inline struct fs_db *
361 mgs_find_fsdb_noref(struct mgs_device *mgs, const char *fsname)
364 struct list_head *tmp;
366 list_for_each(tmp, &mgs->mgs_fs_db_list) {
367 fsdb = list_entry(tmp, struct fs_db, fsdb_list);
368 if (strcmp(fsdb->fsdb_name, fsname) == 0)
375 /* The caller must hold mgs->mgs_mutex. */
376 static void mgs_remove_fsdb_by_name(struct mgs_device *mgs, const char *name)
380 fsdb = mgs_find_fsdb_noref(mgs, name);
382 list_del_init(&fsdb->fsdb_list);
383 /* Drop the reference on the list.*/
384 mgs_put_fsdb(mgs, fsdb);
388 /* The caller must hold mgs->mgs_mutex. */
389 struct fs_db *mgs_find_fsdb(struct mgs_device *mgs, const char *fsname)
393 fsdb = mgs_find_fsdb_noref(mgs, fsname);
395 atomic_inc(&fsdb->fsdb_ref);
400 /* The caller must hold mgs->mgs_mutex. */
401 static struct fs_db *mgs_new_fsdb(const struct lu_env *env,
402 struct mgs_device *mgs, char *fsname)
408 if (strlen(fsname) >= sizeof(fsdb->fsdb_name)) {
409 CERROR("fsname %s is too long\n", fsname);
411 RETURN(ERR_PTR(-EINVAL));
416 RETURN(ERR_PTR(-ENOMEM));
418 strncpy(fsdb->fsdb_name, fsname, sizeof(fsdb->fsdb_name));
419 mutex_init(&fsdb->fsdb_mutex);
420 INIT_LIST_HEAD(&fsdb->fsdb_list);
421 set_bit(FSDB_UDESC, &fsdb->fsdb_flags);
423 INIT_LIST_HEAD(&fsdb->fsdb_clients);
424 atomic_set(&fsdb->fsdb_notify_phase, 0);
425 init_waitqueue_head(&fsdb->fsdb_notify_waitq);
426 init_completion(&fsdb->fsdb_notify_comp);
428 if (strcmp(fsname, MGSSELF_NAME) == 0) {
429 set_bit(FSDB_MGS_SELF, &fsdb->fsdb_flags);
430 fsdb->fsdb_mgs = mgs;
431 if (logname_is_barrier(fsname))
434 OBD_ALLOC(fsdb->fsdb_mdt_index_map, INDEX_MAP_SIZE);
435 if (!fsdb->fsdb_mdt_index_map) {
436 CERROR("No memory for MDT index maps\n");
438 GOTO(err, rc = -ENOMEM);
441 OBD_ALLOC(fsdb->fsdb_ost_index_map, INDEX_MAP_SIZE);
442 if (!fsdb->fsdb_ost_index_map) {
443 CERROR("No memory for OST index maps\n");
445 GOTO(err, rc = -ENOMEM);
448 if (logname_is_barrier(fsname))
451 rc = name_create(&fsdb->fsdb_clilov, fsname, "-clilov");
455 rc = name_create(&fsdb->fsdb_clilmv, fsname, "-clilmv");
459 /* initialise data for NID table */
460 mgs_ir_init_fs(env, mgs, fsdb);
461 lproc_mgs_add_live(mgs, fsdb);
464 if (!test_bit(FSDB_MGS_SELF, &fsdb->fsdb_flags) &&
465 strcmp(PARAMS_FILENAME, fsname) != 0) {
466 /* populate the db from the client llog */
467 rc = mgs_get_fsdb_from_llog(env, mgs, fsdb);
469 CERROR("Can't get db from client log %d\n", rc);
475 /* populate srpc rules from params llog */
476 rc = mgs_get_fsdb_srpc_from_llog(env, mgs, fsdb);
478 CERROR("Can't get db from params log %d\n", rc);
484 /* One ref is for the fsdb on the list.
485 * The other ref is for the caller. */
486 atomic_set(&fsdb->fsdb_ref, 2);
487 list_add(&fsdb->fsdb_list, &mgs->mgs_fs_db_list);
492 atomic_set(&fsdb->fsdb_ref, 1);
493 mgs_put_fsdb(mgs, fsdb);
498 static void mgs_free_fsdb(struct mgs_device *mgs, struct fs_db *fsdb)
500 LASSERT(list_empty(&fsdb->fsdb_list));
502 lproc_mgs_del_live(mgs, fsdb);
504 /* deinitialize fsr */
506 mgs_ir_fini_fs(mgs, fsdb);
508 if (fsdb->fsdb_ost_index_map)
509 OBD_FREE(fsdb->fsdb_ost_index_map, INDEX_MAP_SIZE);
510 if (fsdb->fsdb_mdt_index_map)
511 OBD_FREE(fsdb->fsdb_mdt_index_map, INDEX_MAP_SIZE);
512 name_destroy(&fsdb->fsdb_clilov);
513 name_destroy(&fsdb->fsdb_clilmv);
514 mgs_free_fsdb_srpc(fsdb);
518 void mgs_put_fsdb(struct mgs_device *mgs, struct fs_db *fsdb)
520 if (atomic_dec_and_test(&fsdb->fsdb_ref))
521 mgs_free_fsdb(mgs, fsdb);
524 int mgs_init_fsdb_list(struct mgs_device *mgs)
526 INIT_LIST_HEAD(&mgs->mgs_fs_db_list);
530 int mgs_cleanup_fsdb_list(struct mgs_device *mgs)
533 struct list_head *tmp, *tmp2;
535 mutex_lock(&mgs->mgs_mutex);
536 list_for_each_safe(tmp, tmp2, &mgs->mgs_fs_db_list) {
537 fsdb = list_entry(tmp, struct fs_db, fsdb_list);
538 list_del_init(&fsdb->fsdb_list);
539 mgs_put_fsdb(mgs, fsdb);
541 mutex_unlock(&mgs->mgs_mutex);
545 int mgs_find_or_make_fsdb(const struct lu_env *env, struct mgs_device *mgs,
546 char *name, struct fs_db **dbh)
552 mutex_lock(&mgs->mgs_mutex);
553 fsdb = mgs_find_fsdb(mgs, name);
555 fsdb = mgs_new_fsdb(env, mgs, name);
559 CDEBUG(D_MGS, "Created new db: rc = %d\n", rc);
561 mutex_unlock(&mgs->mgs_mutex);
571 -1= empty client log */
572 int mgs_check_index(const struct lu_env *env,
573 struct mgs_device *mgs,
574 struct mgs_target_info *mti)
581 LASSERT(!(mti->mti_flags & LDD_F_NEED_INDEX));
583 rc = mgs_find_or_make_fsdb(env, mgs, mti->mti_fsname, &fsdb);
585 CERROR("Can't get db for %s\n", mti->mti_fsname);
589 if (test_bit(FSDB_LOG_EMPTY, &fsdb->fsdb_flags))
592 if (mti->mti_flags & LDD_F_SV_TYPE_OST)
593 imap = fsdb->fsdb_ost_index_map;
594 else if (mti->mti_flags & LDD_F_SV_TYPE_MDT)
595 imap = fsdb->fsdb_mdt_index_map;
597 GOTO(out, rc = -EINVAL);
599 if (test_bit(mti->mti_stripe_index, imap))
605 mgs_put_fsdb(mgs, fsdb);
609 static __inline__ int next_index(void *index_map, int map_len)
612 for (i = 0; i < map_len * 8; i++)
613 if (!test_bit(i, index_map)) {
616 CERROR("max index %d exceeded.\n", i);
620 /* Make the mdt/ost server obd name based on the filesystem name */
621 static bool server_make_name(u32 flags, u16 index, const char *fs,
622 char *name_buf, size_t name_buf_size)
624 bool invalid_flag = false;
626 if (flags & (LDD_F_SV_TYPE_MDT | LDD_F_SV_TYPE_OST)) {
627 if (!(flags & LDD_F_SV_ALL))
628 snprintf(name_buf, name_buf_size, "%.8s%c%s%04x", fs,
629 (flags & LDD_F_VIRGIN) ? ':' :
630 ((flags & LDD_F_WRITECONF) ? '=' : '-'),
631 (flags & LDD_F_SV_TYPE_MDT) ? "MDT" : "OST",
633 } else if (flags & LDD_F_SV_TYPE_MGS) {
634 snprintf(name_buf, name_buf_size, "MGS");
636 CERROR("unknown server type %#x\n", flags);
643 0 newly marked as in use
645 +EALREADY for update of an old index */
646 static int mgs_set_index(const struct lu_env *env,
647 struct mgs_device *mgs,
648 struct mgs_target_info *mti)
655 rc = mgs_find_or_make_fsdb(env, mgs, mti->mti_fsname, &fsdb);
657 CERROR("Can't get db for %s\n", mti->mti_fsname);
661 mutex_lock(&fsdb->fsdb_mutex);
662 if (mti->mti_flags & LDD_F_SV_TYPE_OST) {
663 imap = fsdb->fsdb_ost_index_map;
664 } else if (mti->mti_flags & LDD_F_SV_TYPE_MDT) {
665 imap = fsdb->fsdb_mdt_index_map;
667 GOTO(out_up, rc = -EINVAL);
670 if (mti->mti_flags & LDD_F_NEED_INDEX) {
671 rc = next_index(imap, INDEX_MAP_SIZE);
673 GOTO(out_up, rc = -ERANGE);
674 mti->mti_stripe_index = rc;
677 /* the last index(0xffff) is reserved for default value. */
678 if (mti->mti_stripe_index >= INDEX_MAP_SIZE * 8 - 1) {
679 LCONSOLE_ERROR_MSG(0x13f, "Server %s requested index %u, "
680 "but index must be less than %u.\n",
681 mti->mti_svname, mti->mti_stripe_index,
682 INDEX_MAP_SIZE * 8 - 1);
683 GOTO(out_up, rc = -ERANGE);
686 if (test_bit(mti->mti_stripe_index, imap)) {
687 if ((mti->mti_flags & LDD_F_VIRGIN) &&
688 !(mti->mti_flags & LDD_F_WRITECONF)) {
689 LCONSOLE_ERROR_MSG(0x140, "Server %s requested index "
690 "%d, but that index is already in "
691 "use. Use --writeconf to force\n",
693 mti->mti_stripe_index);
694 GOTO(out_up, rc = -EADDRINUSE);
696 CDEBUG(D_MGS, "Server %s updating index %d\n",
697 mti->mti_svname, mti->mti_stripe_index);
698 GOTO(out_up, rc = EALREADY);
701 set_bit(mti->mti_stripe_index, imap);
702 if (mti->mti_flags & LDD_F_SV_TYPE_MDT)
703 fsdb->fsdb_mdt_count++;
706 set_bit(mti->mti_stripe_index, imap);
707 clear_bit(FSDB_LOG_EMPTY, &fsdb->fsdb_flags);
708 if (server_make_name(mti->mti_flags & ~(LDD_F_VIRGIN | LDD_F_WRITECONF),
709 mti->mti_stripe_index, mti->mti_fsname,
710 mti->mti_svname, sizeof(mti->mti_svname))) {
711 CERROR("unknown server type %#x\n", mti->mti_flags);
712 GOTO(out_up, rc = -EINVAL);
715 CDEBUG(D_MGS, "Set index for %s to %d\n", mti->mti_svname,
716 mti->mti_stripe_index);
718 GOTO(out_up, rc = 0);
721 mutex_unlock(&fsdb->fsdb_mutex);
722 mgs_put_fsdb(mgs, fsdb);
726 struct mgs_modify_lookup {
727 struct cfg_marker mml_marker;
731 static int mgs_check_record_match(const struct lu_env *env,
732 struct llog_handle *llh,
733 struct llog_rec_hdr *rec, void *data)
735 struct cfg_marker *mc_marker = data;
736 struct cfg_marker *marker;
737 struct lustre_cfg *lcfg = REC_DATA(rec);
738 int cfg_len = REC_DATA_LEN(rec);
743 if (rec->lrh_type != OBD_CFG_REC) {
744 CDEBUG(D_ERROR, "Unhandled lrh_type: %#x\n", rec->lrh_type);
748 rc = lustre_cfg_sanity_check(lcfg, cfg_len);
750 CDEBUG(D_ERROR, "Insane cfg\n");
754 /* We only care about markers */
755 if (lcfg->lcfg_command != LCFG_MARKER)
758 marker = lustre_cfg_buf(lcfg, 1);
760 if (marker->cm_flags & CM_SKIP)
763 if ((strcmp(mc_marker->cm_comment, marker->cm_comment) == 0) &&
764 (strcmp(mc_marker->cm_tgtname, marker->cm_tgtname) == 0)) {
765 /* Found a non-skipped marker match */
766 CDEBUG(D_MGS, "Matched rec %u marker %d flag %x %s %s\n",
767 rec->lrh_index, marker->cm_step,
768 marker->cm_flags, marker->cm_tgtname,
770 rc = LLOG_PROC_BREAK;
777 * Check an existing config log record with matching comment and device
779 * 0 - checked successfully,
780 * LLOG_PROC_BREAK - record matches
783 static int mgs_check_marker(const struct lu_env *env, struct mgs_device *mgs,
784 struct fs_db *fsdb, struct mgs_target_info *mti,
785 char *logname, char *devname, char *comment)
787 struct llog_handle *loghandle;
788 struct llog_ctxt *ctxt;
789 struct cfg_marker *mc_marker;
794 LASSERT(mutex_is_locked(&fsdb->fsdb_mutex));
795 CDEBUG(D_MGS, "mgs check %s/%s/%s\n", logname, devname, comment);
797 ctxt = llog_get_context(mgs->mgs_obd, LLOG_CONFIG_ORIG_CTXT);
798 LASSERT(ctxt != NULL);
799 rc = llog_open(env, ctxt, &loghandle, NULL, logname, LLOG_OPEN_EXISTS);
806 rc = llog_init_handle(env, loghandle, LLOG_F_IS_PLAIN, NULL);
810 if (llog_get_size(loghandle) <= 1)
811 GOTO(out_close, rc = 0);
813 OBD_ALLOC_PTR(mc_marker);
815 GOTO(out_close, rc = -ENOMEM);
816 if (strlcpy(mc_marker->cm_comment, comment,
817 sizeof(mc_marker->cm_comment)) >=
818 sizeof(mc_marker->cm_comment))
819 GOTO(out_free, rc = -E2BIG);
820 if (strlcpy(mc_marker->cm_tgtname, devname,
821 sizeof(mc_marker->cm_tgtname)) >=
822 sizeof(mc_marker->cm_tgtname))
823 GOTO(out_free, rc = -E2BIG);
825 rc = llog_process(env, loghandle, mgs_check_record_match,
826 (void *)mc_marker, NULL);
829 OBD_FREE_PTR(mc_marker);
832 llog_close(env, loghandle);
834 if (rc && rc != LLOG_PROC_BREAK)
835 CDEBUG(D_ERROR, "%s: mgs check %s/%s failed: rc = %d\n",
836 mgs->mgs_obd->obd_name, mti->mti_svname, comment, rc);
841 static int mgs_modify_handler(const struct lu_env *env,
842 struct llog_handle *llh,
843 struct llog_rec_hdr *rec, void *data)
845 struct mgs_modify_lookup *mml = data;
846 struct cfg_marker *marker;
847 struct lustre_cfg *lcfg = REC_DATA(rec);
848 int cfg_len = REC_DATA_LEN(rec);
852 if (rec->lrh_type != OBD_CFG_REC) {
853 CERROR("unhandled lrh_type: %#x\n", rec->lrh_type);
857 rc = lustre_cfg_sanity_check(lcfg, cfg_len);
859 CERROR("Insane cfg\n");
863 /* We only care about markers */
864 if (lcfg->lcfg_command != LCFG_MARKER)
867 marker = lustre_cfg_buf(lcfg, 1);
868 if ((strcmp(mml->mml_marker.cm_comment, marker->cm_comment) == 0) &&
869 (strcmp(mml->mml_marker.cm_tgtname, marker->cm_tgtname) == 0) &&
870 !(marker->cm_flags & CM_SKIP)) {
871 /* Found a non-skipped marker match */
872 CDEBUG(D_MGS, "Changing rec %u marker %d %x->%x: %s %s\n",
873 rec->lrh_index, marker->cm_step,
874 marker->cm_flags, mml->mml_marker.cm_flags,
875 marker->cm_tgtname, marker->cm_comment);
876 /* Overwrite the old marker llog entry */
877 marker->cm_flags &= ~CM_EXCLUDE; /* in case we're unexcluding */
878 marker->cm_flags |= mml->mml_marker.cm_flags;
879 marker->cm_canceltime = mml->mml_marker.cm_canceltime;
880 rc = llog_write(env, llh, rec, rec->lrh_index);
889 * Modify an existing config log record (for CM_SKIP or CM_EXCLUDE)
891 * 0 - modified successfully,
892 * 1 - no modification was done
895 static int mgs_modify(const struct lu_env *env, struct mgs_device *mgs,
896 struct fs_db *fsdb, struct mgs_target_info *mti,
897 char *logname, char *devname, char *comment, int flags)
899 struct llog_handle *loghandle;
900 struct llog_ctxt *ctxt;
901 struct mgs_modify_lookup *mml;
906 LASSERT(mutex_is_locked(&fsdb->fsdb_mutex));
907 CDEBUG(D_MGS, "modify %s/%s/%s fl=%x\n", logname, devname, comment,
910 ctxt = llog_get_context(mgs->mgs_obd, LLOG_CONFIG_ORIG_CTXT);
911 LASSERT(ctxt != NULL);
912 rc = llog_open(env, ctxt, &loghandle, NULL, logname, LLOG_OPEN_EXISTS);
919 rc = llog_init_handle(env, loghandle, LLOG_F_IS_PLAIN, NULL);
923 if (llog_get_size(loghandle) <= 1)
924 GOTO(out_close, rc = 0);
928 GOTO(out_close, rc = -ENOMEM);
929 if (strlcpy(mml->mml_marker.cm_comment, comment,
930 sizeof(mml->mml_marker.cm_comment)) >=
931 sizeof(mml->mml_marker.cm_comment))
932 GOTO(out_free, rc = -E2BIG);
933 if (strlcpy(mml->mml_marker.cm_tgtname, devname,
934 sizeof(mml->mml_marker.cm_tgtname)) >=
935 sizeof(mml->mml_marker.cm_tgtname))
936 GOTO(out_free, rc = -E2BIG);
937 /* Modify mostly means cancel */
938 mml->mml_marker.cm_flags = flags;
939 mml->mml_marker.cm_canceltime = flags ? ktime_get_real_seconds() : 0;
940 mml->mml_modified = 0;
941 rc = llog_process(env, loghandle, mgs_modify_handler, (void *)mml,
943 if (!rc && !mml->mml_modified)
950 llog_close(env, loghandle);
953 CERROR("%s: modify %s/%s failed: rc = %d\n",
954 mgs->mgs_obd->obd_name, mti->mti_svname, comment, rc);
959 /** This structure is passed to mgs_replace_handler */
960 struct mgs_replace_data {
961 /* Nids are replaced for this target device */
962 struct mgs_target_info target;
963 /* Temporary modified llog */
964 struct llog_handle *temp_llh;
965 /* Flag is set if in target block*/
966 int in_target_device;
967 /* Nids already added. Just skip (multiple nids) */
968 int device_nids_added;
969 /* Flag is set if this block should not be copied */
974 * Check: a) if block should be skipped
975 * b) is it target block
980 * \retval 0 should not to be skipped
981 * \retval 1 should to be skipped
983 static int check_markers(struct lustre_cfg *lcfg,
984 struct mgs_replace_data *mrd)
986 struct cfg_marker *marker;
988 /* Track markers. Find given device */
989 if (lcfg->lcfg_command == LCFG_MARKER) {
990 marker = lustre_cfg_buf(lcfg, 1);
991 /* Clean llog from records marked as CM_EXCLUDE.
992 CM_SKIP records are used for "active" command
993 and can be restored if needed */
994 if ((marker->cm_flags & (CM_EXCLUDE | CM_START)) ==
995 (CM_EXCLUDE | CM_START)) {
1000 if ((marker->cm_flags & (CM_EXCLUDE | CM_END)) ==
1001 (CM_EXCLUDE | CM_END)) {
1006 if (strcmp(mrd->target.mti_svname, marker->cm_tgtname) == 0) {
1007 LASSERT(!(marker->cm_flags & CM_START) ||
1008 !(marker->cm_flags & CM_END));
1009 if (marker->cm_flags & CM_START) {
1010 mrd->in_target_device = 1;
1011 mrd->device_nids_added = 0;
1012 } else if (marker->cm_flags & CM_END)
1013 mrd->in_target_device = 0;
1020 static int record_base(const struct lu_env *env, struct llog_handle *llh,
1021 char *cfgname, lnet_nid_t nid, int cmd,
1022 char *s1, char *s2, char *s3, char *s4)
1024 struct mgs_thread_info *mgi = mgs_env_info(env);
1025 struct llog_cfg_rec *lcr;
1028 CDEBUG(D_MGS, "lcfg %s %#x %s %s %s %s\n", cfgname,
1029 cmd, s1, s2, s3, s4);
1031 lustre_cfg_bufs_reset(&mgi->mgi_bufs, cfgname);
1033 lustre_cfg_bufs_set_string(&mgi->mgi_bufs, 1, s1);
1035 lustre_cfg_bufs_set_string(&mgi->mgi_bufs, 2, s2);
1037 lustre_cfg_bufs_set_string(&mgi->mgi_bufs, 3, s3);
1039 lustre_cfg_bufs_set_string(&mgi->mgi_bufs, 4, s4);
1041 lcr = lustre_cfg_rec_new(cmd, &mgi->mgi_bufs);
1045 lcr->lcr_cfg.lcfg_nid = nid;
1046 rc = llog_write(env, llh, &lcr->lcr_hdr, LLOG_NEXT_IDX);
1048 lustre_cfg_rec_free(lcr);
1052 "failed to write lcfg %s %#x %s %s %s %s: rc = %d\n",
1053 cfgname, cmd, s1, s2, s3, s4, rc);
1057 static inline int record_add_uuid(const struct lu_env *env,
1058 struct llog_handle *llh,
1059 uint64_t nid, char *uuid)
1061 return record_base(env, llh, NULL, nid, LCFG_ADD_UUID, uuid,
1065 static inline int record_add_conn(const struct lu_env *env,
1066 struct llog_handle *llh,
1067 char *devname, char *uuid)
1069 return record_base(env, llh, devname, 0, LCFG_ADD_CONN, uuid,
1073 static inline int record_attach(const struct lu_env *env,
1074 struct llog_handle *llh, char *devname,
1075 char *type, char *uuid)
1077 return record_base(env, llh, devname, 0, LCFG_ATTACH, type, uuid,
1081 static inline int record_setup(const struct lu_env *env,
1082 struct llog_handle *llh, char *devname,
1083 char *s1, char *s2, char *s3, char *s4)
1085 return record_base(env, llh, devname, 0, LCFG_SETUP, s1, s2, s3, s4);
1089 * \retval <0 record processing error
1090 * \retval n record is processed. No need copy original one.
1091 * \retval 0 record is not processed.
1093 static int process_command(const struct lu_env *env, struct lustre_cfg *lcfg,
1094 struct mgs_replace_data *mrd)
1101 if (lcfg->lcfg_command == LCFG_ADD_UUID) {
1102 /* LCFG_ADD_UUID command found. Let's skip original command
1103 and add passed nids */
1104 ptr = mrd->target.mti_params;
1105 while (class_parse_nid(ptr, &nid, &ptr) == 0) {
1106 CDEBUG(D_MGS, "add nid %s with uuid %s, "
1107 "device %s\n", libcfs_nid2str(nid),
1108 mrd->target.mti_params,
1109 mrd->target.mti_svname);
1110 rc = record_add_uuid(env,
1112 mrd->target.mti_params);
1117 if (nids_added == 0) {
1118 CERROR("No new nids were added, nid %s with uuid %s, "
1119 "device %s\n", libcfs_nid2str(nid),
1120 mrd->target.mti_params,
1121 mrd->target.mti_svname);
1124 mrd->device_nids_added = 1;
1130 if (mrd->device_nids_added && lcfg->lcfg_command == LCFG_SETUP) {
1131 /* LCFG_SETUP command found. UUID should be changed */
1132 rc = record_setup(env,
1134 /* devname the same */
1135 lustre_cfg_string(lcfg, 0),
1136 /* s1 is not changed */
1137 lustre_cfg_string(lcfg, 1),
1138 /* new uuid should be
1140 mrd->target.mti_params,
1141 /* s3 is not changed */
1142 lustre_cfg_string(lcfg, 3),
1143 /* s4 is not changed */
1144 lustre_cfg_string(lcfg, 4));
1148 /* Another commands in target device block */
1153 * Handler that called for every record in llog.
1154 * Records are processed in order they placed in llog.
1156 * \param[in] llh log to be processed
1157 * \param[in] rec current record
1158 * \param[in] data mgs_replace_data structure
1162 static int mgs_replace_nids_handler(const struct lu_env *env,
1163 struct llog_handle *llh,
1164 struct llog_rec_hdr *rec,
1167 struct mgs_replace_data *mrd;
1168 struct lustre_cfg *lcfg = REC_DATA(rec);
1169 int cfg_len = REC_DATA_LEN(rec);
1173 mrd = (struct mgs_replace_data *)data;
1175 if (rec->lrh_type != OBD_CFG_REC) {
1176 CERROR("unhandled lrh_type: %#x, cmd %x %s %s\n",
1177 rec->lrh_type, lcfg->lcfg_command,
1178 lustre_cfg_string(lcfg, 0),
1179 lustre_cfg_string(lcfg, 1));
1183 rc = lustre_cfg_sanity_check(lcfg, cfg_len);
1185 /* Do not copy any invalidated records */
1186 GOTO(skip_out, rc = 0);
1189 rc = check_markers(lcfg, mrd);
1190 if (rc || mrd->skip_it)
1191 GOTO(skip_out, rc = 0);
1193 /* Write to new log all commands outside target device block */
1194 if (!mrd->in_target_device)
1195 GOTO(copy_out, rc = 0);
1197 /* Skip all other LCFG_ADD_UUID and LCFG_ADD_CONN records
1198 (failover nids) for this target, assuming that if then
1199 primary is changing then so is the failover */
1200 if (mrd->device_nids_added &&
1201 (lcfg->lcfg_command == LCFG_ADD_UUID ||
1202 lcfg->lcfg_command == LCFG_ADD_CONN))
1203 GOTO(skip_out, rc = 0);
1205 rc = process_command(env, lcfg, mrd);
1212 /* Record is placed in temporary llog as is */
1213 rc = llog_write(env, mrd->temp_llh, rec, LLOG_NEXT_IDX);
1215 CDEBUG(D_MGS, "Copied idx=%d, rc=%d, len=%d, cmd %x %s %s\n",
1216 rec->lrh_index, rc, rec->lrh_len, lcfg->lcfg_command,
1217 lustre_cfg_string(lcfg, 0), lustre_cfg_string(lcfg, 1));
1221 CDEBUG(D_MGS, "Skipped idx=%d, rc=%d, len=%d, cmd %x %s %s\n",
1222 rec->lrh_index, rc, rec->lrh_len, lcfg->lcfg_command,
1223 lustre_cfg_string(lcfg, 0), lustre_cfg_string(lcfg, 1));
1227 static int mgs_log_is_empty(const struct lu_env *env,
1228 struct mgs_device *mgs, char *name)
1230 struct llog_ctxt *ctxt;
1233 ctxt = llog_get_context(mgs->mgs_obd, LLOG_CONFIG_ORIG_CTXT);
1234 LASSERT(ctxt != NULL);
1236 rc = llog_is_empty(env, ctxt, name);
1237 llog_ctxt_put(ctxt);
1241 static int mgs_replace_log(const struct lu_env *env,
1242 struct obd_device *mgs,
1243 char *logname, char *devname,
1244 llog_cb_t replace_handler, void *data)
1246 struct llog_handle *orig_llh, *backup_llh;
1247 struct llog_ctxt *ctxt;
1248 struct mgs_replace_data *mrd;
1249 struct mgs_device *mgs_dev = lu2mgs_dev(mgs->obd_lu_dev);
1250 static struct obd_uuid cfg_uuid = { .uuid = "config_uuid" };
1252 int rc, rc2, buf_size;
1256 ctxt = llog_get_context(mgs, LLOG_CONFIG_ORIG_CTXT);
1257 LASSERT(ctxt != NULL);
1259 if (mgs_log_is_empty(env, mgs_dev, logname)) {
1260 /* Log is empty. Nothing to replace */
1261 GOTO(out_put, rc = 0);
1264 now = ktime_get_real_seconds();
1266 /* max time64_t in decimal fits into 20 bytes long string */
1267 buf_size = strlen(logname) + 1 + 20 + 1 + strlen(".bak") + 1;
1268 OBD_ALLOC(backup, buf_size);
1270 GOTO(out_put, rc = -ENOMEM);
1272 snprintf(backup, buf_size, "%s.%llu.bak", logname, now);
1274 rc = llog_backup(env, mgs, ctxt, ctxt, logname, backup);
1276 /* Now erase original log file. Connections are not allowed.
1277 Backup is already saved */
1278 rc = llog_erase(env, ctxt, NULL, logname);
1281 } else if (rc != -ENOENT) {
1282 CERROR("%s: can't make backup for %s: rc = %d\n",
1283 mgs->obd_name, logname, rc);
1287 /* open local log */
1288 rc = llog_open_create(env, ctxt, &orig_llh, NULL, logname);
1290 GOTO(out_restore, rc);
1292 rc = llog_init_handle(env, orig_llh, LLOG_F_IS_PLAIN, &cfg_uuid);
1294 GOTO(out_closel, rc);
1296 /* open backup llog */
1297 rc = llog_open(env, ctxt, &backup_llh, NULL, backup,
1300 GOTO(out_closel, rc);
1302 rc = llog_init_handle(env, backup_llh, LLOG_F_IS_PLAIN, NULL);
1304 GOTO(out_close, rc);
1306 if (llog_get_size(backup_llh) <= 1)
1307 GOTO(out_close, rc = 0);
1311 GOTO(out_close, rc = -ENOMEM);
1312 /* devname is only needed information to replace UUID records */
1314 strlcpy(mrd->target.mti_svname, devname,
1315 sizeof(mrd->target.mti_svname));
1316 /* data is parsed in llog callback */
1318 strlcpy(mrd->target.mti_params, data,
1319 sizeof(mrd->target.mti_params));
1320 /* Copy records to this temporary llog */
1321 mrd->temp_llh = orig_llh;
1323 rc = llog_process(env, backup_llh, replace_handler,
1327 rc2 = llog_close(NULL, backup_llh);
1331 rc2 = llog_close(NULL, orig_llh);
1337 CERROR("%s: llog should be restored: rc = %d\n",
1339 rc2 = llog_backup(env, mgs, ctxt, ctxt, backup,
1342 CERROR("%s: can't restore backup %s: rc = %d\n",
1343 mgs->obd_name, logname, rc2);
1347 OBD_FREE(backup, buf_size);
1350 llog_ctxt_put(ctxt);
1353 CERROR("%s: failed to replace log %s: rc = %d\n",
1354 mgs->obd_name, logname, rc);
1359 static int mgs_replace_nids_log(const struct lu_env *env,
1360 struct obd_device *obd,
1361 char *logname, char *devname, char *nids)
1363 CDEBUG(D_MGS, "Replace NIDs for %s in %s\n", devname, logname);
1364 return mgs_replace_log(env, obd, logname, devname,
1365 mgs_replace_nids_handler, nids);
1369 * Parse device name and get file system name and/or device index
1371 * @devname device name (ex. lustre-MDT0000)
1372 * @fsname file system name extracted from @devname and returned
1373 * to the caller (optional)
1374 * @index device index extracted from @devname and returned to
1375 * the caller (optional)
1377 * RETURN 0 success if we are only interested in
1378 * extracting fsname from devname.
1381 * LDD_F_SV_TYPE_* Besides extracting the fsname the
1382 * user also wants the index. Report to
1383 * the user the type of obd device the
1384 * returned index belongs too.
1386 * -EINVAL The obd device name is improper so
1387 * fsname could not be extracted.
1389 * -ENXIO Failed to extract the index out of
1390 * the obd device name. Most likely an
1391 * invalid obd device name
1393 static int mgs_parse_devname(char *devname, char *fsname, u32 *index)
1398 /* Extract fsname */
1400 rc = server_name2fsname(devname, fsname, NULL);
1402 CDEBUG(D_MGS, "Device name %s without fsname\n",
1409 rc = server_name2index(devname, index, NULL);
1411 CDEBUG(D_MGS, "Device name %s with wrong index\n",
1417 /* server_name2index can return LDD_F_SV_TYPE_* so always return rc */
1421 /* This is only called during replace_nids */
1422 static int only_mgs_is_running(struct obd_device *mgs_obd)
1424 /* TDB: Is global variable with devices count exists? */
1425 int num_devices = get_devices_count();
1426 int num_exports = 0;
1427 struct obd_export *exp;
1429 spin_lock(&mgs_obd->obd_dev_lock);
1430 list_for_each_entry(exp, &mgs_obd->obd_exports, exp_obd_chain) {
1431 /* skip self export */
1432 if (exp == mgs_obd->obd_self_export)
1434 if (exp_connect_flags(exp) & OBD_CONNECT_MDS_MDS)
1439 CERROR("%s: node %s still connected during replace_nids "
1440 "connect_flags:%llx\n",
1442 libcfs_nid2str(exp->exp_nid_stats->nid),
1443 exp_connect_flags(exp));
1446 spin_unlock(&mgs_obd->obd_dev_lock);
1448 /* osd, MGS and MGC + self_export
1449 (wc -l /proc/fs/lustre/devices <= 2) && (non self exports == 0) */
1450 return (num_devices <= 3) && (num_exports == 0);
1453 static int name_create_mdt(char **logname, char *fsname, int i)
1457 sprintf(mdt_index, "-MDT%04x", i);
1458 return name_create(logname, fsname, mdt_index);
1462 * Replace nids for \a device to \a nids values
1464 * \param obd MGS obd device
1465 * \param devname nids need to be replaced for this device
1466 * (ex. lustre-OST0000)
1467 * \param nids nids list (ex. nid1,nid2,nid3)
1471 int mgs_replace_nids(const struct lu_env *env,
1472 struct mgs_device *mgs,
1473 char *devname, char *nids)
1475 /* Assume fsname is part of device name */
1476 char fsname[MTI_NAME_MAXLEN];
1480 struct fs_db *fsdb = NULL;
1483 struct obd_device *mgs_obd = mgs->mgs_obd;
1486 /* We can only change NIDs if no other nodes are connected */
1487 spin_lock(&mgs_obd->obd_dev_lock);
1488 conn_state = mgs_obd->obd_no_conn;
1489 mgs_obd->obd_no_conn = 1;
1490 spin_unlock(&mgs_obd->obd_dev_lock);
1492 /* We can not change nids if not only MGS is started */
1493 if (!only_mgs_is_running(mgs_obd)) {
1494 CERROR("Only MGS is allowed to be started\n");
1495 GOTO(out, rc = -EINPROGRESS);
1498 /* Get fsname and index */
1499 rc = mgs_parse_devname(devname, fsname, &index);
1503 rc = mgs_find_or_make_fsdb(env, mgs, fsname, &fsdb);
1505 CERROR("%s: can't find fsdb: rc = %d\n", fsname, rc);
1509 /* Process client llogs */
1510 name_create(&logname, fsname, "-client");
1511 rc = mgs_replace_nids_log(env, mgs_obd, logname, devname, nids);
1512 name_destroy(&logname);
1514 CERROR("%s: error while replacing NIDs for %s: rc = %d\n",
1515 fsname, devname, rc);
1519 /* Process MDT llogs */
1520 for (i = 0; i < INDEX_MAP_SIZE * 8; i++) {
1521 if (!test_bit(i, fsdb->fsdb_mdt_index_map))
1523 name_create_mdt(&logname, fsname, i);
1524 rc = mgs_replace_nids_log(env, mgs_obd, logname, devname, nids);
1525 name_destroy(&logname);
1531 spin_lock(&mgs_obd->obd_dev_lock);
1532 mgs_obd->obd_no_conn = conn_state;
1533 spin_unlock(&mgs_obd->obd_dev_lock);
1536 mgs_put_fsdb(mgs, fsdb);
1542 * This is called for every record in llog. Some of records are
1543 * skipped, others are copied to new log as is.
1544 * Records to be skipped are
1545 * marker records marked SKIP
1546 * records enclosed between SKIP markers
1548 * \param[in] llh log to be processed
1549 * \param[in] rec current record
1550 * \param[in] data mgs_replace_data structure
1554 static int mgs_clear_config_handler(const struct lu_env *env,
1555 struct llog_handle *llh,
1556 struct llog_rec_hdr *rec, void *data)
1558 struct mgs_replace_data *mrd;
1559 struct lustre_cfg *lcfg = REC_DATA(rec);
1560 int cfg_len = REC_DATA_LEN(rec);
1565 mrd = (struct mgs_replace_data *)data;
1567 if (rec->lrh_type != OBD_CFG_REC) {
1568 CDEBUG(D_MGS, "Config llog Name=%s, Record Index=%u, "
1569 "Unhandled Record Type=%#x\n", llh->lgh_name,
1570 rec->lrh_index, rec->lrh_type);
1574 rc = lustre_cfg_sanity_check(lcfg, cfg_len);
1576 CDEBUG(D_MGS, "Config llog Name=%s, Invalid config file.",
1581 if (lcfg->lcfg_command == LCFG_MARKER) {
1582 struct cfg_marker *marker;
1584 marker = lustre_cfg_buf(lcfg, 1);
1585 if (marker->cm_flags & CM_SKIP) {
1586 if (marker->cm_flags & CM_START)
1588 if (marker->cm_flags & CM_END)
1590 /* SKIP section started or finished */
1591 CDEBUG(D_MGS, "Skip idx=%d, rc=%d, len=%d, "
1592 "cmd %x %s %s\n", rec->lrh_index, rc,
1593 rec->lrh_len, lcfg->lcfg_command,
1594 lustre_cfg_string(lcfg, 0),
1595 lustre_cfg_string(lcfg, 1));
1600 /* record enclosed between SKIP markers, skip it */
1601 CDEBUG(D_MGS, "Skip idx=%d, rc=%d, len=%d, "
1602 "cmd %x %s %s\n", rec->lrh_index, rc,
1603 rec->lrh_len, lcfg->lcfg_command,
1604 lustre_cfg_string(lcfg, 0),
1605 lustre_cfg_string(lcfg, 1));
1610 /* Record is placed in temporary llog as is */
1611 rc = llog_write(env, mrd->temp_llh, rec, LLOG_NEXT_IDX);
1613 CDEBUG(D_MGS, "Copied idx=%d, rc=%d, len=%d, cmd %x %s %s\n",
1614 rec->lrh_index, rc, rec->lrh_len, lcfg->lcfg_command,
1615 lustre_cfg_string(lcfg, 0), lustre_cfg_string(lcfg, 1));
1620 * Directory CONFIGS/ may contain files which are not config logs to
1621 * be cleared. Skip any llogs with a non-alphanumeric character after
1622 * the last '-'. For example, fsname-MDT0000.sav, fsname-MDT0000.bak,
1623 * fsname-MDT0000.orig, fsname-MDT0000~, fsname-MDT0000.20150516, etc.
1625 static bool config_to_clear(const char *logname)
1630 str = strrchr(logname, '-');
1635 while (isalnum(str[++i]));
1636 return str[i] == '\0';
1640 * Clear config logs for \a name
1643 * \param mgs MGS device
1644 * \param name name of device or of filesystem
1645 * (ex. lustre-OST0000 or lustre) in later case all logs
1650 int mgs_clear_configs(const struct lu_env *env,
1651 struct mgs_device *mgs, const char *name)
1653 struct list_head dentry_list;
1654 struct mgs_direntry *dirent, *n;
1657 struct obd_device *mgs_obd = mgs->mgs_obd;
1662 /* Prevent clients and servers from connecting to mgs */
1663 spin_lock(&mgs_obd->obd_dev_lock);
1664 conn_state = mgs_obd->obd_no_conn;
1665 mgs_obd->obd_no_conn = 1;
1666 spin_unlock(&mgs_obd->obd_dev_lock);
1669 * config logs cannot be cleaned if anything other than
1672 if (!only_mgs_is_running(mgs_obd)) {
1673 CERROR("Only MGS is allowed to be started\n");
1674 GOTO(out, rc = -EBUSY);
1677 /* Find all the logs in the CONFIGS directory */
1678 rc = class_dentry_readdir(env, mgs, &dentry_list);
1680 CERROR("%s: cannot read config directory '%s': rc = %d\n",
1681 mgs_obd->obd_name, MOUNT_CONFIGS_DIR, rc);
1685 if (list_empty(&dentry_list)) {
1686 CERROR("%s: list empty reading config dir '%s': rc = %d\n",
1687 mgs_obd->obd_name, MOUNT_CONFIGS_DIR, -ENOENT);
1688 GOTO(out, rc = -ENOENT);
1691 OBD_ALLOC(namedash, strlen(name) + 2);
1692 if (namedash == NULL)
1693 GOTO(out, rc = -ENOMEM);
1694 snprintf(namedash, strlen(name) + 2, "%s-", name);
1696 list_for_each_entry(dirent, &dentry_list, mde_list) {
1697 if (strcmp(name, dirent->mde_name) &&
1698 strncmp(namedash, dirent->mde_name, strlen(namedash)))
1700 if (!config_to_clear(dirent->mde_name))
1702 CDEBUG(D_MGS, "%s: Clear config log %s\n",
1703 mgs_obd->obd_name, dirent->mde_name);
1704 rc = mgs_replace_log(env, mgs_obd, dirent->mde_name, NULL,
1705 mgs_clear_config_handler, NULL);
1710 list_for_each_entry_safe(dirent, n, &dentry_list, mde_list) {
1711 list_del_init(&dirent->mde_list);
1712 mgs_direntry_free(dirent);
1714 OBD_FREE(namedash, strlen(name) + 2);
1716 spin_lock(&mgs_obd->obd_dev_lock);
1717 mgs_obd->obd_no_conn = conn_state;
1718 spin_unlock(&mgs_obd->obd_dev_lock);
1723 static int record_lov_setup(const struct lu_env *env, struct llog_handle *llh,
1724 char *devname, struct lov_desc *desc)
1726 struct mgs_thread_info *mgi = mgs_env_info(env);
1727 struct llog_cfg_rec *lcr;
1730 lustre_cfg_bufs_reset(&mgi->mgi_bufs, devname);
1731 lustre_cfg_bufs_set(&mgi->mgi_bufs, 1, desc, sizeof(*desc));
1732 lcr = lustre_cfg_rec_new(LCFG_SETUP, &mgi->mgi_bufs);
1736 rc = llog_write(env, llh, &lcr->lcr_hdr, LLOG_NEXT_IDX);
1737 lustre_cfg_rec_free(lcr);
1741 static int record_lmv_setup(const struct lu_env *env, struct llog_handle *llh,
1742 char *devname, struct lmv_desc *desc)
1744 struct mgs_thread_info *mgi = mgs_env_info(env);
1745 struct llog_cfg_rec *lcr;
1748 lustre_cfg_bufs_reset(&mgi->mgi_bufs, devname);
1749 lustre_cfg_bufs_set(&mgi->mgi_bufs, 1, desc, sizeof(*desc));
1750 lcr = lustre_cfg_rec_new(LCFG_SETUP, &mgi->mgi_bufs);
1754 rc = llog_write(env, llh, &lcr->lcr_hdr, LLOG_NEXT_IDX);
1755 lustre_cfg_rec_free(lcr);
1759 static inline int record_mdc_add(const struct lu_env *env,
1760 struct llog_handle *llh,
1761 char *logname, char *mdcuuid,
1762 char *mdtuuid, char *index,
1765 return record_base(env,llh,logname,0,LCFG_ADD_MDC,
1766 mdtuuid,index,gen,mdcuuid);
1769 static inline int record_lov_add(const struct lu_env *env,
1770 struct llog_handle *llh,
1771 char *lov_name, char *ost_uuid,
1772 char *index, char *gen)
1774 return record_base(env, llh, lov_name, 0, LCFG_LOV_ADD_OBD,
1775 ost_uuid, index, gen, NULL);
1778 static inline int record_mount_opt(const struct lu_env *env,
1779 struct llog_handle *llh,
1780 char *profile, char *lov_name,
1783 return record_base(env, llh, NULL, 0, LCFG_MOUNTOPT,
1784 profile, lov_name, mdc_name, NULL);
1787 static int record_marker(const struct lu_env *env,
1788 struct llog_handle *llh,
1789 struct fs_db *fsdb, __u32 flags,
1790 char *tgtname, char *comment)
1792 struct mgs_thread_info *mgi = mgs_env_info(env);
1793 struct llog_cfg_rec *lcr;
1797 if (flags & CM_START)
1799 mgi->mgi_marker.cm_step = fsdb->fsdb_gen;
1800 mgi->mgi_marker.cm_flags = flags;
1801 mgi->mgi_marker.cm_vers = LUSTRE_VERSION_CODE;
1802 cplen = strlcpy(mgi->mgi_marker.cm_tgtname, tgtname,
1803 sizeof(mgi->mgi_marker.cm_tgtname));
1804 if (cplen >= sizeof(mgi->mgi_marker.cm_tgtname))
1806 cplen = strlcpy(mgi->mgi_marker.cm_comment, comment,
1807 sizeof(mgi->mgi_marker.cm_comment));
1808 if (cplen >= sizeof(mgi->mgi_marker.cm_comment))
1810 mgi->mgi_marker.cm_createtime = ktime_get_real_seconds();
1811 mgi->mgi_marker.cm_canceltime = 0;
1812 lustre_cfg_bufs_reset(&mgi->mgi_bufs, NULL);
1813 lustre_cfg_bufs_set(&mgi->mgi_bufs, 1, &mgi->mgi_marker,
1814 sizeof(mgi->mgi_marker));
1815 lcr = lustre_cfg_rec_new(LCFG_MARKER, &mgi->mgi_bufs);
1819 rc = llog_write(env, llh, &lcr->lcr_hdr, LLOG_NEXT_IDX);
1820 lustre_cfg_rec_free(lcr);
1824 static int record_start_log(const struct lu_env *env, struct mgs_device *mgs,
1825 struct llog_handle **llh, char *name)
1827 static struct obd_uuid cfg_uuid = { .uuid = "config_uuid" };
1828 struct llog_ctxt *ctxt;
1833 GOTO(out, rc = -EBUSY);
1835 ctxt = llog_get_context(mgs->mgs_obd, LLOG_CONFIG_ORIG_CTXT);
1837 GOTO(out, rc = -ENODEV);
1838 LASSERT(ctxt->loc_obd == mgs->mgs_obd);
1840 rc = llog_open_create(env, ctxt, llh, NULL, name);
1843 rc = llog_init_handle(env, *llh, LLOG_F_IS_PLAIN, &cfg_uuid);
1845 llog_close(env, *llh);
1847 llog_ctxt_put(ctxt);
1850 CERROR("%s: can't start log %s: rc = %d\n",
1851 mgs->mgs_obd->obd_name, name, rc);
1857 static int record_end_log(const struct lu_env *env, struct llog_handle **llh)
1861 rc = llog_close(env, *llh);
1867 /******************** config "macros" *********************/
1869 /* write an lcfg directly into a log (with markers) */
1870 static int mgs_write_log_direct(const struct lu_env *env,
1871 struct mgs_device *mgs, struct fs_db *fsdb,
1872 char *logname, struct llog_cfg_rec *lcr,
1873 char *devname, char *comment)
1875 struct llog_handle *llh = NULL;
1880 rc = record_start_log(env, mgs, &llh, logname);
1884 /* FIXME These should be a single journal transaction */
1885 rc = record_marker(env, llh, fsdb, CM_START, devname, comment);
1888 rc = llog_write(env, llh, &lcr->lcr_hdr, LLOG_NEXT_IDX);
1891 rc = record_marker(env, llh, fsdb, CM_END, devname, comment);
1895 record_end_log(env, &llh);
1899 /* write the lcfg in all logs for the given fs */
1900 static int mgs_write_log_direct_all(const struct lu_env *env,
1901 struct mgs_device *mgs,
1903 struct mgs_target_info *mti,
1904 struct llog_cfg_rec *lcr, char *devname,
1905 char *comment, int server_only)
1907 struct list_head log_list;
1908 struct mgs_direntry *dirent, *n;
1909 char *fsname = mti->mti_fsname;
1910 int rc = 0, len = strlen(fsname);
1913 /* Find all the logs in the CONFIGS directory */
1914 rc = class_dentry_readdir(env, mgs, &log_list);
1918 /* Could use fsdb index maps instead of directory listing */
1919 list_for_each_entry_safe(dirent, n, &log_list, mde_list) {
1920 list_del_init(&dirent->mde_list);
1921 /* don't write to sptlrpc rule log */
1922 if (strstr(dirent->mde_name, "-sptlrpc") != NULL)
1925 /* caller wants write server logs only */
1926 if (server_only && strstr(dirent->mde_name, "-client") != NULL)
1929 if (strlen(dirent->mde_name) <= len ||
1930 strncmp(fsname, dirent->mde_name, len) != 0 ||
1931 dirent->mde_name[len] != '-')
1934 CDEBUG(D_MGS, "Changing log %s\n", dirent->mde_name);
1935 /* Erase any old settings of this same parameter */
1936 rc = mgs_modify(env, mgs, fsdb, mti, dirent->mde_name,
1937 devname, comment, CM_SKIP);
1939 CERROR("%s: Can't modify llog %s: rc = %d\n",
1940 mgs->mgs_obd->obd_name, dirent->mde_name, rc);
1943 /* Write the new one */
1944 rc = mgs_write_log_direct(env, mgs, fsdb, dirent->mde_name,
1945 lcr, devname, comment);
1947 CERROR("%s: writing log %s: rc = %d\n",
1948 mgs->mgs_obd->obd_name, dirent->mde_name, rc);
1950 mgs_direntry_free(dirent);
1956 static int mgs_write_log_osp_to_mdt(const struct lu_env *env,
1957 struct mgs_device *mgs,
1959 struct mgs_target_info *mti,
1960 int index, char *logname);
1961 static int mgs_write_log_osc_to_lov(const struct lu_env *env,
1962 struct mgs_device *mgs,
1964 struct mgs_target_info *mti,
1965 char *logname, char *suffix, char *lovname,
1966 enum lustre_sec_part sec_part, int flags);
1967 static int name_create_mdt_and_lov(char **logname, char **lovname,
1968 struct fs_db *fsdb, int i);
1970 static int add_param(char *params, char *key, char *val)
1972 char *start = params + strlen(params);
1973 char *end = params + sizeof(((struct mgs_target_info *)0)->mti_params);
1977 keylen = strlen(key);
1978 if (start + 1 + keylen + strlen(val) >= end) {
1979 CERROR("params are too long: %s %s%s\n",
1980 params, key != NULL ? key : "", val);
1984 sprintf(start, " %s%s", key != NULL ? key : "", val);
1989 * Walk through client config log record and convert the related records
1992 static int mgs_steal_client_llog_handler(const struct lu_env *env,
1993 struct llog_handle *llh,
1994 struct llog_rec_hdr *rec, void *data)
1996 struct mgs_device *mgs;
1997 struct obd_device *obd;
1998 struct mgs_target_info *mti, *tmti;
2000 int cfg_len = rec->lrh_len;
2001 char *cfg_buf = (char*) (rec + 1);
2002 struct lustre_cfg *lcfg;
2004 struct llog_handle *mdt_llh = NULL;
2005 static int got_an_osc_or_mdc = 0;
2006 /* 0: not found any osc/mdc;
2010 static int last_step = -1;
2015 mti = ((struct temp_comp*)data)->comp_mti;
2016 tmti = ((struct temp_comp*)data)->comp_tmti;
2017 fsdb = ((struct temp_comp*)data)->comp_fsdb;
2018 obd = ((struct temp_comp *)data)->comp_obd;
2019 mgs = lu2mgs_dev(obd->obd_lu_dev);
2022 if (rec->lrh_type != OBD_CFG_REC) {
2023 CERROR("unhandled lrh_type: %#x\n", rec->lrh_type);
2027 rc = lustre_cfg_sanity_check(cfg_buf, cfg_len);
2029 CERROR("Insane cfg\n");
2033 lcfg = (struct lustre_cfg *)cfg_buf;
2035 if (lcfg->lcfg_command == LCFG_MARKER) {
2036 struct cfg_marker *marker;
2037 marker = lustre_cfg_buf(lcfg, 1);
2038 if (!strncmp(marker->cm_comment, "add osc", 7) &&
2039 (marker->cm_flags & CM_START) &&
2040 !(marker->cm_flags & CM_SKIP)) {
2041 got_an_osc_or_mdc = 1;
2042 cplen = strlcpy(tmti->mti_svname, marker->cm_tgtname,
2043 sizeof(tmti->mti_svname));
2044 if (cplen >= sizeof(tmti->mti_svname))
2046 rc = record_start_log(env, mgs, &mdt_llh,
2050 rc = record_marker(env, mdt_llh, fsdb, CM_START,
2051 mti->mti_svname, "add osc(copied)");
2052 record_end_log(env, &mdt_llh);
2053 last_step = marker->cm_step;
2056 if (!strncmp(marker->cm_comment, "add osc", 7) &&
2057 (marker->cm_flags & CM_END) &&
2058 !(marker->cm_flags & CM_SKIP)) {
2059 LASSERT(last_step == marker->cm_step);
2061 got_an_osc_or_mdc = 0;
2062 memset(tmti, 0, sizeof(*tmti));
2063 rc = record_start_log(env, mgs, &mdt_llh,
2067 rc = record_marker(env, mdt_llh, fsdb, CM_END,
2068 mti->mti_svname, "add osc(copied)");
2069 record_end_log(env, &mdt_llh);
2072 if (!strncmp(marker->cm_comment, "add mdc", 7) &&
2073 (marker->cm_flags & CM_START) &&
2074 !(marker->cm_flags & CM_SKIP)) {
2075 got_an_osc_or_mdc = 2;
2076 last_step = marker->cm_step;
2077 memcpy(tmti->mti_svname, marker->cm_tgtname,
2078 strlen(marker->cm_tgtname));
2082 if (!strncmp(marker->cm_comment, "add mdc", 7) &&
2083 (marker->cm_flags & CM_END) &&
2084 !(marker->cm_flags & CM_SKIP)) {
2085 LASSERT(last_step == marker->cm_step);
2087 got_an_osc_or_mdc = 0;
2088 memset(tmti, 0, sizeof(*tmti));
2093 if (got_an_osc_or_mdc == 0 || last_step < 0)
2096 if (lcfg->lcfg_command == LCFG_ADD_UUID) {
2097 __u64 nodenid = lcfg->lcfg_nid;
2099 if (strlen(tmti->mti_uuid) == 0) {
2100 /* target uuid not set, this config record is before
2101 * LCFG_SETUP, this nid is one of target node nid.
2103 tmti->mti_nids[tmti->mti_nid_count] = nodenid;
2104 tmti->mti_nid_count++;
2106 char nidstr[LNET_NIDSTR_SIZE];
2108 /* failover node nid */
2109 libcfs_nid2str_r(nodenid, nidstr, sizeof(nidstr));
2110 rc = add_param(tmti->mti_params, PARAM_FAILNODE,
2117 if (lcfg->lcfg_command == LCFG_SETUP) {
2120 target = lustre_cfg_string(lcfg, 1);
2121 memcpy(tmti->mti_uuid, target, strlen(target));
2125 /* ignore client side sptlrpc_conf_log */
2126 if (lcfg->lcfg_command == LCFG_SPTLRPC_CONF)
2129 if (lcfg->lcfg_command == LCFG_ADD_MDC &&
2130 strstr(lustre_cfg_string(lcfg, 0), "-clilmv") != NULL) {
2133 if (sscanf(lustre_cfg_buf(lcfg, 2), "%d", &index) != 1)
2136 memcpy(tmti->mti_fsname, mti->mti_fsname,
2137 strlen(mti->mti_fsname));
2138 tmti->mti_stripe_index = index;
2140 rc = mgs_write_log_osp_to_mdt(env, mgs, fsdb, tmti,
2141 mti->mti_stripe_index,
2143 memset(tmti, 0, sizeof(*tmti));
2147 if (lcfg->lcfg_command == LCFG_LOV_ADD_OBD) {
2150 char *logname, *lovname;
2152 rc = name_create_mdt_and_lov(&logname, &lovname, fsdb,
2153 mti->mti_stripe_index);
2156 sprintf(mdt_index, "-MDT%04x", mti->mti_stripe_index);
2158 if (sscanf(lustre_cfg_buf(lcfg, 2), "%d", &index) != 1) {
2159 name_destroy(&logname);
2160 name_destroy(&lovname);
2164 tmti->mti_stripe_index = index;
2165 rc = mgs_write_log_osc_to_lov(env, mgs, fsdb, tmti, logname,
2168 name_destroy(&logname);
2169 name_destroy(&lovname);
2175 /* fsdb->fsdb_mutex is already held in mgs_write_log_target*/
2176 /* stealed from mgs_get_fsdb_from_llog*/
2177 static int mgs_steal_llog_for_mdt_from_client(const struct lu_env *env,
2178 struct mgs_device *mgs,
2180 struct temp_comp* comp)
2182 struct llog_handle *loghandle;
2183 struct mgs_target_info *tmti;
2184 struct llog_ctxt *ctxt;
2189 ctxt = llog_get_context(mgs->mgs_obd, LLOG_CONFIG_ORIG_CTXT);
2190 LASSERT(ctxt != NULL);
2192 OBD_ALLOC_PTR(tmti);
2194 GOTO(out_ctxt, rc = -ENOMEM);
2196 comp->comp_tmti = tmti;
2197 comp->comp_obd = mgs->mgs_obd;
2199 rc = llog_open(env, ctxt, &loghandle, NULL, client_name,
2207 rc = llog_init_handle(env, loghandle, LLOG_F_IS_PLAIN, NULL);
2209 GOTO(out_close, rc);
2211 rc = llog_process_or_fork(env, loghandle, mgs_steal_client_llog_handler,
2212 (void *)comp, NULL, false);
2213 CDEBUG(D_MGS, "steal llog re = %d\n", rc);
2215 llog_close(env, loghandle);
2219 llog_ctxt_put(ctxt);
2223 /* lmv is the second thing for client logs */
2224 /* copied from mgs_write_log_lov. Please refer to that. */
2225 static int mgs_write_log_lmv(const struct lu_env *env,
2226 struct mgs_device *mgs,
2228 struct mgs_target_info *mti,
2229 char *logname, char *lmvname)
2231 struct llog_handle *llh = NULL;
2232 struct lmv_desc *lmvdesc;
2237 CDEBUG(D_MGS, "Writing lmv(%s) log for %s\n", lmvname,logname);
2239 OBD_ALLOC_PTR(lmvdesc);
2240 if (lmvdesc == NULL)
2242 lmvdesc->ld_active_tgt_count = 0;
2243 lmvdesc->ld_tgt_count = 0;
2244 sprintf((char*)lmvdesc->ld_uuid.uuid, "%s_UUID", lmvname);
2245 uuid = (char *)lmvdesc->ld_uuid.uuid;
2247 rc = record_start_log(env, mgs, &llh, logname);
2250 rc = record_marker(env, llh, fsdb, CM_START, lmvname, "lmv setup");
2253 rc = record_attach(env, llh, lmvname, "lmv", uuid);
2256 rc = record_lmv_setup(env, llh, lmvname, lmvdesc);
2259 rc = record_marker(env, llh, fsdb, CM_END, lmvname, "lmv setup");
2263 record_end_log(env, &llh);
2265 OBD_FREE_PTR(lmvdesc);
2269 /* lov is the first thing in the mdt and client logs */
2270 static int mgs_write_log_lov(const struct lu_env *env, struct mgs_device *mgs,
2271 struct fs_db *fsdb, struct mgs_target_info *mti,
2272 char *logname, char *lovname)
2274 struct llog_handle *llh = NULL;
2275 struct lov_desc *lovdesc;
2280 CDEBUG(D_MGS, "Writing lov(%s) log for %s\n", lovname, logname);
2283 #01 L attach 0:lov_mdsA 1:lov 2:71ccb_lov_mdsA_19f961a9e1
2284 #02 L lov_setup 0:lov_mdsA 1:(struct lov_desc)
2285 uuid=lov1_UUID, stripe count=1, size=1048576, offset=0, pattern=0
2288 /* FIXME just make lov_setup accept empty desc (put uuid in buf 2) */
2289 OBD_ALLOC_PTR(lovdesc);
2290 if (lovdesc == NULL)
2292 lovdesc->ld_magic = LOV_DESC_MAGIC;
2293 lovdesc->ld_tgt_count = 0;
2294 /* Defaults. Can be changed later by lcfg config_param */
2295 lovdesc->ld_default_stripe_count = 1;
2296 lovdesc->ld_pattern = LOV_PATTERN_RAID0;
2297 lovdesc->ld_default_stripe_size = LOV_DESC_STRIPE_SIZE_DEFAULT;
2298 lovdesc->ld_default_stripe_offset = -1;
2299 lovdesc->ld_qos_maxage = LOV_DESC_QOS_MAXAGE_DEFAULT;
2300 sprintf((char*)lovdesc->ld_uuid.uuid, "%s_UUID", lovname);
2301 /* can these be the same? */
2302 uuid = (char *)lovdesc->ld_uuid.uuid;
2304 /* This should always be the first entry in a log.
2305 rc = mgs_clear_log(obd, logname); */
2306 rc = record_start_log(env, mgs, &llh, logname);
2309 /* FIXME these should be a single journal transaction */
2310 rc = record_marker(env, llh, fsdb, CM_START, lovname, "lov setup");
2313 rc = record_attach(env, llh, lovname, "lov", uuid);
2316 rc = record_lov_setup(env, llh, lovname, lovdesc);
2319 rc = record_marker(env, llh, fsdb, CM_END, lovname, "lov setup");
2324 record_end_log(env, &llh);
2326 OBD_FREE_PTR(lovdesc);
2330 /* add failnids to open log */
2331 static int mgs_write_log_failnids(const struct lu_env *env,
2332 struct mgs_target_info *mti,
2333 struct llog_handle *llh,
2336 char *failnodeuuid = NULL;
2337 char *ptr = mti->mti_params;
2342 #03 L add_uuid nid=uml1@tcp(0x20000c0a80201) nal=90 0: 1:uml1_UUID
2343 #04 L add_uuid nid=1@elan(0x1000000000001) nal=90 0: 1:uml1_UUID
2344 #05 L setup 0:OSC_uml1_ost1_mdsA 1:ost1_UUID 2:uml1_UUID
2345 #06 L add_uuid nid=uml2@tcp(0x20000c0a80202) nal=90 0: 1:uml2_UUID
2346 #0x L add_uuid nid=2@elan(0x1000000000002) nal=90 0: 1:uml2_UUID
2347 #07 L add_conn 0:OSC_uml1_ost1_mdsA 1:uml2_UUID
2351 * Pull failnid info out of params string, which may contain something
2352 * like "<nid1>,<nid2>:<nid3>,<nid4>". class_parse_nid() does not
2353 * complain about abnormal inputs like ",:<nid1>", "<nid1>:,<nid2>",
2354 * etc. However, convert_hostnames() should have caught those.
2356 while (class_find_param(ptr, PARAM_FAILNODE, &ptr) == 0) {
2357 while (class_parse_nid(ptr, &nid, &ptr) == 0) {
2358 char nidstr[LNET_NIDSTR_SIZE];
2360 if (failnodeuuid == NULL) {
2361 /* We don't know the failover node name,
2362 * so just use the first nid as the uuid */
2363 libcfs_nid2str_r(nid, nidstr, sizeof(nidstr));
2364 rc = name_create(&failnodeuuid, nidstr, "");
2368 CDEBUG(D_MGS, "add nid %s for failover uuid %s, "
2370 libcfs_nid2str_r(nid, nidstr, sizeof(nidstr)),
2371 failnodeuuid, cliname);
2372 rc = record_add_uuid(env, llh, nid, failnodeuuid);
2374 * If *ptr is ':', we have added all NIDs for
2378 rc = record_add_conn(env, llh, cliname,
2380 name_destroy(&failnodeuuid);
2381 failnodeuuid = NULL;
2385 rc = record_add_conn(env, llh, cliname, failnodeuuid);
2386 name_destroy(&failnodeuuid);
2387 failnodeuuid = NULL;
2394 static int mgs_write_log_mdc_to_lmv(const struct lu_env *env,
2395 struct mgs_device *mgs,
2397 struct mgs_target_info *mti,
2398 char *logname, char *lmvname)
2400 struct llog_handle *llh = NULL;
2401 char *mdcname = NULL;
2402 char *nodeuuid = NULL;
2403 char *mdcuuid = NULL;
2404 char *lmvuuid = NULL;
2406 char nidstr[LNET_NIDSTR_SIZE];
2410 if (mgs_log_is_empty(env, mgs, logname)) {
2411 CERROR("log is empty! Logical error\n");
2415 CDEBUG(D_MGS, "adding mdc for %s to log %s:lmv(%s)\n",
2416 mti->mti_svname, logname, lmvname);
2418 libcfs_nid2str_r(mti->mti_nids[0], nidstr, sizeof(nidstr));
2419 rc = name_create(&nodeuuid, nidstr, "");
2422 rc = name_create(&mdcname, mti->mti_svname, "-mdc");
2425 rc = name_create(&mdcuuid, mdcname, "_UUID");
2428 rc = name_create(&lmvuuid, lmvname, "_UUID");
2432 rc = record_start_log(env, mgs, &llh, logname);
2435 rc = record_marker(env, llh, fsdb, CM_START, mti->mti_svname,
2439 for (i = 0; i < mti->mti_nid_count; i++) {
2440 CDEBUG(D_MGS, "add nid %s for mdt\n",
2441 libcfs_nid2str_r(mti->mti_nids[i],
2442 nidstr, sizeof(nidstr)));
2444 rc = record_add_uuid(env, llh, mti->mti_nids[i], nodeuuid);
2449 rc = record_attach(env, llh, mdcname, LUSTRE_MDC_NAME, lmvuuid);
2452 rc = record_setup(env, llh, mdcname, mti->mti_uuid, nodeuuid,
2456 rc = mgs_write_log_failnids(env, mti, llh, mdcname);
2459 snprintf(index, sizeof(index), "%d", mti->mti_stripe_index);
2460 rc = record_mdc_add(env, llh, lmvname, mdcuuid, mti->mti_uuid,
2464 rc = record_marker(env, llh, fsdb, CM_END, mti->mti_svname,
2469 record_end_log(env, &llh);
2471 name_destroy(&lmvuuid);
2472 name_destroy(&mdcuuid);
2473 name_destroy(&mdcname);
2474 name_destroy(&nodeuuid);
2478 static inline int name_create_lov(char **lovname, char *mdtname,
2479 struct fs_db *fsdb, int index)
2482 if (index == 0 && test_bit(FSDB_OSCNAME18, &fsdb->fsdb_flags))
2483 return name_create(lovname, fsdb->fsdb_name, "-mdtlov");
2485 return name_create(lovname, mdtname, "-mdtlov");
2488 static int name_create_mdt_and_lov(char **logname, char **lovname,
2489 struct fs_db *fsdb, int i)
2493 rc = name_create_mdt(logname, fsdb->fsdb_name, i);
2497 if (i == 0 && test_bit(FSDB_OSCNAME18, &fsdb->fsdb_flags))
2498 rc = name_create(lovname, fsdb->fsdb_name, "-mdtlov");
2500 rc = name_create(lovname, *logname, "-mdtlov");
2502 name_destroy(logname);
2508 static inline int name_create_mdt_osc(char **oscname, char *ostname,
2509 struct fs_db *fsdb, int i)
2513 if (i == 0 && test_bit(FSDB_OSCNAME18, &fsdb->fsdb_flags))
2514 sprintf(suffix, "-osc");
2516 sprintf(suffix, "-osc-MDT%04x", i);
2517 return name_create(oscname, ostname, suffix);
2520 /* add new mdc to already existent MDS */
2521 static int mgs_write_log_osp_to_mdt(const struct lu_env *env,
2522 struct mgs_device *mgs,
2524 struct mgs_target_info *mti,
2525 int mdt_index, char *logname)
2527 struct llog_handle *llh = NULL;
2528 char *nodeuuid = NULL;
2529 char *ospname = NULL;
2530 char *lovuuid = NULL;
2531 char *mdtuuid = NULL;
2532 char *svname = NULL;
2533 char *mdtname = NULL;
2534 char *lovname = NULL;
2536 char nidstr[LNET_NIDSTR_SIZE];
2540 if (mgs_log_is_empty(env, mgs, mti->mti_svname)) {
2541 CERROR("log is empty! Logical error\n");
2545 CDEBUG(D_MGS, "adding osp index %d to %s\n", mti->mti_stripe_index,
2548 rc = name_create_mdt(&mdtname, fsdb->fsdb_name, mti->mti_stripe_index);
2552 libcfs_nid2str_r(mti->mti_nids[0], nidstr, sizeof(nidstr));
2553 rc = name_create(&nodeuuid, nidstr, "");
2555 GOTO(out_destory, rc);
2557 rc = name_create(&svname, mdtname, "-osp");
2559 GOTO(out_destory, rc);
2561 sprintf(index_str, "-MDT%04x", mdt_index);
2562 rc = name_create(&ospname, svname, index_str);
2564 GOTO(out_destory, rc);
2566 rc = name_create_lov(&lovname, logname, fsdb, mdt_index);
2568 GOTO(out_destory, rc);
2570 rc = name_create(&lovuuid, lovname, "_UUID");
2572 GOTO(out_destory, rc);
2574 rc = name_create(&mdtuuid, mdtname, "_UUID");
2576 GOTO(out_destory, rc);
2578 rc = record_start_log(env, mgs, &llh, logname);
2580 GOTO(out_destory, rc);
2582 rc = record_marker(env, llh, fsdb, CM_START, mti->mti_svname,
2585 GOTO(out_destory, rc);
2587 for (i = 0; i < mti->mti_nid_count; i++) {
2588 CDEBUG(D_MGS, "add nid %s for mdt\n",
2589 libcfs_nid2str_r(mti->mti_nids[i],
2590 nidstr, sizeof(nidstr)));
2591 rc = record_add_uuid(env, llh, mti->mti_nids[i], nodeuuid);
2596 rc = record_attach(env, llh, ospname, LUSTRE_OSP_NAME, lovuuid);
2600 rc = record_setup(env, llh, ospname, mti->mti_uuid, nodeuuid,
2605 rc = mgs_write_log_failnids(env, mti, llh, ospname);
2609 /* Add mdc(osp) to lod */
2610 snprintf(index_str, sizeof(index_str), "%d", mti->mti_stripe_index);
2611 rc = record_base(env, llh, lovname, 0, LCFG_ADD_MDC, mti->mti_uuid,
2612 index_str, "1", NULL);
2616 rc = record_marker(env, llh, fsdb, CM_END, mti->mti_svname, "add osp");
2621 record_end_log(env, &llh);
2624 name_destroy(&mdtuuid);
2625 name_destroy(&lovuuid);
2626 name_destroy(&lovname);
2627 name_destroy(&ospname);
2628 name_destroy(&svname);
2629 name_destroy(&nodeuuid);
2630 name_destroy(&mdtname);
2634 static int mgs_write_log_mdt0(const struct lu_env *env,
2635 struct mgs_device *mgs,
2637 struct mgs_target_info *mti)
2639 char *log = mti->mti_svname;
2640 struct llog_handle *llh = NULL;
2641 char *uuid, *lovname;
2643 char *ptr = mti->mti_params;
2644 int rc = 0, failout = 0;
2647 OBD_ALLOC(uuid, sizeof(struct obd_uuid));
2651 if (class_find_param(ptr, PARAM_FAILMODE, &ptr) == 0)
2652 failout = (strncmp(ptr, "failout", 7) == 0);
2654 rc = name_create(&lovname, log, "-mdtlov");
2657 if (mgs_log_is_empty(env, mgs, log)) {
2658 rc = mgs_write_log_lov(env, mgs, fsdb, mti, log, lovname);
2663 sprintf(mdt_index, "%d", mti->mti_stripe_index);
2665 rc = record_start_log(env, mgs, &llh, log);
2669 /* add MDT itself */
2671 /* FIXME this whole fn should be a single journal transaction */
2672 sprintf(uuid, "%s_UUID", log);
2673 rc = record_marker(env, llh, fsdb, CM_START, log, "add mdt");
2676 rc = record_attach(env, llh, log, LUSTRE_MDT_NAME, uuid);
2679 rc = record_mount_opt(env, llh, log, lovname, NULL);
2682 rc = record_setup(env, llh, log, uuid, mdt_index, lovname,
2683 failout ? "n" : "f");
2686 rc = record_marker(env, llh, fsdb, CM_END, log, "add mdt");
2690 record_end_log(env, &llh);
2692 name_destroy(&lovname);
2694 OBD_FREE(uuid, sizeof(struct obd_uuid));
2698 /* envelope method for all layers log */
2699 static int mgs_write_log_mdt(const struct lu_env *env,
2700 struct mgs_device *mgs,
2702 struct mgs_target_info *mti)
2704 struct mgs_thread_info *mgi = mgs_env_info(env);
2705 struct llog_handle *llh = NULL;
2710 CDEBUG(D_MGS, "writing new mdt %s\n", mti->mti_svname);
2712 if (mti->mti_uuid[0] == '\0') {
2713 /* Make up our own uuid */
2714 snprintf(mti->mti_uuid, sizeof(mti->mti_uuid),
2715 "%s_UUID", mti->mti_svname);
2719 rc = mgs_write_log_mdt0(env, mgs, fsdb, mti);
2722 /* Append the mdt info to the client log */
2723 rc = name_create(&cliname, mti->mti_fsname, "-client");
2727 if (mgs_log_is_empty(env, mgs, cliname)) {
2728 /* Start client log */
2729 rc = mgs_write_log_lov(env, mgs, fsdb, mti, cliname,
2733 rc = mgs_write_log_lmv(env, mgs, fsdb, mti, cliname,
2740 #09 L add_uuid nid=uml1@tcp(0x20000c0a80201) 0: 1:uml1_UUID
2741 #10 L attach 0:MDC_uml1_mdsA_MNT_client 1:mdc 2:1d834_MNT_client_03f
2742 #11 L setup 0:MDC_uml1_mdsA_MNT_client 1:mdsA_UUID 2:uml1_UUID
2743 #12 L add_uuid nid=uml2@tcp(0x20000c0a80202) 0: 1:uml2_UUID
2744 #13 L add_conn 0:MDC_uml1_mdsA_MNT_client 1:uml2_UUID
2745 #14 L mount_option 0: 1:client 2:lov1 3:MDC_uml1_mdsA_MNT_client
2748 /* copy client info about lov/lmv */
2749 mgi->mgi_comp.comp_mti = mti;
2750 mgi->mgi_comp.comp_fsdb = fsdb;
2752 rc = mgs_steal_llog_for_mdt_from_client(env, mgs, cliname,
2756 rc = mgs_write_log_mdc_to_lmv(env, mgs, fsdb, mti, cliname,
2762 rc = record_start_log(env, mgs, &llh, cliname);
2766 rc = record_marker(env, llh, fsdb, CM_START, cliname, "mount opts");
2769 rc = record_mount_opt(env, llh, cliname, fsdb->fsdb_clilov,
2773 rc = record_marker(env, llh, fsdb, CM_END, cliname, "mount opts");
2777 /* for_all_existing_mdt except current one */
2778 for (i = 0; i < INDEX_MAP_SIZE * 8; i++) {
2779 if (i != mti->mti_stripe_index &&
2780 test_bit(i, fsdb->fsdb_mdt_index_map)) {
2783 rc = name_create_mdt(&logname, fsdb->fsdb_name, i);
2787 /* NB: If the log for the MDT is empty, it means
2788 * the MDT is only added to the index
2789 * map, and not being process yet, i.e. this
2790 * is an unregistered MDT, see mgs_write_log_target().
2791 * so we should skip it. Otherwise
2793 * 1. MGS get register request for MDT1 and MDT2.
2795 * 2. Then both MDT1 and MDT2 are added into
2796 * fsdb_mdt_index_map. (see mgs_set_index()).
2798 * 3. Then MDT1 get the lock of fsdb_mutex, then
2799 * generate the config log, here, it will regard MDT2
2800 * as an existent MDT, and generate "add osp" for
2801 * lustre-MDT0001-osp-MDT0002. Note: at the moment
2802 * MDT0002 config log is still empty, so it will
2803 * add "add osp" even before "lov setup", which
2804 * will definitly cause trouble.
2806 * 4. MDT1 registeration finished, fsdb_mutex is
2807 * released, then MDT2 get in, then in above
2808 * mgs_steal_llog_for_mdt_from_client(), it will
2809 * add another osp log for lustre-MDT0001-osp-MDT0002,
2810 * which will cause another trouble.*/
2811 if (!mgs_log_is_empty(env, mgs, logname))
2812 rc = mgs_write_log_osp_to_mdt(env, mgs, fsdb,
2815 name_destroy(&logname);
2821 record_end_log(env, &llh);
2823 name_destroy(&cliname);
2827 /* Add the ost info to the client/mdt lov */
2828 static int mgs_write_log_osc_to_lov(const struct lu_env *env,
2829 struct mgs_device *mgs, struct fs_db *fsdb,
2830 struct mgs_target_info *mti,
2831 char *logname, char *suffix, char *lovname,
2832 enum lustre_sec_part sec_part, int flags)
2834 struct llog_handle *llh = NULL;
2835 char *nodeuuid = NULL;
2836 char *oscname = NULL;
2837 char *oscuuid = NULL;
2838 char *lovuuid = NULL;
2839 char *svname = NULL;
2841 char nidstr[LNET_NIDSTR_SIZE];
2845 CDEBUG(D_INFO, "adding osc for %s to log %s\n",
2846 mti->mti_svname, logname);
2848 if (mgs_log_is_empty(env, mgs, logname)) {
2849 CERROR("log is empty! Logical error\n");
2853 libcfs_nid2str_r(mti->mti_nids[0], nidstr, sizeof(nidstr));
2854 rc = name_create(&nodeuuid, nidstr, "");
2857 rc = name_create(&svname, mti->mti_svname, "-osc");
2861 /* for the system upgraded from old 1.8, keep using the old osc naming
2862 * style for mdt, see name_create_mdt_osc(). LU-1257 */
2863 if (test_bit(FSDB_OSCNAME18, &fsdb->fsdb_flags))
2864 rc = name_create(&oscname, svname, "");
2866 rc = name_create(&oscname, svname, suffix);
2870 rc = name_create(&oscuuid, oscname, "_UUID");
2873 rc = name_create(&lovuuid, lovname, "_UUID");
2879 #03 L add_uuid nid=uml1@tcp(0x20000c0a80201) 0: 1:uml1_UUID
2881 #04 L add_uuid nid=1@elan(0x1000000000001) nal=90 0: 1:uml1_UUID
2882 #04 L attach 0:OSC_uml1_ost1_MNT_client 1:osc 2:89070_lov1_a41dff51a
2883 #05 L setup 0:OSC_uml1_ost1_MNT_client 1:ost1_UUID 2:uml1_UUID
2885 #06 L add_uuid nid=uml2@tcp(0x20000c0a80202) 0: 1:uml2_UUID
2886 #07 L add_conn 0:OSC_uml1_ost1_MNT_client 1:uml2_UUID
2887 #08 L lov_modify_tgts add 0:lov1 1:ost1_UUID 2(index):0 3(gen):1
2890 rc = record_start_log(env, mgs, &llh, logname);
2894 /* FIXME these should be a single journal transaction */
2895 rc = record_marker(env, llh, fsdb, CM_START | flags, mti->mti_svname,
2900 /* NB: don't change record order, because upon MDT steal OSC config
2901 * from client, it treats all nids before LCFG_SETUP as target nids
2902 * (multiple interfaces), while nids after as failover node nids.
2903 * See mgs_steal_client_llog_handler() LCFG_ADD_UUID.
2905 for (i = 0; i < mti->mti_nid_count; i++) {
2906 CDEBUG(D_MGS, "add nid %s\n",
2907 libcfs_nid2str_r(mti->mti_nids[i],
2908 nidstr, sizeof(nidstr)));
2909 rc = record_add_uuid(env, llh, mti->mti_nids[i], nodeuuid);
2913 rc = record_attach(env, llh, oscname, LUSTRE_OSC_NAME, lovuuid);
2916 rc = record_setup(env, llh, oscname, mti->mti_uuid, nodeuuid,
2920 rc = mgs_write_log_failnids(env, mti, llh, oscname);
2924 snprintf(index, sizeof(index), "%d", mti->mti_stripe_index);
2926 rc = record_lov_add(env, llh, lovname, mti->mti_uuid, index, "1");
2929 rc = record_marker(env, llh, fsdb, CM_END | flags, mti->mti_svname,
2934 record_end_log(env, &llh);
2936 name_destroy(&lovuuid);
2937 name_destroy(&oscuuid);
2938 name_destroy(&oscname);
2939 name_destroy(&svname);
2940 name_destroy(&nodeuuid);
2944 static int mgs_write_log_ost(const struct lu_env *env,
2945 struct mgs_device *mgs, struct fs_db *fsdb,
2946 struct mgs_target_info *mti)
2948 struct llog_handle *llh = NULL;
2949 char *logname, *lovname;
2950 char *ptr = mti->mti_params;
2951 int rc, flags = 0, failout = 0, i;
2954 CDEBUG(D_MGS, "writing new ost %s\n", mti->mti_svname);
2956 /* The ost startup log */
2958 /* If the ost log already exists, that means that someone reformatted
2959 the ost and it called target_add again. */
2960 if (!mgs_log_is_empty(env, mgs, mti->mti_svname)) {
2961 LCONSOLE_ERROR_MSG(0x141, "The config log for %s already "
2962 "exists, yet the server claims it never "
2963 "registered. It may have been reformatted, "
2964 "or the index changed. writeconf the MDT to "
2965 "regenerate all logs.\n", mti->mti_svname);
2970 attach obdfilter ost1 ost1_UUID
2971 setup /dev/loop2 ldiskfs f|n errors=remount-ro,user_xattr
2973 if (class_find_param(ptr, PARAM_FAILMODE, &ptr) == 0)
2974 failout = (strncmp(ptr, "failout", 7) == 0);
2975 rc = record_start_log(env, mgs, &llh, mti->mti_svname);
2978 /* FIXME these should be a single journal transaction */
2979 rc = record_marker(env, llh, fsdb, CM_START, mti->mti_svname,"add ost");
2982 if (*mti->mti_uuid == '\0')
2983 snprintf(mti->mti_uuid, sizeof(mti->mti_uuid),
2984 "%s_UUID", mti->mti_svname);
2985 rc = record_attach(env, llh, mti->mti_svname,
2986 "obdfilter"/*LUSTRE_OST_NAME*/, mti->mti_uuid);
2989 rc = record_setup(env, llh, mti->mti_svname,
2990 "dev"/*ignored*/, "type"/*ignored*/,
2991 failout ? "n" : "f", NULL/*options*/);
2994 rc = record_marker(env, llh, fsdb, CM_END, mti->mti_svname, "add ost");
2998 record_end_log(env, &llh);
3001 /* We also have to update the other logs where this osc is part of
3004 if (test_bit(FSDB_OLDLOG14, &fsdb->fsdb_flags)) {
3005 /* If we're upgrading, the old mdt log already has our
3006 entry. Let's do a fake one for fun. */
3007 /* Note that we can't add any new failnids, since we don't
3008 know the old osc names. */
3009 flags = CM_SKIP | CM_UPGRADE146;
3011 } else if ((mti->mti_flags & LDD_F_UPDATE) != LDD_F_UPDATE) {
3012 /* If the update flag isn't set, don't update client/mdt
3015 LCONSOLE_WARN("Client log for %s was not updated; writeconf "
3016 "the MDT first to regenerate it.\n",
3020 /* Add ost to all MDT lov defs */
3021 for (i = 0; i < INDEX_MAP_SIZE * 8; i++){
3022 if (test_bit(i, fsdb->fsdb_mdt_index_map)) {
3025 rc = name_create_mdt_and_lov(&logname, &lovname, fsdb,
3029 sprintf(mdt_index, "-MDT%04x", i);
3030 rc = mgs_write_log_osc_to_lov(env, mgs, fsdb, mti,
3032 lovname, LUSTRE_SP_MDT,
3034 name_destroy(&logname);
3035 name_destroy(&lovname);
3041 /* Append ost info to the client log */
3042 rc = name_create(&logname, mti->mti_fsname, "-client");
3045 if (mgs_log_is_empty(env, mgs, logname)) {
3046 /* Start client log */
3047 rc = mgs_write_log_lov(env, mgs, fsdb, mti, logname,
3051 rc = mgs_write_log_lmv(env, mgs, fsdb, mti, logname,
3056 rc = mgs_write_log_osc_to_lov(env, mgs, fsdb, mti, logname, "",
3057 fsdb->fsdb_clilov, LUSTRE_SP_CLI, flags);
3059 name_destroy(&logname);
3063 static __inline__ int mgs_param_empty(char *ptr)
3067 if ((tmp = strchr(ptr, '=')) && (*(++tmp) == '\0'))
3072 static int mgs_write_log_failnid_internal(const struct lu_env *env,
3073 struct mgs_device *mgs,
3075 struct mgs_target_info *mti,
3076 char *logname, char *cliname)
3079 struct llog_handle *llh = NULL;
3081 if (mgs_param_empty(mti->mti_params)) {
3082 /* Remove _all_ failnids */
3083 rc = mgs_modify(env, mgs, fsdb, mti, logname,
3084 mti->mti_svname, "add failnid", CM_SKIP);
3085 return rc < 0 ? rc : 0;
3088 /* Otherwise failover nids are additive */
3089 rc = record_start_log(env, mgs, &llh, logname);
3092 /* FIXME this should be a single journal transaction */
3093 rc = record_marker(env, llh, fsdb, CM_START, mti->mti_svname,
3097 rc = mgs_write_log_failnids(env, mti, llh, cliname);
3100 rc = record_marker(env, llh, fsdb, CM_END,
3101 mti->mti_svname, "add failnid");
3103 record_end_log(env, &llh);
3108 /* Add additional failnids to an existing log.
3109 The mdc/osc must have been added to logs first */
3110 /* tcp nids must be in dotted-quad ascii -
3111 we can't resolve hostnames from the kernel. */
3112 static int mgs_write_log_add_failnid(const struct lu_env *env,
3113 struct mgs_device *mgs,
3115 struct mgs_target_info *mti)
3117 char *logname, *cliname;
3121 /* FIXME we currently can't erase the failnids
3122 * given when a target first registers, since they aren't part of
3123 * an "add uuid" stanza
3126 /* Verify that we know about this target */
3127 if (mgs_log_is_empty(env, mgs, mti->mti_svname)) {
3128 LCONSOLE_ERROR_MSG(0x142, "The target %s has not registered "
3129 "yet. It must be started before failnids "
3130 "can be added.\n", mti->mti_svname);
3134 /* Create mdc/osc client name (e.g. lustre-OST0001-osc) */
3135 if (mti->mti_flags & LDD_F_SV_TYPE_MDT) {
3136 rc = name_create(&cliname, mti->mti_svname, "-mdc");
3137 } else if (mti->mti_flags & LDD_F_SV_TYPE_OST) {
3138 rc = name_create(&cliname, mti->mti_svname, "-osc");
3145 /* Add failover nids to the client log */
3146 rc = name_create(&logname, mti->mti_fsname, "-client");
3148 name_destroy(&cliname);
3152 rc = mgs_write_log_failnid_internal(env, mgs, fsdb,mti,logname,cliname);
3153 name_destroy(&logname);
3154 name_destroy(&cliname);
3158 if (mti->mti_flags & LDD_F_SV_TYPE_OST) {
3159 /* Add OST failover nids to the MDT logs as well */
3162 for (i = 0; i < INDEX_MAP_SIZE * 8; i++) {
3163 if (!test_bit(i, fsdb->fsdb_mdt_index_map))
3165 rc = name_create_mdt(&logname, mti->mti_fsname, i);
3168 rc = name_create_mdt_osc(&cliname, mti->mti_svname,
3171 name_destroy(&logname);
3174 rc = mgs_write_log_failnid_internal(env, mgs, fsdb,
3177 name_destroy(&cliname);
3178 name_destroy(&logname);
3187 static int mgs_wlp_lcfg(const struct lu_env *env,
3188 struct mgs_device *mgs, struct fs_db *fsdb,
3189 struct mgs_target_info *mti,
3190 char *logname, struct lustre_cfg_bufs *bufs,
3191 char *tgtname, char *ptr)
3193 char comment[MTI_NAME_MAXLEN];
3195 struct llog_cfg_rec *lcr;
3198 /* Erase any old settings of this same parameter */
3199 memcpy(comment, ptr, MTI_NAME_MAXLEN);
3200 comment[MTI_NAME_MAXLEN - 1] = 0;
3201 /* But don't try to match the value. */
3202 tmp = strchr(comment, '=');
3205 /* FIXME we should skip settings that are the same as old values */
3206 rc = mgs_modify(env, mgs, fsdb, mti, logname, tgtname, comment,CM_SKIP);
3209 del = mgs_param_empty(ptr);
3211 LCONSOLE_INFO("%s parameter %s.%s in log %s\n", del ? "Disabling" : rc ?
3212 "Setting" : "Modifying", tgtname, comment, logname);
3214 /* mgs_modify() will return 1 if nothing had to be done */
3220 lustre_cfg_bufs_reset(bufs, tgtname);
3221 lustre_cfg_bufs_set_string(bufs, 1, ptr);
3222 if (mti->mti_flags & LDD_F_PARAM2)
3223 lustre_cfg_bufs_set_string(bufs, 2, LCTL_UPCALL);
3225 lcr = lustre_cfg_rec_new((mti->mti_flags & LDD_F_PARAM2) ?
3226 LCFG_SET_PARAM : LCFG_PARAM, bufs);
3230 rc = mgs_write_log_direct(env, mgs, fsdb, logname, lcr, tgtname,
3232 lustre_cfg_rec_free(lcr);
3236 /* write global variable settings into log */
3237 static int mgs_write_log_sys(const struct lu_env *env,
3238 struct mgs_device *mgs, struct fs_db *fsdb,
3239 struct mgs_target_info *mti, char *sys, char *ptr)
3241 struct mgs_thread_info *mgi = mgs_env_info(env);
3242 struct lustre_cfg *lcfg;
3243 struct llog_cfg_rec *lcr;
3245 int rc, cmd, convert = 1;
3247 if (class_match_param(ptr, PARAM_TIMEOUT, &tmp) == 0) {
3248 cmd = LCFG_SET_TIMEOUT;
3249 } else if (class_match_param(ptr, PARAM_LDLM_TIMEOUT, &tmp) == 0) {
3250 cmd = LCFG_SET_LDLM_TIMEOUT;
3251 /* Check for known params here so we can return error to lctl */
3252 } else if ((class_match_param(ptr, PARAM_AT_MIN, &tmp) == 0) ||
3253 (class_match_param(ptr, PARAM_AT_MAX, &tmp) == 0) ||
3254 (class_match_param(ptr, PARAM_AT_EXTRA, &tmp) == 0) ||
3255 (class_match_param(ptr, PARAM_AT_EARLY_MARGIN, &tmp) == 0) ||
3256 (class_match_param(ptr, PARAM_AT_HISTORY, &tmp) == 0)) {
3258 } else if (class_match_param(ptr, PARAM_JOBID_VAR, &tmp) == 0) {
3259 convert = 0; /* Don't convert string value to integer */
3265 if (mgs_param_empty(ptr))
3266 CDEBUG(D_MGS, "global '%s' removed\n", sys);
3268 CDEBUG(D_MGS, "global '%s' val=%s\n", sys, tmp);
3270 lustre_cfg_bufs_reset(&mgi->mgi_bufs, NULL);
3271 lustre_cfg_bufs_set_string(&mgi->mgi_bufs, 1, sys);
3272 if (!convert && *tmp != '\0')
3273 lustre_cfg_bufs_set_string(&mgi->mgi_bufs, 2, tmp);
3274 lcr = lustre_cfg_rec_new(cmd, &mgi->mgi_bufs);
3278 lcfg = &lcr->lcr_cfg;
3279 lcfg->lcfg_num = convert ? simple_strtoul(tmp, NULL, 0) : 0;
3280 /* truncate the comment to the parameter name */
3284 /* modify all servers and clients */
3285 rc = mgs_write_log_direct_all(env, mgs, fsdb, mti,
3286 *tmp == '\0' ? NULL : lcr,
3287 mti->mti_fsname, sys, 0);
3288 if (rc == 0 && *tmp != '\0') {
3290 case LCFG_SET_TIMEOUT:
3291 if (!obd_timeout_set || lcfg->lcfg_num > obd_timeout)
3292 class_process_config(lcfg);
3294 case LCFG_SET_LDLM_TIMEOUT:
3295 if (!ldlm_timeout_set || lcfg->lcfg_num > ldlm_timeout)
3296 class_process_config(lcfg);
3303 lustre_cfg_rec_free(lcr);
3307 /* write quota settings into log */
3308 static int mgs_write_log_quota(const struct lu_env *env, struct mgs_device *mgs,
3309 struct fs_db *fsdb, struct mgs_target_info *mti,
3310 char *quota, char *ptr)
3312 struct mgs_thread_info *mgi = mgs_env_info(env);
3313 struct llog_cfg_rec *lcr;
3316 int rc, cmd = LCFG_PARAM;
3318 /* support only 'meta' and 'data' pools so far */
3319 if (class_match_param(ptr, QUOTA_METAPOOL_NAME, &tmp) != 0 &&
3320 class_match_param(ptr, QUOTA_DATAPOOL_NAME, &tmp) != 0) {
3321 CERROR("parameter quota.%s isn't supported (only quota.mdt "
3322 "& quota.ost are)\n", ptr);
3327 CDEBUG(D_MGS, "global '%s' removed\n", quota);
3329 CDEBUG(D_MGS, "global '%s'\n", quota);
3331 if (strchr(tmp, 'u') == NULL && strchr(tmp, 'g') == NULL &&
3332 strchr(tmp, 'p') == NULL &&
3333 strcmp(tmp, "none") != 0) {
3334 CERROR("enable option(%s) isn't supported\n", tmp);
3339 lustre_cfg_bufs_reset(&mgi->mgi_bufs, mti->mti_fsname);
3340 lustre_cfg_bufs_set_string(&mgi->mgi_bufs, 1, quota);
3341 lcr = lustre_cfg_rec_new(cmd, &mgi->mgi_bufs);
3345 /* truncate the comment to the parameter name */
3350 /* XXX we duplicated quota enable information in all server
3351 * config logs, it should be moved to a separate config
3352 * log once we cleanup the config log for global param. */
3353 /* modify all servers */
3354 rc = mgs_write_log_direct_all(env, mgs, fsdb, mti,
3355 *tmp == '\0' ? NULL : lcr,
3356 mti->mti_fsname, quota, 1);
3358 lustre_cfg_rec_free(lcr);
3359 return rc < 0 ? rc : 0;
3362 static int mgs_srpc_set_param_disk(const struct lu_env *env,
3363 struct mgs_device *mgs,
3365 struct mgs_target_info *mti,
3368 struct mgs_thread_info *mgi = mgs_env_info(env);
3369 struct llog_cfg_rec *lcr;
3370 struct llog_handle *llh = NULL;
3372 char *comment, *ptr;
3378 ptr = strchr(param, '=');
3379 LASSERT(ptr != NULL);
3382 OBD_ALLOC(comment, len + 1);
3383 if (comment == NULL)
3385 strncpy(comment, param, len);
3386 comment[len] = '\0';
3389 lustre_cfg_bufs_reset(&mgi->mgi_bufs, mti->mti_svname);
3390 lustre_cfg_bufs_set_string(&mgi->mgi_bufs, 1, param);
3391 lcr = lustre_cfg_rec_new(LCFG_SPTLRPC_CONF, &mgi->mgi_bufs);
3393 GOTO(out_comment, rc = -ENOMEM);
3395 /* construct log name */
3396 rc = name_create(&logname, mti->mti_fsname, "-sptlrpc");
3400 if (mgs_log_is_empty(env, mgs, logname)) {
3401 rc = record_start_log(env, mgs, &llh, logname);
3404 record_end_log(env, &llh);
3407 /* obsolete old one */
3408 rc = mgs_modify(env, mgs, fsdb, mti, logname, mti->mti_svname,
3412 /* write the new one */
3413 rc = mgs_write_log_direct(env, mgs, fsdb, logname, lcr,
3414 mti->mti_svname, comment);
3416 CERROR("%s: error writing log %s: rc = %d\n",
3417 mgs->mgs_obd->obd_name, logname, rc);
3419 name_destroy(&logname);
3421 lustre_cfg_rec_free(lcr);
3423 OBD_FREE(comment, len + 1);
3427 static int mgs_srpc_set_param_udesc_mem(struct fs_db *fsdb,
3432 /* disable the adjustable udesc parameter for now, i.e. use default
3433 * setting that client always ship udesc to MDT if possible. to enable
3434 * it simply remove the following line */
3437 ptr = strchr(param, '=');
3442 if (strcmp(param, PARAM_SRPC_UDESC))
3445 if (strcmp(ptr, "yes") == 0) {
3446 set_bit(FSDB_UDESC, &fsdb->fsdb_flags);
3447 CWARN("Enable user descriptor shipping from client to MDT\n");
3448 } else if (strcmp(ptr, "no") == 0) {
3449 clear_bit(FSDB_UDESC, &fsdb->fsdb_flags);
3450 CWARN("Disable user descriptor shipping from client to MDT\n");
3458 CERROR("Invalid param: %s\n", param);
3462 static int mgs_srpc_set_param_mem(struct fs_db *fsdb,
3466 struct sptlrpc_rule rule;
3467 struct sptlrpc_rule_set *rset;
3471 if (strncmp(param, PARAM_SRPC, sizeof(PARAM_SRPC) - 1) != 0) {
3472 CERROR("Invalid sptlrpc parameter: %s\n", param);
3476 if (strncmp(param, PARAM_SRPC_UDESC,
3477 sizeof(PARAM_SRPC_UDESC) - 1) == 0) {
3478 RETURN(mgs_srpc_set_param_udesc_mem(fsdb, param));
3481 if (strncmp(param, PARAM_SRPC_FLVR, sizeof(PARAM_SRPC_FLVR) - 1) != 0) {
3482 CERROR("Invalid sptlrpc flavor parameter: %s\n", param);
3486 param += sizeof(PARAM_SRPC_FLVR) - 1;
3488 rc = sptlrpc_parse_rule(param, &rule);
3492 /* mgs rules implies must be mgc->mgs */
3493 if (test_bit(FSDB_MGS_SELF, &fsdb->fsdb_flags)) {
3494 if ((rule.sr_from != LUSTRE_SP_MGC &&
3495 rule.sr_from != LUSTRE_SP_ANY) ||
3496 (rule.sr_to != LUSTRE_SP_MGS &&
3497 rule.sr_to != LUSTRE_SP_ANY))
3501 /* preapre room for this coming rule. svcname format should be:
3502 * - fsname: general rule
3503 * - fsname-tgtname: target-specific rule
3505 if (strchr(svname, '-')) {
3506 struct mgs_tgt_srpc_conf *tgtconf;
3509 for (tgtconf = fsdb->fsdb_srpc_tgt; tgtconf != NULL;
3510 tgtconf = tgtconf->mtsc_next) {
3511 if (!strcmp(tgtconf->mtsc_tgt, svname)) {
3520 OBD_ALLOC_PTR(tgtconf);
3521 if (tgtconf == NULL)
3524 name_len = strlen(svname);
3526 OBD_ALLOC(tgtconf->mtsc_tgt, name_len + 1);
3527 if (tgtconf->mtsc_tgt == NULL) {
3528 OBD_FREE_PTR(tgtconf);
3531 memcpy(tgtconf->mtsc_tgt, svname, name_len);
3533 tgtconf->mtsc_next = fsdb->fsdb_srpc_tgt;
3534 fsdb->fsdb_srpc_tgt = tgtconf;
3537 rset = &tgtconf->mtsc_rset;
3538 } else if (strcmp(svname, MGSSELF_NAME) == 0) {
3539 /* put _mgs related srpc rule directly in mgs ruleset */
3540 rset = &fsdb->fsdb_mgs->mgs_lut.lut_sptlrpc_rset;
3542 rset = &fsdb->fsdb_srpc_gen;
3545 rc = sptlrpc_rule_set_merge(rset, &rule);
3550 static int mgs_srpc_set_param(const struct lu_env *env,
3551 struct mgs_device *mgs,
3553 struct mgs_target_info *mti,
3563 /* keep a copy of original param, which could be destroied
3565 copy_size = strlen(param) + 1;
3566 OBD_ALLOC(copy, copy_size);
3569 memcpy(copy, param, copy_size);
3571 rc = mgs_srpc_set_param_mem(fsdb, mti->mti_svname, param);
3575 /* previous steps guaranteed the syntax is correct */
3576 rc = mgs_srpc_set_param_disk(env, mgs, fsdb, mti, copy);
3580 if (test_bit(FSDB_MGS_SELF, &fsdb->fsdb_flags)) {
3582 * for mgs rules, make them effective immediately.
3584 LASSERT(fsdb->fsdb_srpc_tgt == NULL);
3585 sptlrpc_target_update_exp_flavor(mgs->mgs_obd,
3586 &fsdb->fsdb_srpc_gen);
3590 OBD_FREE(copy, copy_size);
3594 struct mgs_srpc_read_data {
3595 struct fs_db *msrd_fsdb;
3599 static int mgs_srpc_read_handler(const struct lu_env *env,
3600 struct llog_handle *llh,
3601 struct llog_rec_hdr *rec, void *data)
3603 struct mgs_srpc_read_data *msrd = data;
3604 struct cfg_marker *marker;
3605 struct lustre_cfg *lcfg = REC_DATA(rec);
3606 char *svname, *param;
3610 if (rec->lrh_type != OBD_CFG_REC) {
3611 CERROR("unhandled lrh_type: %#x\n", rec->lrh_type);
3615 cfg_len = REC_DATA_LEN(rec);
3617 rc = lustre_cfg_sanity_check(lcfg, cfg_len);
3619 CERROR("Insane cfg\n");
3623 if (lcfg->lcfg_command == LCFG_MARKER) {
3624 marker = lustre_cfg_buf(lcfg, 1);
3626 if (marker->cm_flags & CM_START &&
3627 marker->cm_flags & CM_SKIP)
3628 msrd->msrd_skip = 1;
3629 if (marker->cm_flags & CM_END)
3630 msrd->msrd_skip = 0;
3635 if (msrd->msrd_skip)
3638 if (lcfg->lcfg_command != LCFG_SPTLRPC_CONF) {
3639 CERROR("invalid command (%x)\n", lcfg->lcfg_command);
3643 svname = lustre_cfg_string(lcfg, 0);
3644 if (svname == NULL) {
3645 CERROR("svname is empty\n");
3649 param = lustre_cfg_string(lcfg, 1);
3650 if (param == NULL) {
3651 CERROR("param is empty\n");
3655 rc = mgs_srpc_set_param_mem(msrd->msrd_fsdb, svname, param);
3657 CERROR("read sptlrpc record error (%d): %s\n", rc, param);
3662 int mgs_get_fsdb_srpc_from_llog(const struct lu_env *env,
3663 struct mgs_device *mgs,
3666 struct llog_handle *llh = NULL;
3667 struct llog_ctxt *ctxt;
3669 struct mgs_srpc_read_data msrd;
3673 /* construct log name */
3674 rc = name_create(&logname, fsdb->fsdb_name, "-sptlrpc");
3678 ctxt = llog_get_context(mgs->mgs_obd, LLOG_CONFIG_ORIG_CTXT);
3679 LASSERT(ctxt != NULL);
3681 if (mgs_log_is_empty(env, mgs, logname))
3684 rc = llog_open(env, ctxt, &llh, NULL, logname,
3692 rc = llog_init_handle(env, llh, LLOG_F_IS_PLAIN, NULL);
3694 GOTO(out_close, rc);
3696 if (llog_get_size(llh) <= 1)
3697 GOTO(out_close, rc = 0);
3699 msrd.msrd_fsdb = fsdb;
3702 rc = llog_process(env, llh, mgs_srpc_read_handler, (void *)&msrd,
3706 llog_close(env, llh);
3708 llog_ctxt_put(ctxt);
3709 name_destroy(&logname);
3712 CERROR("failed to read sptlrpc config database: %d\n", rc);
3716 static int mgs_write_log_param2(const struct lu_env *env,
3717 struct mgs_device *mgs,
3719 struct mgs_target_info *mti, char *ptr)
3721 struct lustre_cfg_bufs bufs;
3725 CDEBUG(D_MGS, "next param '%s'\n", ptr);
3727 /* PARAM_MGSNODE and PARAM_NETWORK are set only when formating
3728 * or during the inital mount. It can never change after that.
3730 if (!class_match_param(ptr, PARAM_MGSNODE, NULL) ||
3731 !class_match_param(ptr, PARAM_NETWORK, NULL)) {
3736 /* Processed in mgs_write_log_ost. Another value that can't
3737 * be changed by lctl set_param -P.
3739 if (!class_match_param(ptr, PARAM_FAILMODE, NULL)) {
3740 LCONSOLE_ERROR_MSG(0x169,
3741 "%s can only be changed with tunefs.lustre and --writeconf\n",
3747 /* FIXME !!! Support for sptlrpc is incomplete. Currently the change
3748 * doesn't transmit to the client. See LU-7183.
3750 if (!class_match_param(ptr, PARAM_SRPC, NULL)) {
3751 rc = mgs_srpc_set_param(env, mgs, fsdb, mti, ptr);
3755 /* Can't use class_match_param since ptr doesn't start with
3756 * PARAM_FAILNODE. So we look for PARAM_FAILNODE contained in ptr.
3758 if (strstr(ptr, PARAM_FAILNODE)) {
3759 /* Add a failover nidlist. We already processed failovers
3760 * params for new targets in mgs_write_log_target.
3764 /* can't use wildcards with failover.node */
3765 if (strchr(ptr, '*')) {
3770 param = strstr(ptr, PARAM_FAILNODE);
3771 if (strlcpy(mti->mti_params, param, sizeof(mti->mti_params)) >=
3772 sizeof(mti->mti_params)) {
3777 CDEBUG(D_MGS, "Adding failnode with param %s\n",
3779 rc = mgs_write_log_add_failnid(env, mgs, fsdb, mti);
3783 rc = mgs_wlp_lcfg(env, mgs, fsdb, mti, PARAMS_FILENAME, &bufs,
3784 mti->mti_svname, ptr);
3789 /* Permanent settings of all parameters by writing into the appropriate
3790 * configuration logs.
3791 * A parameter with null value ("<param>='\0'") means to erase it out of
3794 static int mgs_write_log_param(const struct lu_env *env,
3795 struct mgs_device *mgs, struct fs_db *fsdb,
3796 struct mgs_target_info *mti, char *ptr)
3798 struct mgs_thread_info *mgi = mgs_env_info(env);
3804 /* For various parameter settings, we have to figure out which logs
3805 care about them (e.g. both mdt and client for lov settings) */
3806 CDEBUG(D_MGS, "next param '%s'\n", ptr);
3808 /* The params are stored in MOUNT_DATA_FILE and modified via
3809 tunefs.lustre, or set using lctl conf_param */
3811 /* Processed in lustre_start_mgc */
3812 if (class_match_param(ptr, PARAM_MGSNODE, NULL) == 0)
3815 /* Processed in ost/mdt */
3816 if (class_match_param(ptr, PARAM_NETWORK, NULL) == 0)
3819 /* Processed in mgs_write_log_ost */
3820 if (class_match_param(ptr, PARAM_FAILMODE, NULL) == 0) {
3821 if (mti->mti_flags & LDD_F_PARAM) {
3822 LCONSOLE_ERROR_MSG(0x169, "%s can only be "
3823 "changed with tunefs.lustre"
3824 "and --writeconf\n", ptr);
3830 if (class_match_param(ptr, PARAM_SRPC, NULL) == 0) {
3831 rc = mgs_srpc_set_param(env, mgs, fsdb, mti, ptr);
3835 if (class_match_param(ptr, PARAM_FAILNODE, NULL) == 0) {
3836 /* Add a failover nidlist */
3838 /* We already processed failovers params for new
3839 targets in mgs_write_log_target */
3840 if (mti->mti_flags & LDD_F_PARAM) {
3841 CDEBUG(D_MGS, "Adding failnode\n");
3842 rc = mgs_write_log_add_failnid(env, mgs, fsdb, mti);
3847 if (class_match_param(ptr, PARAM_SYS, &tmp) == 0) {
3848 rc = mgs_write_log_sys(env, mgs, fsdb, mti, ptr, tmp);
3852 if (class_match_param(ptr, PARAM_QUOTA, &tmp) == 0) {
3853 rc = mgs_write_log_quota(env, mgs, fsdb, mti, ptr, tmp);
3857 if (class_match_param(ptr, PARAM_OSC PARAM_ACTIVE, &tmp) == 0 ||
3858 class_match_param(ptr, PARAM_MDC PARAM_ACTIVE, &tmp) == 0) {
3859 /* active=0 means off, anything else means on */
3860 int flag = (*tmp == '0') ? CM_EXCLUDE : 0;
3861 bool deactive_osc = memcmp(ptr, PARAM_OSC PARAM_ACTIVE,
3862 strlen(PARAM_OSC PARAM_ACTIVE)) == 0;
3865 if (!deactive_osc) {
3868 rc = server_name2index(mti->mti_svname, &index, NULL);
3873 LCONSOLE_ERROR_MSG(0x144, "%s: MDC0 can not be"
3874 " (de)activated.\n",
3876 GOTO(end, rc = -EPERM);
3880 LCONSOLE_WARN("Permanently %sactivating %s\n",
3881 flag ? "de" : "re", mti->mti_svname);
3883 rc = name_create(&logname, mti->mti_fsname, "-client");
3886 rc = mgs_modify(env, mgs, fsdb, mti, logname,
3888 deactive_osc ? "add osc" : "add mdc", flag);
3889 name_destroy(&logname);
3894 /* Add to all MDT logs for DNE */
3895 for (i = 0; i < INDEX_MAP_SIZE * 8; i++) {
3896 if (!test_bit(i, fsdb->fsdb_mdt_index_map))
3898 rc = name_create_mdt(&logname, mti->mti_fsname, i);
3901 rc = mgs_modify(env, mgs, fsdb, mti, logname,
3903 deactive_osc ? "add osc" : "add osp",
3905 name_destroy(&logname);
3911 LCONSOLE_ERROR_MSG(0x145, "Couldn't find %s in"
3912 "log (%d). No permanent "
3913 "changes were made to the "
3915 mti->mti_svname, rc);
3916 if (test_bit(FSDB_OLDLOG14, &fsdb->fsdb_flags))
3917 LCONSOLE_ERROR_MSG(0x146, "This may be"
3922 "update the logs.\n");
3925 /* Fall through to osc/mdc proc for deactivating live
3926 OSC/OSP on running MDT / clients. */
3928 /* Below here, let obd's XXX_process_config methods handle it */
3930 /* All lov. in proc */
3931 if (class_match_param(ptr, PARAM_LOV, NULL) == 0) {
3934 CDEBUG(D_MGS, "lov param %s\n", ptr);
3935 if (!(mti->mti_flags & LDD_F_SV_TYPE_MDT)) {
3936 LCONSOLE_ERROR_MSG(0x147, "LOV params must be "
3937 "set on the MDT, not %s. "
3944 if (mgs_log_is_empty(env, mgs, mti->mti_svname))
3945 GOTO(end, rc = -ENODEV);
3947 rc = name_create_mdt_and_lov(&logname, &mdtlovname, fsdb,
3948 mti->mti_stripe_index);
3951 rc = mgs_wlp_lcfg(env, mgs, fsdb, mti, mti->mti_svname,
3952 &mgi->mgi_bufs, mdtlovname, ptr);
3953 name_destroy(&logname);
3954 name_destroy(&mdtlovname);
3959 rc = name_create(&logname, mti->mti_fsname, "-client");
3962 rc = mgs_wlp_lcfg(env, mgs, fsdb, mti, logname, &mgi->mgi_bufs,
3963 fsdb->fsdb_clilov, ptr);
3964 name_destroy(&logname);
3968 /* All osc., mdc., llite. params in proc */
3969 if ((class_match_param(ptr, PARAM_OSC, NULL) == 0) ||
3970 (class_match_param(ptr, PARAM_MDC, NULL) == 0) ||
3971 (class_match_param(ptr, PARAM_LLITE, NULL) == 0)) {
3974 if (test_bit(FSDB_OLDLOG14, &fsdb->fsdb_flags)) {
3975 LCONSOLE_ERROR_MSG(0x148, "Upgraded client logs for %s"
3976 " cannot be modified. Consider"
3977 " updating the configuration with"
3980 GOTO(end, rc = -EINVAL);
3982 if (memcmp(ptr, PARAM_LLITE, strlen(PARAM_LLITE)) == 0) {
3983 rc = name_create(&cname, mti->mti_fsname, "-client");
3984 /* Add the client type to match the obdname in
3985 class_config_llog_handler */
3986 } else if (mti->mti_flags & LDD_F_SV_TYPE_MDT) {
3987 rc = name_create(&cname, mti->mti_svname, "-mdc");
3988 } else if (mti->mti_flags & LDD_F_SV_TYPE_OST) {
3989 rc = name_create(&cname, mti->mti_svname, "-osc");
3991 GOTO(end, rc = -EINVAL);
3996 /* Forbid direct update of llite root squash parameters.
3997 * These parameters are indirectly set via the MDT settings.
3999 if ((class_match_param(ptr, PARAM_LLITE, &tmp) == 0) &&
4000 ((memcmp(tmp, "root_squash=", 12) == 0) ||
4001 (memcmp(tmp, "nosquash_nids=", 14) == 0))) {
4002 LCONSOLE_ERROR("%s: root squash parameters can only "
4003 "be updated through MDT component\n",
4005 name_destroy(&cname);
4006 GOTO(end, rc = -EINVAL);
4009 CDEBUG(D_MGS, "%.3s param %s\n", ptr, ptr + 4);
4012 rc = name_create(&logname, mti->mti_fsname, "-client");
4014 name_destroy(&cname);
4017 rc = mgs_wlp_lcfg(env, mgs, fsdb, mti, logname, &mgi->mgi_bufs,
4020 /* osc params affect the MDT as well */
4021 if (!rc && (mti->mti_flags & LDD_F_SV_TYPE_OST)) {
4024 for (i = 0; i < INDEX_MAP_SIZE * 8; i++){
4025 if (!test_bit(i, fsdb->fsdb_mdt_index_map))
4027 name_destroy(&cname);
4028 rc = name_create_mdt_osc(&cname, mti->mti_svname,
4030 name_destroy(&logname);
4033 rc = name_create_mdt(&logname,
4034 mti->mti_fsname, i);
4037 if (!mgs_log_is_empty(env, mgs, logname)) {
4038 rc = mgs_wlp_lcfg(env, mgs, fsdb,
4048 /* For mdc activate/deactivate, it affects OSP on MDT as well */
4049 if (class_match_param(ptr, PARAM_MDC PARAM_ACTIVE, &tmp) == 0 &&
4052 char *lodname = NULL;
4053 char *param_str = NULL;
4057 /* replace mdc with osp */
4058 memcpy(ptr, PARAM_OSP, strlen(PARAM_OSP));
4059 rc = server_name2index(mti->mti_svname, &index, NULL);
4061 memcpy(ptr, PARAM_MDC, strlen(PARAM_MDC));
4065 for (i = 0; i < INDEX_MAP_SIZE * 8; i++) {
4066 if (!test_bit(i, fsdb->fsdb_mdt_index_map))
4072 name_destroy(&logname);
4073 rc = name_create_mdt(&logname, mti->mti_fsname,
4078 if (mgs_log_is_empty(env, mgs, logname))
4081 snprintf(suffix, sizeof(suffix), "-osp-MDT%04x",
4083 name_destroy(&cname);
4084 rc = name_create(&cname, mti->mti_svname,
4089 rc = mgs_wlp_lcfg(env, mgs, fsdb, mti, logname,
4090 &mgi->mgi_bufs, cname, ptr);
4094 /* Add configuration log for noitfying LOD
4095 * to active/deactive the OSP. */
4096 name_destroy(¶m_str);
4097 rc = name_create(¶m_str, cname,
4098 (*tmp == '0') ? ".active=0" :
4103 name_destroy(&lodname);
4104 rc = name_create(&lodname, logname, "-mdtlov");
4108 rc = mgs_wlp_lcfg(env, mgs, fsdb, mti, logname,
4109 &mgi->mgi_bufs, lodname,
4114 memcpy(ptr, PARAM_MDC, strlen(PARAM_MDC));
4115 name_destroy(&lodname);
4116 name_destroy(¶m_str);
4119 name_destroy(&logname);
4120 name_destroy(&cname);
4124 /* All mdt. params in proc */
4125 if (class_match_param(ptr, PARAM_MDT, &tmp) == 0) {
4129 CDEBUG(D_MGS, "%.3s param %s\n", ptr, ptr + 4);
4130 if (strncmp(mti->mti_svname, mti->mti_fsname,
4131 MTI_NAME_MAXLEN) == 0)
4132 /* device is unspecified completely? */
4133 rc = LDD_F_SV_TYPE_MDT | LDD_F_SV_ALL;
4135 rc = server_name2index(mti->mti_svname, &idx, NULL);
4138 if ((rc & LDD_F_SV_TYPE_MDT) == 0)
4140 if (rc & LDD_F_SV_ALL) {
4141 for (i = 0; i < INDEX_MAP_SIZE * 8; i++) {
4143 fsdb->fsdb_mdt_index_map))
4145 rc = name_create_mdt(&logname,
4146 mti->mti_fsname, i);
4149 rc = mgs_wlp_lcfg(env, mgs, fsdb, mti,
4150 logname, &mgi->mgi_bufs,
4152 name_destroy(&logname);
4157 if ((memcmp(tmp, "root_squash=", 12) == 0) ||
4158 (memcmp(tmp, "nosquash_nids=", 14) == 0)) {
4159 LCONSOLE_ERROR("%s: root squash parameters "
4160 "cannot be applied to a single MDT\n",
4162 GOTO(end, rc = -EINVAL);
4164 rc = mgs_wlp_lcfg(env, mgs, fsdb, mti,
4165 mti->mti_svname, &mgi->mgi_bufs,
4166 mti->mti_svname, ptr);
4171 /* root squash settings are also applied to llite
4172 * config log (see LU-1778) */
4174 ((memcmp(tmp, "root_squash=", 12) == 0) ||
4175 (memcmp(tmp, "nosquash_nids=", 14) == 0))) {
4179 rc = name_create(&cname, mti->mti_fsname, "-client");
4182 rc = name_create(&logname, mti->mti_fsname, "-client");
4184 name_destroy(&cname);
4187 rc = name_create(&ptr2, PARAM_LLITE, tmp);
4189 name_destroy(&cname);
4190 name_destroy(&logname);
4193 rc = mgs_wlp_lcfg(env, mgs, fsdb, mti, logname,
4194 &mgi->mgi_bufs, cname, ptr2);
4195 name_destroy(&ptr2);
4196 name_destroy(&logname);
4197 name_destroy(&cname);
4202 /* All mdd., ost. and osd. params in proc */
4203 if ((class_match_param(ptr, PARAM_MDD, NULL) == 0) ||
4204 (class_match_param(ptr, PARAM_LOD, NULL) == 0) ||
4205 (class_match_param(ptr, PARAM_OST, NULL) == 0) ||
4206 (class_match_param(ptr, PARAM_OSD, NULL) == 0)) {
4207 CDEBUG(D_MGS, "%.3s param %s\n", ptr, ptr + 4);
4208 if (mgs_log_is_empty(env, mgs, mti->mti_svname))
4209 GOTO(end, rc = -ENODEV);
4211 rc = mgs_wlp_lcfg(env, mgs, fsdb, mti, mti->mti_svname,
4212 &mgi->mgi_bufs, mti->mti_svname, ptr);
4216 LCONSOLE_WARN("Ignoring unrecognized param '%s'\n", ptr);
4220 CERROR("err %d on param '%s'\n", rc, ptr);
4225 int mgs_write_log_target(const struct lu_env *env, struct mgs_device *mgs,
4226 struct mgs_target_info *mti, struct fs_db *fsdb)
4233 /* set/check the new target index */
4234 rc = mgs_set_index(env, mgs, mti);
4238 if (rc == EALREADY) {
4239 LCONSOLE_WARN("Found index %d for %s, updating log\n",
4240 mti->mti_stripe_index, mti->mti_svname);
4241 /* We would like to mark old log sections as invalid
4242 and add new log sections in the client and mdt logs.
4243 But if we add new sections, then live clients will
4244 get repeat setup instructions for already running
4245 osc's. So don't update the client/mdt logs. */
4246 mti->mti_flags &= ~LDD_F_UPDATE;
4250 OBD_FAIL_TIMEOUT(OBD_FAIL_MGS_WRITE_TARGET_DELAY, cfs_fail_val > 0 ?
4253 mutex_lock(&fsdb->fsdb_mutex);
4255 if (mti->mti_flags &
4256 (LDD_F_VIRGIN | LDD_F_UPGRADE14 | LDD_F_WRITECONF)) {
4257 /* Generate a log from scratch */
4258 if (mti->mti_flags & LDD_F_SV_TYPE_MDT) {
4259 rc = mgs_write_log_mdt(env, mgs, fsdb, mti);
4260 } else if (mti->mti_flags & LDD_F_SV_TYPE_OST) {
4261 rc = mgs_write_log_ost(env, mgs, fsdb, mti);
4263 CERROR("Unknown target type %#x, can't create log for "
4264 "%s\n", mti->mti_flags, mti->mti_svname);
4267 CERROR("Can't write logs for %s (%d)\n",
4268 mti->mti_svname, rc);
4272 /* Just update the params from tunefs in mgs_write_log_params */
4273 CDEBUG(D_MGS, "Update params for %s\n", mti->mti_svname);
4274 mti->mti_flags |= LDD_F_PARAM;
4277 /* allocate temporary buffer, where class_get_next_param will
4278 make copy of a current parameter */
4279 OBD_ALLOC(buf, strlen(mti->mti_params) + 1);
4281 GOTO(out_up, rc = -ENOMEM);
4282 params = mti->mti_params;
4283 while (params != NULL) {
4284 rc = class_get_next_param(¶ms, buf);
4287 /* there is no next parameter, that is
4292 CDEBUG(D_MGS, "remaining string: '%s', param: '%s'\n",
4294 rc = mgs_write_log_param(env, mgs, fsdb, mti, buf);
4299 OBD_FREE(buf, strlen(mti->mti_params) + 1);
4302 mutex_unlock(&fsdb->fsdb_mutex);
4306 int mgs_erase_log(const struct lu_env *env, struct mgs_device *mgs, char *name)
4308 struct llog_ctxt *ctxt;
4311 ctxt = llog_get_context(mgs->mgs_obd, LLOG_CONFIG_ORIG_CTXT);
4313 CERROR("%s: MGS config context doesn't exist\n",
4314 mgs->mgs_obd->obd_name);
4317 rc = llog_erase(env, ctxt, NULL, name);
4318 /* llog may not exist */
4321 llog_ctxt_put(ctxt);
4325 CERROR("%s: failed to clear log %s: %d\n",
4326 mgs->mgs_obd->obd_name, name, rc);
4331 /* erase all logs for the given fs */
4332 int mgs_erase_logs(const struct lu_env *env, struct mgs_device *mgs,
4335 struct list_head log_list;
4336 struct mgs_direntry *dirent, *n;
4337 char barrier_name[20] = {};
4340 int rc, len = strlen(fsname);
4343 mutex_lock(&mgs->mgs_mutex);
4345 /* Find all the logs in the CONFIGS directory */
4346 rc = class_dentry_readdir(env, mgs, &log_list);
4348 mutex_unlock(&mgs->mgs_mutex);
4352 if (list_empty(&log_list)) {
4353 mutex_unlock(&mgs->mgs_mutex);
4357 snprintf(barrier_name, sizeof(barrier_name) - 1, "%s-%s",
4358 fsname, BARRIER_FILENAME);
4359 /* Delete the barrier fsdb */
4360 mgs_remove_fsdb_by_name(mgs, barrier_name);
4361 /* Delete the fs db */
4362 mgs_remove_fsdb_by_name(mgs, fsname);
4363 mutex_unlock(&mgs->mgs_mutex);
4365 list_for_each_entry_safe(dirent, n, &log_list, mde_list) {
4366 list_del_init(&dirent->mde_list);
4367 suffix = strrchr(dirent->mde_name, '-');
4368 if (suffix != NULL) {
4369 if ((len == suffix - dirent->mde_name) &&
4370 (strncmp(fsname, dirent->mde_name, len) == 0)) {
4371 CDEBUG(D_MGS, "Removing log %s\n",
4373 mgs_erase_log(env, mgs, dirent->mde_name);
4377 mgs_direntry_free(dirent);
4386 /* list all logs for the given fs */
4387 int mgs_list_logs(const struct lu_env *env, struct mgs_device *mgs,
4388 struct obd_ioctl_data *data)
4390 struct list_head log_list;
4391 struct mgs_direntry *dirent, *n;
4397 /* Find all the logs in the CONFIGS directory */
4398 rc = class_dentry_readdir(env, mgs, &log_list);
4402 out = data->ioc_bulk;
4403 remains = data->ioc_inllen1;
4404 list_for_each_entry_safe(dirent, n, &log_list, mde_list) {
4405 list_del_init(&dirent->mde_list);
4406 suffix = strrchr(dirent->mde_name, '-');
4407 if (suffix != NULL) {
4408 l = snprintf(out, remains, "config_log: %s\n",
4413 mgs_direntry_free(dirent);
4420 struct mgs_lcfg_fork_data {
4421 struct lustre_cfg_bufs mlfd_bufs;
4422 struct mgs_device *mlfd_mgs;
4423 struct llog_handle *mlfd_llh;
4424 const char *mlfd_oldname;
4425 const char *mlfd_newname;
4429 static bool contain_valid_fsname(char *buf, const char *fsname,
4430 int buflen, int namelen)
4432 if (buflen < namelen)
4435 if (memcmp(buf, fsname, namelen) != 0)
4438 if (buf[namelen] != '\0' && buf[namelen] != '-')
4444 static int mgs_lcfg_fork_handler(const struct lu_env *env,
4445 struct llog_handle *o_llh,
4446 struct llog_rec_hdr *o_rec, void *data)
4448 struct mgs_lcfg_fork_data *mlfd = data;
4449 struct lustre_cfg_bufs *n_bufs = &mlfd->mlfd_bufs;
4450 struct lustre_cfg *o_lcfg = (struct lustre_cfg *)(o_rec + 1);
4451 struct llog_cfg_rec *lcr;
4453 char *n_buf = mlfd->mlfd_data;
4455 int o_namelen = strlen(mlfd->mlfd_oldname);
4456 int n_namelen = strlen(mlfd->mlfd_newname);
4457 int diff = n_namelen - o_namelen;
4458 __u32 cmd = o_lcfg->lcfg_command;
4459 __u32 cnt = o_lcfg->lcfg_bufcount;
4465 o_buf = lustre_cfg_buf(o_lcfg, 0);
4466 o_buflen = o_lcfg->lcfg_buflens[0];
4467 if (contain_valid_fsname(o_buf, mlfd->mlfd_oldname, o_buflen,
4469 memcpy(n_buf, mlfd->mlfd_newname, n_namelen);
4470 memcpy(n_buf + n_namelen, o_buf + o_namelen,
4471 o_buflen - o_namelen);
4472 lustre_cfg_bufs_reset(n_bufs, n_buf);
4473 n_buf += cfs_size_round(o_buflen + diff);
4475 lustre_cfg_bufs_reset(n_bufs, o_buflen != 0 ? o_buf : NULL);
4480 struct cfg_marker *o_marker;
4481 struct cfg_marker *n_marker;
4485 CDEBUG(D_MGS, "Unknown cfg marker entry with %d "
4490 /* buf[1] is marker */
4491 o_buf = lustre_cfg_buf(o_lcfg, 1);
4492 o_buflen = o_lcfg->lcfg_buflens[1];
4493 o_marker = (struct cfg_marker *)o_buf;
4494 if (!contain_valid_fsname(o_marker->cm_tgtname,
4496 sizeof(o_marker->cm_tgtname),
4498 lustre_cfg_bufs_set(n_bufs, 1, o_marker,
4503 n_marker = (struct cfg_marker *)n_buf;
4504 *n_marker = *o_marker;
4505 memcpy(n_marker->cm_tgtname, mlfd->mlfd_newname, n_namelen);
4506 tgt_namelen = strlen(o_marker->cm_tgtname);
4507 if (tgt_namelen > o_namelen)
4508 memcpy(n_marker->cm_tgtname + n_namelen,
4509 o_marker->cm_tgtname + o_namelen,
4510 tgt_namelen - o_namelen);
4511 n_marker->cm_tgtname[tgt_namelen + diff] = '\0';
4512 lustre_cfg_bufs_set(n_bufs, 1, n_marker, sizeof(*n_marker));
4516 case LCFG_SET_PARAM: {
4517 for (i = 1; i < cnt; i++)
4518 /* buf[i] is the param value, reuse it directly */
4519 lustre_cfg_bufs_set(n_bufs, i,
4520 lustre_cfg_buf(o_lcfg, i),
4521 o_lcfg->lcfg_buflens[i]);
4527 case LCFG_POOL_DEL: {
4528 if (cnt < 3 || cnt > 4) {
4529 CDEBUG(D_MGS, "Unknown cfg pool (%x) entry with %d "
4530 "buffers\n", cmd, cnt);
4534 /* buf[1] is fsname */
4535 o_buf = lustre_cfg_buf(o_lcfg, 1);
4536 o_buflen = o_lcfg->lcfg_buflens[1];
4537 memcpy(n_buf, mlfd->mlfd_newname, n_namelen);
4538 memcpy(n_buf + n_namelen, o_buf + o_namelen,
4539 o_buflen - o_namelen);
4540 lustre_cfg_bufs_set(n_bufs, 1, n_buf, o_buflen + diff);
4541 n_buf += cfs_size_round(o_buflen + diff);
4543 /* buf[2] is the pool name, reuse it directly */
4544 lustre_cfg_bufs_set(n_bufs, 2, lustre_cfg_buf(o_lcfg, 2),
4545 o_lcfg->lcfg_buflens[2]);
4550 /* buf[3] is ostname */
4551 o_buf = lustre_cfg_buf(o_lcfg, 3);
4552 o_buflen = o_lcfg->lcfg_buflens[3];
4553 memcpy(n_buf, mlfd->mlfd_newname, n_namelen);
4554 memcpy(n_buf + n_namelen, o_buf + o_namelen,
4555 o_buflen - o_namelen);
4556 lustre_cfg_bufs_set(n_bufs, 3, n_buf, o_buflen + diff);
4561 o_buflen = o_lcfg->lcfg_buflens[1];
4562 if (o_buflen == sizeof(struct lov_desc) ||
4563 o_buflen == sizeof(struct lmv_desc)) {
4569 o_buf = lustre_cfg_buf(o_lcfg, 1);
4570 if (o_buflen == sizeof(struct lov_desc)) {
4571 struct lov_desc *o_desc =
4572 (struct lov_desc *)o_buf;
4573 struct lov_desc *n_desc =
4574 (struct lov_desc *)n_buf;
4577 o_uuid = o_desc->ld_uuid.uuid;
4578 n_uuid = n_desc->ld_uuid.uuid;
4579 uuid_len = sizeof(o_desc->ld_uuid.uuid);
4581 struct lmv_desc *o_desc =
4582 (struct lmv_desc *)o_buf;
4583 struct lmv_desc *n_desc =
4584 (struct lmv_desc *)n_buf;
4587 o_uuid = o_desc->ld_uuid.uuid;
4588 n_uuid = n_desc->ld_uuid.uuid;
4589 uuid_len = sizeof(o_desc->ld_uuid.uuid);
4592 if (unlikely(!contain_valid_fsname(o_uuid,
4593 mlfd->mlfd_oldname, uuid_len,
4595 lustre_cfg_bufs_set(n_bufs, 1, o_buf,
4600 memcpy(n_uuid, mlfd->mlfd_newname, n_namelen);
4601 uuid_len = strlen(o_uuid);
4602 if (uuid_len > o_namelen)
4603 memcpy(n_uuid + n_namelen,
4605 uuid_len - o_namelen);
4606 n_uuid[uuid_len + diff] = '\0';
4607 lustre_cfg_bufs_set(n_bufs, 1, n_buf, o_buflen);
4609 } /* else case fall through */
4610 } /* else case fall through */
4613 for (i = 1; i < cnt; i++) {
4614 o_buflen = o_lcfg->lcfg_buflens[i];
4618 o_buf = lustre_cfg_buf(o_lcfg, i);
4619 if (!contain_valid_fsname(o_buf, mlfd->mlfd_oldname,
4620 o_buflen, o_namelen)) {
4621 lustre_cfg_bufs_set(n_bufs, i, o_buf, o_buflen);
4625 memcpy(n_buf, mlfd->mlfd_newname, n_namelen);
4626 if (o_buflen == o_namelen) {
4627 lustre_cfg_bufs_set(n_bufs, i, n_buf,
4629 n_buf += cfs_size_round(n_namelen);
4633 memcpy(n_buf + n_namelen, o_buf + o_namelen,
4634 o_buflen - o_namelen);
4635 lustre_cfg_bufs_set(n_bufs, i, n_buf, o_buflen + diff);
4636 n_buf += cfs_size_round(o_buflen + diff);
4642 lcr = lustre_cfg_rec_new(cmd, n_bufs);
4646 lcr->lcr_cfg = *o_lcfg;
4647 rc = llog_write(env, mlfd->mlfd_llh, &lcr->lcr_hdr, LLOG_NEXT_IDX);
4648 lustre_cfg_rec_free(lcr);
4653 static int mgs_lcfg_fork_one(const struct lu_env *env, struct mgs_device *mgs,
4654 struct mgs_direntry *mde, const char *oldname,
4655 const char *newname)
4657 struct llog_handle *old_llh = NULL;
4658 struct llog_handle *new_llh = NULL;
4659 struct llog_ctxt *ctxt = NULL;
4660 struct mgs_lcfg_fork_data *mlfd = NULL;
4661 char *name_buf = NULL;
4663 int old_namelen = strlen(oldname);
4664 int new_namelen = strlen(newname);
4668 name_buflen = mde->mde_len + new_namelen - old_namelen;
4669 OBD_ALLOC(name_buf, name_buflen);
4673 memcpy(name_buf, newname, new_namelen);
4674 memcpy(name_buf + new_namelen, mde->mde_name + old_namelen,
4675 mde->mde_len - old_namelen);
4677 CDEBUG(D_MGS, "Fork the config-log from %s to %s\n",
4678 mde->mde_name, name_buf);
4680 ctxt = llog_get_context(mgs->mgs_obd, LLOG_CONFIG_ORIG_CTXT);
4683 rc = llog_open_create(env, ctxt, &new_llh, NULL, name_buf);
4687 rc = llog_init_handle(env, new_llh, LLOG_F_IS_PLAIN, NULL);
4691 if (unlikely(mgs_log_is_empty(env, mgs, mde->mde_name)))
4694 rc = llog_open(env, ctxt, &old_llh, NULL, mde->mde_name,
4699 rc = llog_init_handle(env, old_llh, LLOG_F_IS_PLAIN, NULL);
4703 new_llh->lgh_hdr->llh_tgtuuid = old_llh->lgh_hdr->llh_tgtuuid;
4705 OBD_ALLOC(mlfd, LLOG_MIN_CHUNK_SIZE);
4707 GOTO(out, rc = -ENOMEM);
4709 mlfd->mlfd_mgs = mgs;
4710 mlfd->mlfd_llh = new_llh;
4711 mlfd->mlfd_oldname = oldname;
4712 mlfd->mlfd_newname = newname;
4714 rc = llog_process(env, old_llh, mgs_lcfg_fork_handler, mlfd, NULL);
4715 OBD_FREE(mlfd, LLOG_MIN_CHUNK_SIZE);
4721 llog_close(env, old_llh);
4723 llog_close(env, new_llh);
4725 OBD_FREE(name_buf, name_buflen);
4727 llog_ctxt_put(ctxt);
4732 int mgs_lcfg_fork(const struct lu_env *env, struct mgs_device *mgs,
4733 const char *oldname, const char *newname)
4735 struct list_head log_list;
4736 struct mgs_direntry *dirent, *n;
4737 int olen = strlen(oldname);
4738 int nlen = strlen(newname);
4743 if (unlikely(!oldname || oldname[0] == '\0' ||
4744 !newname || newname[0] == '\0'))
4747 if (strcmp(oldname, newname) == 0)
4750 /* lock it to prevent fork/erase/register in parallel. */
4751 mutex_lock(&mgs->mgs_mutex);
4753 rc = class_dentry_readdir(env, mgs, &log_list);
4755 mutex_unlock(&mgs->mgs_mutex);
4759 if (list_empty(&log_list)) {
4760 mutex_unlock(&mgs->mgs_mutex);
4764 list_for_each_entry_safe(dirent, n, &log_list, mde_list) {
4767 ptr = strrchr(dirent->mde_name, '-');
4769 int tlen = ptr - dirent->mde_name;
4772 strncmp(newname, dirent->mde_name, tlen) == 0)
4773 GOTO(out, rc = -EEXIST);
4776 strncmp(oldname, dirent->mde_name, tlen) == 0)
4780 list_del_init(&dirent->mde_list);
4781 mgs_direntry_free(dirent);
4784 if (list_empty(&log_list)) {
4785 mutex_unlock(&mgs->mgs_mutex);
4789 list_for_each_entry(dirent, &log_list, mde_list) {
4790 rc = mgs_lcfg_fork_one(env, mgs, dirent, oldname, newname);
4798 mutex_unlock(&mgs->mgs_mutex);
4800 list_for_each_entry_safe(dirent, n, &log_list, mde_list) {
4801 list_del_init(&dirent->mde_list);
4802 mgs_direntry_free(dirent);
4805 if (rc && count > 0)
4806 mgs_erase_logs(env, mgs, newname);
4811 int mgs_lcfg_erase(const struct lu_env *env, struct mgs_device *mgs,
4817 if (unlikely(!fsname || fsname[0] == '\0'))
4820 rc = mgs_erase_logs(env, mgs, fsname);
4825 static int mgs_xattr_del(const struct lu_env *env, struct dt_object *obj)
4827 struct dt_device *dev;
4828 struct thandle *th = NULL;
4833 dev = container_of0(obj->do_lu.lo_dev, struct dt_device, dd_lu_dev);
4834 th = dt_trans_create(env, dev);
4836 RETURN(PTR_ERR(th));
4838 rc = dt_declare_xattr_del(env, obj, XATTR_TARGET_RENAME, th);
4842 rc = dt_trans_start_local(env, dev, th);
4846 dt_write_lock(env, obj, 0);
4847 rc = dt_xattr_del(env, obj, XATTR_TARGET_RENAME, th);
4852 dt_write_unlock(env, obj);
4855 dt_trans_stop(env, dev, th);
4860 int mgs_lcfg_rename(const struct lu_env *env, struct mgs_device *mgs)
4862 struct list_head log_list;
4863 struct mgs_direntry *dirent, *n;
4865 struct lu_buf buf = {
4867 .lb_len = sizeof(fsname)
4873 rc = class_dentry_readdir(env, mgs, &log_list);
4877 if (list_empty(&log_list))
4880 list_for_each_entry_safe(dirent, n, &log_list, mde_list) {
4881 struct dt_object *o = NULL;
4886 list_del_init(&dirent->mde_list);
4887 ptr = strrchr(dirent->mde_name, '-');
4891 len = ptr - dirent->mde_name;
4892 if (unlikely(len >= sizeof(oldname))) {
4893 CDEBUG(D_MGS, "Skip invalid configuration file %s\n",
4898 o = local_file_find(env, mgs->mgs_los, mgs->mgs_configs_dir,
4902 CDEBUG(D_MGS, "Fail to locate file %s: rc = %d\n",
4903 dirent->mde_name, rc);
4907 rc = dt_xattr_get(env, o, &buf, XATTR_TARGET_RENAME);
4913 "Fail to get EA for %s: rc = %d\n",
4914 dirent->mde_name, rc);
4918 if (unlikely(rc == len &&
4919 memcmp(fsname, dirent->mde_name, len) == 0)) {
4920 /* The new fsname is the same as the old one. */
4921 rc = mgs_xattr_del(env, o);
4925 memcpy(oldname, dirent->mde_name, len);
4926 oldname[len] = '\0';
4928 rc = mgs_lcfg_fork_one(env, mgs, dirent, oldname, fsname);
4929 if (rc && rc != -EEXIST) {
4930 CDEBUG(D_MGS, "Fail to fork %s: rc = %d\n",
4931 dirent->mde_name, rc);
4935 rc = mgs_erase_log(env, mgs, dirent->mde_name);
4937 CDEBUG(D_MGS, "Fail to erase old %s: rc = %d\n",
4938 dirent->mde_name, rc);
4939 /* keep it there if failed to remove it. */
4944 if (o && !IS_ERR(o))
4945 lu_object_put(env, &o->do_lu);
4947 mgs_direntry_free(dirent);
4952 list_for_each_entry_safe(dirent, n, &log_list, mde_list) {
4953 list_del_init(&dirent->mde_list);
4954 mgs_direntry_free(dirent);
4960 /* Setup _mgs fsdb and log
4962 int mgs__mgs_fsdb_setup(const struct lu_env *env, struct mgs_device *mgs)
4964 struct fs_db *fsdb = NULL;
4968 rc = mgs_find_or_make_fsdb(env, mgs, MGSSELF_NAME, &fsdb);
4970 mgs_put_fsdb(mgs, fsdb);
4975 /* Setup params fsdb and log
4977 int mgs_params_fsdb_setup(const struct lu_env *env, struct mgs_device *mgs)
4979 struct fs_db *fsdb = NULL;
4980 struct llog_handle *params_llh = NULL;
4984 rc = mgs_find_or_make_fsdb(env, mgs, PARAMS_FILENAME, &fsdb);
4986 mutex_lock(&fsdb->fsdb_mutex);
4987 rc = record_start_log(env, mgs, ¶ms_llh, PARAMS_FILENAME);
4989 rc = record_end_log(env, ¶ms_llh);
4990 mutex_unlock(&fsdb->fsdb_mutex);
4991 mgs_put_fsdb(mgs, fsdb);
4997 /* Cleanup params fsdb and log
4999 int mgs_params_fsdb_cleanup(const struct lu_env *env, struct mgs_device *mgs)
5003 rc = mgs_erase_logs(env, mgs, PARAMS_FILENAME);
5004 return rc == -ENOENT ? 0 : rc;
5008 * Fill in the mgs_target_info based on data devname and param provide.
5010 * @env thread context
5012 * @mti mgs target info. We want to set this based other paramters
5013 * passed to this function. Once setup we write it to the config
5015 * @devname optional OBD device name
5016 * @param string that contains both what tunable to set and the value to
5019 * RETURN 0 for success
5020 * negative error number on failure
5022 static int mgs_set_conf_param(const struct lu_env *env, struct mgs_device *mgs,
5023 struct mgs_target_info *mti, const char *devname,
5026 struct fs_db *fsdb = NULL;
5031 /* lustre, lustre-mdtlov, lustre-client, lustre-MDT0000 */
5035 /* We have two possible cases here:
5037 * 1) the device name embedded in the param:
5038 * lustre-OST0000.osc.max_dirty_mb=32
5040 * 2) the file system name is embedded in
5041 * the param: lustre.sys.at.min=0
5043 len = strcspn(param, ".=");
5044 if (!len || param[len] == '=')
5047 if (len >= sizeof(mti->mti_svname))
5050 snprintf(mti->mti_svname, sizeof(mti->mti_svname),
5051 "%.*s", (int)len, param);
5054 if (strlcpy(mti->mti_svname, devname, sizeof(mti->mti_svname)) >=
5055 sizeof(mti->mti_svname))
5059 if (!strlen(mti->mti_svname)) {
5060 LCONSOLE_ERROR_MSG(0x14d, "No target specified: %s\n", param);
5064 dev_type = mgs_parse_devname(mti->mti_svname, mti->mti_fsname,
5065 &mti->mti_stripe_index);
5067 /* For this case we have an invalid obd device name */
5069 CDEBUG(D_MGS, "%s don't contain an index\n", mti->mti_svname);
5070 strlcpy(mti->mti_fsname, mti->mti_svname, MTI_NAME_MAXLEN);
5073 /* Not an obd device, assume devname is the fsname.
5074 * User might of only provided fsname and not obd device
5077 CDEBUG(D_MGS, "%s is seen as a file system name\n", mti->mti_svname);
5078 strlcpy(mti->mti_fsname, mti->mti_svname, MTI_NAME_MAXLEN);
5083 GOTO(out, rc = dev_type);
5085 /* param related to llite isn't allowed to set by OST or MDT */
5086 if (dev_type & LDD_F_SV_TYPE_OST ||
5087 dev_type & LDD_F_SV_TYPE_MDT) {
5088 /* param related to llite isn't allowed to set by OST
5091 if (!strncmp(param, PARAM_LLITE,
5092 sizeof(PARAM_LLITE) - 1))
5093 GOTO(out, rc = -EINVAL);
5095 /* Strip -osc or -mdc suffix from svname */
5096 if (server_make_name(dev_type, mti->mti_stripe_index,
5097 mti->mti_fsname, mti->mti_svname,
5098 sizeof(mti->mti_svname)))
5099 GOTO(out, rc = -EINVAL);
5104 if (strlcpy(mti->mti_params, param, sizeof(mti->mti_params)) >=
5105 sizeof(mti->mti_params))
5106 GOTO(out, rc = -E2BIG);
5108 CDEBUG(D_MGS, "set_conf_param fs='%s' device='%s' param='%s'\n",
5109 mti->mti_fsname, mti->mti_svname, mti->mti_params);
5111 rc = mgs_find_or_make_fsdb(env, mgs, mti->mti_fsname, &fsdb);
5115 if (!test_bit(FSDB_MGS_SELF, &fsdb->fsdb_flags) &&
5116 test_bit(FSDB_LOG_EMPTY, &fsdb->fsdb_flags)) {
5117 CERROR("No filesystem targets for %s. cfg_device from lctl "
5118 "is '%s'\n", mti->mti_fsname, mti->mti_svname);
5119 mgs_unlink_fsdb(mgs, fsdb);
5120 GOTO(out, rc = -EINVAL);
5124 * Revoke lock so everyone updates. Should be alright if
5125 * someone was already reading while we were updating the logs,
5126 * so we don't really need to hold the lock while we're
5129 mti->mti_flags = dev_type | LDD_F_PARAM;
5130 mutex_lock(&fsdb->fsdb_mutex);
5131 rc = mgs_write_log_param(env, mgs, fsdb, mti, mti->mti_params);
5132 mutex_unlock(&fsdb->fsdb_mutex);
5133 mgs_revoke_lock(mgs, fsdb, CONFIG_T_CONFIG);
5137 mgs_put_fsdb(mgs, fsdb);
5142 static int mgs_set_param2(const struct lu_env *env, struct mgs_device *mgs,
5143 struct mgs_target_info *mti, const char *param)
5145 struct fs_db *fsdb = NULL;
5150 if (strlcpy(mti->mti_params, param, sizeof(mti->mti_params)) >=
5151 sizeof(mti->mti_params))
5152 GOTO(out, rc = -E2BIG);
5154 /* obdname2fsname reports devname as an obd device */
5155 len = strcspn(param, ".=");
5156 if (len && param[len] != '=') {
5160 ptr = strchr(param, '.');
5162 len = strlen(param);
5165 if (len >= sizeof(mti->mti_svname))
5166 GOTO(out, rc = -E2BIG);
5168 snprintf(mti->mti_svname, sizeof(mti->mti_svname), "%.*s",
5171 obdname2fsname(mti->mti_svname, mti->mti_fsname,
5172 sizeof(mti->mti_fsname));
5174 snprintf(mti->mti_svname, sizeof(mti->mti_svname), "general");
5177 CDEBUG(D_MGS, "set_param2 fs='%s' device='%s' param='%s'\n",
5178 mti->mti_fsname, mti->mti_svname, mti->mti_params);
5180 /* The return value should be the device type i.e LDD_F_SV_TYPE_XXX.
5181 * A returned error tells us we don't have a target obd device.
5183 dev_type = server_name2index(mti->mti_svname, &mti->mti_stripe_index,
5188 /* the return value should be the device type i.e LDD_F_SV_TYPE_XXX.
5189 * Strip -osc or -mdc suffix from svname
5191 if ((dev_type & LDD_F_SV_TYPE_OST || dev_type & LDD_F_SV_TYPE_MDT) &&
5192 server_make_name(dev_type, mti->mti_stripe_index,
5193 mti->mti_fsname, mti->mti_svname,
5194 sizeof(mti->mti_svname)))
5195 GOTO(out, rc = -EINVAL);
5197 rc = mgs_find_or_make_fsdb(env, mgs, PARAMS_FILENAME, &fsdb);
5201 * Revoke lock so everyone updates. Should be alright if
5202 * someone was already reading while we were updating the logs,
5203 * so we don't really need to hold the lock while we're
5206 mti->mti_flags = dev_type | LDD_F_PARAM2;
5207 mutex_lock(&fsdb->fsdb_mutex);
5208 rc = mgs_write_log_param2(env, mgs, fsdb, mti, mti->mti_params);
5209 mutex_unlock(&fsdb->fsdb_mutex);
5210 mgs_revoke_lock(mgs, fsdb, CONFIG_T_PARAMS);
5211 mgs_put_fsdb(mgs, fsdb);
5216 /* Set a permanent (config log) param for a target or fs
5218 * @lcfg buf0 may contain the device (testfs-MDT0000) name
5219 * buf1 contains the single parameter
5221 int mgs_set_param(const struct lu_env *env, struct mgs_device *mgs,
5222 struct lustre_cfg *lcfg)
5224 const char *param = lustre_cfg_string(lcfg, 1);
5225 struct mgs_target_info *mti;
5228 /* Create a fake mti to hold everything */
5233 print_lustre_cfg(lcfg);
5235 if (lcfg->lcfg_command == LCFG_PARAM) {
5236 /* For the case of lctl conf_param devname can be
5237 * lustre, lustre-mdtlov, lustre-client, lustre-MDT0000
5239 const char *devname = lustre_cfg_string(lcfg, 0);
5241 rc = mgs_set_conf_param(env, mgs, mti, devname, param);
5243 /* In the case of lctl set_param -P lcfg[0] will always
5244 * be 'general'. At least for now.
5246 rc = mgs_set_param2(env, mgs, mti, param);
5254 static int mgs_write_log_pool(const struct lu_env *env,
5255 struct mgs_device *mgs, char *logname,
5256 struct fs_db *fsdb, char *tgtname,
5257 enum lcfg_command_type cmd,
5258 char *fsname, char *poolname,
5259 char *ostname, char *comment)
5261 struct llog_handle *llh = NULL;
5264 rc = record_start_log(env, mgs, &llh, logname);
5267 rc = record_marker(env, llh, fsdb, CM_START, tgtname, comment);
5270 rc = record_base(env, llh, tgtname, 0, cmd,
5271 fsname, poolname, ostname, NULL);
5274 rc = record_marker(env, llh, fsdb, CM_END, tgtname, comment);
5276 record_end_log(env, &llh);
5280 int mgs_nodemap_cmd(const struct lu_env *env, struct mgs_device *mgs,
5281 enum lcfg_command_type cmd, const char *nodemap_name,
5292 case LCFG_NODEMAP_ADD:
5293 rc = nodemap_add(nodemap_name);
5295 case LCFG_NODEMAP_DEL:
5296 rc = nodemap_del(nodemap_name);
5298 case LCFG_NODEMAP_ADD_RANGE:
5299 rc = nodemap_parse_range(param, nid);
5302 rc = nodemap_add_range(nodemap_name, nid);
5304 case LCFG_NODEMAP_DEL_RANGE:
5305 rc = nodemap_parse_range(param, nid);
5308 rc = nodemap_del_range(nodemap_name, nid);
5310 case LCFG_NODEMAP_ADMIN:
5311 bool_switch = simple_strtoul(param, NULL, 10);
5312 rc = nodemap_set_allow_root(nodemap_name, bool_switch);
5314 case LCFG_NODEMAP_DENY_UNKNOWN:
5315 bool_switch = simple_strtoul(param, NULL, 10);
5316 rc = nodemap_set_deny_unknown(nodemap_name, bool_switch);
5318 case LCFG_NODEMAP_AUDIT_MODE:
5319 rc = kstrtoul(param, 10, (unsigned long *)&bool_switch);
5321 rc = nodemap_set_audit_mode(nodemap_name, bool_switch);
5323 case LCFG_NODEMAP_MAP_MODE:
5324 if (strcmp("both", param) == 0)
5325 rc = nodemap_set_mapping_mode(nodemap_name,
5327 else if (strcmp("uid_only", param) == 0)
5328 rc = nodemap_set_mapping_mode(nodemap_name,
5329 NODEMAP_MAP_UID_ONLY);
5330 else if (strcmp("gid_only", param) == 0)
5331 rc = nodemap_set_mapping_mode(nodemap_name,
5332 NODEMAP_MAP_GID_ONLY);
5336 case LCFG_NODEMAP_TRUSTED:
5337 bool_switch = simple_strtoul(param, NULL, 10);
5338 rc = nodemap_set_trust_client_ids(nodemap_name, bool_switch);
5340 case LCFG_NODEMAP_SQUASH_UID:
5341 int_id = simple_strtoul(param, NULL, 10);
5342 rc = nodemap_set_squash_uid(nodemap_name, int_id);
5344 case LCFG_NODEMAP_SQUASH_GID:
5345 int_id = simple_strtoul(param, NULL, 10);
5346 rc = nodemap_set_squash_gid(nodemap_name, int_id);
5348 case LCFG_NODEMAP_ADD_UIDMAP:
5349 case LCFG_NODEMAP_ADD_GIDMAP:
5350 rc = nodemap_parse_idmap(param, idmap);
5353 if (cmd == LCFG_NODEMAP_ADD_UIDMAP)
5354 rc = nodemap_add_idmap(nodemap_name, NODEMAP_UID,
5357 rc = nodemap_add_idmap(nodemap_name, NODEMAP_GID,
5360 case LCFG_NODEMAP_DEL_UIDMAP:
5361 case LCFG_NODEMAP_DEL_GIDMAP:
5362 rc = nodemap_parse_idmap(param, idmap);
5365 if (cmd == LCFG_NODEMAP_DEL_UIDMAP)
5366 rc = nodemap_del_idmap(nodemap_name, NODEMAP_UID,
5369 rc = nodemap_del_idmap(nodemap_name, NODEMAP_GID,
5372 case LCFG_NODEMAP_SET_FILESET:
5373 rc = nodemap_set_fileset(nodemap_name, param);
5382 int mgs_pool_cmd(const struct lu_env *env, struct mgs_device *mgs,
5383 enum lcfg_command_type cmd, char *fsname,
5384 char *poolname, char *ostname)
5389 char *label = NULL, *canceled_label = NULL;
5391 struct mgs_target_info *mti = NULL;
5392 bool checked = false;
5393 bool locked = false;
5398 rc = mgs_find_or_make_fsdb(env, mgs, fsname, &fsdb);
5400 CERROR("Can't get db for %s\n", fsname);
5403 if (test_bit(FSDB_LOG_EMPTY, &fsdb->fsdb_flags)) {
5404 CERROR("%s is not defined\n", fsname);
5406 GOTO(out_fsdb, rc = -EINVAL);
5409 label_sz = 10 + strlen(fsname) + strlen(poolname);
5411 /* check if ostname match fsname */
5412 if (ostname != NULL) {
5415 ptr = strrchr(ostname, '-');
5416 if ((ptr == NULL) ||
5417 (strncmp(fsname, ostname, ptr-ostname) != 0))
5419 label_sz += strlen(ostname);
5422 OBD_ALLOC(label, label_sz);
5424 GOTO(out_fsdb, rc = -ENOMEM);
5429 "new %s.%s", fsname, poolname);
5433 "add %s.%s.%s", fsname, poolname, ostname);
5436 OBD_ALLOC(canceled_label, label_sz);
5437 if (canceled_label == NULL)
5438 GOTO(out_label, rc = -ENOMEM);
5440 "rem %s.%s.%s", fsname, poolname, ostname);
5441 sprintf(canceled_label,
5442 "add %s.%s.%s", fsname, poolname, ostname);
5445 OBD_ALLOC(canceled_label, label_sz);
5446 if (canceled_label == NULL)
5447 GOTO(out_label, rc = -ENOMEM);
5449 "del %s.%s", fsname, poolname);
5450 sprintf(canceled_label,
5451 "new %s.%s", fsname, poolname);
5459 GOTO(out_cancel, rc = -ENOMEM);
5460 strncpy(mti->mti_svname, "lov pool", sizeof(mti->mti_svname));
5462 mutex_lock(&fsdb->fsdb_mutex);
5464 /* write pool def to all MDT logs */
5465 for (i = 0; i < INDEX_MAP_SIZE * 8; i++) {
5466 if (test_bit(i, fsdb->fsdb_mdt_index_map)) {
5467 rc = name_create_mdt_and_lov(&logname, &lovname,
5472 if (!checked && (canceled_label == NULL)) {
5473 rc = mgs_check_marker(env, mgs, fsdb, mti,
5474 logname, lovname, label);
5476 name_destroy(&logname);
5477 name_destroy(&lovname);
5479 rc = (rc == LLOG_PROC_BREAK ?
5484 if (canceled_label != NULL)
5485 rc = mgs_modify(env, mgs, fsdb, mti, logname,
5486 lovname, canceled_label,
5490 rc = mgs_write_log_pool(env, mgs, logname,
5494 name_destroy(&logname);
5495 name_destroy(&lovname);
5501 rc = name_create(&logname, fsname, "-client");
5505 if (!checked && (canceled_label == NULL)) {
5506 rc = mgs_check_marker(env, mgs, fsdb, mti, logname,
5507 fsdb->fsdb_clilov, label);
5509 name_destroy(&logname);
5510 GOTO(out_mti, rc = (rc == LLOG_PROC_BREAK ?
5514 if (canceled_label != NULL) {
5515 rc = mgs_modify(env, mgs, fsdb, mti, logname,
5516 fsdb->fsdb_clilov, canceled_label, CM_SKIP);
5518 name_destroy(&logname);
5523 rc = mgs_write_log_pool(env, mgs, logname, fsdb, fsdb->fsdb_clilov,
5524 cmd, fsname, poolname, ostname, label);
5525 mutex_unlock(&fsdb->fsdb_mutex);
5527 name_destroy(&logname);
5528 /* request for update */
5529 mgs_revoke_lock(mgs, fsdb, CONFIG_T_CONFIG);
5535 mutex_unlock(&fsdb->fsdb_mutex);
5539 if (canceled_label != NULL)
5540 OBD_FREE(canceled_label, label_sz);
5542 OBD_FREE(label, label_sz);
5545 mgs_unlink_fsdb(mgs, fsdb);
5546 mgs_put_fsdb(mgs, fsdb);