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,
3030 snprintf(mdt_index, sizeof(mdt_index), "-MDT%04x", i);
3031 rc = mgs_write_log_osc_to_lov(env, mgs, fsdb, mti,
3033 lovname, LUSTRE_SP_MDT,
3035 name_destroy(&logname);
3036 name_destroy(&lovname);
3042 /* Append ost info to the client log */
3043 rc = name_create(&logname, mti->mti_fsname, "-client");
3046 if (mgs_log_is_empty(env, mgs, logname)) {
3047 /* Start client log */
3048 rc = mgs_write_log_lov(env, mgs, fsdb, mti, logname,
3052 rc = mgs_write_log_lmv(env, mgs, fsdb, mti, logname,
3057 rc = mgs_write_log_osc_to_lov(env, mgs, fsdb, mti, logname, "",
3058 fsdb->fsdb_clilov, LUSTRE_SP_CLI, flags);
3060 name_destroy(&logname);
3064 static __inline__ int mgs_param_empty(char *ptr)
3068 if ((tmp = strchr(ptr, '=')) && (*(++tmp) == '\0'))
3073 static int mgs_write_log_failnid_internal(const struct lu_env *env,
3074 struct mgs_device *mgs,
3076 struct mgs_target_info *mti,
3077 char *logname, char *cliname)
3080 struct llog_handle *llh = NULL;
3082 if (mgs_param_empty(mti->mti_params)) {
3083 /* Remove _all_ failnids */
3084 rc = mgs_modify(env, mgs, fsdb, mti, logname,
3085 mti->mti_svname, "add failnid", CM_SKIP);
3086 return rc < 0 ? rc : 0;
3089 /* Otherwise failover nids are additive */
3090 rc = record_start_log(env, mgs, &llh, logname);
3093 /* FIXME this should be a single journal transaction */
3094 rc = record_marker(env, llh, fsdb, CM_START, mti->mti_svname,
3098 rc = mgs_write_log_failnids(env, mti, llh, cliname);
3101 rc = record_marker(env, llh, fsdb, CM_END,
3102 mti->mti_svname, "add failnid");
3104 record_end_log(env, &llh);
3109 /* Add additional failnids to an existing log.
3110 The mdc/osc must have been added to logs first */
3111 /* tcp nids must be in dotted-quad ascii -
3112 we can't resolve hostnames from the kernel. */
3113 static int mgs_write_log_add_failnid(const struct lu_env *env,
3114 struct mgs_device *mgs,
3116 struct mgs_target_info *mti)
3118 char *logname, *cliname;
3122 /* FIXME we currently can't erase the failnids
3123 * given when a target first registers, since they aren't part of
3124 * an "add uuid" stanza
3127 /* Verify that we know about this target */
3128 if (mgs_log_is_empty(env, mgs, mti->mti_svname)) {
3129 LCONSOLE_ERROR_MSG(0x142, "The target %s has not registered "
3130 "yet. It must be started before failnids "
3131 "can be added.\n", mti->mti_svname);
3135 /* Create mdc/osc client name (e.g. lustre-OST0001-osc) */
3136 if (mti->mti_flags & LDD_F_SV_TYPE_MDT) {
3137 rc = name_create(&cliname, mti->mti_svname, "-mdc");
3138 } else if (mti->mti_flags & LDD_F_SV_TYPE_OST) {
3139 rc = name_create(&cliname, mti->mti_svname, "-osc");
3146 /* Add failover nids to the client log */
3147 rc = name_create(&logname, mti->mti_fsname, "-client");
3149 name_destroy(&cliname);
3153 rc = mgs_write_log_failnid_internal(env, mgs, fsdb,mti,logname,cliname);
3154 name_destroy(&logname);
3155 name_destroy(&cliname);
3159 if (mti->mti_flags & LDD_F_SV_TYPE_OST) {
3160 /* Add OST failover nids to the MDT logs as well */
3163 for (i = 0; i < INDEX_MAP_SIZE * 8; i++) {
3164 if (!test_bit(i, fsdb->fsdb_mdt_index_map))
3166 rc = name_create_mdt(&logname, mti->mti_fsname, i);
3169 rc = name_create_mdt_osc(&cliname, mti->mti_svname,
3172 name_destroy(&logname);
3175 rc = mgs_write_log_failnid_internal(env, mgs, fsdb,
3178 name_destroy(&cliname);
3179 name_destroy(&logname);
3188 static int mgs_wlp_lcfg(const struct lu_env *env,
3189 struct mgs_device *mgs, struct fs_db *fsdb,
3190 struct mgs_target_info *mti,
3191 char *logname, struct lustre_cfg_bufs *bufs,
3192 char *tgtname, char *ptr)
3194 char comment[MTI_NAME_MAXLEN];
3196 struct llog_cfg_rec *lcr;
3199 /* Erase any old settings of this same parameter */
3200 memcpy(comment, ptr, MTI_NAME_MAXLEN);
3201 comment[MTI_NAME_MAXLEN - 1] = 0;
3202 /* But don't try to match the value. */
3203 tmp = strchr(comment, '=');
3206 /* FIXME we should skip settings that are the same as old values */
3207 rc = mgs_modify(env, mgs, fsdb, mti, logname, tgtname, comment,CM_SKIP);
3210 del = mgs_param_empty(ptr);
3212 LCONSOLE_INFO("%s parameter %s.%s in log %s\n", del ? "Disabling" : rc ?
3213 "Setting" : "Modifying", tgtname, comment, logname);
3215 /* mgs_modify() will return 1 if nothing had to be done */
3221 lustre_cfg_bufs_reset(bufs, tgtname);
3222 lustre_cfg_bufs_set_string(bufs, 1, ptr);
3223 if (mti->mti_flags & LDD_F_PARAM2)
3224 lustre_cfg_bufs_set_string(bufs, 2, LCTL_UPCALL);
3226 lcr = lustre_cfg_rec_new((mti->mti_flags & LDD_F_PARAM2) ?
3227 LCFG_SET_PARAM : LCFG_PARAM, bufs);
3231 rc = mgs_write_log_direct(env, mgs, fsdb, logname, lcr, tgtname,
3233 lustre_cfg_rec_free(lcr);
3237 /* write global variable settings into log */
3238 static int mgs_write_log_sys(const struct lu_env *env,
3239 struct mgs_device *mgs, struct fs_db *fsdb,
3240 struct mgs_target_info *mti, char *sys, char *ptr)
3242 struct mgs_thread_info *mgi = mgs_env_info(env);
3243 struct lustre_cfg *lcfg;
3244 struct llog_cfg_rec *lcr;
3246 int rc, cmd, convert = 1;
3248 if (class_match_param(ptr, PARAM_TIMEOUT, &tmp) == 0) {
3249 cmd = LCFG_SET_TIMEOUT;
3250 } else if (class_match_param(ptr, PARAM_LDLM_TIMEOUT, &tmp) == 0) {
3251 cmd = LCFG_SET_LDLM_TIMEOUT;
3252 /* Check for known params here so we can return error to lctl */
3253 } else if ((class_match_param(ptr, PARAM_AT_MIN, &tmp) == 0) ||
3254 (class_match_param(ptr, PARAM_AT_MAX, &tmp) == 0) ||
3255 (class_match_param(ptr, PARAM_AT_EXTRA, &tmp) == 0) ||
3256 (class_match_param(ptr, PARAM_AT_EARLY_MARGIN, &tmp) == 0) ||
3257 (class_match_param(ptr, PARAM_AT_HISTORY, &tmp) == 0)) {
3259 } else if (class_match_param(ptr, PARAM_JOBID_VAR, &tmp) == 0) {
3260 convert = 0; /* Don't convert string value to integer */
3266 if (mgs_param_empty(ptr))
3267 CDEBUG(D_MGS, "global '%s' removed\n", sys);
3269 CDEBUG(D_MGS, "global '%s' val=%s\n", sys, tmp);
3271 lustre_cfg_bufs_reset(&mgi->mgi_bufs, NULL);
3272 lustre_cfg_bufs_set_string(&mgi->mgi_bufs, 1, sys);
3273 if (!convert && *tmp != '\0')
3274 lustre_cfg_bufs_set_string(&mgi->mgi_bufs, 2, tmp);
3275 lcr = lustre_cfg_rec_new(cmd, &mgi->mgi_bufs);
3279 lcfg = &lcr->lcr_cfg;
3280 lcfg->lcfg_num = convert ? simple_strtoul(tmp, NULL, 0) : 0;
3281 /* truncate the comment to the parameter name */
3285 /* modify all servers and clients */
3286 rc = mgs_write_log_direct_all(env, mgs, fsdb, mti,
3287 *tmp == '\0' ? NULL : lcr,
3288 mti->mti_fsname, sys, 0);
3289 if (rc == 0 && *tmp != '\0') {
3291 case LCFG_SET_TIMEOUT:
3292 if (!obd_timeout_set || lcfg->lcfg_num > obd_timeout)
3293 class_process_config(lcfg);
3295 case LCFG_SET_LDLM_TIMEOUT:
3296 if (!ldlm_timeout_set || lcfg->lcfg_num > ldlm_timeout)
3297 class_process_config(lcfg);
3304 lustre_cfg_rec_free(lcr);
3308 /* write quota settings into log */
3309 static int mgs_write_log_quota(const struct lu_env *env, struct mgs_device *mgs,
3310 struct fs_db *fsdb, struct mgs_target_info *mti,
3311 char *quota, char *ptr)
3313 struct mgs_thread_info *mgi = mgs_env_info(env);
3314 struct llog_cfg_rec *lcr;
3317 int rc, cmd = LCFG_PARAM;
3319 /* support only 'meta' and 'data' pools so far */
3320 if (class_match_param(ptr, QUOTA_METAPOOL_NAME, &tmp) != 0 &&
3321 class_match_param(ptr, QUOTA_DATAPOOL_NAME, &tmp) != 0) {
3322 CERROR("parameter quota.%s isn't supported (only quota.mdt "
3323 "& quota.ost are)\n", ptr);
3328 CDEBUG(D_MGS, "global '%s' removed\n", quota);
3330 CDEBUG(D_MGS, "global '%s'\n", quota);
3332 if (strchr(tmp, 'u') == NULL && strchr(tmp, 'g') == NULL &&
3333 strchr(tmp, 'p') == NULL &&
3334 strcmp(tmp, "none") != 0) {
3335 CERROR("enable option(%s) isn't supported\n", tmp);
3340 lustre_cfg_bufs_reset(&mgi->mgi_bufs, mti->mti_fsname);
3341 lustre_cfg_bufs_set_string(&mgi->mgi_bufs, 1, quota);
3342 lcr = lustre_cfg_rec_new(cmd, &mgi->mgi_bufs);
3346 /* truncate the comment to the parameter name */
3351 /* XXX we duplicated quota enable information in all server
3352 * config logs, it should be moved to a separate config
3353 * log once we cleanup the config log for global param. */
3354 /* modify all servers */
3355 rc = mgs_write_log_direct_all(env, mgs, fsdb, mti,
3356 *tmp == '\0' ? NULL : lcr,
3357 mti->mti_fsname, quota, 1);
3359 lustre_cfg_rec_free(lcr);
3360 return rc < 0 ? rc : 0;
3363 static int mgs_srpc_set_param_disk(const struct lu_env *env,
3364 struct mgs_device *mgs,
3366 struct mgs_target_info *mti,
3369 struct mgs_thread_info *mgi = mgs_env_info(env);
3370 struct llog_cfg_rec *lcr;
3371 struct llog_handle *llh = NULL;
3373 char *comment, *ptr;
3379 ptr = strchr(param, '=');
3380 LASSERT(ptr != NULL);
3383 OBD_ALLOC(comment, len + 1);
3384 if (comment == NULL)
3386 strncpy(comment, param, len);
3387 comment[len] = '\0';
3390 lustre_cfg_bufs_reset(&mgi->mgi_bufs, mti->mti_svname);
3391 lustre_cfg_bufs_set_string(&mgi->mgi_bufs, 1, param);
3392 lcr = lustre_cfg_rec_new(LCFG_SPTLRPC_CONF, &mgi->mgi_bufs);
3394 GOTO(out_comment, rc = -ENOMEM);
3396 /* construct log name */
3397 rc = name_create(&logname, mti->mti_fsname, "-sptlrpc");
3401 if (mgs_log_is_empty(env, mgs, logname)) {
3402 rc = record_start_log(env, mgs, &llh, logname);
3405 record_end_log(env, &llh);
3408 /* obsolete old one */
3409 rc = mgs_modify(env, mgs, fsdb, mti, logname, mti->mti_svname,
3413 /* write the new one */
3414 rc = mgs_write_log_direct(env, mgs, fsdb, logname, lcr,
3415 mti->mti_svname, comment);
3417 CERROR("%s: error writing log %s: rc = %d\n",
3418 mgs->mgs_obd->obd_name, logname, rc);
3420 name_destroy(&logname);
3422 lustre_cfg_rec_free(lcr);
3424 OBD_FREE(comment, len + 1);
3428 static int mgs_srpc_set_param_udesc_mem(struct fs_db *fsdb,
3433 /* disable the adjustable udesc parameter for now, i.e. use default
3434 * setting that client always ship udesc to MDT if possible. to enable
3435 * it simply remove the following line */
3438 ptr = strchr(param, '=');
3443 if (strcmp(param, PARAM_SRPC_UDESC))
3446 if (strcmp(ptr, "yes") == 0) {
3447 set_bit(FSDB_UDESC, &fsdb->fsdb_flags);
3448 CWARN("Enable user descriptor shipping from client to MDT\n");
3449 } else if (strcmp(ptr, "no") == 0) {
3450 clear_bit(FSDB_UDESC, &fsdb->fsdb_flags);
3451 CWARN("Disable user descriptor shipping from client to MDT\n");
3459 CERROR("Invalid param: %s\n", param);
3463 static int mgs_srpc_set_param_mem(struct fs_db *fsdb,
3467 struct sptlrpc_rule rule;
3468 struct sptlrpc_rule_set *rset;
3472 if (strncmp(param, PARAM_SRPC, sizeof(PARAM_SRPC) - 1) != 0) {
3473 CERROR("Invalid sptlrpc parameter: %s\n", param);
3477 if (strncmp(param, PARAM_SRPC_UDESC,
3478 sizeof(PARAM_SRPC_UDESC) - 1) == 0) {
3479 RETURN(mgs_srpc_set_param_udesc_mem(fsdb, param));
3482 if (strncmp(param, PARAM_SRPC_FLVR, sizeof(PARAM_SRPC_FLVR) - 1) != 0) {
3483 CERROR("Invalid sptlrpc flavor parameter: %s\n", param);
3487 param += sizeof(PARAM_SRPC_FLVR) - 1;
3489 rc = sptlrpc_parse_rule(param, &rule);
3493 /* mgs rules implies must be mgc->mgs */
3494 if (test_bit(FSDB_MGS_SELF, &fsdb->fsdb_flags)) {
3495 if ((rule.sr_from != LUSTRE_SP_MGC &&
3496 rule.sr_from != LUSTRE_SP_ANY) ||
3497 (rule.sr_to != LUSTRE_SP_MGS &&
3498 rule.sr_to != LUSTRE_SP_ANY))
3502 /* preapre room for this coming rule. svcname format should be:
3503 * - fsname: general rule
3504 * - fsname-tgtname: target-specific rule
3506 if (strchr(svname, '-')) {
3507 struct mgs_tgt_srpc_conf *tgtconf;
3510 for (tgtconf = fsdb->fsdb_srpc_tgt; tgtconf != NULL;
3511 tgtconf = tgtconf->mtsc_next) {
3512 if (!strcmp(tgtconf->mtsc_tgt, svname)) {
3521 OBD_ALLOC_PTR(tgtconf);
3522 if (tgtconf == NULL)
3525 name_len = strlen(svname);
3527 OBD_ALLOC(tgtconf->mtsc_tgt, name_len + 1);
3528 if (tgtconf->mtsc_tgt == NULL) {
3529 OBD_FREE_PTR(tgtconf);
3532 memcpy(tgtconf->mtsc_tgt, svname, name_len);
3534 tgtconf->mtsc_next = fsdb->fsdb_srpc_tgt;
3535 fsdb->fsdb_srpc_tgt = tgtconf;
3538 rset = &tgtconf->mtsc_rset;
3539 } else if (strcmp(svname, MGSSELF_NAME) == 0) {
3540 /* put _mgs related srpc rule directly in mgs ruleset */
3541 rset = &fsdb->fsdb_mgs->mgs_lut.lut_sptlrpc_rset;
3543 rset = &fsdb->fsdb_srpc_gen;
3546 rc = sptlrpc_rule_set_merge(rset, &rule);
3551 static int mgs_srpc_set_param(const struct lu_env *env,
3552 struct mgs_device *mgs,
3554 struct mgs_target_info *mti,
3564 /* keep a copy of original param, which could be destroied
3566 copy_size = strlen(param) + 1;
3567 OBD_ALLOC(copy, copy_size);
3570 memcpy(copy, param, copy_size);
3572 rc = mgs_srpc_set_param_mem(fsdb, mti->mti_svname, param);
3576 /* previous steps guaranteed the syntax is correct */
3577 rc = mgs_srpc_set_param_disk(env, mgs, fsdb, mti, copy);
3581 if (test_bit(FSDB_MGS_SELF, &fsdb->fsdb_flags)) {
3583 * for mgs rules, make them effective immediately.
3585 LASSERT(fsdb->fsdb_srpc_tgt == NULL);
3586 sptlrpc_target_update_exp_flavor(mgs->mgs_obd,
3587 &fsdb->fsdb_srpc_gen);
3591 OBD_FREE(copy, copy_size);
3595 struct mgs_srpc_read_data {
3596 struct fs_db *msrd_fsdb;
3600 static int mgs_srpc_read_handler(const struct lu_env *env,
3601 struct llog_handle *llh,
3602 struct llog_rec_hdr *rec, void *data)
3604 struct mgs_srpc_read_data *msrd = data;
3605 struct cfg_marker *marker;
3606 struct lustre_cfg *lcfg = REC_DATA(rec);
3607 char *svname, *param;
3611 if (rec->lrh_type != OBD_CFG_REC) {
3612 CERROR("unhandled lrh_type: %#x\n", rec->lrh_type);
3616 cfg_len = REC_DATA_LEN(rec);
3618 rc = lustre_cfg_sanity_check(lcfg, cfg_len);
3620 CERROR("Insane cfg\n");
3624 if (lcfg->lcfg_command == LCFG_MARKER) {
3625 marker = lustre_cfg_buf(lcfg, 1);
3627 if (marker->cm_flags & CM_START &&
3628 marker->cm_flags & CM_SKIP)
3629 msrd->msrd_skip = 1;
3630 if (marker->cm_flags & CM_END)
3631 msrd->msrd_skip = 0;
3636 if (msrd->msrd_skip)
3639 if (lcfg->lcfg_command != LCFG_SPTLRPC_CONF) {
3640 CERROR("invalid command (%x)\n", lcfg->lcfg_command);
3644 svname = lustre_cfg_string(lcfg, 0);
3645 if (svname == NULL) {
3646 CERROR("svname is empty\n");
3650 param = lustre_cfg_string(lcfg, 1);
3651 if (param == NULL) {
3652 CERROR("param is empty\n");
3656 rc = mgs_srpc_set_param_mem(msrd->msrd_fsdb, svname, param);
3658 CERROR("read sptlrpc record error (%d): %s\n", rc, param);
3663 int mgs_get_fsdb_srpc_from_llog(const struct lu_env *env,
3664 struct mgs_device *mgs,
3667 struct llog_handle *llh = NULL;
3668 struct llog_ctxt *ctxt;
3670 struct mgs_srpc_read_data msrd;
3674 /* construct log name */
3675 rc = name_create(&logname, fsdb->fsdb_name, "-sptlrpc");
3679 ctxt = llog_get_context(mgs->mgs_obd, LLOG_CONFIG_ORIG_CTXT);
3680 LASSERT(ctxt != NULL);
3682 if (mgs_log_is_empty(env, mgs, logname))
3685 rc = llog_open(env, ctxt, &llh, NULL, logname,
3693 rc = llog_init_handle(env, llh, LLOG_F_IS_PLAIN, NULL);
3695 GOTO(out_close, rc);
3697 if (llog_get_size(llh) <= 1)
3698 GOTO(out_close, rc = 0);
3700 msrd.msrd_fsdb = fsdb;
3703 rc = llog_process(env, llh, mgs_srpc_read_handler, (void *)&msrd,
3707 llog_close(env, llh);
3709 llog_ctxt_put(ctxt);
3710 name_destroy(&logname);
3713 CERROR("failed to read sptlrpc config database: %d\n", rc);
3717 static int mgs_write_log_param2(const struct lu_env *env,
3718 struct mgs_device *mgs,
3720 struct mgs_target_info *mti, char *ptr)
3722 struct lustre_cfg_bufs bufs;
3726 CDEBUG(D_MGS, "next param '%s'\n", ptr);
3728 /* PARAM_MGSNODE and PARAM_NETWORK are set only when formating
3729 * or during the inital mount. It can never change after that.
3731 if (!class_match_param(ptr, PARAM_MGSNODE, NULL) ||
3732 !class_match_param(ptr, PARAM_NETWORK, NULL)) {
3737 /* Processed in mgs_write_log_ost. Another value that can't
3738 * be changed by lctl set_param -P.
3740 if (!class_match_param(ptr, PARAM_FAILMODE, NULL)) {
3741 LCONSOLE_ERROR_MSG(0x169,
3742 "%s can only be changed with tunefs.lustre and --writeconf\n",
3748 /* FIXME !!! Support for sptlrpc is incomplete. Currently the change
3749 * doesn't transmit to the client. See LU-7183.
3751 if (!class_match_param(ptr, PARAM_SRPC, NULL)) {
3752 rc = mgs_srpc_set_param(env, mgs, fsdb, mti, ptr);
3756 /* Can't use class_match_param since ptr doesn't start with
3757 * PARAM_FAILNODE. So we look for PARAM_FAILNODE contained in ptr.
3759 if (strstr(ptr, PARAM_FAILNODE)) {
3760 /* Add a failover nidlist. We already processed failovers
3761 * params for new targets in mgs_write_log_target.
3765 /* can't use wildcards with failover.node */
3766 if (strchr(ptr, '*')) {
3771 param = strstr(ptr, PARAM_FAILNODE);
3772 if (strlcpy(mti->mti_params, param, sizeof(mti->mti_params)) >=
3773 sizeof(mti->mti_params)) {
3778 CDEBUG(D_MGS, "Adding failnode with param %s\n",
3780 rc = mgs_write_log_add_failnid(env, mgs, fsdb, mti);
3784 rc = mgs_wlp_lcfg(env, mgs, fsdb, mti, PARAMS_FILENAME, &bufs,
3785 mti->mti_svname, ptr);
3790 /* Permanent settings of all parameters by writing into the appropriate
3791 * configuration logs.
3792 * A parameter with null value ("<param>='\0'") means to erase it out of
3795 static int mgs_write_log_param(const struct lu_env *env,
3796 struct mgs_device *mgs, struct fs_db *fsdb,
3797 struct mgs_target_info *mti, char *ptr)
3799 struct mgs_thread_info *mgi = mgs_env_info(env);
3805 /* For various parameter settings, we have to figure out which logs
3806 care about them (e.g. both mdt and client for lov settings) */
3807 CDEBUG(D_MGS, "next param '%s'\n", ptr);
3809 /* The params are stored in MOUNT_DATA_FILE and modified via
3810 tunefs.lustre, or set using lctl conf_param */
3812 /* Processed in lustre_start_mgc */
3813 if (class_match_param(ptr, PARAM_MGSNODE, NULL) == 0)
3816 /* Processed in ost/mdt */
3817 if (class_match_param(ptr, PARAM_NETWORK, NULL) == 0)
3820 /* Processed in mgs_write_log_ost */
3821 if (class_match_param(ptr, PARAM_FAILMODE, NULL) == 0) {
3822 if (mti->mti_flags & LDD_F_PARAM) {
3823 LCONSOLE_ERROR_MSG(0x169, "%s can only be "
3824 "changed with tunefs.lustre"
3825 "and --writeconf\n", ptr);
3831 if (class_match_param(ptr, PARAM_SRPC, NULL) == 0) {
3832 rc = mgs_srpc_set_param(env, mgs, fsdb, mti, ptr);
3836 if (class_match_param(ptr, PARAM_FAILNODE, NULL) == 0) {
3837 /* Add a failover nidlist */
3839 /* We already processed failovers params for new
3840 targets in mgs_write_log_target */
3841 if (mti->mti_flags & LDD_F_PARAM) {
3842 CDEBUG(D_MGS, "Adding failnode\n");
3843 rc = mgs_write_log_add_failnid(env, mgs, fsdb, mti);
3848 if (class_match_param(ptr, PARAM_SYS, &tmp) == 0) {
3849 rc = mgs_write_log_sys(env, mgs, fsdb, mti, ptr, tmp);
3853 if (class_match_param(ptr, PARAM_QUOTA, &tmp) == 0) {
3854 rc = mgs_write_log_quota(env, mgs, fsdb, mti, ptr, tmp);
3858 if (class_match_param(ptr, PARAM_OSC PARAM_ACTIVE, &tmp) == 0 ||
3859 class_match_param(ptr, PARAM_MDC PARAM_ACTIVE, &tmp) == 0) {
3860 /* active=0 means off, anything else means on */
3861 int flag = (*tmp == '0') ? CM_EXCLUDE : 0;
3862 bool deactive_osc = memcmp(ptr, PARAM_OSC PARAM_ACTIVE,
3863 strlen(PARAM_OSC PARAM_ACTIVE)) == 0;
3866 if (!deactive_osc) {
3869 rc = server_name2index(mti->mti_svname, &index, NULL);
3874 LCONSOLE_ERROR_MSG(0x144, "%s: MDC0 can not be"
3875 " (de)activated.\n",
3877 GOTO(end, rc = -EPERM);
3881 LCONSOLE_WARN("Permanently %sactivating %s\n",
3882 flag ? "de" : "re", mti->mti_svname);
3884 rc = name_create(&logname, mti->mti_fsname, "-client");
3887 rc = mgs_modify(env, mgs, fsdb, mti, logname,
3889 deactive_osc ? "add osc" : "add mdc", flag);
3890 name_destroy(&logname);
3895 /* Add to all MDT logs for DNE */
3896 for (i = 0; i < INDEX_MAP_SIZE * 8; i++) {
3897 if (!test_bit(i, fsdb->fsdb_mdt_index_map))
3899 rc = name_create_mdt(&logname, mti->mti_fsname, i);
3902 rc = mgs_modify(env, mgs, fsdb, mti, logname,
3904 deactive_osc ? "add osc" : "add osp",
3906 name_destroy(&logname);
3912 LCONSOLE_ERROR_MSG(0x145, "Couldn't find %s in"
3913 "log (%d). No permanent "
3914 "changes were made to the "
3916 mti->mti_svname, rc);
3917 if (test_bit(FSDB_OLDLOG14, &fsdb->fsdb_flags))
3918 LCONSOLE_ERROR_MSG(0x146, "This may be"
3923 "update the logs.\n");
3926 /* Fall through to osc/mdc proc for deactivating live
3927 OSC/OSP on running MDT / clients. */
3929 /* Below here, let obd's XXX_process_config methods handle it */
3931 /* All lov. in proc */
3932 if (class_match_param(ptr, PARAM_LOV, NULL) == 0) {
3935 CDEBUG(D_MGS, "lov param %s\n", ptr);
3936 if (!(mti->mti_flags & LDD_F_SV_TYPE_MDT)) {
3937 LCONSOLE_ERROR_MSG(0x147, "LOV params must be "
3938 "set on the MDT, not %s. "
3945 if (mgs_log_is_empty(env, mgs, mti->mti_svname))
3946 GOTO(end, rc = -ENODEV);
3948 rc = name_create_mdt_and_lov(&logname, &mdtlovname, fsdb,
3949 mti->mti_stripe_index);
3952 rc = mgs_wlp_lcfg(env, mgs, fsdb, mti, mti->mti_svname,
3953 &mgi->mgi_bufs, mdtlovname, ptr);
3954 name_destroy(&logname);
3955 name_destroy(&mdtlovname);
3960 rc = name_create(&logname, mti->mti_fsname, "-client");
3963 rc = mgs_wlp_lcfg(env, mgs, fsdb, mti, logname, &mgi->mgi_bufs,
3964 fsdb->fsdb_clilov, ptr);
3965 name_destroy(&logname);
3969 /* All osc., mdc., llite. params in proc */
3970 if ((class_match_param(ptr, PARAM_OSC, NULL) == 0) ||
3971 (class_match_param(ptr, PARAM_MDC, NULL) == 0) ||
3972 (class_match_param(ptr, PARAM_LLITE, NULL) == 0)) {
3975 if (test_bit(FSDB_OLDLOG14, &fsdb->fsdb_flags)) {
3976 LCONSOLE_ERROR_MSG(0x148, "Upgraded client logs for %s"
3977 " cannot be modified. Consider"
3978 " updating the configuration with"
3981 GOTO(end, rc = -EINVAL);
3983 if (memcmp(ptr, PARAM_LLITE, strlen(PARAM_LLITE)) == 0) {
3984 rc = name_create(&cname, mti->mti_fsname, "-client");
3985 /* Add the client type to match the obdname in
3986 class_config_llog_handler */
3987 } else if (mti->mti_flags & LDD_F_SV_TYPE_MDT) {
3988 rc = name_create(&cname, mti->mti_svname, "-mdc");
3989 } else if (mti->mti_flags & LDD_F_SV_TYPE_OST) {
3990 rc = name_create(&cname, mti->mti_svname, "-osc");
3992 GOTO(end, rc = -EINVAL);
3997 /* Forbid direct update of llite root squash parameters.
3998 * These parameters are indirectly set via the MDT settings.
4000 if ((class_match_param(ptr, PARAM_LLITE, &tmp) == 0) &&
4001 ((memcmp(tmp, "root_squash=", 12) == 0) ||
4002 (memcmp(tmp, "nosquash_nids=", 14) == 0))) {
4003 LCONSOLE_ERROR("%s: root squash parameters can only "
4004 "be updated through MDT component\n",
4006 name_destroy(&cname);
4007 GOTO(end, rc = -EINVAL);
4010 CDEBUG(D_MGS, "%.3s param %s\n", ptr, ptr + 4);
4013 rc = name_create(&logname, mti->mti_fsname, "-client");
4015 name_destroy(&cname);
4018 rc = mgs_wlp_lcfg(env, mgs, fsdb, mti, logname, &mgi->mgi_bufs,
4021 /* osc params affect the MDT as well */
4022 if (!rc && (mti->mti_flags & LDD_F_SV_TYPE_OST)) {
4025 for (i = 0; i < INDEX_MAP_SIZE * 8; i++){
4026 if (!test_bit(i, fsdb->fsdb_mdt_index_map))
4028 name_destroy(&cname);
4029 rc = name_create_mdt_osc(&cname, mti->mti_svname,
4031 name_destroy(&logname);
4034 rc = name_create_mdt(&logname,
4035 mti->mti_fsname, i);
4038 if (!mgs_log_is_empty(env, mgs, logname)) {
4039 rc = mgs_wlp_lcfg(env, mgs, fsdb,
4049 /* For mdc activate/deactivate, it affects OSP on MDT as well */
4050 if (class_match_param(ptr, PARAM_MDC PARAM_ACTIVE, &tmp) == 0 &&
4053 char *lodname = NULL;
4054 char *param_str = NULL;
4058 /* replace mdc with osp */
4059 memcpy(ptr, PARAM_OSP, strlen(PARAM_OSP));
4060 rc = server_name2index(mti->mti_svname, &index, NULL);
4062 memcpy(ptr, PARAM_MDC, strlen(PARAM_MDC));
4066 for (i = 0; i < INDEX_MAP_SIZE * 8; i++) {
4067 if (!test_bit(i, fsdb->fsdb_mdt_index_map))
4073 name_destroy(&logname);
4074 rc = name_create_mdt(&logname, mti->mti_fsname,
4079 if (mgs_log_is_empty(env, mgs, logname))
4082 snprintf(suffix, sizeof(suffix), "-osp-MDT%04x",
4084 name_destroy(&cname);
4085 rc = name_create(&cname, mti->mti_svname,
4090 rc = mgs_wlp_lcfg(env, mgs, fsdb, mti, logname,
4091 &mgi->mgi_bufs, cname, ptr);
4095 /* Add configuration log for noitfying LOD
4096 * to active/deactive the OSP. */
4097 name_destroy(¶m_str);
4098 rc = name_create(¶m_str, cname,
4099 (*tmp == '0') ? ".active=0" :
4104 name_destroy(&lodname);
4105 rc = name_create(&lodname, logname, "-mdtlov");
4109 rc = mgs_wlp_lcfg(env, mgs, fsdb, mti, logname,
4110 &mgi->mgi_bufs, lodname,
4115 memcpy(ptr, PARAM_MDC, strlen(PARAM_MDC));
4116 name_destroy(&lodname);
4117 name_destroy(¶m_str);
4120 name_destroy(&logname);
4121 name_destroy(&cname);
4125 /* All mdt. params in proc */
4126 if (class_match_param(ptr, PARAM_MDT, &tmp) == 0) {
4130 CDEBUG(D_MGS, "%.3s param %s\n", ptr, ptr + 4);
4131 if (strncmp(mti->mti_svname, mti->mti_fsname,
4132 MTI_NAME_MAXLEN) == 0)
4133 /* device is unspecified completely? */
4134 rc = LDD_F_SV_TYPE_MDT | LDD_F_SV_ALL;
4136 rc = server_name2index(mti->mti_svname, &idx, NULL);
4139 if ((rc & LDD_F_SV_TYPE_MDT) == 0)
4141 if (rc & LDD_F_SV_ALL) {
4142 for (i = 0; i < INDEX_MAP_SIZE * 8; i++) {
4144 fsdb->fsdb_mdt_index_map))
4146 rc = name_create_mdt(&logname,
4147 mti->mti_fsname, i);
4150 rc = mgs_wlp_lcfg(env, mgs, fsdb, mti,
4151 logname, &mgi->mgi_bufs,
4153 name_destroy(&logname);
4158 if ((memcmp(tmp, "root_squash=", 12) == 0) ||
4159 (memcmp(tmp, "nosquash_nids=", 14) == 0)) {
4160 LCONSOLE_ERROR("%s: root squash parameters "
4161 "cannot be applied to a single MDT\n",
4163 GOTO(end, rc = -EINVAL);
4165 rc = mgs_wlp_lcfg(env, mgs, fsdb, mti,
4166 mti->mti_svname, &mgi->mgi_bufs,
4167 mti->mti_svname, ptr);
4172 /* root squash settings are also applied to llite
4173 * config log (see LU-1778) */
4175 ((memcmp(tmp, "root_squash=", 12) == 0) ||
4176 (memcmp(tmp, "nosquash_nids=", 14) == 0))) {
4180 rc = name_create(&cname, mti->mti_fsname, "-client");
4183 rc = name_create(&logname, mti->mti_fsname, "-client");
4185 name_destroy(&cname);
4188 rc = name_create(&ptr2, PARAM_LLITE, tmp);
4190 name_destroy(&cname);
4191 name_destroy(&logname);
4194 rc = mgs_wlp_lcfg(env, mgs, fsdb, mti, logname,
4195 &mgi->mgi_bufs, cname, ptr2);
4196 name_destroy(&ptr2);
4197 name_destroy(&logname);
4198 name_destroy(&cname);
4203 /* All mdd., ost. and osd. params in proc */
4204 if ((class_match_param(ptr, PARAM_MDD, NULL) == 0) ||
4205 (class_match_param(ptr, PARAM_LOD, NULL) == 0) ||
4206 (class_match_param(ptr, PARAM_OST, NULL) == 0) ||
4207 (class_match_param(ptr, PARAM_OSD, NULL) == 0)) {
4208 CDEBUG(D_MGS, "%.3s param %s\n", ptr, ptr + 4);
4209 if (mgs_log_is_empty(env, mgs, mti->mti_svname))
4210 GOTO(end, rc = -ENODEV);
4212 rc = mgs_wlp_lcfg(env, mgs, fsdb, mti, mti->mti_svname,
4213 &mgi->mgi_bufs, mti->mti_svname, ptr);
4217 LCONSOLE_WARN("Ignoring unrecognized param '%s'\n", ptr);
4221 CERROR("err %d on param '%s'\n", rc, ptr);
4226 int mgs_write_log_target(const struct lu_env *env, struct mgs_device *mgs,
4227 struct mgs_target_info *mti, struct fs_db *fsdb)
4234 /* set/check the new target index */
4235 rc = mgs_set_index(env, mgs, mti);
4239 if (rc == EALREADY) {
4240 LCONSOLE_WARN("Found index %d for %s, updating log\n",
4241 mti->mti_stripe_index, mti->mti_svname);
4242 /* We would like to mark old log sections as invalid
4243 and add new log sections in the client and mdt logs.
4244 But if we add new sections, then live clients will
4245 get repeat setup instructions for already running
4246 osc's. So don't update the client/mdt logs. */
4247 mti->mti_flags &= ~LDD_F_UPDATE;
4251 OBD_FAIL_TIMEOUT(OBD_FAIL_MGS_WRITE_TARGET_DELAY, cfs_fail_val > 0 ?
4254 mutex_lock(&fsdb->fsdb_mutex);
4256 if (mti->mti_flags &
4257 (LDD_F_VIRGIN | LDD_F_UPGRADE14 | LDD_F_WRITECONF)) {
4258 /* Generate a log from scratch */
4259 if (mti->mti_flags & LDD_F_SV_TYPE_MDT) {
4260 rc = mgs_write_log_mdt(env, mgs, fsdb, mti);
4261 } else if (mti->mti_flags & LDD_F_SV_TYPE_OST) {
4262 rc = mgs_write_log_ost(env, mgs, fsdb, mti);
4264 CERROR("Unknown target type %#x, can't create log for "
4265 "%s\n", mti->mti_flags, mti->mti_svname);
4268 CERROR("Can't write logs for %s (%d)\n",
4269 mti->mti_svname, rc);
4273 /* Just update the params from tunefs in mgs_write_log_params */
4274 CDEBUG(D_MGS, "Update params for %s\n", mti->mti_svname);
4275 mti->mti_flags |= LDD_F_PARAM;
4278 /* allocate temporary buffer, where class_get_next_param will
4279 make copy of a current parameter */
4280 OBD_ALLOC(buf, strlen(mti->mti_params) + 1);
4282 GOTO(out_up, rc = -ENOMEM);
4283 params = mti->mti_params;
4284 while (params != NULL) {
4285 rc = class_get_next_param(¶ms, buf);
4288 /* there is no next parameter, that is
4293 CDEBUG(D_MGS, "remaining string: '%s', param: '%s'\n",
4295 rc = mgs_write_log_param(env, mgs, fsdb, mti, buf);
4300 OBD_FREE(buf, strlen(mti->mti_params) + 1);
4303 mutex_unlock(&fsdb->fsdb_mutex);
4307 int mgs_erase_log(const struct lu_env *env, struct mgs_device *mgs, char *name)
4309 struct llog_ctxt *ctxt;
4312 ctxt = llog_get_context(mgs->mgs_obd, LLOG_CONFIG_ORIG_CTXT);
4314 CERROR("%s: MGS config context doesn't exist\n",
4315 mgs->mgs_obd->obd_name);
4318 rc = llog_erase(env, ctxt, NULL, name);
4319 /* llog may not exist */
4322 llog_ctxt_put(ctxt);
4326 CERROR("%s: failed to clear log %s: %d\n",
4327 mgs->mgs_obd->obd_name, name, rc);
4332 /* erase all logs for the given fs */
4333 int mgs_erase_logs(const struct lu_env *env, struct mgs_device *mgs,
4336 struct list_head log_list;
4337 struct mgs_direntry *dirent, *n;
4338 char barrier_name[20] = {};
4341 int rc, len = strlen(fsname);
4344 mutex_lock(&mgs->mgs_mutex);
4346 /* Find all the logs in the CONFIGS directory */
4347 rc = class_dentry_readdir(env, mgs, &log_list);
4349 mutex_unlock(&mgs->mgs_mutex);
4353 if (list_empty(&log_list)) {
4354 mutex_unlock(&mgs->mgs_mutex);
4358 snprintf(barrier_name, sizeof(barrier_name) - 1, "%s-%s",
4359 fsname, BARRIER_FILENAME);
4360 /* Delete the barrier fsdb */
4361 mgs_remove_fsdb_by_name(mgs, barrier_name);
4362 /* Delete the fs db */
4363 mgs_remove_fsdb_by_name(mgs, fsname);
4364 mutex_unlock(&mgs->mgs_mutex);
4366 list_for_each_entry_safe(dirent, n, &log_list, mde_list) {
4367 list_del_init(&dirent->mde_list);
4368 suffix = strrchr(dirent->mde_name, '-');
4369 if (suffix != NULL) {
4370 if ((len == suffix - dirent->mde_name) &&
4371 (strncmp(fsname, dirent->mde_name, len) == 0)) {
4372 CDEBUG(D_MGS, "Removing log %s\n",
4374 mgs_erase_log(env, mgs, dirent->mde_name);
4378 mgs_direntry_free(dirent);
4387 /* list all logs for the given fs */
4388 int mgs_list_logs(const struct lu_env *env, struct mgs_device *mgs,
4389 struct obd_ioctl_data *data)
4391 struct list_head log_list;
4392 struct mgs_direntry *dirent, *n;
4398 /* Find all the logs in the CONFIGS directory */
4399 rc = class_dentry_readdir(env, mgs, &log_list);
4403 out = data->ioc_bulk;
4404 remains = data->ioc_inllen1;
4405 list_for_each_entry_safe(dirent, n, &log_list, mde_list) {
4406 list_del_init(&dirent->mde_list);
4407 suffix = strrchr(dirent->mde_name, '-');
4408 if (suffix != NULL) {
4409 l = snprintf(out, remains, "config_log: %s\n",
4414 mgs_direntry_free(dirent);
4421 struct mgs_lcfg_fork_data {
4422 struct lustre_cfg_bufs mlfd_bufs;
4423 struct mgs_device *mlfd_mgs;
4424 struct llog_handle *mlfd_llh;
4425 const char *mlfd_oldname;
4426 const char *mlfd_newname;
4430 static bool contain_valid_fsname(char *buf, const char *fsname,
4431 int buflen, int namelen)
4433 if (buflen < namelen)
4436 if (memcmp(buf, fsname, namelen) != 0)
4439 if (buf[namelen] != '\0' && buf[namelen] != '-')
4445 static int mgs_lcfg_fork_handler(const struct lu_env *env,
4446 struct llog_handle *o_llh,
4447 struct llog_rec_hdr *o_rec, void *data)
4449 struct mgs_lcfg_fork_data *mlfd = data;
4450 struct lustre_cfg_bufs *n_bufs = &mlfd->mlfd_bufs;
4451 struct lustre_cfg *o_lcfg = (struct lustre_cfg *)(o_rec + 1);
4452 struct llog_cfg_rec *lcr;
4454 char *n_buf = mlfd->mlfd_data;
4456 int o_namelen = strlen(mlfd->mlfd_oldname);
4457 int n_namelen = strlen(mlfd->mlfd_newname);
4458 int diff = n_namelen - o_namelen;
4459 __u32 cmd = o_lcfg->lcfg_command;
4460 __u32 cnt = o_lcfg->lcfg_bufcount;
4466 o_buf = lustre_cfg_buf(o_lcfg, 0);
4467 o_buflen = o_lcfg->lcfg_buflens[0];
4468 if (contain_valid_fsname(o_buf, mlfd->mlfd_oldname, o_buflen,
4470 memcpy(n_buf, mlfd->mlfd_newname, n_namelen);
4471 memcpy(n_buf + n_namelen, o_buf + o_namelen,
4472 o_buflen - o_namelen);
4473 lustre_cfg_bufs_reset(n_bufs, n_buf);
4474 n_buf += cfs_size_round(o_buflen + diff);
4476 lustre_cfg_bufs_reset(n_bufs, o_buflen != 0 ? o_buf : NULL);
4481 struct cfg_marker *o_marker;
4482 struct cfg_marker *n_marker;
4486 CDEBUG(D_MGS, "Unknown cfg marker entry with %d "
4491 /* buf[1] is marker */
4492 o_buf = lustre_cfg_buf(o_lcfg, 1);
4493 o_buflen = o_lcfg->lcfg_buflens[1];
4494 o_marker = (struct cfg_marker *)o_buf;
4495 if (!contain_valid_fsname(o_marker->cm_tgtname,
4497 sizeof(o_marker->cm_tgtname),
4499 lustre_cfg_bufs_set(n_bufs, 1, o_marker,
4504 n_marker = (struct cfg_marker *)n_buf;
4505 *n_marker = *o_marker;
4506 memcpy(n_marker->cm_tgtname, mlfd->mlfd_newname, n_namelen);
4507 tgt_namelen = strlen(o_marker->cm_tgtname);
4508 if (tgt_namelen > o_namelen)
4509 memcpy(n_marker->cm_tgtname + n_namelen,
4510 o_marker->cm_tgtname + o_namelen,
4511 tgt_namelen - o_namelen);
4512 n_marker->cm_tgtname[tgt_namelen + diff] = '\0';
4513 lustre_cfg_bufs_set(n_bufs, 1, n_marker, sizeof(*n_marker));
4517 case LCFG_SET_PARAM: {
4518 for (i = 1; i < cnt; i++)
4519 /* buf[i] is the param value, reuse it directly */
4520 lustre_cfg_bufs_set(n_bufs, i,
4521 lustre_cfg_buf(o_lcfg, i),
4522 o_lcfg->lcfg_buflens[i]);
4528 case LCFG_POOL_DEL: {
4529 if (cnt < 3 || cnt > 4) {
4530 CDEBUG(D_MGS, "Unknown cfg pool (%x) entry with %d "
4531 "buffers\n", cmd, cnt);
4535 /* buf[1] is fsname */
4536 o_buf = lustre_cfg_buf(o_lcfg, 1);
4537 o_buflen = o_lcfg->lcfg_buflens[1];
4538 memcpy(n_buf, mlfd->mlfd_newname, n_namelen);
4539 memcpy(n_buf + n_namelen, o_buf + o_namelen,
4540 o_buflen - o_namelen);
4541 lustre_cfg_bufs_set(n_bufs, 1, n_buf, o_buflen + diff);
4542 n_buf += cfs_size_round(o_buflen + diff);
4544 /* buf[2] is the pool name, reuse it directly */
4545 lustre_cfg_bufs_set(n_bufs, 2, lustre_cfg_buf(o_lcfg, 2),
4546 o_lcfg->lcfg_buflens[2]);
4551 /* buf[3] is ostname */
4552 o_buf = lustre_cfg_buf(o_lcfg, 3);
4553 o_buflen = o_lcfg->lcfg_buflens[3];
4554 memcpy(n_buf, mlfd->mlfd_newname, n_namelen);
4555 memcpy(n_buf + n_namelen, o_buf + o_namelen,
4556 o_buflen - o_namelen);
4557 lustre_cfg_bufs_set(n_bufs, 3, n_buf, o_buflen + diff);
4562 o_buflen = o_lcfg->lcfg_buflens[1];
4563 if (o_buflen == sizeof(struct lov_desc) ||
4564 o_buflen == sizeof(struct lmv_desc)) {
4570 o_buf = lustre_cfg_buf(o_lcfg, 1);
4571 if (o_buflen == sizeof(struct lov_desc)) {
4572 struct lov_desc *o_desc =
4573 (struct lov_desc *)o_buf;
4574 struct lov_desc *n_desc =
4575 (struct lov_desc *)n_buf;
4578 o_uuid = o_desc->ld_uuid.uuid;
4579 n_uuid = n_desc->ld_uuid.uuid;
4580 uuid_len = sizeof(o_desc->ld_uuid.uuid);
4582 struct lmv_desc *o_desc =
4583 (struct lmv_desc *)o_buf;
4584 struct lmv_desc *n_desc =
4585 (struct lmv_desc *)n_buf;
4588 o_uuid = o_desc->ld_uuid.uuid;
4589 n_uuid = n_desc->ld_uuid.uuid;
4590 uuid_len = sizeof(o_desc->ld_uuid.uuid);
4593 if (unlikely(!contain_valid_fsname(o_uuid,
4594 mlfd->mlfd_oldname, uuid_len,
4596 lustre_cfg_bufs_set(n_bufs, 1, o_buf,
4601 memcpy(n_uuid, mlfd->mlfd_newname, n_namelen);
4602 uuid_len = strlen(o_uuid);
4603 if (uuid_len > o_namelen)
4604 memcpy(n_uuid + n_namelen,
4606 uuid_len - o_namelen);
4607 n_uuid[uuid_len + diff] = '\0';
4608 lustre_cfg_bufs_set(n_bufs, 1, n_buf, o_buflen);
4610 } /* else case fall through */
4611 } /* else case fall through */
4614 for (i = 1; i < cnt; i++) {
4615 o_buflen = o_lcfg->lcfg_buflens[i];
4619 o_buf = lustre_cfg_buf(o_lcfg, i);
4620 if (!contain_valid_fsname(o_buf, mlfd->mlfd_oldname,
4621 o_buflen, o_namelen)) {
4622 lustre_cfg_bufs_set(n_bufs, i, o_buf, o_buflen);
4626 memcpy(n_buf, mlfd->mlfd_newname, n_namelen);
4627 if (o_buflen == o_namelen) {
4628 lustre_cfg_bufs_set(n_bufs, i, n_buf,
4630 n_buf += cfs_size_round(n_namelen);
4634 memcpy(n_buf + n_namelen, o_buf + o_namelen,
4635 o_buflen - o_namelen);
4636 lustre_cfg_bufs_set(n_bufs, i, n_buf, o_buflen + diff);
4637 n_buf += cfs_size_round(o_buflen + diff);
4643 lcr = lustre_cfg_rec_new(cmd, n_bufs);
4647 lcr->lcr_cfg = *o_lcfg;
4648 rc = llog_write(env, mlfd->mlfd_llh, &lcr->lcr_hdr, LLOG_NEXT_IDX);
4649 lustre_cfg_rec_free(lcr);
4654 static int mgs_lcfg_fork_one(const struct lu_env *env, struct mgs_device *mgs,
4655 struct mgs_direntry *mde, const char *oldname,
4656 const char *newname)
4658 struct llog_handle *old_llh = NULL;
4659 struct llog_handle *new_llh = NULL;
4660 struct llog_ctxt *ctxt = NULL;
4661 struct mgs_lcfg_fork_data *mlfd = NULL;
4662 char *name_buf = NULL;
4664 int old_namelen = strlen(oldname);
4665 int new_namelen = strlen(newname);
4669 name_buflen = mde->mde_len + new_namelen - old_namelen;
4670 OBD_ALLOC(name_buf, name_buflen);
4674 memcpy(name_buf, newname, new_namelen);
4675 memcpy(name_buf + new_namelen, mde->mde_name + old_namelen,
4676 mde->mde_len - old_namelen);
4678 CDEBUG(D_MGS, "Fork the config-log from %s to %s\n",
4679 mde->mde_name, name_buf);
4681 ctxt = llog_get_context(mgs->mgs_obd, LLOG_CONFIG_ORIG_CTXT);
4684 rc = llog_open_create(env, ctxt, &new_llh, NULL, name_buf);
4688 rc = llog_init_handle(env, new_llh, LLOG_F_IS_PLAIN, NULL);
4692 if (unlikely(mgs_log_is_empty(env, mgs, mde->mde_name)))
4695 rc = llog_open(env, ctxt, &old_llh, NULL, mde->mde_name,
4700 rc = llog_init_handle(env, old_llh, LLOG_F_IS_PLAIN, NULL);
4704 new_llh->lgh_hdr->llh_tgtuuid = old_llh->lgh_hdr->llh_tgtuuid;
4706 OBD_ALLOC(mlfd, LLOG_MIN_CHUNK_SIZE);
4708 GOTO(out, rc = -ENOMEM);
4710 mlfd->mlfd_mgs = mgs;
4711 mlfd->mlfd_llh = new_llh;
4712 mlfd->mlfd_oldname = oldname;
4713 mlfd->mlfd_newname = newname;
4715 rc = llog_process(env, old_llh, mgs_lcfg_fork_handler, mlfd, NULL);
4716 OBD_FREE(mlfd, LLOG_MIN_CHUNK_SIZE);
4722 llog_close(env, old_llh);
4724 llog_close(env, new_llh);
4726 OBD_FREE(name_buf, name_buflen);
4728 llog_ctxt_put(ctxt);
4733 int mgs_lcfg_fork(const struct lu_env *env, struct mgs_device *mgs,
4734 const char *oldname, const char *newname)
4736 struct list_head log_list;
4737 struct mgs_direntry *dirent, *n;
4738 int olen = strlen(oldname);
4739 int nlen = strlen(newname);
4744 if (unlikely(!oldname || oldname[0] == '\0' ||
4745 !newname || newname[0] == '\0'))
4748 if (strcmp(oldname, newname) == 0)
4751 /* lock it to prevent fork/erase/register in parallel. */
4752 mutex_lock(&mgs->mgs_mutex);
4754 rc = class_dentry_readdir(env, mgs, &log_list);
4756 mutex_unlock(&mgs->mgs_mutex);
4760 if (list_empty(&log_list)) {
4761 mutex_unlock(&mgs->mgs_mutex);
4765 list_for_each_entry_safe(dirent, n, &log_list, mde_list) {
4768 ptr = strrchr(dirent->mde_name, '-');
4770 int tlen = ptr - dirent->mde_name;
4773 strncmp(newname, dirent->mde_name, tlen) == 0)
4774 GOTO(out, rc = -EEXIST);
4777 strncmp(oldname, dirent->mde_name, tlen) == 0)
4781 list_del_init(&dirent->mde_list);
4782 mgs_direntry_free(dirent);
4785 if (list_empty(&log_list)) {
4786 mutex_unlock(&mgs->mgs_mutex);
4790 list_for_each_entry(dirent, &log_list, mde_list) {
4791 rc = mgs_lcfg_fork_one(env, mgs, dirent, oldname, newname);
4799 mutex_unlock(&mgs->mgs_mutex);
4801 list_for_each_entry_safe(dirent, n, &log_list, mde_list) {
4802 list_del_init(&dirent->mde_list);
4803 mgs_direntry_free(dirent);
4806 if (rc && count > 0)
4807 mgs_erase_logs(env, mgs, newname);
4812 int mgs_lcfg_erase(const struct lu_env *env, struct mgs_device *mgs,
4818 if (unlikely(!fsname || fsname[0] == '\0'))
4821 rc = mgs_erase_logs(env, mgs, fsname);
4826 static int mgs_xattr_del(const struct lu_env *env, struct dt_object *obj)
4828 struct dt_device *dev;
4829 struct thandle *th = NULL;
4834 dev = container_of0(obj->do_lu.lo_dev, struct dt_device, dd_lu_dev);
4835 th = dt_trans_create(env, dev);
4837 RETURN(PTR_ERR(th));
4839 rc = dt_declare_xattr_del(env, obj, XATTR_TARGET_RENAME, th);
4843 rc = dt_trans_start_local(env, dev, th);
4847 dt_write_lock(env, obj, 0);
4848 rc = dt_xattr_del(env, obj, XATTR_TARGET_RENAME, th);
4853 dt_write_unlock(env, obj);
4856 dt_trans_stop(env, dev, th);
4861 int mgs_lcfg_rename(const struct lu_env *env, struct mgs_device *mgs)
4863 struct list_head log_list;
4864 struct mgs_direntry *dirent, *n;
4866 struct lu_buf buf = {
4868 .lb_len = sizeof(fsname)
4874 rc = class_dentry_readdir(env, mgs, &log_list);
4878 if (list_empty(&log_list))
4881 list_for_each_entry_safe(dirent, n, &log_list, mde_list) {
4882 struct dt_object *o = NULL;
4887 list_del_init(&dirent->mde_list);
4888 ptr = strrchr(dirent->mde_name, '-');
4892 len = ptr - dirent->mde_name;
4893 if (unlikely(len >= sizeof(oldname))) {
4894 CDEBUG(D_MGS, "Skip invalid configuration file %s\n",
4899 o = local_file_find(env, mgs->mgs_los, mgs->mgs_configs_dir,
4903 CDEBUG(D_MGS, "Fail to locate file %s: rc = %d\n",
4904 dirent->mde_name, rc);
4908 rc = dt_xattr_get(env, o, &buf, XATTR_TARGET_RENAME);
4914 "Fail to get EA for %s: rc = %d\n",
4915 dirent->mde_name, rc);
4919 if (unlikely(rc == len &&
4920 memcmp(fsname, dirent->mde_name, len) == 0)) {
4921 /* The new fsname is the same as the old one. */
4922 rc = mgs_xattr_del(env, o);
4926 memcpy(oldname, dirent->mde_name, len);
4927 oldname[len] = '\0';
4929 rc = mgs_lcfg_fork_one(env, mgs, dirent, oldname, fsname);
4930 if (rc && rc != -EEXIST) {
4931 CDEBUG(D_MGS, "Fail to fork %s: rc = %d\n",
4932 dirent->mde_name, rc);
4936 rc = mgs_erase_log(env, mgs, dirent->mde_name);
4938 CDEBUG(D_MGS, "Fail to erase old %s: rc = %d\n",
4939 dirent->mde_name, rc);
4940 /* keep it there if failed to remove it. */
4945 if (o && !IS_ERR(o))
4946 lu_object_put(env, &o->do_lu);
4948 mgs_direntry_free(dirent);
4953 list_for_each_entry_safe(dirent, n, &log_list, mde_list) {
4954 list_del_init(&dirent->mde_list);
4955 mgs_direntry_free(dirent);
4961 /* Setup _mgs fsdb and log
4963 int mgs__mgs_fsdb_setup(const struct lu_env *env, struct mgs_device *mgs)
4965 struct fs_db *fsdb = NULL;
4969 rc = mgs_find_or_make_fsdb(env, mgs, MGSSELF_NAME, &fsdb);
4971 mgs_put_fsdb(mgs, fsdb);
4976 /* Setup params fsdb and log
4978 int mgs_params_fsdb_setup(const struct lu_env *env, struct mgs_device *mgs)
4980 struct fs_db *fsdb = NULL;
4981 struct llog_handle *params_llh = NULL;
4985 rc = mgs_find_or_make_fsdb(env, mgs, PARAMS_FILENAME, &fsdb);
4987 mutex_lock(&fsdb->fsdb_mutex);
4988 rc = record_start_log(env, mgs, ¶ms_llh, PARAMS_FILENAME);
4990 rc = record_end_log(env, ¶ms_llh);
4991 mutex_unlock(&fsdb->fsdb_mutex);
4992 mgs_put_fsdb(mgs, fsdb);
4998 /* Cleanup params fsdb and log
5000 int mgs_params_fsdb_cleanup(const struct lu_env *env, struct mgs_device *mgs)
5004 rc = mgs_erase_logs(env, mgs, PARAMS_FILENAME);
5005 return rc == -ENOENT ? 0 : rc;
5009 * Fill in the mgs_target_info based on data devname and param provide.
5011 * @env thread context
5013 * @mti mgs target info. We want to set this based other paramters
5014 * passed to this function. Once setup we write it to the config
5016 * @devname optional OBD device name
5017 * @param string that contains both what tunable to set and the value to
5020 * RETURN 0 for success
5021 * negative error number on failure
5023 static int mgs_set_conf_param(const struct lu_env *env, struct mgs_device *mgs,
5024 struct mgs_target_info *mti, const char *devname,
5027 struct fs_db *fsdb = NULL;
5032 /* lustre, lustre-mdtlov, lustre-client, lustre-MDT0000 */
5036 /* We have two possible cases here:
5038 * 1) the device name embedded in the param:
5039 * lustre-OST0000.osc.max_dirty_mb=32
5041 * 2) the file system name is embedded in
5042 * the param: lustre.sys.at.min=0
5044 len = strcspn(param, ".=");
5045 if (!len || param[len] == '=')
5048 if (len >= sizeof(mti->mti_svname))
5051 snprintf(mti->mti_svname, sizeof(mti->mti_svname),
5052 "%.*s", (int)len, param);
5055 if (strlcpy(mti->mti_svname, devname, sizeof(mti->mti_svname)) >=
5056 sizeof(mti->mti_svname))
5060 if (!strlen(mti->mti_svname)) {
5061 LCONSOLE_ERROR_MSG(0x14d, "No target specified: %s\n", param);
5065 dev_type = mgs_parse_devname(mti->mti_svname, mti->mti_fsname,
5066 &mti->mti_stripe_index);
5068 /* For this case we have an invalid obd device name */
5070 CDEBUG(D_MGS, "%s don't contain an index\n", mti->mti_svname);
5071 strlcpy(mti->mti_fsname, mti->mti_svname, MTI_NAME_MAXLEN);
5074 /* Not an obd device, assume devname is the fsname.
5075 * User might of only provided fsname and not obd device
5078 CDEBUG(D_MGS, "%s is seen as a file system name\n", mti->mti_svname);
5079 strlcpy(mti->mti_fsname, mti->mti_svname, MTI_NAME_MAXLEN);
5084 GOTO(out, rc = dev_type);
5086 /* param related to llite isn't allowed to set by OST or MDT */
5087 if (dev_type & LDD_F_SV_TYPE_OST ||
5088 dev_type & LDD_F_SV_TYPE_MDT) {
5089 /* param related to llite isn't allowed to set by OST
5092 if (!strncmp(param, PARAM_LLITE,
5093 sizeof(PARAM_LLITE) - 1))
5094 GOTO(out, rc = -EINVAL);
5096 /* Strip -osc or -mdc suffix from svname */
5097 if (server_make_name(dev_type, mti->mti_stripe_index,
5098 mti->mti_fsname, mti->mti_svname,
5099 sizeof(mti->mti_svname)))
5100 GOTO(out, rc = -EINVAL);
5105 if (strlcpy(mti->mti_params, param, sizeof(mti->mti_params)) >=
5106 sizeof(mti->mti_params))
5107 GOTO(out, rc = -E2BIG);
5109 CDEBUG(D_MGS, "set_conf_param fs='%s' device='%s' param='%s'\n",
5110 mti->mti_fsname, mti->mti_svname, mti->mti_params);
5112 rc = mgs_find_or_make_fsdb(env, mgs, mti->mti_fsname, &fsdb);
5116 if (!test_bit(FSDB_MGS_SELF, &fsdb->fsdb_flags) &&
5117 test_bit(FSDB_LOG_EMPTY, &fsdb->fsdb_flags)) {
5118 CERROR("No filesystem targets for %s. cfg_device from lctl "
5119 "is '%s'\n", mti->mti_fsname, mti->mti_svname);
5120 mgs_unlink_fsdb(mgs, fsdb);
5121 GOTO(out, rc = -EINVAL);
5125 * Revoke lock so everyone updates. Should be alright if
5126 * someone was already reading while we were updating the logs,
5127 * so we don't really need to hold the lock while we're
5130 mti->mti_flags = dev_type | LDD_F_PARAM;
5131 mutex_lock(&fsdb->fsdb_mutex);
5132 rc = mgs_write_log_param(env, mgs, fsdb, mti, mti->mti_params);
5133 mutex_unlock(&fsdb->fsdb_mutex);
5134 mgs_revoke_lock(mgs, fsdb, CONFIG_T_CONFIG);
5138 mgs_put_fsdb(mgs, fsdb);
5143 static int mgs_set_param2(const struct lu_env *env, struct mgs_device *mgs,
5144 struct mgs_target_info *mti, const char *param)
5146 struct fs_db *fsdb = NULL;
5151 if (strlcpy(mti->mti_params, param, sizeof(mti->mti_params)) >=
5152 sizeof(mti->mti_params))
5153 GOTO(out, rc = -E2BIG);
5155 /* obdname2fsname reports devname as an obd device */
5156 len = strcspn(param, ".=");
5157 if (len && param[len] != '=') {
5161 ptr = strchr(param, '.');
5163 len = strlen(param);
5166 if (len >= sizeof(mti->mti_svname))
5167 GOTO(out, rc = -E2BIG);
5169 snprintf(mti->mti_svname, sizeof(mti->mti_svname), "%.*s",
5172 obdname2fsname(mti->mti_svname, mti->mti_fsname,
5173 sizeof(mti->mti_fsname));
5175 snprintf(mti->mti_svname, sizeof(mti->mti_svname), "general");
5178 CDEBUG(D_MGS, "set_param2 fs='%s' device='%s' param='%s'\n",
5179 mti->mti_fsname, mti->mti_svname, mti->mti_params);
5181 /* The return value should be the device type i.e LDD_F_SV_TYPE_XXX.
5182 * A returned error tells us we don't have a target obd device.
5184 dev_type = server_name2index(mti->mti_svname, &mti->mti_stripe_index,
5189 /* the return value should be the device type i.e LDD_F_SV_TYPE_XXX.
5190 * Strip -osc or -mdc suffix from svname
5192 if ((dev_type & LDD_F_SV_TYPE_OST || dev_type & LDD_F_SV_TYPE_MDT) &&
5193 server_make_name(dev_type, mti->mti_stripe_index,
5194 mti->mti_fsname, mti->mti_svname,
5195 sizeof(mti->mti_svname)))
5196 GOTO(out, rc = -EINVAL);
5198 rc = mgs_find_or_make_fsdb(env, mgs, PARAMS_FILENAME, &fsdb);
5202 * Revoke lock so everyone updates. Should be alright if
5203 * someone was already reading while we were updating the logs,
5204 * so we don't really need to hold the lock while we're
5207 mti->mti_flags = dev_type | LDD_F_PARAM2;
5208 mutex_lock(&fsdb->fsdb_mutex);
5209 rc = mgs_write_log_param2(env, mgs, fsdb, mti, mti->mti_params);
5210 mutex_unlock(&fsdb->fsdb_mutex);
5211 mgs_revoke_lock(mgs, fsdb, CONFIG_T_PARAMS);
5212 mgs_put_fsdb(mgs, fsdb);
5217 /* Set a permanent (config log) param for a target or fs
5219 * @lcfg buf0 may contain the device (testfs-MDT0000) name
5220 * buf1 contains the single parameter
5222 int mgs_set_param(const struct lu_env *env, struct mgs_device *mgs,
5223 struct lustre_cfg *lcfg)
5225 const char *param = lustre_cfg_string(lcfg, 1);
5226 struct mgs_target_info *mti;
5229 /* Create a fake mti to hold everything */
5234 print_lustre_cfg(lcfg);
5236 if (lcfg->lcfg_command == LCFG_PARAM) {
5237 /* For the case of lctl conf_param devname can be
5238 * lustre, lustre-mdtlov, lustre-client, lustre-MDT0000
5240 const char *devname = lustre_cfg_string(lcfg, 0);
5242 rc = mgs_set_conf_param(env, mgs, mti, devname, param);
5244 /* In the case of lctl set_param -P lcfg[0] will always
5245 * be 'general'. At least for now.
5247 rc = mgs_set_param2(env, mgs, mti, param);
5255 static int mgs_write_log_pool(const struct lu_env *env,
5256 struct mgs_device *mgs, char *logname,
5257 struct fs_db *fsdb, char *tgtname,
5258 enum lcfg_command_type cmd,
5259 char *fsname, char *poolname,
5260 char *ostname, char *comment)
5262 struct llog_handle *llh = NULL;
5265 rc = record_start_log(env, mgs, &llh, logname);
5268 rc = record_marker(env, llh, fsdb, CM_START, tgtname, comment);
5271 rc = record_base(env, llh, tgtname, 0, cmd,
5272 fsname, poolname, ostname, NULL);
5275 rc = record_marker(env, llh, fsdb, CM_END, tgtname, comment);
5277 record_end_log(env, &llh);
5281 int mgs_nodemap_cmd(const struct lu_env *env, struct mgs_device *mgs,
5282 enum lcfg_command_type cmd, const char *nodemap_name,
5293 case LCFG_NODEMAP_ADD:
5294 rc = nodemap_add(nodemap_name);
5296 case LCFG_NODEMAP_DEL:
5297 rc = nodemap_del(nodemap_name);
5299 case LCFG_NODEMAP_ADD_RANGE:
5300 rc = nodemap_parse_range(param, nid);
5303 rc = nodemap_add_range(nodemap_name, nid);
5305 case LCFG_NODEMAP_DEL_RANGE:
5306 rc = nodemap_parse_range(param, nid);
5309 rc = nodemap_del_range(nodemap_name, nid);
5311 case LCFG_NODEMAP_ADMIN:
5312 bool_switch = simple_strtoul(param, NULL, 10);
5313 rc = nodemap_set_allow_root(nodemap_name, bool_switch);
5315 case LCFG_NODEMAP_DENY_UNKNOWN:
5316 bool_switch = simple_strtoul(param, NULL, 10);
5317 rc = nodemap_set_deny_unknown(nodemap_name, bool_switch);
5319 case LCFG_NODEMAP_AUDIT_MODE:
5320 rc = kstrtoul(param, 10, (unsigned long *)&bool_switch);
5322 rc = nodemap_set_audit_mode(nodemap_name, bool_switch);
5324 case LCFG_NODEMAP_MAP_MODE:
5325 if (strcmp("both", param) == 0)
5326 rc = nodemap_set_mapping_mode(nodemap_name,
5328 else if (strcmp("uid_only", param) == 0)
5329 rc = nodemap_set_mapping_mode(nodemap_name,
5330 NODEMAP_MAP_UID_ONLY);
5331 else if (strcmp("gid_only", param) == 0)
5332 rc = nodemap_set_mapping_mode(nodemap_name,
5333 NODEMAP_MAP_GID_ONLY);
5337 case LCFG_NODEMAP_TRUSTED:
5338 bool_switch = simple_strtoul(param, NULL, 10);
5339 rc = nodemap_set_trust_client_ids(nodemap_name, bool_switch);
5341 case LCFG_NODEMAP_SQUASH_UID:
5342 int_id = simple_strtoul(param, NULL, 10);
5343 rc = nodemap_set_squash_uid(nodemap_name, int_id);
5345 case LCFG_NODEMAP_SQUASH_GID:
5346 int_id = simple_strtoul(param, NULL, 10);
5347 rc = nodemap_set_squash_gid(nodemap_name, int_id);
5349 case LCFG_NODEMAP_ADD_UIDMAP:
5350 case LCFG_NODEMAP_ADD_GIDMAP:
5351 rc = nodemap_parse_idmap(param, idmap);
5354 if (cmd == LCFG_NODEMAP_ADD_UIDMAP)
5355 rc = nodemap_add_idmap(nodemap_name, NODEMAP_UID,
5358 rc = nodemap_add_idmap(nodemap_name, NODEMAP_GID,
5361 case LCFG_NODEMAP_DEL_UIDMAP:
5362 case LCFG_NODEMAP_DEL_GIDMAP:
5363 rc = nodemap_parse_idmap(param, idmap);
5366 if (cmd == LCFG_NODEMAP_DEL_UIDMAP)
5367 rc = nodemap_del_idmap(nodemap_name, NODEMAP_UID,
5370 rc = nodemap_del_idmap(nodemap_name, NODEMAP_GID,
5373 case LCFG_NODEMAP_SET_FILESET:
5374 rc = nodemap_set_fileset(nodemap_name, param);
5383 int mgs_pool_cmd(const struct lu_env *env, struct mgs_device *mgs,
5384 enum lcfg_command_type cmd, char *fsname,
5385 char *poolname, char *ostname)
5390 char *label = NULL, *canceled_label = NULL;
5392 struct mgs_target_info *mti = NULL;
5393 bool checked = false;
5394 bool locked = false;
5399 rc = mgs_find_or_make_fsdb(env, mgs, fsname, &fsdb);
5401 CERROR("Can't get db for %s\n", fsname);
5404 if (test_bit(FSDB_LOG_EMPTY, &fsdb->fsdb_flags)) {
5405 CERROR("%s is not defined\n", fsname);
5407 GOTO(out_fsdb, rc = -EINVAL);
5410 label_sz = 10 + strlen(fsname) + strlen(poolname);
5412 /* check if ostname match fsname */
5413 if (ostname != NULL) {
5416 ptr = strrchr(ostname, '-');
5417 if ((ptr == NULL) ||
5418 (strncmp(fsname, ostname, ptr-ostname) != 0))
5420 label_sz += strlen(ostname);
5423 OBD_ALLOC(label, label_sz);
5425 GOTO(out_fsdb, rc = -ENOMEM);
5430 "new %s.%s", fsname, poolname);
5434 "add %s.%s.%s", fsname, poolname, ostname);
5437 OBD_ALLOC(canceled_label, label_sz);
5438 if (canceled_label == NULL)
5439 GOTO(out_label, rc = -ENOMEM);
5441 "rem %s.%s.%s", fsname, poolname, ostname);
5442 sprintf(canceled_label,
5443 "add %s.%s.%s", fsname, poolname, ostname);
5446 OBD_ALLOC(canceled_label, label_sz);
5447 if (canceled_label == NULL)
5448 GOTO(out_label, rc = -ENOMEM);
5450 "del %s.%s", fsname, poolname);
5451 sprintf(canceled_label,
5452 "new %s.%s", fsname, poolname);
5460 GOTO(out_cancel, rc = -ENOMEM);
5461 strncpy(mti->mti_svname, "lov pool", sizeof(mti->mti_svname));
5463 mutex_lock(&fsdb->fsdb_mutex);
5465 /* write pool def to all MDT logs */
5466 for (i = 0; i < INDEX_MAP_SIZE * 8; i++) {
5467 if (test_bit(i, fsdb->fsdb_mdt_index_map)) {
5468 rc = name_create_mdt_and_lov(&logname, &lovname,
5473 if (!checked && (canceled_label == NULL)) {
5474 rc = mgs_check_marker(env, mgs, fsdb, mti,
5475 logname, lovname, label);
5477 name_destroy(&logname);
5478 name_destroy(&lovname);
5480 rc = (rc == LLOG_PROC_BREAK ?
5485 if (canceled_label != NULL)
5486 rc = mgs_modify(env, mgs, fsdb, mti, logname,
5487 lovname, canceled_label,
5491 rc = mgs_write_log_pool(env, mgs, logname,
5495 name_destroy(&logname);
5496 name_destroy(&lovname);
5502 rc = name_create(&logname, fsname, "-client");
5506 if (!checked && (canceled_label == NULL)) {
5507 rc = mgs_check_marker(env, mgs, fsdb, mti, logname,
5508 fsdb->fsdb_clilov, label);
5510 name_destroy(&logname);
5511 GOTO(out_mti, rc = (rc == LLOG_PROC_BREAK ?
5515 if (canceled_label != NULL) {
5516 rc = mgs_modify(env, mgs, fsdb, mti, logname,
5517 fsdb->fsdb_clilov, canceled_label, CM_SKIP);
5519 name_destroy(&logname);
5524 rc = mgs_write_log_pool(env, mgs, logname, fsdb, fsdb->fsdb_clilov,
5525 cmd, fsname, poolname, ostname, label);
5526 mutex_unlock(&fsdb->fsdb_mutex);
5528 name_destroy(&logname);
5529 /* request for update */
5530 mgs_revoke_lock(mgs, fsdb, CONFIG_T_CONFIG);
5536 mutex_unlock(&fsdb->fsdb_mutex);
5540 if (canceled_label != NULL)
5541 OBD_FREE(canceled_label, label_sz);
5543 OBD_FREE(label, label_sz);
5546 mgs_unlink_fsdb(mgs, fsdb);
5547 mgs_put_fsdb(mgs, fsdb);