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/
31 * lustre/mgs/mgs_llog.c
33 * Lustre Management Server (mgs) config llog creation
35 * Author: Nathan Rutman <nathan@clusterfs.com>
36 * Author: Alex Zhuravlev <bzzz@whamcloud.com>
37 * Author: Mikhail Pershin <tappro@whamcloud.com>
40 #define DEBUG_SUBSYSTEM S_MGS
41 #define D_MGS D_CONFIG
44 #include <uapi/linux/lustre/lustre_ioctl.h>
45 #include <uapi/linux/lustre/lustre_param.h>
46 #include <lustre_sec.h>
47 #include <lustre_quota.h>
48 #include <lustre_sec.h>
50 #include "mgs_internal.h"
52 /********************** Class functions ********************/
55 * Find all logs in CONFIG directory and link then into list.
57 * \param[in] env pointer to the thread context
58 * \param[in] mgs pointer to the mgs device
59 * \param[out] log_list the list to hold the found llog name entry
61 * \retval 0 for success
62 * \retval negative error number on failure
64 int class_dentry_readdir(const struct lu_env *env, struct mgs_device *mgs,
65 struct list_head *log_list)
67 struct dt_object *dir = mgs->mgs_configs_dir;
68 const struct dt_it_ops *iops;
70 struct mgs_direntry *de;
74 INIT_LIST_HEAD(log_list);
77 LASSERT(dir->do_index_ops);
79 iops = &dir->do_index_ops->dio_it;
80 it = iops->init(env, dir, LUDA_64BITHASH);
84 rc = iops->load(env, it, 0);
90 key = (void *)iops->key(env, it);
92 CERROR("%s: key failed when listing %s: rc = %d\n",
93 mgs->mgs_obd->obd_name, MOUNT_CONFIGS_DIR,
97 key_sz = iops->key_size(env, it);
100 /* filter out "." and ".." entries */
104 if (key_sz == 2 && key[1] == '.')
108 /* filter out backup files */
109 if (lu_name_is_backup_file(key, key_sz, NULL)) {
110 CDEBUG(D_MGS, "Skipping backup file %.*s\n",
115 de = mgs_direntry_alloc(key_sz + 1);
121 memcpy(de->mde_name, key, key_sz);
122 de->mde_name[key_sz] = 0;
124 list_add(&de->mde_list, log_list);
127 rc = iops->next(env, it);
137 struct mgs_direntry *n;
139 CERROR("%s: key failed when listing %s: rc = %d\n",
140 mgs->mgs_obd->obd_name, MOUNT_CONFIGS_DIR, rc);
142 list_for_each_entry_safe(de, n, log_list, mde_list) {
143 list_del_init(&de->mde_list);
144 mgs_direntry_free(de);
151 /******************** DB functions *********************/
153 static inline int name_create(char **newname, char *prefix, char *suffix)
156 OBD_ALLOC(*newname, strlen(prefix) + strlen(suffix) + 1);
159 sprintf(*newname, "%s%s", prefix, suffix);
163 static inline void name_destroy(char **name)
166 OBD_FREE(*name, strlen(*name) + 1);
170 struct mgs_fsdb_handler_data
176 /* from the (client) config log, figure out:
177 1. which ost's/mdt's are configured (by index)
178 2. what the last config step is
179 3. COMPAT_18 osc name
181 /* It might be better to have a separate db file, instead of parsing the info
182 out of the client log. This is slow and potentially error-prone. */
183 static int mgs_fsdb_handler(const struct lu_env *env, struct llog_handle *llh,
184 struct llog_rec_hdr *rec, void *data)
186 struct mgs_fsdb_handler_data *d = data;
187 struct fs_db *fsdb = d->fsdb;
188 int cfg_len = rec->lrh_len;
189 char *cfg_buf = (char*) (rec + 1);
190 struct lustre_cfg *lcfg;
195 if (rec->lrh_type != OBD_CFG_REC) {
196 CERROR("unhandled lrh_type: %#x\n", rec->lrh_type);
200 rc = lustre_cfg_sanity_check(cfg_buf, cfg_len);
202 CERROR("Insane cfg\n");
206 lcfg = (struct lustre_cfg *)cfg_buf;
208 CDEBUG(D_INFO, "cmd %x %s %s\n", lcfg->lcfg_command,
209 lustre_cfg_string(lcfg, 0), lustre_cfg_string(lcfg, 1));
211 /* Figure out ost indicies */
212 /* lov_modify_tgts add 0:lov1 1:ost1_UUID 2(index):0 3(gen):1 */
213 if (lcfg->lcfg_command == LCFG_LOV_ADD_OBD ||
214 lcfg->lcfg_command == LCFG_LOV_DEL_OBD) {
215 rc = kstrtouint(lustre_cfg_string(lcfg, 2), 10, &index);
219 CDEBUG(D_MGS, "OST index for %s is %u (%s)\n",
220 lustre_cfg_string(lcfg, 1), index,
221 lustre_cfg_string(lcfg, 2));
222 set_bit(index, fsdb->fsdb_ost_index_map);
225 /* Figure out mdt indicies */
226 /* attach 0:MDC_uml1_mdsA_MNT_client 1:mdc 2:1d834_MNT_client_03f */
227 if ((lcfg->lcfg_command == LCFG_ATTACH) &&
228 (strcmp(lustre_cfg_string(lcfg, 1), LUSTRE_MDC_NAME) == 0)) {
229 rc = server_name2index(lustre_cfg_string(lcfg, 0),
231 if (rc != LDD_F_SV_TYPE_MDT) {
232 CWARN("Unparsable MDC name %s, assuming index 0\n",
233 lustre_cfg_string(lcfg, 0));
237 CDEBUG(D_MGS, "MDT index is %u\n", index);
238 if (!test_bit(index, fsdb->fsdb_mdt_index_map)) {
239 set_bit(index, fsdb->fsdb_mdt_index_map);
240 fsdb->fsdb_mdt_count++;
245 * figure out the old config. fsdb_gen = 0 means old log
246 * It is obsoleted and not supported anymore
248 if (fsdb->fsdb_gen == 0) {
249 CERROR("Old config format is not supported\n");
254 * compat to 1.8, check osc name used by MDT0 to OSTs, bz18548.
256 if (!test_bit(FSDB_OSCNAME18, &fsdb->fsdb_flags) &&
257 lcfg->lcfg_command == LCFG_ATTACH &&
258 strcmp(lustre_cfg_string(lcfg, 1), LUSTRE_OSC_NAME) == 0) {
259 if (OBD_OCD_VERSION_MAJOR(d->ver) == 1 &&
260 OBD_OCD_VERSION_MINOR(d->ver) <= 8) {
261 CWARN("MDT using 1.8 OSC name scheme\n");
262 set_bit(FSDB_OSCNAME18, &fsdb->fsdb_flags);
266 if (lcfg->lcfg_command == LCFG_MARKER) {
267 struct cfg_marker *marker;
268 marker = lustre_cfg_buf(lcfg, 1);
270 d->ver = marker->cm_vers;
272 /* Keep track of the latest marker step */
273 fsdb->fsdb_gen = max(fsdb->fsdb_gen, marker->cm_step);
279 /* fsdb->fsdb_mutex is already held in mgs_find_or_make_fsdb*/
280 static int mgs_get_fsdb_from_llog(const struct lu_env *env,
281 struct mgs_device *mgs,
285 struct llog_handle *loghandle;
286 struct llog_ctxt *ctxt;
287 struct mgs_fsdb_handler_data d = {
294 ctxt = llog_get_context(mgs->mgs_obd, LLOG_CONFIG_ORIG_CTXT);
295 LASSERT(ctxt != NULL);
296 rc = name_create(&logname, fsdb->fsdb_name, "-client");
299 rc = llog_open_create(env, ctxt, &loghandle, NULL, logname);
303 rc = llog_init_handle(env, loghandle, LLOG_F_IS_PLAIN, NULL);
307 if (llog_get_size(loghandle) <= 1)
308 set_bit(FSDB_LOG_EMPTY, &fsdb->fsdb_flags);
310 rc = llog_process(env, loghandle, mgs_fsdb_handler, (void *)&d, NULL);
311 CDEBUG(D_INFO, "get_db = %d\n", rc);
313 llog_close(env, loghandle);
315 name_destroy(&logname);
322 static void mgs_free_fsdb_srpc(struct fs_db *fsdb)
324 struct mgs_tgt_srpc_conf *tgtconf;
326 /* free target-specific rules */
327 while (fsdb->fsdb_srpc_tgt) {
328 tgtconf = fsdb->fsdb_srpc_tgt;
329 fsdb->fsdb_srpc_tgt = tgtconf->mtsc_next;
331 LASSERT(tgtconf->mtsc_tgt);
333 sptlrpc_rule_set_free(&tgtconf->mtsc_rset);
334 OBD_FREE(tgtconf->mtsc_tgt, strlen(tgtconf->mtsc_tgt) + 1);
335 OBD_FREE_PTR(tgtconf);
338 /* free general rules */
339 sptlrpc_rule_set_free(&fsdb->fsdb_srpc_gen);
342 static void mgs_unlink_fsdb(struct mgs_device *mgs, struct fs_db *fsdb)
344 mutex_lock(&mgs->mgs_mutex);
345 if (likely(!list_empty(&fsdb->fsdb_list))) {
346 LASSERTF(atomic_read(&fsdb->fsdb_ref) >= 2,
347 "Invalid ref %d on %s\n",
348 atomic_read(&fsdb->fsdb_ref),
351 list_del_init(&fsdb->fsdb_list);
352 /* Drop the reference on the list.*/
353 mgs_put_fsdb(mgs, fsdb);
355 mutex_unlock(&mgs->mgs_mutex);
358 /* The caller must hold mgs->mgs_mutex. */
359 static inline struct fs_db *
360 mgs_find_fsdb_noref(struct mgs_device *mgs, const char *fsname)
363 struct list_head *tmp;
365 list_for_each(tmp, &mgs->mgs_fs_db_list) {
366 fsdb = list_entry(tmp, struct fs_db, fsdb_list);
367 if (strcmp(fsdb->fsdb_name, fsname) == 0)
374 /* The caller must hold mgs->mgs_mutex. */
375 static void mgs_remove_fsdb_by_name(struct mgs_device *mgs, const char *name)
379 fsdb = mgs_find_fsdb_noref(mgs, name);
381 list_del_init(&fsdb->fsdb_list);
382 /* Drop the reference on the list.*/
383 mgs_put_fsdb(mgs, fsdb);
387 /* The caller must hold mgs->mgs_mutex. */
388 struct fs_db *mgs_find_fsdb(struct mgs_device *mgs, const char *fsname)
392 fsdb = mgs_find_fsdb_noref(mgs, fsname);
394 atomic_inc(&fsdb->fsdb_ref);
399 /* The caller must hold mgs->mgs_mutex. */
400 static struct fs_db *mgs_new_fsdb(const struct lu_env *env,
401 struct mgs_device *mgs, char *fsname)
407 if (strlen(fsname) >= sizeof(fsdb->fsdb_name)) {
408 CERROR("fsname %s is too long\n", fsname);
410 RETURN(ERR_PTR(-EINVAL));
415 RETURN(ERR_PTR(-ENOMEM));
417 strncpy(fsdb->fsdb_name, fsname, sizeof(fsdb->fsdb_name));
418 mutex_init(&fsdb->fsdb_mutex);
419 INIT_LIST_HEAD(&fsdb->fsdb_list);
420 set_bit(FSDB_UDESC, &fsdb->fsdb_flags);
422 INIT_LIST_HEAD(&fsdb->fsdb_clients);
423 atomic_set(&fsdb->fsdb_notify_phase, 0);
424 init_waitqueue_head(&fsdb->fsdb_notify_waitq);
425 init_completion(&fsdb->fsdb_notify_comp);
427 if (strcmp(fsname, MGSSELF_NAME) == 0) {
428 set_bit(FSDB_MGS_SELF, &fsdb->fsdb_flags);
429 fsdb->fsdb_mgs = mgs;
430 if (logname_is_barrier(fsname))
433 OBD_ALLOC(fsdb->fsdb_mdt_index_map, INDEX_MAP_SIZE);
434 if (!fsdb->fsdb_mdt_index_map) {
435 CERROR("No memory for MDT index maps\n");
437 GOTO(err, rc = -ENOMEM);
440 OBD_ALLOC(fsdb->fsdb_ost_index_map, INDEX_MAP_SIZE);
441 if (!fsdb->fsdb_ost_index_map) {
442 CERROR("No memory for OST index maps\n");
444 GOTO(err, rc = -ENOMEM);
447 if (logname_is_barrier(fsname))
450 rc = name_create(&fsdb->fsdb_clilov, fsname, "-clilov");
454 rc = name_create(&fsdb->fsdb_clilmv, fsname, "-clilmv");
458 /* initialise data for NID table */
459 mgs_ir_init_fs(env, mgs, fsdb);
460 lproc_mgs_add_live(mgs, fsdb);
463 if (!test_bit(FSDB_MGS_SELF, &fsdb->fsdb_flags) &&
464 strcmp(PARAMS_FILENAME, fsname) != 0) {
465 /* populate the db from the client llog */
466 rc = mgs_get_fsdb_from_llog(env, mgs, fsdb);
468 CERROR("Can't get db from client log %d\n", rc);
474 /* populate srpc rules from params llog */
475 rc = mgs_get_fsdb_srpc_from_llog(env, mgs, fsdb);
477 CERROR("Can't get db from params log %d\n", rc);
483 /* One ref is for the fsdb on the list.
484 * The other ref is for the caller. */
485 atomic_set(&fsdb->fsdb_ref, 2);
486 list_add(&fsdb->fsdb_list, &mgs->mgs_fs_db_list);
491 atomic_set(&fsdb->fsdb_ref, 1);
492 mgs_put_fsdb(mgs, fsdb);
497 static void mgs_free_fsdb(struct mgs_device *mgs, struct fs_db *fsdb)
499 LASSERT(list_empty(&fsdb->fsdb_list));
501 lproc_mgs_del_live(mgs, fsdb);
503 /* deinitialize fsr */
505 mgs_ir_fini_fs(mgs, fsdb);
507 if (fsdb->fsdb_ost_index_map)
508 OBD_FREE(fsdb->fsdb_ost_index_map, INDEX_MAP_SIZE);
509 if (fsdb->fsdb_mdt_index_map)
510 OBD_FREE(fsdb->fsdb_mdt_index_map, INDEX_MAP_SIZE);
511 name_destroy(&fsdb->fsdb_clilov);
512 name_destroy(&fsdb->fsdb_clilmv);
513 mgs_free_fsdb_srpc(fsdb);
517 void mgs_put_fsdb(struct mgs_device *mgs, struct fs_db *fsdb)
519 if (atomic_dec_and_test(&fsdb->fsdb_ref))
520 mgs_free_fsdb(mgs, fsdb);
523 int mgs_init_fsdb_list(struct mgs_device *mgs)
525 INIT_LIST_HEAD(&mgs->mgs_fs_db_list);
529 int mgs_cleanup_fsdb_list(struct mgs_device *mgs)
532 struct list_head *tmp, *tmp2;
534 mutex_lock(&mgs->mgs_mutex);
535 list_for_each_safe(tmp, tmp2, &mgs->mgs_fs_db_list) {
536 fsdb = list_entry(tmp, struct fs_db, fsdb_list);
537 list_del_init(&fsdb->fsdb_list);
538 mgs_put_fsdb(mgs, fsdb);
540 mutex_unlock(&mgs->mgs_mutex);
544 /* The caller must hold mgs->mgs_mutex. */
545 int mgs_find_or_make_fsdb_nolock(const struct lu_env *env,
546 struct mgs_device *mgs,
547 char *name, struct fs_db **dbh)
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);
568 int mgs_find_or_make_fsdb(const struct lu_env *env, struct mgs_device *mgs,
569 char *name, struct fs_db **dbh)
574 mutex_lock(&mgs->mgs_mutex);
575 rc = mgs_find_or_make_fsdb_nolock(env, mgs, name, dbh);
576 mutex_unlock(&mgs->mgs_mutex);
583 -1= empty client log */
584 int mgs_check_index(const struct lu_env *env,
585 struct mgs_device *mgs,
586 struct mgs_target_info *mti)
593 LASSERT(!(mti->mti_flags & LDD_F_NEED_INDEX));
595 rc = mgs_find_or_make_fsdb(env, mgs, mti->mti_fsname, &fsdb);
597 CERROR("Can't get db for %s\n", mti->mti_fsname);
601 if (test_bit(FSDB_LOG_EMPTY, &fsdb->fsdb_flags))
604 if (mti->mti_flags & LDD_F_SV_TYPE_OST)
605 imap = fsdb->fsdb_ost_index_map;
606 else if (mti->mti_flags & LDD_F_SV_TYPE_MDT)
607 imap = fsdb->fsdb_mdt_index_map;
609 GOTO(out, rc = -EINVAL);
611 if (test_bit(mti->mti_stripe_index, imap))
617 mgs_put_fsdb(mgs, fsdb);
621 static __inline__ int next_index(void *index_map, int map_len)
624 for (i = 0; i < map_len * 8; i++)
625 if (!test_bit(i, index_map)) {
628 CERROR("max index %d exceeded.\n", i);
632 /* Make the mdt/ost server obd name based on the filesystem name */
633 static bool server_make_name(u32 flags, u16 index, const char *fs,
634 char *name_buf, size_t name_buf_size)
636 bool invalid_flag = false;
638 if (flags & (LDD_F_SV_TYPE_MDT | LDD_F_SV_TYPE_OST)) {
639 if (!(flags & LDD_F_SV_ALL))
640 snprintf(name_buf, name_buf_size, "%.8s%c%s%04x", fs,
641 (flags & LDD_F_VIRGIN) ? ':' :
642 ((flags & LDD_F_WRITECONF) ? '=' : '-'),
643 (flags & LDD_F_SV_TYPE_MDT) ? "MDT" : "OST",
645 } else if (flags & LDD_F_SV_TYPE_MGS) {
646 snprintf(name_buf, name_buf_size, "MGS");
648 CERROR("unknown server type %#x\n", flags);
655 0 newly marked as in use
657 +EALREADY for update of an old index */
658 static int mgs_set_index(const struct lu_env *env,
659 struct mgs_device *mgs,
660 struct mgs_target_info *mti)
667 rc = mgs_find_or_make_fsdb(env, mgs, mti->mti_fsname, &fsdb);
669 CERROR("Can't get db for %s\n", mti->mti_fsname);
673 mutex_lock(&fsdb->fsdb_mutex);
674 if (mti->mti_flags & LDD_F_SV_TYPE_OST) {
675 imap = fsdb->fsdb_ost_index_map;
676 } else if (mti->mti_flags & LDD_F_SV_TYPE_MDT) {
677 imap = fsdb->fsdb_mdt_index_map;
679 GOTO(out_up, rc = -EINVAL);
682 if (mti->mti_flags & LDD_F_NEED_INDEX) {
683 rc = next_index(imap, INDEX_MAP_SIZE);
685 GOTO(out_up, rc = -ERANGE);
686 mti->mti_stripe_index = rc;
689 /* the last index(0xffff) is reserved for default value. */
690 if (mti->mti_stripe_index >= INDEX_MAP_SIZE * 8 - 1) {
691 LCONSOLE_ERROR_MSG(0x13f, "Server %s requested index %u, "
692 "but index must be less than %u.\n",
693 mti->mti_svname, mti->mti_stripe_index,
694 INDEX_MAP_SIZE * 8 - 1);
695 GOTO(out_up, rc = -ERANGE);
698 if (test_bit(mti->mti_stripe_index, imap)) {
699 if ((mti->mti_flags & LDD_F_VIRGIN) &&
700 !(mti->mti_flags & LDD_F_WRITECONF)) {
701 LCONSOLE_ERROR_MSG(0x140, "Server %s requested index "
702 "%d, but that index is already in "
703 "use. Use --writeconf to force\n",
705 mti->mti_stripe_index);
706 GOTO(out_up, rc = -EADDRINUSE);
708 CDEBUG(D_MGS, "Server %s updating index %d\n",
709 mti->mti_svname, mti->mti_stripe_index);
710 GOTO(out_up, rc = EALREADY);
713 set_bit(mti->mti_stripe_index, imap);
714 if (mti->mti_flags & LDD_F_SV_TYPE_MDT)
715 fsdb->fsdb_mdt_count++;
718 set_bit(mti->mti_stripe_index, imap);
719 clear_bit(FSDB_LOG_EMPTY, &fsdb->fsdb_flags);
720 if (server_make_name(mti->mti_flags & ~(LDD_F_VIRGIN | LDD_F_WRITECONF),
721 mti->mti_stripe_index, mti->mti_fsname,
722 mti->mti_svname, sizeof(mti->mti_svname))) {
723 CERROR("unknown server type %#x\n", mti->mti_flags);
724 GOTO(out_up, rc = -EINVAL);
727 CDEBUG(D_MGS, "Set index for %s to %d\n", mti->mti_svname,
728 mti->mti_stripe_index);
730 GOTO(out_up, rc = 0);
733 mutex_unlock(&fsdb->fsdb_mutex);
734 mgs_put_fsdb(mgs, fsdb);
738 struct mgs_modify_lookup {
739 struct cfg_marker mml_marker;
743 static int mgs_check_record_match(const struct lu_env *env,
744 struct llog_handle *llh,
745 struct llog_rec_hdr *rec, void *data)
747 struct cfg_marker *mc_marker = data;
748 struct cfg_marker *marker;
749 struct lustre_cfg *lcfg = REC_DATA(rec);
750 int cfg_len = REC_DATA_LEN(rec);
755 if (rec->lrh_type != OBD_CFG_REC) {
756 CDEBUG(D_ERROR, "Unhandled lrh_type: %#x\n", rec->lrh_type);
760 rc = lustre_cfg_sanity_check(lcfg, cfg_len);
762 CDEBUG(D_ERROR, "Insane cfg\n");
766 /* We only care about markers */
767 if (lcfg->lcfg_command != LCFG_MARKER)
770 marker = lustre_cfg_buf(lcfg, 1);
772 if (marker->cm_flags & CM_SKIP)
775 if ((strcmp(mc_marker->cm_comment, marker->cm_comment) == 0) &&
776 (strcmp(mc_marker->cm_tgtname, marker->cm_tgtname) == 0)) {
777 /* Found a non-skipped marker match */
778 CDEBUG(D_MGS, "Matched rec %u marker %d flag %x %s %s\n",
779 rec->lrh_index, marker->cm_step,
780 marker->cm_flags, marker->cm_tgtname,
782 rc = LLOG_PROC_BREAK;
789 * Check an existing config log record with matching comment and device
791 * 0 - checked successfully,
792 * LLOG_PROC_BREAK - record matches
795 static int mgs_check_marker(const struct lu_env *env, struct mgs_device *mgs,
796 struct fs_db *fsdb, struct mgs_target_info *mti,
797 char *logname, char *devname, char *comment)
799 struct llog_handle *loghandle;
800 struct llog_ctxt *ctxt;
801 struct cfg_marker *mc_marker;
806 LASSERT(mutex_is_locked(&fsdb->fsdb_mutex));
807 CDEBUG(D_MGS, "mgs check %s/%s/%s\n", logname, devname, comment);
809 ctxt = llog_get_context(mgs->mgs_obd, LLOG_CONFIG_ORIG_CTXT);
810 LASSERT(ctxt != NULL);
811 rc = llog_open(env, ctxt, &loghandle, NULL, logname, LLOG_OPEN_EXISTS);
818 rc = llog_init_handle(env, loghandle, LLOG_F_IS_PLAIN, NULL);
822 if (llog_get_size(loghandle) <= 1)
823 GOTO(out_close, rc = 0);
825 OBD_ALLOC_PTR(mc_marker);
827 GOTO(out_close, rc = -ENOMEM);
828 if (strlcpy(mc_marker->cm_comment, comment,
829 sizeof(mc_marker->cm_comment)) >=
830 sizeof(mc_marker->cm_comment))
831 GOTO(out_free, rc = -E2BIG);
832 if (strlcpy(mc_marker->cm_tgtname, devname,
833 sizeof(mc_marker->cm_tgtname)) >=
834 sizeof(mc_marker->cm_tgtname))
835 GOTO(out_free, rc = -E2BIG);
837 rc = llog_process(env, loghandle, mgs_check_record_match,
838 (void *)mc_marker, NULL);
841 OBD_FREE_PTR(mc_marker);
844 llog_close(env, loghandle);
846 if (rc && rc != LLOG_PROC_BREAK)
847 CDEBUG(D_ERROR, "%s: mgs check %s/%s failed: rc = %d\n",
848 mgs->mgs_obd->obd_name, mti->mti_svname, comment, rc);
853 static int mgs_modify_handler(const struct lu_env *env,
854 struct llog_handle *llh,
855 struct llog_rec_hdr *rec, void *data)
857 struct mgs_modify_lookup *mml = data;
858 struct cfg_marker *marker;
859 struct lustre_cfg *lcfg = REC_DATA(rec);
860 int cfg_len = REC_DATA_LEN(rec);
864 if (rec->lrh_type != OBD_CFG_REC) {
865 CERROR("unhandled lrh_type: %#x\n", rec->lrh_type);
869 rc = lustre_cfg_sanity_check(lcfg, cfg_len);
871 CERROR("Insane cfg\n");
875 /* We only care about markers */
876 if (lcfg->lcfg_command != LCFG_MARKER)
879 marker = lustre_cfg_buf(lcfg, 1);
880 if ((strcmp(mml->mml_marker.cm_comment, marker->cm_comment) == 0) &&
881 (strcmp(mml->mml_marker.cm_tgtname, marker->cm_tgtname) == 0) &&
882 !(marker->cm_flags & CM_SKIP)) {
883 /* Found a non-skipped marker match */
884 CDEBUG(D_MGS, "Changing rec %u marker %d %x->%x: %s %s\n",
885 rec->lrh_index, marker->cm_step,
886 marker->cm_flags, mml->mml_marker.cm_flags,
887 marker->cm_tgtname, marker->cm_comment);
888 /* Overwrite the old marker llog entry */
889 marker->cm_flags &= ~CM_EXCLUDE; /* in case we're unexcluding */
890 marker->cm_flags |= mml->mml_marker.cm_flags;
891 marker->cm_canceltime = mml->mml_marker.cm_canceltime;
892 rc = llog_write(env, llh, rec, rec->lrh_index);
901 * Modify an existing config log record (for CM_SKIP or CM_EXCLUDE)
903 * 0 - modified successfully,
904 * 1 - no modification was done
907 static int mgs_modify(const struct lu_env *env, struct mgs_device *mgs,
908 struct fs_db *fsdb, struct mgs_target_info *mti,
909 char *logname, char *devname, char *comment, int flags)
911 struct llog_handle *loghandle;
912 struct llog_ctxt *ctxt;
913 struct mgs_modify_lookup *mml;
918 LASSERT(mutex_is_locked(&fsdb->fsdb_mutex));
919 CDEBUG(D_MGS, "modify %s/%s/%s fl=%x\n", logname, devname, comment,
922 ctxt = llog_get_context(mgs->mgs_obd, LLOG_CONFIG_ORIG_CTXT);
923 LASSERT(ctxt != NULL);
924 rc = llog_open(env, ctxt, &loghandle, NULL, logname, LLOG_OPEN_EXISTS);
931 rc = llog_init_handle(env, loghandle, LLOG_F_IS_PLAIN, NULL);
935 if (llog_get_size(loghandle) <= 1)
936 GOTO(out_close, rc = 0);
940 GOTO(out_close, rc = -ENOMEM);
941 if (strlcpy(mml->mml_marker.cm_comment, comment,
942 sizeof(mml->mml_marker.cm_comment)) >=
943 sizeof(mml->mml_marker.cm_comment))
944 GOTO(out_free, rc = -E2BIG);
945 if (strlcpy(mml->mml_marker.cm_tgtname, devname,
946 sizeof(mml->mml_marker.cm_tgtname)) >=
947 sizeof(mml->mml_marker.cm_tgtname))
948 GOTO(out_free, rc = -E2BIG);
949 /* Modify mostly means cancel */
950 mml->mml_marker.cm_flags = flags;
951 mml->mml_marker.cm_canceltime = flags ? ktime_get_real_seconds() : 0;
952 mml->mml_modified = 0;
953 rc = llog_process(env, loghandle, mgs_modify_handler, (void *)mml,
955 if (!rc && !mml->mml_modified)
962 llog_close(env, loghandle);
965 CERROR("%s: modify %s/%s failed: rc = %d\n",
966 mgs->mgs_obd->obd_name, mti->mti_svname, comment, rc);
979 /** This structure is passed to mgs_replace_handler */
980 struct mgs_replace_data {
981 /* Nids are replaced for this target device */
982 struct mgs_target_info target;
983 /* Temporary modified llog */
984 struct llog_handle *temp_llh;
985 enum replace_state state;
991 * Check: a) if block should be skipped
992 * b) is it target block
997 * \retval 0 should not to be skipped
998 * \retval 1 should to be skipped
1000 static int check_markers(struct lustre_cfg *lcfg,
1001 struct mgs_replace_data *mrd)
1003 struct cfg_marker *marker;
1005 /* Track markers. Find given device */
1006 if (lcfg->lcfg_command == LCFG_MARKER) {
1007 marker = lustre_cfg_buf(lcfg, 1);
1008 /* Clean llog from records marked as CM_SKIP.
1009 CM_EXCLUDE records are used for "active" command
1010 and can be restored if needed */
1011 if ((marker->cm_flags & (CM_SKIP | CM_START)) ==
1012 (CM_SKIP | CM_START)) {
1013 mrd->state = REPLACE_SKIP;
1017 if ((marker->cm_flags & (CM_SKIP | CM_END)) ==
1018 (CM_SKIP | CM_END)) {
1019 mrd->state = REPLACE_COPY;
1023 if (strcmp(mrd->target.mti_svname, marker->cm_tgtname) == 0) {
1024 LASSERT(!(marker->cm_flags & CM_START) ||
1025 !(marker->cm_flags & CM_END));
1026 if (marker->cm_flags & CM_START) {
1027 if (!strncmp(marker->cm_comment,
1028 "add failnid", 11)) {
1029 mrd->state = REPLACE_SKIP;
1031 mrd->state = REPLACE_UUID;
1032 mrd->failover = NULL;
1034 } else if (marker->cm_flags & CM_END)
1035 mrd->state = REPLACE_COPY;
1037 if (!strncmp(marker->cm_comment,
1046 static int record_base(const struct lu_env *env, struct llog_handle *llh,
1047 char *cfgname, lnet_nid_t nid, int cmd,
1048 char *s1, char *s2, char *s3, char *s4)
1050 struct mgs_thread_info *mgi = mgs_env_info(env);
1051 struct llog_cfg_rec *lcr;
1054 CDEBUG(D_MGS, "lcfg %s %#x %s %s %s %s\n", cfgname,
1055 cmd, s1, s2, s3, s4);
1057 lustre_cfg_bufs_reset(&mgi->mgi_bufs, cfgname);
1059 lustre_cfg_bufs_set_string(&mgi->mgi_bufs, 1, s1);
1061 lustre_cfg_bufs_set_string(&mgi->mgi_bufs, 2, s2);
1063 lustre_cfg_bufs_set_string(&mgi->mgi_bufs, 3, s3);
1065 lustre_cfg_bufs_set_string(&mgi->mgi_bufs, 4, s4);
1067 lcr = lustre_cfg_rec_new(cmd, &mgi->mgi_bufs);
1071 lcr->lcr_cfg.lcfg_nid = nid;
1072 rc = llog_write(env, llh, &lcr->lcr_hdr, LLOG_NEXT_IDX);
1074 lustre_cfg_rec_free(lcr);
1078 "failed to write lcfg %s %#x %s %s %s %s: rc = %d\n",
1079 cfgname, cmd, s1, s2, s3, s4, rc);
1083 static inline int record_add_uuid(const struct lu_env *env,
1084 struct llog_handle *llh,
1085 uint64_t nid, char *uuid)
1087 return record_base(env, llh, NULL, nid, LCFG_ADD_UUID, uuid,
1091 static inline int record_add_conn(const struct lu_env *env,
1092 struct llog_handle *llh,
1093 char *devname, char *uuid)
1095 return record_base(env, llh, devname, 0, LCFG_ADD_CONN, uuid,
1099 static inline int record_attach(const struct lu_env *env,
1100 struct llog_handle *llh, char *devname,
1101 char *type, char *uuid)
1103 return record_base(env, llh, devname, 0, LCFG_ATTACH, type, uuid,
1107 static inline int record_setup(const struct lu_env *env,
1108 struct llog_handle *llh, char *devname,
1109 char *s1, char *s2, char *s3, char *s4)
1111 return record_base(env, llh, devname, 0, LCFG_SETUP, s1, s2, s3, s4);
1115 * \retval <0 record processing error
1116 * \retval n record is processed. No need copy original one.
1117 * \retval 0 record is not processed.
1119 static int process_command(const struct lu_env *env, struct lustre_cfg *lcfg,
1120 struct mgs_replace_data *mrd)
1127 if (mrd->state == REPLACE_UUID &&
1128 lcfg->lcfg_command == LCFG_ADD_UUID) {
1129 /* LCFG_ADD_UUID command found. Let's skip original command
1130 and add passed nids */
1131 ptr = mrd->target.mti_params;
1132 while (class_parse_nid(ptr, &nid, &ptr) == 0) {
1133 if (!mrd->nodeuuid) {
1134 rc = name_create(&mrd->nodeuuid,
1135 libcfs_nid2str(nid), "");
1137 CERROR("Can't create uuid for "
1138 "nid %s, device %s\n",
1139 libcfs_nid2str(nid),
1140 mrd->target.mti_svname);
1144 CDEBUG(D_MGS, "add nid %s with uuid %s, "
1145 "device %s\n", libcfs_nid2str(nid),
1146 mrd->target.mti_params,
1148 rc = record_add_uuid(env,
1155 mrd->failover = ptr;
1160 if (nids_added == 0) {
1161 CERROR("No new nids were added, nid %s with uuid %s, "
1162 "device %s\n", libcfs_nid2str(nid),
1163 mrd->nodeuuid ? mrd->nodeuuid : "NULL",
1164 mrd->target.mti_svname);
1165 name_destroy(&mrd->nodeuuid);
1168 mrd->state = REPLACE_SETUP;
1174 if (mrd->state == REPLACE_SETUP && lcfg->lcfg_command == LCFG_SETUP) {
1175 /* LCFG_SETUP command found. UUID should be changed */
1176 rc = record_setup(env,
1178 /* devname the same */
1179 lustre_cfg_string(lcfg, 0),
1180 /* s1 is not changed */
1181 lustre_cfg_string(lcfg, 1),
1183 /* s3 is not changed */
1184 lustre_cfg_string(lcfg, 3),
1185 /* s4 is not changed */
1186 lustre_cfg_string(lcfg, 4));
1188 name_destroy(&mrd->nodeuuid);
1192 if (mrd->failover) {
1193 ptr = mrd->failover;
1194 while (class_parse_nid(ptr, &nid, &ptr) == 0) {
1195 if (mrd->nodeuuid == NULL) {
1196 rc = name_create(&mrd->nodeuuid,
1197 libcfs_nid2str(nid),
1203 CDEBUG(D_MGS, "add nid %s for failover %s\n",
1204 libcfs_nid2str(nid), mrd->nodeuuid);
1205 rc = record_add_uuid(env, mrd->temp_llh, nid,
1208 name_destroy(&mrd->nodeuuid);
1212 rc = record_add_conn(env,
1214 lustre_cfg_string(lcfg, 0),
1216 name_destroy(&mrd->nodeuuid);
1221 if (mrd->nodeuuid) {
1222 rc = record_add_conn(env, mrd->temp_llh,
1223 lustre_cfg_string(lcfg, 0),
1225 name_destroy(&mrd->nodeuuid);
1230 mrd->state = REPLACE_DONE;
1234 /* All new UUID are added. Skip. */
1235 if (mrd->state == REPLACE_SETUP &&
1236 lcfg->lcfg_command == LCFG_ADD_UUID)
1239 /* Another commands in target device block */
1244 * Handler that called for every record in llog.
1245 * Records are processed in order they placed in llog.
1247 * \param[in] llh log to be processed
1248 * \param[in] rec current record
1249 * \param[in] data mgs_replace_data structure
1253 static int mgs_replace_nids_handler(const struct lu_env *env,
1254 struct llog_handle *llh,
1255 struct llog_rec_hdr *rec,
1258 struct mgs_replace_data *mrd;
1259 struct lustre_cfg *lcfg = REC_DATA(rec);
1260 int cfg_len = REC_DATA_LEN(rec);
1264 mrd = (struct mgs_replace_data *)data;
1266 if (rec->lrh_type != OBD_CFG_REC) {
1267 CERROR("unhandled lrh_type: %#x, cmd %x %s %s\n",
1268 rec->lrh_type, lcfg->lcfg_command,
1269 lustre_cfg_string(lcfg, 0),
1270 lustre_cfg_string(lcfg, 1));
1274 rc = lustre_cfg_sanity_check(lcfg, cfg_len);
1276 /* Do not copy any invalidated records */
1277 GOTO(skip_out, rc = 0);
1280 rc = check_markers(lcfg, mrd);
1281 if (rc || mrd->state == REPLACE_SKIP)
1282 GOTO(skip_out, rc = 0);
1284 /* Write to new log all commands outside target device block */
1285 if (mrd->state == REPLACE_COPY)
1286 GOTO(copy_out, rc = 0);
1288 if (mrd->state == REPLACE_DONE &&
1289 (lcfg->lcfg_command == LCFG_ADD_UUID ||
1290 lcfg->lcfg_command == LCFG_ADD_CONN)) {
1292 CWARN("Previous failover is deleted, but new one is "
1293 "not set. This means you configure system "
1294 "without failover or passed wrong replace_nids "
1295 "command parameters. Device %s, passed nids %s\n",
1296 mrd->target.mti_svname, mrd->target.mti_params);
1297 GOTO(skip_out, rc = 0);
1300 rc = process_command(env, lcfg, mrd);
1307 /* Record is placed in temporary llog as is */
1308 rc = llog_write(env, mrd->temp_llh, rec, LLOG_NEXT_IDX);
1310 CDEBUG(D_MGS, "Copied idx=%d, rc=%d, len=%d, cmd %x %s %s\n",
1311 rec->lrh_index, rc, rec->lrh_len, lcfg->lcfg_command,
1312 lustre_cfg_string(lcfg, 0), lustre_cfg_string(lcfg, 1));
1316 CDEBUG(D_MGS, "Skipped idx=%d, rc=%d, len=%d, cmd %x %s %s\n",
1317 rec->lrh_index, rc, rec->lrh_len, lcfg->lcfg_command,
1318 lustre_cfg_string(lcfg, 0), lustre_cfg_string(lcfg, 1));
1322 static int mgs_log_is_empty(const struct lu_env *env,
1323 struct mgs_device *mgs, char *name)
1325 struct llog_ctxt *ctxt;
1328 ctxt = llog_get_context(mgs->mgs_obd, LLOG_CONFIG_ORIG_CTXT);
1329 LASSERT(ctxt != NULL);
1331 rc = llog_is_empty(env, ctxt, name);
1332 llog_ctxt_put(ctxt);
1336 static int mgs_replace_log(const struct lu_env *env,
1337 struct obd_device *mgs,
1338 char *logname, char *devname,
1339 llog_cb_t replace_handler, void *data)
1341 struct llog_handle *orig_llh, *backup_llh;
1342 struct llog_ctxt *ctxt;
1343 struct mgs_replace_data *mrd;
1344 struct mgs_device *mgs_dev = lu2mgs_dev(mgs->obd_lu_dev);
1345 static struct obd_uuid cfg_uuid = { .uuid = "config_uuid" };
1347 int rc, rc2, buf_size;
1351 ctxt = llog_get_context(mgs, LLOG_CONFIG_ORIG_CTXT);
1352 LASSERT(ctxt != NULL);
1354 if (mgs_log_is_empty(env, mgs_dev, logname)) {
1355 /* Log is empty. Nothing to replace */
1356 GOTO(out_put, rc = 0);
1359 now = ktime_get_real_seconds();
1361 /* max time64_t in decimal fits into 20 bytes long string */
1362 buf_size = strlen(logname) + 1 + 20 + 1 + strlen(".bak") + 1;
1363 OBD_ALLOC(backup, buf_size);
1365 GOTO(out_put, rc = -ENOMEM);
1367 snprintf(backup, buf_size, "%s.%llu.bak", logname, now);
1369 rc = llog_backup(env, mgs, ctxt, ctxt, logname, backup);
1371 /* Now erase original log file. Connections are not allowed.
1372 Backup is already saved */
1373 rc = llog_erase(env, ctxt, NULL, logname);
1376 } else if (rc != -ENOENT) {
1377 CERROR("%s: can't make backup for %s: rc = %d\n",
1378 mgs->obd_name, logname, rc);
1382 /* open local log */
1383 rc = llog_open_create(env, ctxt, &orig_llh, NULL, logname);
1385 GOTO(out_restore, rc);
1387 rc = llog_init_handle(env, orig_llh, LLOG_F_IS_PLAIN, &cfg_uuid);
1389 GOTO(out_closel, rc);
1391 /* open backup llog */
1392 rc = llog_open(env, ctxt, &backup_llh, NULL, backup,
1395 GOTO(out_closel, rc);
1397 rc = llog_init_handle(env, backup_llh, LLOG_F_IS_PLAIN, NULL);
1399 GOTO(out_close, rc);
1401 if (llog_get_size(backup_llh) <= 1)
1402 GOTO(out_close, rc = 0);
1406 GOTO(out_close, rc = -ENOMEM);
1407 /* devname is only needed information to replace UUID records */
1409 strlcpy(mrd->target.mti_svname, devname,
1410 sizeof(mrd->target.mti_svname));
1411 /* data is parsed in llog callback */
1413 strlcpy(mrd->target.mti_params, data,
1414 sizeof(mrd->target.mti_params));
1415 /* Copy records to this temporary llog */
1416 mrd->temp_llh = orig_llh;
1418 rc = llog_process(env, backup_llh, replace_handler,
1422 rc2 = llog_close(NULL, backup_llh);
1426 rc2 = llog_close(NULL, orig_llh);
1432 CERROR("%s: llog should be restored: rc = %d\n",
1434 rc2 = llog_backup(env, mgs, ctxt, ctxt, backup,
1437 CERROR("%s: can't restore backup %s: rc = %d\n",
1438 mgs->obd_name, logname, rc2);
1442 OBD_FREE(backup, buf_size);
1445 llog_ctxt_put(ctxt);
1448 CERROR("%s: failed to replace log %s: rc = %d\n",
1449 mgs->obd_name, logname, rc);
1454 static int mgs_replace_nids_log(const struct lu_env *env,
1455 struct obd_device *obd,
1456 char *logname, char *devname, char *nids)
1458 CDEBUG(D_MGS, "Replace NIDs for %s in %s\n", devname, logname);
1459 return mgs_replace_log(env, obd, logname, devname,
1460 mgs_replace_nids_handler, nids);
1464 * Parse device name and get file system name and/or device index
1466 * @devname device name (ex. lustre-MDT0000)
1467 * @fsname file system name extracted from @devname and returned
1468 * to the caller (optional)
1469 * @index device index extracted from @devname and returned to
1470 * the caller (optional)
1472 * RETURN 0 success if we are only interested in
1473 * extracting fsname from devname.
1476 * LDD_F_SV_TYPE_* Besides extracting the fsname the
1477 * user also wants the index. Report to
1478 * the user the type of obd device the
1479 * returned index belongs too.
1481 * -EINVAL The obd device name is improper so
1482 * fsname could not be extracted.
1484 * -ENXIO Failed to extract the index out of
1485 * the obd device name. Most likely an
1486 * invalid obd device name
1488 static int mgs_parse_devname(char *devname, char *fsname, u32 *index)
1493 /* Extract fsname */
1495 rc = server_name2fsname(devname, fsname, NULL);
1497 CDEBUG(D_MGS, "Device name %s without fsname\n",
1504 rc = server_name2index(devname, index, NULL);
1506 CDEBUG(D_MGS, "Device name %s with wrong index\n",
1512 /* server_name2index can return LDD_F_SV_TYPE_* so always return rc */
1516 /* This is only called during replace_nids */
1517 static int only_mgs_is_running(struct obd_device *mgs_obd)
1519 /* TDB: Is global variable with devices count exists? */
1520 int num_devices = get_devices_count();
1521 int num_exports = 0;
1522 struct obd_export *exp;
1524 spin_lock(&mgs_obd->obd_dev_lock);
1525 list_for_each_entry(exp, &mgs_obd->obd_exports, exp_obd_chain) {
1526 /* skip self export */
1527 if (exp == mgs_obd->obd_self_export)
1532 if (num_exports > 1)
1533 CERROR("%s: node %s still connected during replace_nids connect_flags:%llx\n",
1535 libcfs_nid2str(exp->exp_nid_stats->nid),
1536 exp_connect_flags(exp));
1538 spin_unlock(&mgs_obd->obd_dev_lock);
1540 /* osd, MGS and MGC + MGC export (nosvc starts MGC)
1541 * (wc -l /proc/fs/lustre/devices <= 3) && (non self exports == 1)
1543 return (num_devices <= 3) && (num_exports <= 1);
1546 static int name_create_mdt(char **logname, char *fsname, int mdt_idx)
1550 if (mdt_idx > INDEX_MAP_MAX_VALUE)
1553 snprintf(postfix, sizeof(postfix), "-MDT%04x", mdt_idx);
1554 return name_create(logname, fsname, postfix);
1558 * Replace nids for \a device to \a nids values
1560 * \param obd MGS obd device
1561 * \param devname nids need to be replaced for this device
1562 * (ex. lustre-OST0000)
1563 * \param nids nids list (ex. nid1,nid2,nid3)
1567 int mgs_replace_nids(const struct lu_env *env,
1568 struct mgs_device *mgs,
1569 char *devname, char *nids)
1571 /* Assume fsname is part of device name */
1572 char fsname[MTI_NAME_MAXLEN];
1576 struct fs_db *fsdb = NULL;
1579 struct obd_device *mgs_obd = mgs->mgs_obd;
1582 /* We can only change NIDs if no other nodes are connected */
1583 spin_lock(&mgs_obd->obd_dev_lock);
1584 conn_state = mgs_obd->obd_no_conn;
1585 mgs_obd->obd_no_conn = 1;
1586 spin_unlock(&mgs_obd->obd_dev_lock);
1588 /* We can not change nids if not only MGS is started */
1589 if (!only_mgs_is_running(mgs_obd)) {
1590 CERROR("Only MGS is allowed to be started\n");
1591 GOTO(out, rc = -EINPROGRESS);
1594 /* Get fsname and index */
1595 rc = mgs_parse_devname(devname, fsname, &index);
1599 rc = mgs_find_or_make_fsdb(env, mgs, fsname, &fsdb);
1601 CERROR("%s: can't find fsdb: rc = %d\n", fsname, rc);
1605 /* Process client llogs */
1606 rc = name_create(&logname, fsname, "-client");
1609 rc = mgs_replace_nids_log(env, mgs_obd, logname, devname, nids);
1610 name_destroy(&logname);
1612 CERROR("%s: error while replacing NIDs for %s: rc = %d\n",
1613 fsname, devname, rc);
1617 /* Process MDT llogs */
1618 for (i = 0; i < INDEX_MAP_SIZE * 8; i++) {
1619 if (!test_bit(i, fsdb->fsdb_mdt_index_map))
1621 rc = name_create_mdt(&logname, fsname, i);
1624 rc = mgs_replace_nids_log(env, mgs_obd, logname, devname, nids);
1625 name_destroy(&logname);
1631 spin_lock(&mgs_obd->obd_dev_lock);
1632 mgs_obd->obd_no_conn = conn_state;
1633 spin_unlock(&mgs_obd->obd_dev_lock);
1636 mgs_put_fsdb(mgs, fsdb);
1642 * This is called for every record in llog. Some of records are
1643 * skipped, others are copied to new log as is.
1644 * Records to be skipped are
1645 * marker records marked SKIP
1646 * records enclosed between SKIP markers
1648 * \param[in] llh log to be processed
1649 * \param[in] rec current record
1650 * \param[in] data mgs_replace_data structure
1654 static int mgs_clear_config_handler(const struct lu_env *env,
1655 struct llog_handle *llh,
1656 struct llog_rec_hdr *rec, void *data)
1658 struct mgs_replace_data *mrd;
1659 struct lustre_cfg *lcfg = REC_DATA(rec);
1660 int cfg_len = REC_DATA_LEN(rec);
1665 mrd = (struct mgs_replace_data *)data;
1667 if (rec->lrh_type != OBD_CFG_REC) {
1668 CDEBUG(D_MGS, "Config llog Name=%s, Record Index=%u, "
1669 "Unhandled Record Type=%#x\n", llh->lgh_name,
1670 rec->lrh_index, rec->lrh_type);
1674 rc = lustre_cfg_sanity_check(lcfg, cfg_len);
1676 CDEBUG(D_MGS, "Config llog Name=%s, Invalid config file.",
1681 if (lcfg->lcfg_command == LCFG_MARKER) {
1682 struct cfg_marker *marker;
1684 marker = lustre_cfg_buf(lcfg, 1);
1685 if (marker->cm_flags & CM_SKIP) {
1686 if (marker->cm_flags & CM_START)
1687 mrd->state = REPLACE_SKIP;
1688 if (marker->cm_flags & CM_END)
1689 mrd->state = REPLACE_COPY;
1690 /* SKIP section started or finished */
1691 CDEBUG(D_MGS, "Skip idx=%d, rc=%d, len=%d, "
1692 "cmd %x %s %s\n", rec->lrh_index, rc,
1693 rec->lrh_len, lcfg->lcfg_command,
1694 lustre_cfg_string(lcfg, 0),
1695 lustre_cfg_string(lcfg, 1));
1699 if (mrd->state == REPLACE_SKIP) {
1700 /* record enclosed between SKIP markers, skip it */
1701 CDEBUG(D_MGS, "Skip idx=%d, rc=%d, len=%d, "
1702 "cmd %x %s %s\n", rec->lrh_index, rc,
1703 rec->lrh_len, lcfg->lcfg_command,
1704 lustre_cfg_string(lcfg, 0),
1705 lustre_cfg_string(lcfg, 1));
1710 /* Record is placed in temporary llog as is */
1711 rc = llog_write(env, mrd->temp_llh, rec, LLOG_NEXT_IDX);
1713 CDEBUG(D_MGS, "Copied idx=%d, rc=%d, len=%d, cmd %x %s %s\n",
1714 rec->lrh_index, rc, rec->lrh_len, lcfg->lcfg_command,
1715 lustre_cfg_string(lcfg, 0), lustre_cfg_string(lcfg, 1));
1720 * Directory CONFIGS/ may contain files which are not config logs to
1721 * be cleared. Skip any llogs with a non-alphanumeric character after
1722 * the last '-'. For example, fsname-MDT0000.sav, fsname-MDT0000.bak,
1723 * fsname-MDT0000.orig, fsname-MDT0000~, fsname-MDT0000.20150516, etc.
1725 static bool config_to_clear(const char *logname)
1730 str = strrchr(logname, '-');
1735 while (isalnum(str[++i]));
1736 return str[i] == '\0';
1740 * Clear config logs for \a name
1743 * \param mgs MGS device
1744 * \param name name of device or of filesystem
1745 * (ex. lustre-OST0000 or lustre) in later case all logs
1750 int mgs_clear_configs(const struct lu_env *env,
1751 struct mgs_device *mgs, const char *name)
1753 struct list_head dentry_list;
1754 struct mgs_direntry *dirent, *n;
1757 struct obd_device *mgs_obd = mgs->mgs_obd;
1762 /* Prevent clients and servers from connecting to mgs */
1763 spin_lock(&mgs_obd->obd_dev_lock);
1764 conn_state = mgs_obd->obd_no_conn;
1765 mgs_obd->obd_no_conn = 1;
1766 spin_unlock(&mgs_obd->obd_dev_lock);
1769 * config logs cannot be cleaned if anything other than
1772 if (!only_mgs_is_running(mgs_obd)) {
1773 CERROR("Only MGS is allowed to be started\n");
1774 GOTO(out, rc = -EBUSY);
1777 /* Find all the logs in the CONFIGS directory */
1778 rc = class_dentry_readdir(env, mgs, &dentry_list);
1780 CERROR("%s: cannot read config directory '%s': rc = %d\n",
1781 mgs_obd->obd_name, MOUNT_CONFIGS_DIR, rc);
1785 if (list_empty(&dentry_list)) {
1786 CERROR("%s: list empty reading config dir '%s': rc = %d\n",
1787 mgs_obd->obd_name, MOUNT_CONFIGS_DIR, -ENOENT);
1788 GOTO(out, rc = -ENOENT);
1791 OBD_ALLOC(namedash, strlen(name) + 2);
1792 if (namedash == NULL)
1793 GOTO(out, rc = -ENOMEM);
1794 snprintf(namedash, strlen(name) + 2, "%s-", name);
1796 list_for_each_entry(dirent, &dentry_list, mde_list) {
1797 if (strcmp(name, dirent->mde_name) &&
1798 strncmp(namedash, dirent->mde_name, strlen(namedash)))
1800 if (!config_to_clear(dirent->mde_name))
1802 CDEBUG(D_MGS, "%s: Clear config log %s\n",
1803 mgs_obd->obd_name, dirent->mde_name);
1804 rc = mgs_replace_log(env, mgs_obd, dirent->mde_name, NULL,
1805 mgs_clear_config_handler, NULL);
1810 list_for_each_entry_safe(dirent, n, &dentry_list, mde_list) {
1811 list_del_init(&dirent->mde_list);
1812 mgs_direntry_free(dirent);
1814 OBD_FREE(namedash, strlen(name) + 2);
1816 spin_lock(&mgs_obd->obd_dev_lock);
1817 mgs_obd->obd_no_conn = conn_state;
1818 spin_unlock(&mgs_obd->obd_dev_lock);
1823 static int record_lov_setup(const struct lu_env *env, struct llog_handle *llh,
1824 char *devname, struct lov_desc *desc)
1826 struct mgs_thread_info *mgi = mgs_env_info(env);
1827 struct llog_cfg_rec *lcr;
1830 lustre_cfg_bufs_reset(&mgi->mgi_bufs, devname);
1831 lustre_cfg_bufs_set(&mgi->mgi_bufs, 1, desc, sizeof(*desc));
1832 lcr = lustre_cfg_rec_new(LCFG_SETUP, &mgi->mgi_bufs);
1836 rc = llog_write(env, llh, &lcr->lcr_hdr, LLOG_NEXT_IDX);
1837 lustre_cfg_rec_free(lcr);
1841 static int record_lmv_setup(const struct lu_env *env, struct llog_handle *llh,
1842 char *devname, struct lmv_desc *desc)
1844 struct mgs_thread_info *mgi = mgs_env_info(env);
1845 struct llog_cfg_rec *lcr;
1848 lustre_cfg_bufs_reset(&mgi->mgi_bufs, devname);
1849 lustre_cfg_bufs_set(&mgi->mgi_bufs, 1, desc, sizeof(*desc));
1850 lcr = lustre_cfg_rec_new(LCFG_SETUP, &mgi->mgi_bufs);
1854 rc = llog_write(env, llh, &lcr->lcr_hdr, LLOG_NEXT_IDX);
1855 lustre_cfg_rec_free(lcr);
1859 static inline int record_mdc_add(const struct lu_env *env,
1860 struct llog_handle *llh,
1861 char *logname, char *mdcuuid,
1862 char *mdtuuid, char *index,
1865 return record_base(env,llh,logname,0,LCFG_ADD_MDC,
1866 mdtuuid,index,gen,mdcuuid);
1869 static inline int record_lov_add(const struct lu_env *env,
1870 struct llog_handle *llh,
1871 char *lov_name, char *ost_uuid,
1872 char *index, char *gen)
1874 return record_base(env, llh, lov_name, 0, LCFG_LOV_ADD_OBD,
1875 ost_uuid, index, gen, NULL);
1878 static inline int record_mount_opt(const struct lu_env *env,
1879 struct llog_handle *llh,
1880 char *profile, char *lov_name,
1883 return record_base(env, llh, NULL, 0, LCFG_MOUNTOPT,
1884 profile, lov_name, mdc_name, NULL);
1887 static int record_marker(const struct lu_env *env,
1888 struct llog_handle *llh,
1889 struct fs_db *fsdb, __u32 flags,
1890 char *tgtname, char *comment)
1892 struct mgs_thread_info *mgi = mgs_env_info(env);
1893 struct llog_cfg_rec *lcr;
1897 if (flags & CM_START)
1899 mgi->mgi_marker.cm_step = fsdb->fsdb_gen;
1900 mgi->mgi_marker.cm_flags = flags;
1901 mgi->mgi_marker.cm_vers = LUSTRE_VERSION_CODE;
1902 cplen = strlcpy(mgi->mgi_marker.cm_tgtname, tgtname,
1903 sizeof(mgi->mgi_marker.cm_tgtname));
1904 if (cplen >= sizeof(mgi->mgi_marker.cm_tgtname))
1906 cplen = strlcpy(mgi->mgi_marker.cm_comment, comment,
1907 sizeof(mgi->mgi_marker.cm_comment));
1908 if (cplen >= sizeof(mgi->mgi_marker.cm_comment))
1910 mgi->mgi_marker.cm_createtime = ktime_get_real_seconds();
1911 mgi->mgi_marker.cm_canceltime = 0;
1912 lustre_cfg_bufs_reset(&mgi->mgi_bufs, NULL);
1913 lustre_cfg_bufs_set(&mgi->mgi_bufs, 1, &mgi->mgi_marker,
1914 sizeof(mgi->mgi_marker));
1915 lcr = lustre_cfg_rec_new(LCFG_MARKER, &mgi->mgi_bufs);
1919 rc = llog_write(env, llh, &lcr->lcr_hdr, LLOG_NEXT_IDX);
1920 lustre_cfg_rec_free(lcr);
1924 static int record_start_log(const struct lu_env *env, struct mgs_device *mgs,
1925 struct llog_handle **llh, char *name)
1927 static struct obd_uuid cfg_uuid = { .uuid = "config_uuid" };
1928 struct llog_ctxt *ctxt;
1933 GOTO(out, rc = -EBUSY);
1935 ctxt = llog_get_context(mgs->mgs_obd, LLOG_CONFIG_ORIG_CTXT);
1937 GOTO(out, rc = -ENODEV);
1938 LASSERT(ctxt->loc_obd == mgs->mgs_obd);
1940 rc = llog_open_create(env, ctxt, llh, NULL, name);
1943 rc = llog_init_handle(env, *llh, LLOG_F_IS_PLAIN, &cfg_uuid);
1945 llog_close(env, *llh);
1947 llog_ctxt_put(ctxt);
1950 CERROR("%s: can't start log %s: rc = %d\n",
1951 mgs->mgs_obd->obd_name, name, rc);
1957 static int record_end_log(const struct lu_env *env, struct llog_handle **llh)
1961 rc = llog_close(env, *llh);
1967 /******************** config "macros" *********************/
1969 /* write an lcfg directly into a log (with markers) */
1970 static int mgs_write_log_direct(const struct lu_env *env,
1971 struct mgs_device *mgs, struct fs_db *fsdb,
1972 char *logname, struct llog_cfg_rec *lcr,
1973 char *devname, char *comment)
1975 struct llog_handle *llh = NULL;
1980 rc = record_start_log(env, mgs, &llh, logname);
1984 /* FIXME These should be a single journal transaction */
1985 rc = record_marker(env, llh, fsdb, CM_START, devname, comment);
1988 rc = llog_write(env, llh, &lcr->lcr_hdr, LLOG_NEXT_IDX);
1991 rc = record_marker(env, llh, fsdb, CM_END, devname, comment);
1995 record_end_log(env, &llh);
1999 /* write the lcfg in all logs for the given fs */
2000 static int mgs_write_log_direct_all(const struct lu_env *env,
2001 struct mgs_device *mgs,
2003 struct mgs_target_info *mti,
2004 struct llog_cfg_rec *lcr, char *devname,
2005 char *comment, int server_only)
2007 struct list_head log_list;
2008 struct mgs_direntry *dirent, *n;
2009 char *fsname = mti->mti_fsname;
2010 int rc = 0, len = strlen(fsname);
2013 /* Find all the logs in the CONFIGS directory */
2014 rc = class_dentry_readdir(env, mgs, &log_list);
2018 /* Could use fsdb index maps instead of directory listing */
2019 list_for_each_entry_safe(dirent, n, &log_list, mde_list) {
2020 list_del_init(&dirent->mde_list);
2021 /* don't write to sptlrpc rule log */
2022 if (strstr(dirent->mde_name, "-sptlrpc") != NULL)
2025 /* caller wants write server logs only */
2026 if (server_only && strstr(dirent->mde_name, "-client") != NULL)
2029 if (strlen(dirent->mde_name) <= len ||
2030 strncmp(fsname, dirent->mde_name, len) != 0 ||
2031 dirent->mde_name[len] != '-')
2034 CDEBUG(D_MGS, "Changing log %s\n", dirent->mde_name);
2035 /* Erase any old settings of this same parameter */
2036 rc = mgs_modify(env, mgs, fsdb, mti, dirent->mde_name,
2037 devname, comment, CM_SKIP);
2039 CERROR("%s: Can't modify llog %s: rc = %d\n",
2040 mgs->mgs_obd->obd_name, dirent->mde_name, rc);
2043 /* Write the new one */
2044 rc = mgs_write_log_direct(env, mgs, fsdb, dirent->mde_name,
2045 lcr, devname, comment);
2047 CERROR("%s: writing log %s: rc = %d\n",
2048 mgs->mgs_obd->obd_name, dirent->mde_name, rc);
2050 mgs_direntry_free(dirent);
2056 static int mgs_write_log_osp_to_mdt(const struct lu_env *env,
2057 struct mgs_device *mgs,
2059 struct mgs_target_info *mti,
2060 int index, char *logname);
2061 static int mgs_write_log_osc_to_lov(const struct lu_env *env,
2062 struct mgs_device *mgs,
2064 struct mgs_target_info *mti,
2065 char *logname, char *suffix, char *lovname,
2066 enum lustre_sec_part sec_part, int flags);
2067 static int name_create_mdt_and_lov(char **logname, char **lovname,
2068 struct fs_db *fsdb, int i);
2070 static int add_param(char *params, char *key, char *val)
2072 char *start = params + strlen(params);
2073 char *end = params + sizeof(((struct mgs_target_info *)0)->mti_params);
2077 keylen = strlen(key);
2078 if (start + 1 + keylen + strlen(val) >= end) {
2079 CERROR("params are too long: %s %s%s\n",
2080 params, key != NULL ? key : "", val);
2084 sprintf(start, " %s%s", key != NULL ? key : "", val);
2089 * Walk through client config log record and convert the related records
2092 static int mgs_steal_client_llog_handler(const struct lu_env *env,
2093 struct llog_handle *llh,
2094 struct llog_rec_hdr *rec, void *data)
2096 struct mgs_device *mgs;
2097 struct obd_device *obd;
2098 struct mgs_target_info *mti, *tmti;
2100 int cfg_len = rec->lrh_len;
2101 char *cfg_buf = (char*) (rec + 1);
2102 struct lustre_cfg *lcfg;
2104 struct llog_handle *mdt_llh = NULL;
2105 static int got_an_osc_or_mdc = 0;
2106 /* 0: not found any osc/mdc;
2110 static int last_step = -1;
2115 mti = ((struct temp_comp*)data)->comp_mti;
2116 tmti = ((struct temp_comp*)data)->comp_tmti;
2117 fsdb = ((struct temp_comp*)data)->comp_fsdb;
2118 obd = ((struct temp_comp *)data)->comp_obd;
2119 mgs = lu2mgs_dev(obd->obd_lu_dev);
2122 if (rec->lrh_type != OBD_CFG_REC) {
2123 CERROR("unhandled lrh_type: %#x\n", rec->lrh_type);
2127 rc = lustre_cfg_sanity_check(cfg_buf, cfg_len);
2129 CERROR("Insane cfg\n");
2133 lcfg = (struct lustre_cfg *)cfg_buf;
2135 if (lcfg->lcfg_command == LCFG_MARKER) {
2136 struct cfg_marker *marker;
2137 marker = lustre_cfg_buf(lcfg, 1);
2138 if (!strncmp(marker->cm_comment, "add osc", 7) &&
2139 (marker->cm_flags & CM_START) &&
2140 !(marker->cm_flags & CM_SKIP)) {
2141 got_an_osc_or_mdc = 1;
2142 cplen = strlcpy(tmti->mti_svname, marker->cm_tgtname,
2143 sizeof(tmti->mti_svname));
2144 if (cplen >= sizeof(tmti->mti_svname))
2146 rc = record_start_log(env, mgs, &mdt_llh,
2150 rc = record_marker(env, mdt_llh, fsdb, CM_START,
2151 mti->mti_svname, "add osc(copied)");
2152 record_end_log(env, &mdt_llh);
2153 last_step = marker->cm_step;
2156 if (!strncmp(marker->cm_comment, "add osc", 7) &&
2157 (marker->cm_flags & CM_END) &&
2158 !(marker->cm_flags & CM_SKIP)) {
2159 LASSERT(last_step == marker->cm_step);
2161 got_an_osc_or_mdc = 0;
2162 memset(tmti, 0, sizeof(*tmti));
2163 rc = record_start_log(env, mgs, &mdt_llh,
2167 rc = record_marker(env, mdt_llh, fsdb, CM_END,
2168 mti->mti_svname, "add osc(copied)");
2169 record_end_log(env, &mdt_llh);
2172 if (!strncmp(marker->cm_comment, "add mdc", 7) &&
2173 (marker->cm_flags & CM_START) &&
2174 !(marker->cm_flags & CM_SKIP)) {
2175 got_an_osc_or_mdc = 2;
2176 last_step = marker->cm_step;
2177 memcpy(tmti->mti_svname, marker->cm_tgtname,
2178 strlen(marker->cm_tgtname));
2182 if (!strncmp(marker->cm_comment, "add mdc", 7) &&
2183 (marker->cm_flags & CM_END) &&
2184 !(marker->cm_flags & CM_SKIP)) {
2185 LASSERT(last_step == marker->cm_step);
2187 got_an_osc_or_mdc = 0;
2188 memset(tmti, 0, sizeof(*tmti));
2193 if (got_an_osc_or_mdc == 0 || last_step < 0)
2196 if (lcfg->lcfg_command == LCFG_ADD_UUID) {
2197 __u64 nodenid = lcfg->lcfg_nid;
2199 if (strlen(tmti->mti_uuid) == 0) {
2200 /* target uuid not set, this config record is before
2201 * LCFG_SETUP, this nid is one of target node nid.
2203 tmti->mti_nids[tmti->mti_nid_count] = nodenid;
2204 tmti->mti_nid_count++;
2206 char nidstr[LNET_NIDSTR_SIZE];
2208 /* failover node nid */
2209 libcfs_nid2str_r(nodenid, nidstr, sizeof(nidstr));
2210 rc = add_param(tmti->mti_params, PARAM_FAILNODE,
2217 if (lcfg->lcfg_command == LCFG_SETUP) {
2220 target = lustre_cfg_string(lcfg, 1);
2221 memcpy(tmti->mti_uuid, target, strlen(target));
2225 /* ignore client side sptlrpc_conf_log */
2226 if (lcfg->lcfg_command == LCFG_SPTLRPC_CONF)
2229 if (lcfg->lcfg_command == LCFG_ADD_MDC &&
2230 strstr(lustre_cfg_string(lcfg, 0), "-clilmv") != NULL) {
2233 if (sscanf(lustre_cfg_buf(lcfg, 2), "%d", &index) != 1)
2236 memcpy(tmti->mti_fsname, mti->mti_fsname,
2237 strlen(mti->mti_fsname));
2238 tmti->mti_stripe_index = index;
2240 rc = mgs_write_log_osp_to_mdt(env, mgs, fsdb, tmti,
2241 mti->mti_stripe_index,
2243 memset(tmti, 0, sizeof(*tmti));
2247 if (lcfg->lcfg_command == LCFG_LOV_ADD_OBD) {
2250 char *logname, *lovname;
2252 rc = name_create_mdt_and_lov(&logname, &lovname, fsdb,
2253 mti->mti_stripe_index);
2256 sprintf(mdt_index, "-MDT%04x", mti->mti_stripe_index);
2258 if (sscanf(lustre_cfg_buf(lcfg, 2), "%d", &index) != 1) {
2259 name_destroy(&logname);
2260 name_destroy(&lovname);
2264 tmti->mti_stripe_index = index;
2265 rc = mgs_write_log_osc_to_lov(env, mgs, fsdb, tmti, logname,
2268 name_destroy(&logname);
2269 name_destroy(&lovname);
2275 /* fsdb->fsdb_mutex is already held in mgs_write_log_target*/
2276 /* stealed from mgs_get_fsdb_from_llog*/
2277 static int mgs_steal_llog_for_mdt_from_client(const struct lu_env *env,
2278 struct mgs_device *mgs,
2280 struct temp_comp* comp)
2282 struct llog_handle *loghandle;
2283 struct mgs_target_info *tmti;
2284 struct llog_ctxt *ctxt;
2289 ctxt = llog_get_context(mgs->mgs_obd, LLOG_CONFIG_ORIG_CTXT);
2290 LASSERT(ctxt != NULL);
2292 OBD_ALLOC_PTR(tmti);
2294 GOTO(out_ctxt, rc = -ENOMEM);
2296 comp->comp_tmti = tmti;
2297 comp->comp_obd = mgs->mgs_obd;
2299 rc = llog_open(env, ctxt, &loghandle, NULL, client_name,
2307 rc = llog_init_handle(env, loghandle, LLOG_F_IS_PLAIN, NULL);
2309 GOTO(out_close, rc);
2311 rc = llog_process_or_fork(env, loghandle, mgs_steal_client_llog_handler,
2312 (void *)comp, NULL, false);
2313 CDEBUG(D_MGS, "steal llog re = %d\n", rc);
2315 llog_close(env, loghandle);
2319 llog_ctxt_put(ctxt);
2323 /* lmv is the second thing for client logs */
2324 /* copied from mgs_write_log_lov. Please refer to that. */
2325 static int mgs_write_log_lmv(const struct lu_env *env,
2326 struct mgs_device *mgs,
2328 struct mgs_target_info *mti,
2329 char *logname, char *lmvname)
2331 struct llog_handle *llh = NULL;
2332 struct lmv_desc *lmvdesc;
2337 CDEBUG(D_MGS, "Writing lmv(%s) log for %s\n", lmvname,logname);
2339 OBD_ALLOC_PTR(lmvdesc);
2340 if (lmvdesc == NULL)
2342 lmvdesc->ld_active_tgt_count = 0;
2343 lmvdesc->ld_tgt_count = 0;
2344 sprintf((char*)lmvdesc->ld_uuid.uuid, "%s_UUID", lmvname);
2345 uuid = (char *)lmvdesc->ld_uuid.uuid;
2347 rc = record_start_log(env, mgs, &llh, logname);
2350 rc = record_marker(env, llh, fsdb, CM_START, lmvname, "lmv setup");
2353 rc = record_attach(env, llh, lmvname, "lmv", uuid);
2356 rc = record_lmv_setup(env, llh, lmvname, lmvdesc);
2359 rc = record_marker(env, llh, fsdb, CM_END, lmvname, "lmv setup");
2363 record_end_log(env, &llh);
2365 OBD_FREE_PTR(lmvdesc);
2369 /* lov is the first thing in the mdt and client logs */
2370 static int mgs_write_log_lov(const struct lu_env *env, struct mgs_device *mgs,
2371 struct fs_db *fsdb, struct mgs_target_info *mti,
2372 char *logname, char *lovname)
2374 struct llog_handle *llh = NULL;
2375 struct lov_desc *lovdesc;
2380 CDEBUG(D_MGS, "Writing lov(%s) log for %s\n", lovname, logname);
2383 #01 L attach 0:lov_mdsA 1:lov 2:71ccb_lov_mdsA_19f961a9e1
2384 #02 L lov_setup 0:lov_mdsA 1:(struct lov_desc)
2385 uuid=lov1_UUID, stripe count=1, size=1048576, offset=0, pattern=0
2388 /* FIXME just make lov_setup accept empty desc (put uuid in buf 2) */
2389 OBD_ALLOC_PTR(lovdesc);
2390 if (lovdesc == NULL)
2392 lovdesc->ld_magic = LOV_DESC_MAGIC;
2393 lovdesc->ld_tgt_count = 0;
2394 /* Defaults. Can be changed later by lcfg config_param */
2395 lovdesc->ld_default_stripe_count = 1;
2396 lovdesc->ld_pattern = LOV_PATTERN_RAID0;
2397 lovdesc->ld_default_stripe_size = LOV_DESC_STRIPE_SIZE_DEFAULT;
2398 lovdesc->ld_default_stripe_offset = -1;
2399 lovdesc->ld_qos_maxage = LOV_DESC_QOS_MAXAGE_DEFAULT;
2400 sprintf((char*)lovdesc->ld_uuid.uuid, "%s_UUID", lovname);
2401 /* can these be the same? */
2402 uuid = (char *)lovdesc->ld_uuid.uuid;
2404 /* This should always be the first entry in a log.
2405 rc = mgs_clear_log(obd, logname); */
2406 rc = record_start_log(env, mgs, &llh, logname);
2409 /* FIXME these should be a single journal transaction */
2410 rc = record_marker(env, llh, fsdb, CM_START, lovname, "lov setup");
2413 rc = record_attach(env, llh, lovname, "lov", uuid);
2416 rc = record_lov_setup(env, llh, lovname, lovdesc);
2419 rc = record_marker(env, llh, fsdb, CM_END, lovname, "lov setup");
2424 record_end_log(env, &llh);
2426 OBD_FREE_PTR(lovdesc);
2430 /* add failnids to open log */
2431 static int mgs_write_log_failnids(const struct lu_env *env,
2432 struct mgs_target_info *mti,
2433 struct llog_handle *llh,
2436 char *failnodeuuid = NULL;
2437 char *ptr = mti->mti_params;
2442 #03 L add_uuid nid=uml1@tcp(0x20000c0a80201) nal=90 0: 1:uml1_UUID
2443 #04 L add_uuid nid=1@elan(0x1000000000001) nal=90 0: 1:uml1_UUID
2444 #05 L setup 0:OSC_uml1_ost1_mdsA 1:ost1_UUID 2:uml1_UUID
2445 #06 L add_uuid nid=uml2@tcp(0x20000c0a80202) nal=90 0: 1:uml2_UUID
2446 #0x L add_uuid nid=2@elan(0x1000000000002) nal=90 0: 1:uml2_UUID
2447 #07 L add_conn 0:OSC_uml1_ost1_mdsA 1:uml2_UUID
2451 * Pull failnid info out of params string, which may contain something
2452 * like "<nid1>,<nid2>:<nid3>,<nid4>". class_parse_nid() does not
2453 * complain about abnormal inputs like ",:<nid1>", "<nid1>:,<nid2>",
2454 * etc. However, convert_hostnames() should have caught those.
2456 while (class_find_param(ptr, PARAM_FAILNODE, &ptr) == 0) {
2457 while (class_parse_nid(ptr, &nid, &ptr) == 0) {
2458 char nidstr[LNET_NIDSTR_SIZE];
2460 if (failnodeuuid == NULL) {
2461 /* We don't know the failover node name,
2462 * so just use the first nid as the uuid */
2463 libcfs_nid2str_r(nid, nidstr, sizeof(nidstr));
2464 rc = name_create(&failnodeuuid, nidstr, "");
2468 CDEBUG(D_MGS, "add nid %s for failover uuid %s, "
2470 libcfs_nid2str_r(nid, nidstr, sizeof(nidstr)),
2471 failnodeuuid, cliname);
2472 rc = record_add_uuid(env, llh, nid, failnodeuuid);
2474 * If *ptr is ':', we have added all NIDs for
2478 rc = record_add_conn(env, llh, cliname,
2480 name_destroy(&failnodeuuid);
2481 failnodeuuid = NULL;
2485 rc = record_add_conn(env, llh, cliname, failnodeuuid);
2486 name_destroy(&failnodeuuid);
2487 failnodeuuid = NULL;
2494 static int mgs_write_log_mdc_to_lmv(const struct lu_env *env,
2495 struct mgs_device *mgs,
2497 struct mgs_target_info *mti,
2498 char *logname, char *lmvname)
2500 struct llog_handle *llh = NULL;
2501 char *mdcname = NULL;
2502 char *nodeuuid = NULL;
2503 char *mdcuuid = NULL;
2504 char *lmvuuid = NULL;
2506 char nidstr[LNET_NIDSTR_SIZE];
2510 if (mgs_log_is_empty(env, mgs, logname)) {
2511 CERROR("log is empty! Logical error\n");
2515 CDEBUG(D_MGS, "adding mdc for %s to log %s:lmv(%s)\n",
2516 mti->mti_svname, logname, lmvname);
2518 libcfs_nid2str_r(mti->mti_nids[0], nidstr, sizeof(nidstr));
2519 rc = name_create(&nodeuuid, nidstr, "");
2522 rc = name_create(&mdcname, mti->mti_svname, "-mdc");
2525 rc = name_create(&mdcuuid, mdcname, "_UUID");
2528 rc = name_create(&lmvuuid, lmvname, "_UUID");
2532 rc = record_start_log(env, mgs, &llh, logname);
2535 rc = record_marker(env, llh, fsdb, CM_START, mti->mti_svname,
2539 for (i = 0; i < mti->mti_nid_count; i++) {
2540 CDEBUG(D_MGS, "add nid %s for mdt\n",
2541 libcfs_nid2str_r(mti->mti_nids[i],
2542 nidstr, sizeof(nidstr)));
2544 rc = record_add_uuid(env, llh, mti->mti_nids[i], nodeuuid);
2549 rc = record_attach(env, llh, mdcname, LUSTRE_MDC_NAME, lmvuuid);
2552 rc = record_setup(env, llh, mdcname, mti->mti_uuid, nodeuuid,
2556 rc = mgs_write_log_failnids(env, mti, llh, mdcname);
2559 snprintf(index, sizeof(index), "%d", mti->mti_stripe_index);
2560 rc = record_mdc_add(env, llh, lmvname, mdcuuid, mti->mti_uuid,
2564 rc = record_marker(env, llh, fsdb, CM_END, mti->mti_svname,
2569 record_end_log(env, &llh);
2571 name_destroy(&lmvuuid);
2572 name_destroy(&mdcuuid);
2573 name_destroy(&mdcname);
2574 name_destroy(&nodeuuid);
2578 static inline int name_create_lov(char **lovname, char *mdtname,
2579 struct fs_db *fsdb, int index)
2582 if (index == 0 && test_bit(FSDB_OSCNAME18, &fsdb->fsdb_flags))
2583 return name_create(lovname, fsdb->fsdb_name, "-mdtlov");
2585 return name_create(lovname, mdtname, "-mdtlov");
2588 static int name_create_mdt_and_lov(char **logname, char **lovname,
2589 struct fs_db *fsdb, int i)
2593 rc = name_create_mdt(logname, fsdb->fsdb_name, i);
2597 if (i == 0 && test_bit(FSDB_OSCNAME18, &fsdb->fsdb_flags))
2598 rc = name_create(lovname, fsdb->fsdb_name, "-mdtlov");
2600 rc = name_create(lovname, *logname, "-mdtlov");
2602 name_destroy(logname);
2608 static inline int name_create_mdt_osc(char **oscname, char *ostname,
2609 struct fs_db *fsdb, int i)
2613 if (i == 0 && test_bit(FSDB_OSCNAME18, &fsdb->fsdb_flags))
2614 sprintf(suffix, "-osc");
2616 sprintf(suffix, "-osc-MDT%04x", i);
2617 return name_create(oscname, ostname, suffix);
2620 /* add new mdc to already existent MDS */
2621 static int mgs_write_log_osp_to_mdt(const struct lu_env *env,
2622 struct mgs_device *mgs,
2624 struct mgs_target_info *mti,
2625 int mdt_index, char *logname)
2627 struct llog_handle *llh = NULL;
2628 char *nodeuuid = NULL;
2629 char *ospname = NULL;
2630 char *lovuuid = NULL;
2631 char *mdtuuid = NULL;
2632 char *svname = NULL;
2633 char *mdtname = NULL;
2634 char *lovname = NULL;
2636 char nidstr[LNET_NIDSTR_SIZE];
2640 if (mgs_log_is_empty(env, mgs, mti->mti_svname)) {
2641 CERROR("log is empty! Logical error\n");
2645 CDEBUG(D_MGS, "adding osp index %d to %s\n", mti->mti_stripe_index,
2648 rc = name_create_mdt(&mdtname, fsdb->fsdb_name, mti->mti_stripe_index);
2652 libcfs_nid2str_r(mti->mti_nids[0], nidstr, sizeof(nidstr));
2653 rc = name_create(&nodeuuid, nidstr, "");
2655 GOTO(out_destory, rc);
2657 rc = name_create(&svname, mdtname, "-osp");
2659 GOTO(out_destory, rc);
2661 sprintf(index_str, "-MDT%04x", mdt_index);
2662 rc = name_create(&ospname, svname, index_str);
2664 GOTO(out_destory, rc);
2666 rc = name_create_lov(&lovname, logname, fsdb, mdt_index);
2668 GOTO(out_destory, rc);
2670 rc = name_create(&lovuuid, lovname, "_UUID");
2672 GOTO(out_destory, rc);
2674 rc = name_create(&mdtuuid, mdtname, "_UUID");
2676 GOTO(out_destory, rc);
2678 rc = record_start_log(env, mgs, &llh, logname);
2680 GOTO(out_destory, rc);
2682 rc = record_marker(env, llh, fsdb, CM_START, mti->mti_svname,
2685 GOTO(out_destory, rc);
2687 for (i = 0; i < mti->mti_nid_count; i++) {
2688 CDEBUG(D_MGS, "add nid %s for mdt\n",
2689 libcfs_nid2str_r(mti->mti_nids[i],
2690 nidstr, sizeof(nidstr)));
2691 rc = record_add_uuid(env, llh, mti->mti_nids[i], nodeuuid);
2696 rc = record_attach(env, llh, ospname, LUSTRE_OSP_NAME, lovuuid);
2700 rc = record_setup(env, llh, ospname, mti->mti_uuid, nodeuuid,
2705 rc = mgs_write_log_failnids(env, mti, llh, ospname);
2709 /* Add mdc(osp) to lod */
2710 snprintf(index_str, sizeof(index_str), "%d", mti->mti_stripe_index);
2711 rc = record_base(env, llh, lovname, 0, LCFG_ADD_MDC, mti->mti_uuid,
2712 index_str, "1", NULL);
2716 rc = record_marker(env, llh, fsdb, CM_END, mti->mti_svname, "add osp");
2721 record_end_log(env, &llh);
2724 name_destroy(&mdtuuid);
2725 name_destroy(&lovuuid);
2726 name_destroy(&lovname);
2727 name_destroy(&ospname);
2728 name_destroy(&svname);
2729 name_destroy(&nodeuuid);
2730 name_destroy(&mdtname);
2734 static int mgs_write_log_mdt0(const struct lu_env *env,
2735 struct mgs_device *mgs,
2737 struct mgs_target_info *mti)
2739 char *log = mti->mti_svname;
2740 struct llog_handle *llh = NULL;
2741 struct obd_uuid *uuid;
2744 char *ptr = mti->mti_params;
2745 int rc = 0, failout = 0;
2748 OBD_ALLOC_PTR(uuid);
2752 if (class_find_param(ptr, PARAM_FAILMODE, &ptr) == 0)
2753 failout = (strncmp(ptr, "failout", 7) == 0);
2755 rc = name_create(&lovname, log, "-mdtlov");
2758 if (mgs_log_is_empty(env, mgs, log)) {
2759 rc = mgs_write_log_lov(env, mgs, fsdb, mti, log, lovname);
2764 sprintf(mdt_index, "%d", mti->mti_stripe_index);
2766 rc = record_start_log(env, mgs, &llh, log);
2770 /* add MDT itself */
2772 /* FIXME this whole fn should be a single journal transaction */
2773 sprintf(uuid->uuid, "%s_UUID", log);
2774 rc = record_marker(env, llh, fsdb, CM_START, log, "add mdt");
2777 rc = record_attach(env, llh, log, LUSTRE_MDT_NAME, uuid->uuid);
2780 rc = record_mount_opt(env, llh, log, lovname, NULL);
2783 rc = record_setup(env, llh, log, uuid->uuid, mdt_index, lovname,
2784 failout ? "n" : "f");
2787 rc = record_marker(env, llh, fsdb, CM_END, log, "add mdt");
2791 record_end_log(env, &llh);
2793 name_destroy(&lovname);
2799 /* envelope method for all layers log */
2800 static int mgs_write_log_mdt(const struct lu_env *env,
2801 struct mgs_device *mgs,
2803 struct mgs_target_info *mti)
2805 struct mgs_thread_info *mgi = mgs_env_info(env);
2806 struct llog_handle *llh = NULL;
2811 CDEBUG(D_MGS, "writing new mdt %s\n", mti->mti_svname);
2813 if (mti->mti_uuid[0] == '\0') {
2814 /* Make up our own uuid */
2815 snprintf(mti->mti_uuid, sizeof(mti->mti_uuid),
2816 "%s_UUID", mti->mti_svname);
2820 rc = mgs_write_log_mdt0(env, mgs, fsdb, mti);
2823 /* Append the mdt info to the client log */
2824 rc = name_create(&cliname, mti->mti_fsname, "-client");
2828 if (mgs_log_is_empty(env, mgs, cliname)) {
2829 /* Start client log */
2830 rc = mgs_write_log_lov(env, mgs, fsdb, mti, cliname,
2834 rc = mgs_write_log_lmv(env, mgs, fsdb, mti, cliname,
2841 #09 L add_uuid nid=uml1@tcp(0x20000c0a80201) 0: 1:uml1_UUID
2842 #10 L attach 0:MDC_uml1_mdsA_MNT_client 1:mdc 2:1d834_MNT_client_03f
2843 #11 L setup 0:MDC_uml1_mdsA_MNT_client 1:mdsA_UUID 2:uml1_UUID
2844 #12 L add_uuid nid=uml2@tcp(0x20000c0a80202) 0: 1:uml2_UUID
2845 #13 L add_conn 0:MDC_uml1_mdsA_MNT_client 1:uml2_UUID
2846 #14 L mount_option 0: 1:client 2:lov1 3:MDC_uml1_mdsA_MNT_client
2849 /* copy client info about lov/lmv */
2850 mgi->mgi_comp.comp_mti = mti;
2851 mgi->mgi_comp.comp_fsdb = fsdb;
2853 rc = mgs_steal_llog_for_mdt_from_client(env, mgs, cliname,
2857 rc = mgs_write_log_mdc_to_lmv(env, mgs, fsdb, mti, cliname,
2863 rc = record_start_log(env, mgs, &llh, cliname);
2867 rc = record_marker(env, llh, fsdb, CM_START, cliname, "mount opts");
2870 rc = record_mount_opt(env, llh, cliname, fsdb->fsdb_clilov,
2874 rc = record_marker(env, llh, fsdb, CM_END, cliname, "mount opts");
2878 /* for_all_existing_mdt except current one */
2879 for (i = 0; i < INDEX_MAP_SIZE * 8; i++) {
2880 if (i != mti->mti_stripe_index &&
2881 test_bit(i, fsdb->fsdb_mdt_index_map)) {
2884 rc = name_create_mdt(&logname, fsdb->fsdb_name, i);
2888 /* NB: If the log for the MDT is empty, it means
2889 * the MDT is only added to the index
2890 * map, and not being process yet, i.e. this
2891 * is an unregistered MDT, see mgs_write_log_target().
2892 * so we should skip it. Otherwise
2894 * 1. MGS get register request for MDT1 and MDT2.
2896 * 2. Then both MDT1 and MDT2 are added into
2897 * fsdb_mdt_index_map. (see mgs_set_index()).
2899 * 3. Then MDT1 get the lock of fsdb_mutex, then
2900 * generate the config log, here, it will regard MDT2
2901 * as an existent MDT, and generate "add osp" for
2902 * lustre-MDT0001-osp-MDT0002. Note: at the moment
2903 * MDT0002 config log is still empty, so it will
2904 * add "add osp" even before "lov setup", which
2905 * will definitly cause trouble.
2907 * 4. MDT1 registeration finished, fsdb_mutex is
2908 * released, then MDT2 get in, then in above
2909 * mgs_steal_llog_for_mdt_from_client(), it will
2910 * add another osp log for lustre-MDT0001-osp-MDT0002,
2911 * which will cause another trouble.*/
2912 if (!mgs_log_is_empty(env, mgs, logname))
2913 rc = mgs_write_log_osp_to_mdt(env, mgs, fsdb,
2916 name_destroy(&logname);
2922 record_end_log(env, &llh);
2924 name_destroy(&cliname);
2928 /* Add the ost info to the client/mdt lov */
2929 static int mgs_write_log_osc_to_lov(const struct lu_env *env,
2930 struct mgs_device *mgs, struct fs_db *fsdb,
2931 struct mgs_target_info *mti,
2932 char *logname, char *suffix, char *lovname,
2933 enum lustre_sec_part sec_part, int flags)
2935 struct llog_handle *llh = NULL;
2936 char *nodeuuid = NULL;
2937 char *oscname = NULL;
2938 char *oscuuid = NULL;
2939 char *lovuuid = NULL;
2940 char *svname = NULL;
2942 char nidstr[LNET_NIDSTR_SIZE];
2946 CDEBUG(D_INFO, "adding osc for %s to log %s\n",
2947 mti->mti_svname, logname);
2949 if (mgs_log_is_empty(env, mgs, logname)) {
2950 CERROR("log is empty! Logical error\n");
2954 libcfs_nid2str_r(mti->mti_nids[0], nidstr, sizeof(nidstr));
2955 rc = name_create(&nodeuuid, nidstr, "");
2958 rc = name_create(&svname, mti->mti_svname, "-osc");
2962 /* for the system upgraded from old 1.8, keep using the old osc naming
2963 * style for mdt, see name_create_mdt_osc(). LU-1257 */
2964 if (test_bit(FSDB_OSCNAME18, &fsdb->fsdb_flags))
2965 rc = name_create(&oscname, svname, "");
2967 rc = name_create(&oscname, svname, suffix);
2971 rc = name_create(&oscuuid, oscname, "_UUID");
2974 rc = name_create(&lovuuid, lovname, "_UUID");
2980 #03 L add_uuid nid=uml1@tcp(0x20000c0a80201) 0: 1:uml1_UUID
2982 #04 L add_uuid nid=1@elan(0x1000000000001) nal=90 0: 1:uml1_UUID
2983 #04 L attach 0:OSC_uml1_ost1_MNT_client 1:osc 2:89070_lov1_a41dff51a
2984 #05 L setup 0:OSC_uml1_ost1_MNT_client 1:ost1_UUID 2:uml1_UUID
2986 #06 L add_uuid nid=uml2@tcp(0x20000c0a80202) 0: 1:uml2_UUID
2987 #07 L add_conn 0:OSC_uml1_ost1_MNT_client 1:uml2_UUID
2988 #08 L lov_modify_tgts add 0:lov1 1:ost1_UUID 2(index):0 3(gen):1
2991 rc = record_start_log(env, mgs, &llh, logname);
2995 /* FIXME these should be a single journal transaction */
2996 rc = record_marker(env, llh, fsdb, CM_START | flags, mti->mti_svname,
3001 /* NB: don't change record order, because upon MDT steal OSC config
3002 * from client, it treats all nids before LCFG_SETUP as target nids
3003 * (multiple interfaces), while nids after as failover node nids.
3004 * See mgs_steal_client_llog_handler() LCFG_ADD_UUID.
3006 for (i = 0; i < mti->mti_nid_count; i++) {
3007 CDEBUG(D_MGS, "add nid %s\n",
3008 libcfs_nid2str_r(mti->mti_nids[i],
3009 nidstr, sizeof(nidstr)));
3010 rc = record_add_uuid(env, llh, mti->mti_nids[i], nodeuuid);
3014 rc = record_attach(env, llh, oscname, LUSTRE_OSC_NAME, lovuuid);
3017 rc = record_setup(env, llh, oscname, mti->mti_uuid, nodeuuid,
3021 rc = mgs_write_log_failnids(env, mti, llh, oscname);
3025 snprintf(index, sizeof(index), "%d", mti->mti_stripe_index);
3027 rc = record_lov_add(env, llh, lovname, mti->mti_uuid, index, "1");
3030 rc = record_marker(env, llh, fsdb, CM_END | flags, mti->mti_svname,
3035 record_end_log(env, &llh);
3037 name_destroy(&lovuuid);
3038 name_destroy(&oscuuid);
3039 name_destroy(&oscname);
3040 name_destroy(&svname);
3041 name_destroy(&nodeuuid);
3045 static int mgs_write_log_ost(const struct lu_env *env,
3046 struct mgs_device *mgs, struct fs_db *fsdb,
3047 struct mgs_target_info *mti)
3049 struct llog_handle *llh = NULL;
3050 char *logname, *lovname;
3051 char *ptr = mti->mti_params;
3052 int rc, flags = 0, failout = 0, i;
3055 CDEBUG(D_MGS, "writing new ost %s\n", mti->mti_svname);
3057 /* The ost startup log */
3059 /* If the ost log already exists, that means that someone reformatted
3060 the ost and it called target_add again. */
3061 if (!mgs_log_is_empty(env, mgs, mti->mti_svname)) {
3062 LCONSOLE_ERROR_MSG(0x141, "The config log for %s already "
3063 "exists, yet the server claims it never "
3064 "registered. It may have been reformatted, "
3065 "or the index changed. writeconf the MDT to "
3066 "regenerate all logs.\n", mti->mti_svname);
3071 attach obdfilter ost1 ost1_UUID
3072 setup /dev/loop2 ldiskfs f|n errors=remount-ro,user_xattr
3074 if (class_find_param(ptr, PARAM_FAILMODE, &ptr) == 0)
3075 failout = (strncmp(ptr, "failout", 7) == 0);
3076 rc = record_start_log(env, mgs, &llh, mti->mti_svname);
3079 /* FIXME these should be a single journal transaction */
3080 rc = record_marker(env, llh, fsdb, CM_START, mti->mti_svname,"add ost");
3083 if (*mti->mti_uuid == '\0')
3084 snprintf(mti->mti_uuid, sizeof(mti->mti_uuid),
3085 "%s_UUID", mti->mti_svname);
3086 rc = record_attach(env, llh, mti->mti_svname,
3087 "obdfilter"/*LUSTRE_OST_NAME*/, mti->mti_uuid);
3090 rc = record_setup(env, llh, mti->mti_svname,
3091 "dev"/*ignored*/, "type"/*ignored*/,
3092 failout ? "n" : "f", NULL/*options*/);
3095 rc = record_marker(env, llh, fsdb, CM_END, mti->mti_svname, "add ost");
3099 record_end_log(env, &llh);
3102 /* We also have to update the other logs where this osc is part of
3105 if (test_bit(FSDB_OLDLOG14, &fsdb->fsdb_flags)) {
3106 /* If we're upgrading, the old mdt log already has our
3107 entry. Let's do a fake one for fun. */
3108 /* Note that we can't add any new failnids, since we don't
3109 know the old osc names. */
3110 flags = CM_SKIP | CM_UPGRADE146;
3112 } else if ((mti->mti_flags & LDD_F_UPDATE) != LDD_F_UPDATE) {
3113 /* If the update flag isn't set, don't update client/mdt
3116 LCONSOLE_WARN("Client log for %s was not updated; writeconf "
3117 "the MDT first to regenerate it.\n",
3121 /* Add ost to all MDT lov defs */
3122 for (i = 0; i < INDEX_MAP_SIZE * 8; i++){
3123 if (test_bit(i, fsdb->fsdb_mdt_index_map)) {
3126 rc = name_create_mdt_and_lov(&logname, &lovname, fsdb,
3131 snprintf(mdt_index, sizeof(mdt_index), "-MDT%04x", i);
3132 rc = mgs_write_log_osc_to_lov(env, mgs, fsdb, mti,
3134 lovname, LUSTRE_SP_MDT,
3136 name_destroy(&logname);
3137 name_destroy(&lovname);
3143 /* Append ost info to the client log */
3144 rc = name_create(&logname, mti->mti_fsname, "-client");
3147 if (mgs_log_is_empty(env, mgs, logname)) {
3148 /* Start client log */
3149 rc = mgs_write_log_lov(env, mgs, fsdb, mti, logname,
3153 rc = mgs_write_log_lmv(env, mgs, fsdb, mti, logname,
3158 rc = mgs_write_log_osc_to_lov(env, mgs, fsdb, mti, logname, "",
3159 fsdb->fsdb_clilov, LUSTRE_SP_CLI, flags);
3161 name_destroy(&logname);
3165 static __inline__ int mgs_param_empty(char *ptr)
3169 if ((tmp = strchr(ptr, '=')) && (*(++tmp) == '\0'))
3174 static int mgs_write_log_failnid_internal(const struct lu_env *env,
3175 struct mgs_device *mgs,
3177 struct mgs_target_info *mti,
3178 char *logname, char *cliname)
3181 struct llog_handle *llh = NULL;
3183 if (mgs_param_empty(mti->mti_params)) {
3184 /* Remove _all_ failnids */
3185 rc = mgs_modify(env, mgs, fsdb, mti, logname,
3186 mti->mti_svname, "add failnid", CM_SKIP);
3187 return rc < 0 ? rc : 0;
3190 /* Otherwise failover nids are additive */
3191 rc = record_start_log(env, mgs, &llh, logname);
3194 /* FIXME this should be a single journal transaction */
3195 rc = record_marker(env, llh, fsdb, CM_START, mti->mti_svname,
3199 rc = mgs_write_log_failnids(env, mti, llh, cliname);
3202 rc = record_marker(env, llh, fsdb, CM_END,
3203 mti->mti_svname, "add failnid");
3205 record_end_log(env, &llh);
3210 /* Add additional failnids to an existing log.
3211 The mdc/osc must have been added to logs first */
3212 /* tcp nids must be in dotted-quad ascii -
3213 we can't resolve hostnames from the kernel. */
3214 static int mgs_write_log_add_failnid(const struct lu_env *env,
3215 struct mgs_device *mgs,
3217 struct mgs_target_info *mti)
3219 char *logname, *cliname;
3223 /* FIXME we currently can't erase the failnids
3224 * given when a target first registers, since they aren't part of
3225 * an "add uuid" stanza
3228 /* Verify that we know about this target */
3229 if (mgs_log_is_empty(env, mgs, mti->mti_svname)) {
3230 LCONSOLE_ERROR_MSG(0x142, "The target %s has not registered "
3231 "yet. It must be started before failnids "
3232 "can be added.\n", mti->mti_svname);
3236 /* Create mdc/osc client name (e.g. lustre-OST0001-osc) */
3237 if (mti->mti_flags & LDD_F_SV_TYPE_MDT) {
3238 rc = name_create(&cliname, mti->mti_svname, "-mdc");
3239 } else if (mti->mti_flags & LDD_F_SV_TYPE_OST) {
3240 rc = name_create(&cliname, mti->mti_svname, "-osc");
3247 /* Add failover nids to the client log */
3248 rc = name_create(&logname, mti->mti_fsname, "-client");
3250 name_destroy(&cliname);
3254 rc = mgs_write_log_failnid_internal(env, mgs, fsdb,mti,logname,cliname);
3255 name_destroy(&logname);
3256 name_destroy(&cliname);
3260 if (mti->mti_flags & LDD_F_SV_TYPE_OST) {
3261 /* Add OST failover nids to the MDT logs as well */
3264 for (i = 0; i < INDEX_MAP_SIZE * 8; i++) {
3265 if (!test_bit(i, fsdb->fsdb_mdt_index_map))
3267 rc = name_create_mdt(&logname, mti->mti_fsname, i);
3270 rc = name_create_mdt_osc(&cliname, mti->mti_svname,
3273 name_destroy(&logname);
3276 rc = mgs_write_log_failnid_internal(env, mgs, fsdb,
3279 name_destroy(&cliname);
3280 name_destroy(&logname);
3289 static int mgs_wlp_lcfg(const struct lu_env *env,
3290 struct mgs_device *mgs, struct fs_db *fsdb,
3291 struct mgs_target_info *mti,
3292 char *logname, struct lustre_cfg_bufs *bufs,
3293 char *tgtname, char *ptr)
3295 char comment[MTI_NAME_MAXLEN];
3297 struct llog_cfg_rec *lcr;
3300 /* Erase any old settings of this same parameter */
3301 strlcpy(comment, ptr, sizeof(comment));
3302 /* But don't try to match the value. */
3303 tmp = strchr(comment, '=');
3306 /* FIXME we should skip settings that are the same as old values */
3307 rc = mgs_modify(env, mgs, fsdb, mti, logname, tgtname, comment,CM_SKIP);
3310 del = mgs_param_empty(ptr);
3312 LCONSOLE_INFO("%s parameter %s.%s in log %s\n", del ? "Disabling" : rc ?
3313 "Setting" : "Modifying", tgtname, comment, logname);
3315 /* mgs_modify() will return 1 if nothing had to be done */
3321 lustre_cfg_bufs_reset(bufs, tgtname);
3322 lustre_cfg_bufs_set_string(bufs, 1, ptr);
3323 if (mti->mti_flags & LDD_F_PARAM2)
3324 lustre_cfg_bufs_set_string(bufs, 2, LCTL_UPCALL);
3326 lcr = lustre_cfg_rec_new((mti->mti_flags & LDD_F_PARAM2) ?
3327 LCFG_SET_PARAM : LCFG_PARAM, bufs);
3331 rc = mgs_write_log_direct(env, mgs, fsdb, logname, lcr, tgtname,
3333 lustre_cfg_rec_free(lcr);
3337 /* write global variable settings into log */
3338 static int mgs_write_log_sys(const struct lu_env *env,
3339 struct mgs_device *mgs, struct fs_db *fsdb,
3340 struct mgs_target_info *mti, char *sys, char *ptr)
3342 struct mgs_thread_info *mgi = mgs_env_info(env);
3343 struct lustre_cfg *lcfg;
3344 struct llog_cfg_rec *lcr;
3346 int rc, cmd, convert = 1;
3348 if (class_match_param(ptr, PARAM_TIMEOUT, &tmp) == 0) {
3349 cmd = LCFG_SET_TIMEOUT;
3350 } else if (class_match_param(ptr, PARAM_LDLM_TIMEOUT, &tmp) == 0) {
3351 cmd = LCFG_SET_LDLM_TIMEOUT;
3352 /* Check for known params here so we can return error to lctl */
3353 } else if ((class_match_param(ptr, PARAM_AT_MIN, &tmp) == 0) ||
3354 (class_match_param(ptr, PARAM_AT_MAX, &tmp) == 0) ||
3355 (class_match_param(ptr, PARAM_AT_EXTRA, &tmp) == 0) ||
3356 (class_match_param(ptr, PARAM_AT_EARLY_MARGIN, &tmp) == 0) ||
3357 (class_match_param(ptr, PARAM_AT_HISTORY, &tmp) == 0)) {
3359 } else if (class_match_param(ptr, PARAM_JOBID_VAR, &tmp) == 0) {
3360 convert = 0; /* Don't convert string value to integer */
3366 if (mgs_param_empty(ptr))
3367 CDEBUG(D_MGS, "global '%s' removed\n", sys);
3369 CDEBUG(D_MGS, "global '%s' val=%s\n", sys, tmp);
3371 lustre_cfg_bufs_reset(&mgi->mgi_bufs, NULL);
3372 lustre_cfg_bufs_set_string(&mgi->mgi_bufs, 1, sys);
3373 if (!convert && *tmp != '\0')
3374 lustre_cfg_bufs_set_string(&mgi->mgi_bufs, 2, tmp);
3375 lcr = lustre_cfg_rec_new(cmd, &mgi->mgi_bufs);
3379 lcfg = &lcr->lcr_cfg;
3381 rc = kstrtouint(tmp, 0, &lcfg->lcfg_num);
3383 GOTO(out_rec_free, rc);
3388 /* truncate the comment to the parameter name */
3392 /* modify all servers and clients */
3393 rc = mgs_write_log_direct_all(env, mgs, fsdb, mti,
3394 *tmp == '\0' ? NULL : lcr,
3395 mti->mti_fsname, sys, 0);
3396 if (rc == 0 && *tmp != '\0') {
3398 case LCFG_SET_TIMEOUT:
3399 if (!obd_timeout_set || lcfg->lcfg_num > obd_timeout)
3400 class_process_config(lcfg);
3402 case LCFG_SET_LDLM_TIMEOUT:
3403 if (!ldlm_timeout_set || lcfg->lcfg_num > ldlm_timeout)
3404 class_process_config(lcfg);
3412 lustre_cfg_rec_free(lcr);
3416 /* write quota settings into log */
3417 static int mgs_write_log_quota(const struct lu_env *env, struct mgs_device *mgs,
3418 struct fs_db *fsdb, struct mgs_target_info *mti,
3419 char *quota, char *ptr)
3421 struct mgs_thread_info *mgi = mgs_env_info(env);
3422 struct llog_cfg_rec *lcr;
3425 int rc, cmd = LCFG_PARAM;
3427 /* support only 'meta' and 'data' pools so far */
3428 if (class_match_param(ptr, QUOTA_METAPOOL_NAME, &tmp) != 0 &&
3429 class_match_param(ptr, QUOTA_DATAPOOL_NAME, &tmp) != 0) {
3430 CERROR("parameter quota.%s isn't supported (only quota.mdt "
3431 "& quota.ost are)\n", ptr);
3436 CDEBUG(D_MGS, "global '%s' removed\n", quota);
3438 CDEBUG(D_MGS, "global '%s'\n", quota);
3440 if (strchr(tmp, 'u') == NULL && strchr(tmp, 'g') == NULL &&
3441 strchr(tmp, 'p') == NULL &&
3442 strcmp(tmp, "none") != 0) {
3443 CERROR("enable option(%s) isn't supported\n", tmp);
3448 lustre_cfg_bufs_reset(&mgi->mgi_bufs, mti->mti_fsname);
3449 lustre_cfg_bufs_set_string(&mgi->mgi_bufs, 1, quota);
3450 lcr = lustre_cfg_rec_new(cmd, &mgi->mgi_bufs);
3454 /* truncate the comment to the parameter name */
3459 /* XXX we duplicated quota enable information in all server
3460 * config logs, it should be moved to a separate config
3461 * log once we cleanup the config log for global param. */
3462 /* modify all servers */
3463 rc = mgs_write_log_direct_all(env, mgs, fsdb, mti,
3464 *tmp == '\0' ? NULL : lcr,
3465 mti->mti_fsname, quota, 1);
3467 lustre_cfg_rec_free(lcr);
3468 return rc < 0 ? rc : 0;
3471 static int mgs_srpc_set_param_disk(const struct lu_env *env,
3472 struct mgs_device *mgs,
3474 struct mgs_target_info *mti,
3477 struct mgs_thread_info *mgi = mgs_env_info(env);
3478 struct llog_cfg_rec *lcr;
3479 struct llog_handle *llh = NULL;
3481 char *comment, *ptr;
3487 ptr = strchr(param, '=');
3488 LASSERT(ptr != NULL);
3491 OBD_ALLOC(comment, len + 1);
3492 if (comment == NULL)
3494 strncpy(comment, param, len);
3495 comment[len] = '\0';
3498 lustre_cfg_bufs_reset(&mgi->mgi_bufs, mti->mti_svname);
3499 lustre_cfg_bufs_set_string(&mgi->mgi_bufs, 1, param);
3500 lcr = lustre_cfg_rec_new(LCFG_SPTLRPC_CONF, &mgi->mgi_bufs);
3502 GOTO(out_comment, rc = -ENOMEM);
3504 /* construct log name */
3505 rc = name_create(&logname, mti->mti_fsname, "-sptlrpc");
3509 if (mgs_log_is_empty(env, mgs, logname)) {
3510 rc = record_start_log(env, mgs, &llh, logname);
3513 record_end_log(env, &llh);
3516 /* obsolete old one */
3517 rc = mgs_modify(env, mgs, fsdb, mti, logname, mti->mti_svname,
3521 /* write the new one */
3522 rc = mgs_write_log_direct(env, mgs, fsdb, logname, lcr,
3523 mti->mti_svname, comment);
3525 CERROR("%s: error writing log %s: rc = %d\n",
3526 mgs->mgs_obd->obd_name, logname, rc);
3528 name_destroy(&logname);
3530 lustre_cfg_rec_free(lcr);
3532 OBD_FREE(comment, len + 1);
3536 static int mgs_srpc_set_param_udesc_mem(struct fs_db *fsdb,
3541 /* disable the adjustable udesc parameter for now, i.e. use default
3542 * setting that client always ship udesc to MDT if possible. to enable
3543 * it simply remove the following line */
3546 ptr = strchr(param, '=');
3551 if (strcmp(param, PARAM_SRPC_UDESC))
3554 if (strcmp(ptr, "yes") == 0) {
3555 set_bit(FSDB_UDESC, &fsdb->fsdb_flags);
3556 CWARN("Enable user descriptor shipping from client to MDT\n");
3557 } else if (strcmp(ptr, "no") == 0) {
3558 clear_bit(FSDB_UDESC, &fsdb->fsdb_flags);
3559 CWARN("Disable user descriptor shipping from client to MDT\n");
3567 CERROR("Invalid param: %s\n", param);
3571 static int mgs_srpc_set_param_mem(struct fs_db *fsdb,
3575 struct sptlrpc_rule rule;
3576 struct sptlrpc_rule_set *rset;
3580 if (strncmp(param, PARAM_SRPC, sizeof(PARAM_SRPC) - 1) != 0) {
3581 CERROR("Invalid sptlrpc parameter: %s\n", param);
3585 if (strncmp(param, PARAM_SRPC_UDESC,
3586 sizeof(PARAM_SRPC_UDESC) - 1) == 0) {
3587 RETURN(mgs_srpc_set_param_udesc_mem(fsdb, param));
3590 if (strncmp(param, PARAM_SRPC_FLVR, sizeof(PARAM_SRPC_FLVR) - 1) != 0) {
3591 CERROR("Invalid sptlrpc flavor parameter: %s\n", param);
3595 param += sizeof(PARAM_SRPC_FLVR) - 1;
3597 rc = sptlrpc_parse_rule(param, &rule);
3601 /* mgs rules implies must be mgc->mgs */
3602 if (test_bit(FSDB_MGS_SELF, &fsdb->fsdb_flags)) {
3603 if ((rule.sr_from != LUSTRE_SP_MGC &&
3604 rule.sr_from != LUSTRE_SP_ANY) ||
3605 (rule.sr_to != LUSTRE_SP_MGS &&
3606 rule.sr_to != LUSTRE_SP_ANY))
3610 /* preapre room for this coming rule. svcname format should be:
3611 * - fsname: general rule
3612 * - fsname-tgtname: target-specific rule
3614 if (strchr(svname, '-')) {
3615 struct mgs_tgt_srpc_conf *tgtconf;
3618 for (tgtconf = fsdb->fsdb_srpc_tgt; tgtconf != NULL;
3619 tgtconf = tgtconf->mtsc_next) {
3620 if (!strcmp(tgtconf->mtsc_tgt, svname)) {
3629 OBD_ALLOC_PTR(tgtconf);
3630 if (tgtconf == NULL)
3633 name_len = strlen(svname);
3635 OBD_ALLOC(tgtconf->mtsc_tgt, name_len + 1);
3636 if (tgtconf->mtsc_tgt == NULL) {
3637 OBD_FREE_PTR(tgtconf);
3640 memcpy(tgtconf->mtsc_tgt, svname, name_len);
3642 tgtconf->mtsc_next = fsdb->fsdb_srpc_tgt;
3643 fsdb->fsdb_srpc_tgt = tgtconf;
3646 rset = &tgtconf->mtsc_rset;
3647 } else if (strcmp(svname, MGSSELF_NAME) == 0) {
3648 /* put _mgs related srpc rule directly in mgs ruleset */
3649 rset = &fsdb->fsdb_mgs->mgs_lut.lut_sptlrpc_rset;
3651 rset = &fsdb->fsdb_srpc_gen;
3654 rc = sptlrpc_rule_set_merge(rset, &rule);
3659 static int mgs_srpc_set_param(const struct lu_env *env,
3660 struct mgs_device *mgs,
3662 struct mgs_target_info *mti,
3672 /* keep a copy of original param, which could be destroied
3674 copy_size = strlen(param) + 1;
3675 OBD_ALLOC(copy, copy_size);
3678 memcpy(copy, param, copy_size);
3680 rc = mgs_srpc_set_param_mem(fsdb, mti->mti_svname, param);
3684 /* previous steps guaranteed the syntax is correct */
3685 rc = mgs_srpc_set_param_disk(env, mgs, fsdb, mti, copy);
3689 if (test_bit(FSDB_MGS_SELF, &fsdb->fsdb_flags)) {
3691 * for mgs rules, make them effective immediately.
3693 LASSERT(fsdb->fsdb_srpc_tgt == NULL);
3694 sptlrpc_target_update_exp_flavor(mgs->mgs_obd,
3695 &fsdb->fsdb_srpc_gen);
3699 OBD_FREE(copy, copy_size);
3703 struct mgs_srpc_read_data {
3704 struct fs_db *msrd_fsdb;
3708 static int mgs_srpc_read_handler(const struct lu_env *env,
3709 struct llog_handle *llh,
3710 struct llog_rec_hdr *rec, void *data)
3712 struct mgs_srpc_read_data *msrd = data;
3713 struct cfg_marker *marker;
3714 struct lustre_cfg *lcfg = REC_DATA(rec);
3715 char *svname, *param;
3719 if (rec->lrh_type != OBD_CFG_REC) {
3720 CERROR("unhandled lrh_type: %#x\n", rec->lrh_type);
3724 cfg_len = REC_DATA_LEN(rec);
3726 rc = lustre_cfg_sanity_check(lcfg, cfg_len);
3728 CERROR("Insane cfg\n");
3732 if (lcfg->lcfg_command == LCFG_MARKER) {
3733 marker = lustre_cfg_buf(lcfg, 1);
3735 if (marker->cm_flags & CM_START &&
3736 marker->cm_flags & CM_SKIP)
3737 msrd->msrd_skip = 1;
3738 if (marker->cm_flags & CM_END)
3739 msrd->msrd_skip = 0;
3744 if (msrd->msrd_skip)
3747 if (lcfg->lcfg_command != LCFG_SPTLRPC_CONF) {
3748 CERROR("invalid command (%x)\n", lcfg->lcfg_command);
3752 svname = lustre_cfg_string(lcfg, 0);
3753 if (svname == NULL) {
3754 CERROR("svname is empty\n");
3758 param = lustre_cfg_string(lcfg, 1);
3759 if (param == NULL) {
3760 CERROR("param is empty\n");
3764 rc = mgs_srpc_set_param_mem(msrd->msrd_fsdb, svname, param);
3766 CERROR("read sptlrpc record error (%d): %s\n", rc, param);
3771 int mgs_get_fsdb_srpc_from_llog(const struct lu_env *env,
3772 struct mgs_device *mgs,
3775 struct llog_handle *llh = NULL;
3776 struct llog_ctxt *ctxt;
3778 struct mgs_srpc_read_data msrd;
3782 /* construct log name */
3783 rc = name_create(&logname, fsdb->fsdb_name, "-sptlrpc");
3787 ctxt = llog_get_context(mgs->mgs_obd, LLOG_CONFIG_ORIG_CTXT);
3788 LASSERT(ctxt != NULL);
3790 if (mgs_log_is_empty(env, mgs, logname))
3793 rc = llog_open(env, ctxt, &llh, NULL, logname,
3801 rc = llog_init_handle(env, llh, LLOG_F_IS_PLAIN, NULL);
3803 GOTO(out_close, rc);
3805 if (llog_get_size(llh) <= 1)
3806 GOTO(out_close, rc = 0);
3808 msrd.msrd_fsdb = fsdb;
3811 rc = llog_process(env, llh, mgs_srpc_read_handler, (void *)&msrd,
3815 llog_close(env, llh);
3817 llog_ctxt_put(ctxt);
3818 name_destroy(&logname);
3821 CERROR("failed to read sptlrpc config database: %d\n", rc);
3825 static int mgs_write_log_param2(const struct lu_env *env,
3826 struct mgs_device *mgs,
3828 struct mgs_target_info *mti, char *ptr)
3830 struct lustre_cfg_bufs bufs;
3834 CDEBUG(D_MGS, "next param '%s'\n", ptr);
3836 /* PARAM_MGSNODE and PARAM_NETWORK are set only when formating
3837 * or during the inital mount. It can never change after that.
3839 if (!class_match_param(ptr, PARAM_MGSNODE, NULL) ||
3840 !class_match_param(ptr, PARAM_NETWORK, NULL)) {
3845 /* Processed in mgs_write_log_ost. Another value that can't
3846 * be changed by lctl set_param -P.
3848 if (!class_match_param(ptr, PARAM_FAILMODE, NULL)) {
3849 LCONSOLE_ERROR_MSG(0x169,
3850 "%s can only be changed with tunefs.lustre and --writeconf\n",
3856 /* FIXME !!! Support for sptlrpc is incomplete. Currently the change
3857 * doesn't transmit to the client. See LU-7183.
3859 if (!class_match_param(ptr, PARAM_SRPC, NULL)) {
3860 rc = mgs_srpc_set_param(env, mgs, fsdb, mti, ptr);
3864 /* Can't use class_match_param since ptr doesn't start with
3865 * PARAM_FAILNODE. So we look for PARAM_FAILNODE contained in ptr.
3867 if (strstr(ptr, PARAM_FAILNODE)) {
3868 /* Add a failover nidlist. We already processed failovers
3869 * params for new targets in mgs_write_log_target.
3873 /* can't use wildcards with failover.node */
3874 if (strchr(ptr, '*')) {
3879 param = strstr(ptr, PARAM_FAILNODE);
3880 if (strlcpy(mti->mti_params, param, sizeof(mti->mti_params)) >=
3881 sizeof(mti->mti_params)) {
3886 CDEBUG(D_MGS, "Adding failnode with param %s\n",
3888 rc = mgs_write_log_add_failnid(env, mgs, fsdb, mti);
3892 rc = mgs_wlp_lcfg(env, mgs, fsdb, mti, PARAMS_FILENAME, &bufs,
3893 mti->mti_svname, ptr);
3898 /* Permanent settings of all parameters by writing into the appropriate
3899 * configuration logs.
3900 * A parameter with null value ("<param>='\0'") means to erase it out of
3903 static int mgs_write_log_param(const struct lu_env *env,
3904 struct mgs_device *mgs, struct fs_db *fsdb,
3905 struct mgs_target_info *mti, char *ptr)
3907 struct mgs_thread_info *mgi = mgs_env_info(env);
3913 /* For various parameter settings, we have to figure out which logs
3914 care about them (e.g. both mdt and client for lov settings) */
3915 CDEBUG(D_MGS, "next param '%s'\n", ptr);
3917 /* The params are stored in MOUNT_DATA_FILE and modified via
3918 tunefs.lustre, or set using lctl conf_param */
3920 /* Processed in lustre_start_mgc */
3921 if (class_match_param(ptr, PARAM_MGSNODE, NULL) == 0)
3924 /* Processed in ost/mdt */
3925 if (class_match_param(ptr, PARAM_NETWORK, NULL) == 0)
3928 /* Processed in mgs_write_log_ost */
3929 if (class_match_param(ptr, PARAM_FAILMODE, NULL) == 0) {
3930 if (mti->mti_flags & LDD_F_PARAM) {
3931 LCONSOLE_ERROR_MSG(0x169,
3932 "%s can only be changed with tunefs.lustre and --writeconf\n",
3939 if (class_match_param(ptr, PARAM_SRPC, NULL) == 0) {
3940 rc = mgs_srpc_set_param(env, mgs, fsdb, mti, ptr);
3944 if (class_match_param(ptr, PARAM_FAILNODE, NULL) == 0) {
3945 /* Add a failover nidlist */
3947 /* We already processed failovers params for new
3948 targets in mgs_write_log_target */
3949 if (mti->mti_flags & LDD_F_PARAM) {
3950 CDEBUG(D_MGS, "Adding failnode\n");
3951 rc = mgs_write_log_add_failnid(env, mgs, fsdb, mti);
3956 if (class_match_param(ptr, PARAM_SYS, &tmp) == 0) {
3957 rc = mgs_write_log_sys(env, mgs, fsdb, mti, ptr, tmp);
3961 if (class_match_param(ptr, PARAM_QUOTA, &tmp) == 0) {
3962 rc = mgs_write_log_quota(env, mgs, fsdb, mti, ptr, tmp);
3966 if (class_match_param(ptr, PARAM_OSC PARAM_ACTIVE, &tmp) == 0 ||
3967 class_match_param(ptr, PARAM_MDC PARAM_ACTIVE, &tmp) == 0) {
3968 /* active=0 means off, anything else means on */
3969 int flag = (*tmp == '0') ? CM_EXCLUDE : 0;
3970 bool deactive_osc = memcmp(ptr, PARAM_OSC PARAM_ACTIVE,
3971 strlen(PARAM_OSC PARAM_ACTIVE)) == 0;
3974 if (!deactive_osc) {
3977 rc = server_name2index(mti->mti_svname, &index, NULL);
3982 LCONSOLE_ERROR_MSG(0x144, "%s: MDC0 can not be"
3983 " (de)activated.\n",
3985 GOTO(end, rc = -EPERM);
3989 LCONSOLE_WARN("Permanently %sactivating %s\n",
3990 flag ? "de" : "re", mti->mti_svname);
3992 rc = name_create(&logname, mti->mti_fsname, "-client");
3995 rc = mgs_modify(env, mgs, fsdb, mti, logname,
3997 deactive_osc ? "add osc" : "add mdc", flag);
3998 name_destroy(&logname);
4003 /* Add to all MDT logs for DNE */
4004 for (i = 0; i < INDEX_MAP_SIZE * 8; i++) {
4005 if (!test_bit(i, fsdb->fsdb_mdt_index_map))
4007 rc = name_create_mdt(&logname, mti->mti_fsname, i);
4010 rc = mgs_modify(env, mgs, fsdb, mti, logname,
4012 deactive_osc ? "add osc" : "add osp",
4014 name_destroy(&logname);
4020 LCONSOLE_ERROR_MSG(0x145,
4021 "Couldn't find %s in log (%d). No permanent changes were made to the config log.\n",
4022 mti->mti_svname, rc);
4023 if (test_bit(FSDB_OLDLOG14, &fsdb->fsdb_flags))
4024 LCONSOLE_ERROR_MSG(0x146,
4025 "This may be because the log is in the old 1.4 style. Consider --writeconf to update the logs.\n");
4028 /* Fall through to osc/mdc proc for deactivating live
4029 OSC/OSP on running MDT / clients. */
4031 /* Below here, let obd's XXX_process_config methods handle it */
4033 /* All lov. in proc */
4034 if (class_match_param(ptr, PARAM_LOV, NULL) == 0) {
4037 CDEBUG(D_MGS, "lov param %s\n", ptr);
4038 if (!(mti->mti_flags & LDD_F_SV_TYPE_MDT)) {
4039 LCONSOLE_ERROR_MSG(0x147, "LOV params must be "
4040 "set on the MDT, not %s. "
4047 if (mgs_log_is_empty(env, mgs, mti->mti_svname))
4048 GOTO(end, rc = -ENODEV);
4050 rc = name_create_mdt_and_lov(&logname, &mdtlovname, fsdb,
4051 mti->mti_stripe_index);
4054 rc = mgs_wlp_lcfg(env, mgs, fsdb, mti, mti->mti_svname,
4055 &mgi->mgi_bufs, mdtlovname, ptr);
4056 name_destroy(&logname);
4057 name_destroy(&mdtlovname);
4062 rc = name_create(&logname, mti->mti_fsname, "-client");
4065 rc = mgs_wlp_lcfg(env, mgs, fsdb, mti, logname, &mgi->mgi_bufs,
4066 fsdb->fsdb_clilov, ptr);
4067 name_destroy(&logname);
4071 /* All osc., mdc., llite. params in proc */
4072 if ((class_match_param(ptr, PARAM_OSC, NULL) == 0) ||
4073 (class_match_param(ptr, PARAM_MDC, NULL) == 0) ||
4074 (class_match_param(ptr, PARAM_LLITE, NULL) == 0)) {
4077 if (test_bit(FSDB_OLDLOG14, &fsdb->fsdb_flags)) {
4078 LCONSOLE_ERROR_MSG(0x148, "Upgraded client logs for %s"
4079 " cannot be modified. Consider"
4080 " updating the configuration with"
4083 GOTO(end, rc = -EINVAL);
4085 if (memcmp(ptr, PARAM_LLITE, strlen(PARAM_LLITE)) == 0) {
4086 rc = name_create(&cname, mti->mti_fsname, "-client");
4087 /* Add the client type to match the obdname in
4088 class_config_llog_handler */
4089 } else if (mti->mti_flags & LDD_F_SV_TYPE_MDT) {
4090 rc = name_create(&cname, mti->mti_svname, "-mdc");
4091 } else if (mti->mti_flags & LDD_F_SV_TYPE_OST) {
4092 rc = name_create(&cname, mti->mti_svname, "-osc");
4094 GOTO(end, rc = -EINVAL);
4099 /* Forbid direct update of llite root squash parameters.
4100 * These parameters are indirectly set via the MDT settings.
4102 if ((class_match_param(ptr, PARAM_LLITE, &tmp) == 0) &&
4103 ((memcmp(tmp, "root_squash=", 12) == 0) ||
4104 (memcmp(tmp, "nosquash_nids=", 14) == 0))) {
4105 LCONSOLE_ERROR("%s: root squash parameters can only "
4106 "be updated through MDT component\n",
4108 name_destroy(&cname);
4109 GOTO(end, rc = -EINVAL);
4112 CDEBUG(D_MGS, "%.3s param %s\n", ptr, ptr + 4);
4115 rc = name_create(&logname, mti->mti_fsname, "-client");
4117 name_destroy(&cname);
4120 rc = mgs_wlp_lcfg(env, mgs, fsdb, mti, logname, &mgi->mgi_bufs,
4123 /* osc params affect the MDT as well */
4124 if (!rc && (mti->mti_flags & LDD_F_SV_TYPE_OST)) {
4127 for (i = 0; i < INDEX_MAP_SIZE * 8; i++){
4128 if (!test_bit(i, fsdb->fsdb_mdt_index_map))
4130 name_destroy(&cname);
4131 rc = name_create_mdt_osc(&cname, mti->mti_svname,
4133 name_destroy(&logname);
4136 rc = name_create_mdt(&logname,
4137 mti->mti_fsname, i);
4140 if (!mgs_log_is_empty(env, mgs, logname)) {
4141 rc = mgs_wlp_lcfg(env, mgs, fsdb,
4151 /* For mdc activate/deactivate, it affects OSP on MDT as well */
4152 if (class_match_param(ptr, PARAM_MDC PARAM_ACTIVE, &tmp) == 0 &&
4155 char *lodname = NULL;
4156 char *param_str = NULL;
4160 /* replace mdc with osp */
4161 memcpy(ptr, PARAM_OSP, strlen(PARAM_OSP));
4162 rc = server_name2index(mti->mti_svname, &index, NULL);
4164 memcpy(ptr, PARAM_MDC, strlen(PARAM_MDC));
4168 for (i = 0; i < INDEX_MAP_SIZE * 8; i++) {
4169 if (!test_bit(i, fsdb->fsdb_mdt_index_map))
4175 name_destroy(&logname);
4176 rc = name_create_mdt(&logname, mti->mti_fsname,
4181 if (mgs_log_is_empty(env, mgs, logname))
4184 snprintf(suffix, sizeof(suffix), "-osp-MDT%04x",
4186 name_destroy(&cname);
4187 rc = name_create(&cname, mti->mti_svname,
4192 rc = mgs_wlp_lcfg(env, mgs, fsdb, mti, logname,
4193 &mgi->mgi_bufs, cname, ptr);
4197 /* Add configuration log for noitfying LOD
4198 * to active/deactive the OSP. */
4199 name_destroy(¶m_str);
4200 rc = name_create(¶m_str, cname,
4201 (*tmp == '0') ? ".active=0" :
4206 name_destroy(&lodname);
4207 rc = name_create(&lodname, logname, "-mdtlov");
4211 rc = mgs_wlp_lcfg(env, mgs, fsdb, mti, logname,
4212 &mgi->mgi_bufs, lodname,
4217 memcpy(ptr, PARAM_MDC, strlen(PARAM_MDC));
4218 name_destroy(&lodname);
4219 name_destroy(¶m_str);
4222 name_destroy(&logname);
4223 name_destroy(&cname);
4227 /* All mdt. params in proc */
4228 if (class_match_param(ptr, PARAM_MDT, &tmp) == 0) {
4232 CDEBUG(D_MGS, "%.3s param %s\n", ptr, ptr + 4);
4233 if (strncmp(mti->mti_svname, mti->mti_fsname,
4234 MTI_NAME_MAXLEN) == 0)
4235 /* device is unspecified completely? */
4236 rc = LDD_F_SV_TYPE_MDT | LDD_F_SV_ALL;
4238 rc = server_name2index(mti->mti_svname, &idx, NULL);
4241 if ((rc & LDD_F_SV_TYPE_MDT) == 0)
4243 if (rc & LDD_F_SV_ALL) {
4244 for (i = 0; i < INDEX_MAP_SIZE * 8; i++) {
4246 fsdb->fsdb_mdt_index_map))
4248 rc = name_create_mdt(&logname,
4249 mti->mti_fsname, i);
4252 rc = mgs_wlp_lcfg(env, mgs, fsdb, mti,
4253 logname, &mgi->mgi_bufs,
4255 name_destroy(&logname);
4260 if ((memcmp(tmp, "root_squash=", 12) == 0) ||
4261 (memcmp(tmp, "nosquash_nids=", 14) == 0)) {
4262 LCONSOLE_ERROR("%s: root squash parameters "
4263 "cannot be applied to a single MDT\n",
4265 GOTO(end, rc = -EINVAL);
4267 rc = mgs_wlp_lcfg(env, mgs, fsdb, mti,
4268 mti->mti_svname, &mgi->mgi_bufs,
4269 mti->mti_svname, ptr);
4274 /* root squash settings are also applied to llite
4275 * config log (see LU-1778) */
4277 ((memcmp(tmp, "root_squash=", 12) == 0) ||
4278 (memcmp(tmp, "nosquash_nids=", 14) == 0))) {
4282 rc = name_create(&cname, mti->mti_fsname, "-client");
4285 rc = name_create(&logname, mti->mti_fsname, "-client");
4287 name_destroy(&cname);
4290 rc = name_create(&ptr2, PARAM_LLITE, tmp);
4292 name_destroy(&cname);
4293 name_destroy(&logname);
4296 rc = mgs_wlp_lcfg(env, mgs, fsdb, mti, logname,
4297 &mgi->mgi_bufs, cname, ptr2);
4298 name_destroy(&ptr2);
4299 name_destroy(&logname);
4300 name_destroy(&cname);
4305 /* All mdd., ost. and osd. params in proc */
4306 if ((class_match_param(ptr, PARAM_MDD, NULL) == 0) ||
4307 (class_match_param(ptr, PARAM_LOD, NULL) == 0) ||
4308 (class_match_param(ptr, PARAM_OST, NULL) == 0) ||
4309 (class_match_param(ptr, PARAM_OSD, NULL) == 0)) {
4310 CDEBUG(D_MGS, "%.3s param %s\n", ptr, ptr + 4);
4311 if (mgs_log_is_empty(env, mgs, mti->mti_svname))
4312 GOTO(end, rc = -ENODEV);
4314 rc = mgs_wlp_lcfg(env, mgs, fsdb, mti, mti->mti_svname,
4315 &mgi->mgi_bufs, mti->mti_svname, ptr);
4319 LCONSOLE_WARN("Ignoring unrecognized param '%s'\n", ptr);
4323 CERROR("err %d on param '%s'\n", rc, ptr);
4328 int mgs_write_log_target(const struct lu_env *env, struct mgs_device *mgs,
4329 struct mgs_target_info *mti, struct fs_db *fsdb)
4336 /* set/check the new target index */
4337 rc = mgs_set_index(env, mgs, mti);
4341 if (rc == EALREADY) {
4342 LCONSOLE_WARN("Found index %d for %s, updating log\n",
4343 mti->mti_stripe_index, mti->mti_svname);
4344 /* We would like to mark old log sections as invalid
4345 and add new log sections in the client and mdt logs.
4346 But if we add new sections, then live clients will
4347 get repeat setup instructions for already running
4348 osc's. So don't update the client/mdt logs. */
4349 mti->mti_flags &= ~LDD_F_UPDATE;
4353 OBD_FAIL_TIMEOUT(OBD_FAIL_MGS_WRITE_TARGET_DELAY, cfs_fail_val > 0 ?
4356 mutex_lock(&fsdb->fsdb_mutex);
4358 if (mti->mti_flags & (LDD_F_VIRGIN | LDD_F_WRITECONF)) {
4359 /* Generate a log from scratch */
4360 if (mti->mti_flags & LDD_F_SV_TYPE_MDT) {
4361 rc = mgs_write_log_mdt(env, mgs, fsdb, mti);
4362 } else if (mti->mti_flags & LDD_F_SV_TYPE_OST) {
4363 rc = mgs_write_log_ost(env, mgs, fsdb, mti);
4365 CERROR("Unknown target type %#x, can't create log for %s\n",
4366 mti->mti_flags, mti->mti_svname);
4369 CERROR("Can't write logs for %s (%d)\n",
4370 mti->mti_svname, rc);
4374 /* Just update the params from tunefs in mgs_write_log_params */
4375 CDEBUG(D_MGS, "Update params for %s\n", mti->mti_svname);
4376 mti->mti_flags |= LDD_F_PARAM;
4379 /* allocate temporary buffer, where class_get_next_param will
4380 make copy of a current parameter */
4381 OBD_ALLOC(buf, strlen(mti->mti_params) + 1);
4383 GOTO(out_up, rc = -ENOMEM);
4384 params = mti->mti_params;
4385 while (params != NULL) {
4386 rc = class_get_next_param(¶ms, buf);
4389 /* there is no next parameter, that is
4394 CDEBUG(D_MGS, "remaining string: '%s', param: '%s'\n",
4396 rc = mgs_write_log_param(env, mgs, fsdb, mti, buf);
4401 OBD_FREE(buf, strlen(mti->mti_params) + 1);
4404 mutex_unlock(&fsdb->fsdb_mutex);
4408 int mgs_erase_log(const struct lu_env *env, struct mgs_device *mgs, char *name)
4410 struct llog_ctxt *ctxt;
4413 ctxt = llog_get_context(mgs->mgs_obd, LLOG_CONFIG_ORIG_CTXT);
4415 CERROR("%s: MGS config context doesn't exist\n",
4416 mgs->mgs_obd->obd_name);
4419 rc = llog_erase(env, ctxt, NULL, name);
4420 /* llog may not exist */
4423 llog_ctxt_put(ctxt);
4427 CERROR("%s: failed to clear log %s: %d\n",
4428 mgs->mgs_obd->obd_name, name, rc);
4433 /* erase all logs for the given fs */
4434 int mgs_erase_logs(const struct lu_env *env, struct mgs_device *mgs,
4437 struct list_head log_list;
4438 struct mgs_direntry *dirent, *n;
4439 char barrier_name[20] = {};
4442 int rc, len = strlen(fsname);
4445 mutex_lock(&mgs->mgs_mutex);
4447 /* Find all the logs in the CONFIGS directory */
4448 rc = class_dentry_readdir(env, mgs, &log_list);
4450 mutex_unlock(&mgs->mgs_mutex);
4454 if (list_empty(&log_list)) {
4455 mutex_unlock(&mgs->mgs_mutex);
4459 snprintf(barrier_name, sizeof(barrier_name) - 1, "%s-%s",
4460 fsname, BARRIER_FILENAME);
4461 /* Delete the barrier fsdb */
4462 mgs_remove_fsdb_by_name(mgs, barrier_name);
4463 /* Delete the fs db */
4464 mgs_remove_fsdb_by_name(mgs, fsname);
4465 mutex_unlock(&mgs->mgs_mutex);
4467 list_for_each_entry_safe(dirent, n, &log_list, mde_list) {
4468 list_del_init(&dirent->mde_list);
4469 suffix = strrchr(dirent->mde_name, '-');
4470 if (suffix != NULL) {
4471 if ((len == suffix - dirent->mde_name) &&
4472 (strncmp(fsname, dirent->mde_name, len) == 0)) {
4473 CDEBUG(D_MGS, "Removing log %s\n",
4475 mgs_erase_log(env, mgs, dirent->mde_name);
4479 mgs_direntry_free(dirent);
4488 /* list all logs for the given fs */
4489 int mgs_list_logs(const struct lu_env *env, struct mgs_device *mgs,
4490 struct obd_ioctl_data *data)
4492 struct list_head log_list;
4493 struct mgs_direntry *dirent, *n;
4494 char *out, *suffix, prefix[] = "config_log: ";
4495 int prefix_len = strlen(prefix);
4496 int len, remains, start = 0, rc;
4500 /* Find all the logs in the CONFIGS directory */
4501 rc = class_dentry_readdir(env, mgs, &log_list);
4505 out = data->ioc_bulk;
4506 remains = data->ioc_inllen1;
4507 /* OBD_FAIL: fetch the config_log records from the specified one */
4508 if (OBD_FAIL_CHECK(OBD_FAIL_CATLIST))
4509 data->ioc_count = cfs_fail_val;
4511 list_for_each_entry_safe(dirent, n, &log_list, mde_list) {
4512 list_del_init(&dirent->mde_list);
4513 suffix = strrchr(dirent->mde_name, '-');
4514 if (suffix != NULL) {
4515 len = prefix_len + dirent->mde_len + 1;
4516 if (remains - len < 0) {
4517 /* No enough space for this record */
4518 mgs_direntry_free(dirent);
4522 if (start < data->ioc_count) {
4523 mgs_direntry_free(dirent);
4526 len = scnprintf(out, remains, "%s%s\n", prefix,
4531 mgs_direntry_free(dirent);
4539 data->ioc_count = start;
4543 struct mgs_lcfg_fork_data {
4544 struct lustre_cfg_bufs mlfd_bufs;
4545 struct mgs_device *mlfd_mgs;
4546 struct llog_handle *mlfd_llh;
4547 const char *mlfd_oldname;
4548 const char *mlfd_newname;
4552 static bool contain_valid_fsname(char *buf, const char *fsname,
4553 int buflen, int namelen)
4555 if (buflen < namelen)
4558 if (memcmp(buf, fsname, namelen) != 0)
4561 if (buf[namelen] != '\0' && buf[namelen] != '-')
4567 static int mgs_lcfg_fork_handler(const struct lu_env *env,
4568 struct llog_handle *o_llh,
4569 struct llog_rec_hdr *o_rec, void *data)
4571 struct mgs_lcfg_fork_data *mlfd = data;
4572 struct lustre_cfg_bufs *n_bufs = &mlfd->mlfd_bufs;
4573 struct lustre_cfg *o_lcfg = (struct lustre_cfg *)(o_rec + 1);
4574 struct llog_cfg_rec *lcr;
4576 char *n_buf = mlfd->mlfd_data;
4578 int o_namelen = strlen(mlfd->mlfd_oldname);
4579 int n_namelen = strlen(mlfd->mlfd_newname);
4580 int diff = n_namelen - o_namelen;
4581 __u32 cmd = o_lcfg->lcfg_command;
4582 __u32 cnt = o_lcfg->lcfg_bufcount;
4588 o_buf = lustre_cfg_buf(o_lcfg, 0);
4589 o_buflen = o_lcfg->lcfg_buflens[0];
4590 if (contain_valid_fsname(o_buf, mlfd->mlfd_oldname, o_buflen,
4592 memcpy(n_buf, mlfd->mlfd_newname, n_namelen);
4593 memcpy(n_buf + n_namelen, o_buf + o_namelen,
4594 o_buflen - o_namelen);
4595 lustre_cfg_bufs_reset(n_bufs, n_buf);
4596 n_buf += cfs_size_round(o_buflen + diff);
4598 lustre_cfg_bufs_reset(n_bufs, o_buflen != 0 ? o_buf : NULL);
4603 struct cfg_marker *o_marker;
4604 struct cfg_marker *n_marker;
4608 CDEBUG(D_MGS, "Unknown cfg marker entry with %d "
4613 /* buf[1] is marker */
4614 o_buf = lustre_cfg_buf(o_lcfg, 1);
4615 o_buflen = o_lcfg->lcfg_buflens[1];
4616 o_marker = (struct cfg_marker *)o_buf;
4617 if (!contain_valid_fsname(o_marker->cm_tgtname,
4619 sizeof(o_marker->cm_tgtname),
4621 lustre_cfg_bufs_set(n_bufs, 1, o_marker,
4626 n_marker = (struct cfg_marker *)n_buf;
4627 *n_marker = *o_marker;
4628 memcpy(n_marker->cm_tgtname, mlfd->mlfd_newname, n_namelen);
4629 tgt_namelen = strlen(o_marker->cm_tgtname);
4630 if (tgt_namelen > o_namelen)
4631 memcpy(n_marker->cm_tgtname + n_namelen,
4632 o_marker->cm_tgtname + o_namelen,
4633 tgt_namelen - o_namelen);
4634 n_marker->cm_tgtname[tgt_namelen + diff] = '\0';
4635 lustre_cfg_bufs_set(n_bufs, 1, n_marker, sizeof(*n_marker));
4639 case LCFG_SET_PARAM: {
4640 for (i = 1; i < cnt; i++)
4641 /* buf[i] is the param value, reuse it directly */
4642 lustre_cfg_bufs_set(n_bufs, i,
4643 lustre_cfg_buf(o_lcfg, i),
4644 o_lcfg->lcfg_buflens[i]);
4650 case LCFG_POOL_DEL: {
4651 if (cnt < 3 || cnt > 4) {
4652 CDEBUG(D_MGS, "Unknown cfg pool (%x) entry with %d "
4653 "buffers\n", cmd, cnt);
4657 /* buf[1] is fsname */
4658 o_buf = lustre_cfg_buf(o_lcfg, 1);
4659 o_buflen = o_lcfg->lcfg_buflens[1];
4660 memcpy(n_buf, mlfd->mlfd_newname, n_namelen);
4661 memcpy(n_buf + n_namelen, o_buf + o_namelen,
4662 o_buflen - o_namelen);
4663 lustre_cfg_bufs_set(n_bufs, 1, n_buf, o_buflen + diff);
4664 n_buf += cfs_size_round(o_buflen + diff);
4666 /* buf[2] is the pool name, reuse it directly */
4667 lustre_cfg_bufs_set(n_bufs, 2, lustre_cfg_buf(o_lcfg, 2),
4668 o_lcfg->lcfg_buflens[2]);
4673 /* buf[3] is ostname */
4674 o_buf = lustre_cfg_buf(o_lcfg, 3);
4675 o_buflen = o_lcfg->lcfg_buflens[3];
4676 memcpy(n_buf, mlfd->mlfd_newname, n_namelen);
4677 memcpy(n_buf + n_namelen, o_buf + o_namelen,
4678 o_buflen - o_namelen);
4679 lustre_cfg_bufs_set(n_bufs, 3, n_buf, o_buflen + diff);
4684 o_buflen = o_lcfg->lcfg_buflens[1];
4685 if (o_buflen == sizeof(struct lov_desc) ||
4686 o_buflen == sizeof(struct lmv_desc)) {
4692 o_buf = lustre_cfg_buf(o_lcfg, 1);
4693 if (o_buflen == sizeof(struct lov_desc)) {
4694 struct lov_desc *o_desc =
4695 (struct lov_desc *)o_buf;
4696 struct lov_desc *n_desc =
4697 (struct lov_desc *)n_buf;
4700 o_uuid = o_desc->ld_uuid.uuid;
4701 n_uuid = n_desc->ld_uuid.uuid;
4702 uuid_len = sizeof(o_desc->ld_uuid.uuid);
4704 struct lmv_desc *o_desc =
4705 (struct lmv_desc *)o_buf;
4706 struct lmv_desc *n_desc =
4707 (struct lmv_desc *)n_buf;
4710 o_uuid = o_desc->ld_uuid.uuid;
4711 n_uuid = n_desc->ld_uuid.uuid;
4712 uuid_len = sizeof(o_desc->ld_uuid.uuid);
4715 if (unlikely(!contain_valid_fsname(o_uuid,
4716 mlfd->mlfd_oldname, uuid_len,
4718 lustre_cfg_bufs_set(n_bufs, 1, o_buf,
4723 memcpy(n_uuid, mlfd->mlfd_newname, n_namelen);
4724 uuid_len = strlen(o_uuid);
4725 if (uuid_len > o_namelen)
4726 memcpy(n_uuid + n_namelen,
4728 uuid_len - o_namelen);
4729 n_uuid[uuid_len + diff] = '\0';
4730 lustre_cfg_bufs_set(n_bufs, 1, n_buf, o_buflen);
4732 } /* else case fall through */
4733 } /* else case fall through */
4737 for (i = 1; i < cnt; i++) {
4738 o_buflen = o_lcfg->lcfg_buflens[i];
4742 o_buf = lustre_cfg_buf(o_lcfg, i);
4743 if (!contain_valid_fsname(o_buf, mlfd->mlfd_oldname,
4744 o_buflen, o_namelen)) {
4745 lustre_cfg_bufs_set(n_bufs, i, o_buf, o_buflen);
4749 memcpy(n_buf, mlfd->mlfd_newname, n_namelen);
4750 if (o_buflen == o_namelen) {
4751 lustre_cfg_bufs_set(n_bufs, i, n_buf,
4753 n_buf += cfs_size_round(n_namelen);
4757 memcpy(n_buf + n_namelen, o_buf + o_namelen,
4758 o_buflen - o_namelen);
4759 lustre_cfg_bufs_set(n_bufs, i, n_buf, o_buflen + diff);
4760 n_buf += cfs_size_round(o_buflen + diff);
4766 lcr = lustre_cfg_rec_new(cmd, n_bufs);
4770 lcr->lcr_cfg = *o_lcfg;
4771 rc = llog_write(env, mlfd->mlfd_llh, &lcr->lcr_hdr, LLOG_NEXT_IDX);
4772 lustre_cfg_rec_free(lcr);
4777 static int mgs_lcfg_fork_one(const struct lu_env *env, struct mgs_device *mgs,
4778 struct mgs_direntry *mde, const char *oldname,
4779 const char *newname)
4781 struct llog_handle *old_llh = NULL;
4782 struct llog_handle *new_llh = NULL;
4783 struct llog_ctxt *ctxt = NULL;
4784 struct mgs_lcfg_fork_data *mlfd = NULL;
4785 char *name_buf = NULL;
4787 int old_namelen = strlen(oldname);
4788 int new_namelen = strlen(newname);
4792 name_buflen = mde->mde_len + new_namelen - old_namelen;
4793 OBD_ALLOC(name_buf, name_buflen);
4797 memcpy(name_buf, newname, new_namelen);
4798 memcpy(name_buf + new_namelen, mde->mde_name + old_namelen,
4799 mde->mde_len - old_namelen);
4801 CDEBUG(D_MGS, "Fork the config-log from %s to %s\n",
4802 mde->mde_name, name_buf);
4804 ctxt = llog_get_context(mgs->mgs_obd, LLOG_CONFIG_ORIG_CTXT);
4807 rc = llog_open_create(env, ctxt, &new_llh, NULL, name_buf);
4811 rc = llog_init_handle(env, new_llh, LLOG_F_IS_PLAIN, NULL);
4815 if (unlikely(mgs_log_is_empty(env, mgs, mde->mde_name)))
4818 rc = llog_open(env, ctxt, &old_llh, NULL, mde->mde_name,
4823 rc = llog_init_handle(env, old_llh, LLOG_F_IS_PLAIN, NULL);
4827 new_llh->lgh_hdr->llh_tgtuuid = old_llh->lgh_hdr->llh_tgtuuid;
4829 OBD_ALLOC(mlfd, LLOG_MIN_CHUNK_SIZE);
4831 GOTO(out, rc = -ENOMEM);
4833 mlfd->mlfd_mgs = mgs;
4834 mlfd->mlfd_llh = new_llh;
4835 mlfd->mlfd_oldname = oldname;
4836 mlfd->mlfd_newname = newname;
4838 rc = llog_process(env, old_llh, mgs_lcfg_fork_handler, mlfd, NULL);
4839 OBD_FREE(mlfd, LLOG_MIN_CHUNK_SIZE);
4845 llog_close(env, old_llh);
4847 llog_close(env, new_llh);
4849 OBD_FREE(name_buf, name_buflen);
4851 llog_ctxt_put(ctxt);
4856 int mgs_lcfg_fork(const struct lu_env *env, struct mgs_device *mgs,
4857 const char *oldname, const char *newname)
4859 struct list_head log_list;
4860 struct mgs_direntry *dirent, *n;
4861 int olen = strlen(oldname);
4862 int nlen = strlen(newname);
4867 if (unlikely(!oldname || oldname[0] == '\0' ||
4868 !newname || newname[0] == '\0'))
4871 if (strcmp(oldname, newname) == 0)
4874 /* lock it to prevent fork/erase/register in parallel. */
4875 mutex_lock(&mgs->mgs_mutex);
4877 rc = class_dentry_readdir(env, mgs, &log_list);
4879 mutex_unlock(&mgs->mgs_mutex);
4883 if (list_empty(&log_list)) {
4884 mutex_unlock(&mgs->mgs_mutex);
4888 list_for_each_entry_safe(dirent, n, &log_list, mde_list) {
4891 ptr = strrchr(dirent->mde_name, '-');
4893 int tlen = ptr - dirent->mde_name;
4896 strncmp(newname, dirent->mde_name, tlen) == 0)
4897 GOTO(out, rc = -EEXIST);
4900 strncmp(oldname, dirent->mde_name, tlen) == 0)
4904 list_del_init(&dirent->mde_list);
4905 mgs_direntry_free(dirent);
4908 if (list_empty(&log_list)) {
4909 mutex_unlock(&mgs->mgs_mutex);
4913 list_for_each_entry(dirent, &log_list, mde_list) {
4914 rc = mgs_lcfg_fork_one(env, mgs, dirent, oldname, newname);
4922 mutex_unlock(&mgs->mgs_mutex);
4924 list_for_each_entry_safe(dirent, n, &log_list, mde_list) {
4925 list_del_init(&dirent->mde_list);
4926 mgs_direntry_free(dirent);
4929 if (rc && count > 0)
4930 mgs_erase_logs(env, mgs, newname);
4935 int mgs_lcfg_erase(const struct lu_env *env, struct mgs_device *mgs,
4941 if (unlikely(!fsname || fsname[0] == '\0'))
4944 rc = mgs_erase_logs(env, mgs, fsname);
4949 static int mgs_xattr_del(const struct lu_env *env, struct dt_object *obj)
4951 struct dt_device *dev;
4952 struct thandle *th = NULL;
4957 dev = container_of(obj->do_lu.lo_dev, struct dt_device, dd_lu_dev);
4958 th = dt_trans_create(env, dev);
4960 RETURN(PTR_ERR(th));
4962 rc = dt_declare_xattr_del(env, obj, XATTR_TARGET_RENAME, th);
4966 rc = dt_trans_start_local(env, dev, th);
4970 dt_write_lock(env, obj, 0);
4971 rc = dt_xattr_del(env, obj, XATTR_TARGET_RENAME, th);
4976 dt_write_unlock(env, obj);
4979 dt_trans_stop(env, dev, th);
4984 int mgs_lcfg_rename(const struct lu_env *env, struct mgs_device *mgs)
4986 struct list_head log_list;
4987 struct mgs_direntry *dirent, *n;
4989 struct lu_buf buf = {
4991 .lb_len = sizeof(fsname)
4997 rc = class_dentry_readdir(env, mgs, &log_list);
5001 if (list_empty(&log_list))
5004 list_for_each_entry_safe(dirent, n, &log_list, mde_list) {
5005 struct dt_object *o = NULL;
5010 list_del_init(&dirent->mde_list);
5011 ptr = strrchr(dirent->mde_name, '-');
5015 len = ptr - dirent->mde_name;
5016 if (unlikely(len >= sizeof(oldname))) {
5017 CDEBUG(D_MGS, "Skip invalid configuration file %s\n",
5022 o = local_file_find(env, mgs->mgs_los, mgs->mgs_configs_dir,
5026 CDEBUG(D_MGS, "Fail to locate file %s: rc = %d\n",
5027 dirent->mde_name, rc);
5031 rc = dt_xattr_get(env, o, &buf, XATTR_TARGET_RENAME);
5037 "Fail to get EA for %s: rc = %d\n",
5038 dirent->mde_name, rc);
5042 if (unlikely(rc == len &&
5043 memcmp(fsname, dirent->mde_name, len) == 0)) {
5044 /* The new fsname is the same as the old one. */
5045 rc = mgs_xattr_del(env, o);
5049 memcpy(oldname, dirent->mde_name, len);
5050 oldname[len] = '\0';
5052 rc = mgs_lcfg_fork_one(env, mgs, dirent, oldname, fsname);
5053 if (rc && rc != -EEXIST) {
5054 CDEBUG(D_MGS, "Fail to fork %s: rc = %d\n",
5055 dirent->mde_name, rc);
5059 rc = mgs_erase_log(env, mgs, dirent->mde_name);
5061 CDEBUG(D_MGS, "Fail to erase old %s: rc = %d\n",
5062 dirent->mde_name, rc);
5063 /* keep it there if failed to remove it. */
5068 if (o && !IS_ERR(o))
5069 lu_object_put(env, &o->do_lu);
5071 mgs_direntry_free(dirent);
5076 list_for_each_entry_safe(dirent, n, &log_list, mde_list) {
5077 list_del_init(&dirent->mde_list);
5078 mgs_direntry_free(dirent);
5084 /* Setup _mgs fsdb and log
5086 int mgs__mgs_fsdb_setup(const struct lu_env *env, struct mgs_device *mgs)
5088 struct fs_db *fsdb = NULL;
5092 rc = mgs_find_or_make_fsdb(env, mgs, MGSSELF_NAME, &fsdb);
5094 mgs_put_fsdb(mgs, fsdb);
5099 /* Setup params fsdb and log
5101 int mgs_params_fsdb_setup(const struct lu_env *env, struct mgs_device *mgs)
5103 struct fs_db *fsdb = NULL;
5104 struct llog_handle *params_llh = NULL;
5108 rc = mgs_find_or_make_fsdb(env, mgs, PARAMS_FILENAME, &fsdb);
5110 mutex_lock(&fsdb->fsdb_mutex);
5111 rc = record_start_log(env, mgs, ¶ms_llh, PARAMS_FILENAME);
5113 rc = record_end_log(env, ¶ms_llh);
5114 mutex_unlock(&fsdb->fsdb_mutex);
5115 mgs_put_fsdb(mgs, fsdb);
5121 /* Cleanup params fsdb and log
5123 int mgs_params_fsdb_cleanup(const struct lu_env *env, struct mgs_device *mgs)
5127 rc = mgs_erase_logs(env, mgs, PARAMS_FILENAME);
5128 return rc == -ENOENT ? 0 : rc;
5132 * Fill in the mgs_target_info based on data devname and param provide.
5134 * @env thread context
5136 * @mti mgs target info. We want to set this based other paramters
5137 * passed to this function. Once setup we write it to the config
5139 * @devname optional OBD device name
5140 * @param string that contains both what tunable to set and the value to
5143 * RETURN 0 for success
5144 * negative error number on failure
5146 static int mgs_set_conf_param(const struct lu_env *env, struct mgs_device *mgs,
5147 struct mgs_target_info *mti, const char *devname,
5150 struct fs_db *fsdb = NULL;
5155 /* lustre, lustre-mdtlov, lustre-client, lustre-MDT0000 */
5159 /* We have two possible cases here:
5161 * 1) the device name embedded in the param:
5162 * lustre-OST0000.osc.max_dirty_mb=32
5164 * 2) the file system name is embedded in
5165 * the param: lustre.sys.at.min=0
5167 len = strcspn(param, ".=");
5168 if (!len || param[len] == '=')
5171 if (len >= sizeof(mti->mti_svname))
5174 snprintf(mti->mti_svname, sizeof(mti->mti_svname),
5175 "%.*s", (int)len, param);
5178 if (strlcpy(mti->mti_svname, devname, sizeof(mti->mti_svname)) >=
5179 sizeof(mti->mti_svname))
5183 if (!strlen(mti->mti_svname)) {
5184 LCONSOLE_ERROR_MSG(0x14d, "No target specified: %s\n", param);
5188 dev_type = mgs_parse_devname(mti->mti_svname, mti->mti_fsname,
5189 &mti->mti_stripe_index);
5191 /* For this case we have an invalid obd device name */
5193 CDEBUG(D_MGS, "%s don't contain an index\n", mti->mti_svname);
5194 strlcpy(mti->mti_fsname, mti->mti_svname, MTI_NAME_MAXLEN);
5197 /* Not an obd device, assume devname is the fsname.
5198 * User might of only provided fsname and not obd device
5201 CDEBUG(D_MGS, "%s is seen as a file system name\n", mti->mti_svname);
5202 strlcpy(mti->mti_fsname, mti->mti_svname, MTI_NAME_MAXLEN);
5207 GOTO(out, rc = dev_type);
5209 /* param related to llite isn't allowed to set by OST or MDT */
5210 if (dev_type & LDD_F_SV_TYPE_OST ||
5211 dev_type & LDD_F_SV_TYPE_MDT) {
5212 /* param related to llite isn't allowed to set by OST
5215 if (!strncmp(param, PARAM_LLITE,
5216 sizeof(PARAM_LLITE) - 1))
5217 GOTO(out, rc = -EINVAL);
5219 /* Strip -osc or -mdc suffix from svname */
5220 if (server_make_name(dev_type, mti->mti_stripe_index,
5221 mti->mti_fsname, mti->mti_svname,
5222 sizeof(mti->mti_svname)))
5223 GOTO(out, rc = -EINVAL);
5228 if (strlcpy(mti->mti_params, param, sizeof(mti->mti_params)) >=
5229 sizeof(mti->mti_params))
5230 GOTO(out, rc = -E2BIG);
5232 CDEBUG(D_MGS, "set_conf_param fs='%s' device='%s' param='%s'\n",
5233 mti->mti_fsname, mti->mti_svname, mti->mti_params);
5235 rc = mgs_find_or_make_fsdb(env, mgs, mti->mti_fsname, &fsdb);
5239 if (!test_bit(FSDB_MGS_SELF, &fsdb->fsdb_flags) &&
5240 test_bit(FSDB_LOG_EMPTY, &fsdb->fsdb_flags)) {
5241 CERROR("No filesystem targets for %s. cfg_device from lctl "
5242 "is '%s'\n", mti->mti_fsname, mti->mti_svname);
5243 mgs_unlink_fsdb(mgs, fsdb);
5244 GOTO(out, rc = -EINVAL);
5248 * Revoke lock so everyone updates. Should be alright if
5249 * someone was already reading while we were updating the logs,
5250 * so we don't really need to hold the lock while we're
5253 mti->mti_flags = dev_type | LDD_F_PARAM;
5254 mutex_lock(&fsdb->fsdb_mutex);
5255 rc = mgs_write_log_param(env, mgs, fsdb, mti, mti->mti_params);
5256 mutex_unlock(&fsdb->fsdb_mutex);
5257 mgs_revoke_lock(mgs, fsdb, CONFIG_T_CONFIG);
5261 mgs_put_fsdb(mgs, fsdb);
5266 static int mgs_set_param2(const struct lu_env *env, struct mgs_device *mgs,
5267 struct mgs_target_info *mti, const char *param)
5269 struct fs_db *fsdb = NULL;
5274 if (strlcpy(mti->mti_params, param, sizeof(mti->mti_params)) >=
5275 sizeof(mti->mti_params))
5276 GOTO(out, rc = -E2BIG);
5278 len = strcspn(param, ".=");
5279 if (len && param[len] != '=') {
5280 struct list_head *tmp;
5284 ptr = strchr(param, '.');
5286 len = strlen(param);
5289 if (len >= sizeof(mti->mti_svname))
5290 GOTO(out, rc = -E2BIG);
5292 snprintf(mti->mti_svname, sizeof(mti->mti_svname), "%.*s",
5295 mutex_lock(&mgs->mgs_mutex);
5296 if (unlikely(list_empty(&mgs->mgs_fs_db_list))) {
5297 mutex_unlock(&mgs->mgs_mutex);
5298 GOTO(out, rc = -ENODEV);
5301 list_for_each(tmp, &mgs->mgs_fs_db_list) {
5302 fsdb = list_entry(tmp, struct fs_db, fsdb_list);
5303 if (fsdb->fsdb_has_lproc_entry &&
5304 strcmp(fsdb->fsdb_name, "params") != 0 &&
5305 strstr(param, fsdb->fsdb_name)) {
5306 snprintf(mti->mti_svname,
5307 sizeof(mti->mti_svname), "%s",
5315 snprintf(mti->mti_svname, sizeof(mti->mti_svname),
5318 mutex_unlock(&mgs->mgs_mutex);
5320 snprintf(mti->mti_svname, sizeof(mti->mti_svname), "general");
5323 CDEBUG(D_MGS, "set_param2 fs='%s' device='%s' param='%s'\n",
5324 mti->mti_fsname, mti->mti_svname, mti->mti_params);
5326 /* The return value should be the device type i.e LDD_F_SV_TYPE_XXX.
5327 * A returned error tells us we don't have a target obd device.
5329 dev_type = server_name2index(mti->mti_svname, &mti->mti_stripe_index,
5334 /* the return value should be the device type i.e LDD_F_SV_TYPE_XXX.
5335 * Strip -osc or -mdc suffix from svname
5337 if ((dev_type & LDD_F_SV_TYPE_OST || dev_type & LDD_F_SV_TYPE_MDT) &&
5338 server_make_name(dev_type, mti->mti_stripe_index,
5339 mti->mti_fsname, mti->mti_svname,
5340 sizeof(mti->mti_svname)))
5341 GOTO(out, rc = -EINVAL);
5343 rc = mgs_find_or_make_fsdb(env, mgs, PARAMS_FILENAME, &fsdb);
5347 * Revoke lock so everyone updates. Should be alright if
5348 * someone was already reading while we were updating the logs,
5349 * so we don't really need to hold the lock while we're
5352 mti->mti_flags = dev_type | LDD_F_PARAM2;
5353 mutex_lock(&fsdb->fsdb_mutex);
5354 rc = mgs_write_log_param2(env, mgs, fsdb, mti, mti->mti_params);
5355 mutex_unlock(&fsdb->fsdb_mutex);
5356 mgs_revoke_lock(mgs, fsdb, CONFIG_T_PARAMS);
5357 mgs_put_fsdb(mgs, fsdb);
5362 /* Set a permanent (config log) param for a target or fs
5364 * @lcfg buf0 may contain the device (testfs-MDT0000) name
5365 * buf1 contains the single parameter
5367 int mgs_set_param(const struct lu_env *env, struct mgs_device *mgs,
5368 struct lustre_cfg *lcfg)
5370 const char *param = lustre_cfg_string(lcfg, 1);
5371 struct mgs_target_info *mti;
5374 /* Create a fake mti to hold everything */
5379 print_lustre_cfg(lcfg);
5381 if (lcfg->lcfg_command == LCFG_PARAM) {
5382 /* For the case of lctl conf_param devname can be
5383 * lustre, lustre-mdtlov, lustre-client, lustre-MDT0000
5385 const char *devname = lustre_cfg_string(lcfg, 0);
5387 rc = mgs_set_conf_param(env, mgs, mti, devname, param);
5389 /* In the case of lctl set_param -P lcfg[0] will always
5390 * be 'general'. At least for now.
5392 rc = mgs_set_param2(env, mgs, mti, param);
5400 static int mgs_write_log_pool(const struct lu_env *env,
5401 struct mgs_device *mgs, char *logname,
5402 struct fs_db *fsdb, char *tgtname,
5403 enum lcfg_command_type cmd,
5404 char *fsname, char *poolname,
5405 char *ostname, char *comment)
5407 struct llog_handle *llh = NULL;
5410 rc = record_start_log(env, mgs, &llh, logname);
5413 rc = record_marker(env, llh, fsdb, CM_START, tgtname, comment);
5416 rc = record_base(env, llh, tgtname, 0, cmd,
5417 fsname, poolname, ostname, NULL);
5420 rc = record_marker(env, llh, fsdb, CM_END, tgtname, comment);
5422 record_end_log(env, &llh);
5426 int mgs_nodemap_cmd(const struct lu_env *env, struct mgs_device *mgs,
5427 enum lcfg_command_type cmd, const char *nodemap_name,
5438 case LCFG_NODEMAP_ADD:
5439 rc = nodemap_add(nodemap_name);
5441 case LCFG_NODEMAP_DEL:
5442 rc = nodemap_del(nodemap_name);
5444 case LCFG_NODEMAP_ADD_RANGE:
5445 rc = nodemap_parse_range(param, nid);
5448 rc = nodemap_add_range(nodemap_name, nid);
5450 case LCFG_NODEMAP_DEL_RANGE:
5451 rc = nodemap_parse_range(param, nid);
5454 rc = nodemap_del_range(nodemap_name, nid);
5456 case LCFG_NODEMAP_ADMIN:
5457 rc = kstrtobool(param, &bool_switch);
5460 rc = nodemap_set_allow_root(nodemap_name, bool_switch);
5462 case LCFG_NODEMAP_DENY_UNKNOWN:
5463 rc = kstrtobool(param, &bool_switch);
5466 rc = nodemap_set_deny_unknown(nodemap_name, bool_switch);
5468 case LCFG_NODEMAP_AUDIT_MODE:
5469 rc = kstrtobool(param, &bool_switch);
5471 rc = nodemap_set_audit_mode(nodemap_name, bool_switch);
5473 case LCFG_NODEMAP_FORBID_ENCRYPT:
5474 rc = kstrtobool(param, &bool_switch);
5476 rc = nodemap_set_forbid_encryption(nodemap_name,
5479 case LCFG_NODEMAP_MAP_MODE:
5480 if (strcmp("both", param) == 0)
5481 rc = nodemap_set_mapping_mode(nodemap_name,
5483 else if (strcmp("uid_only", param) == 0)
5484 rc = nodemap_set_mapping_mode(nodemap_name,
5485 NODEMAP_MAP_UID_ONLY);
5486 else if (strcmp("gid_only", param) == 0)
5487 rc = nodemap_set_mapping_mode(nodemap_name,
5488 NODEMAP_MAP_GID_ONLY);
5492 case LCFG_NODEMAP_TRUSTED:
5493 rc = kstrtobool(param, &bool_switch);
5496 rc = nodemap_set_trust_client_ids(nodemap_name, bool_switch);
5498 case LCFG_NODEMAP_SQUASH_UID:
5499 rc = kstrtouint(param, 10, &int_id);
5502 rc = nodemap_set_squash_uid(nodemap_name, int_id);
5504 case LCFG_NODEMAP_SQUASH_GID:
5505 rc = kstrtouint(param, 10, &int_id);
5508 rc = nodemap_set_squash_gid(nodemap_name, int_id);
5510 case LCFG_NODEMAP_ADD_UIDMAP:
5511 case LCFG_NODEMAP_ADD_GIDMAP:
5512 rc = nodemap_parse_idmap(param, idmap);
5515 if (cmd == LCFG_NODEMAP_ADD_UIDMAP)
5516 rc = nodemap_add_idmap(nodemap_name, NODEMAP_UID,
5519 rc = nodemap_add_idmap(nodemap_name, NODEMAP_GID,
5522 case LCFG_NODEMAP_DEL_UIDMAP:
5523 case LCFG_NODEMAP_DEL_GIDMAP:
5524 rc = nodemap_parse_idmap(param, idmap);
5527 if (cmd == LCFG_NODEMAP_DEL_UIDMAP)
5528 rc = nodemap_del_idmap(nodemap_name, NODEMAP_UID,
5531 rc = nodemap_del_idmap(nodemap_name, NODEMAP_GID,
5534 case LCFG_NODEMAP_SET_FILESET:
5535 rc = nodemap_set_fileset(nodemap_name, param);
5537 case LCFG_NODEMAP_SET_SEPOL:
5538 rc = nodemap_set_sepol(nodemap_name, param);
5547 int mgs_pool_cmd(const struct lu_env *env, struct mgs_device *mgs,
5548 enum lcfg_command_type cmd, char *fsname,
5549 char *poolname, char *ostname)
5554 char *label = NULL, *canceled_label = NULL;
5556 struct mgs_target_info *mti = NULL;
5557 bool checked = false;
5558 bool locked = false;
5563 rc = mgs_find_or_make_fsdb(env, mgs, fsname, &fsdb);
5565 CERROR("Can't get db for %s\n", fsname);
5568 if (test_bit(FSDB_LOG_EMPTY, &fsdb->fsdb_flags)) {
5569 CERROR("%s is not defined\n", fsname);
5571 GOTO(out_fsdb, rc = -EINVAL);
5574 label_sz = 10 + strlen(fsname) + strlen(poolname);
5576 /* check if ostname match fsname */
5577 if (ostname != NULL) {
5580 ptr = strrchr(ostname, '-');
5581 if ((ptr == NULL) ||
5582 (strncmp(fsname, ostname, ptr-ostname) != 0))
5584 label_sz += strlen(ostname);
5587 OBD_ALLOC(label, label_sz);
5589 GOTO(out_fsdb, rc = -ENOMEM);
5594 "new %s.%s", fsname, poolname);
5598 "add %s.%s.%s", fsname, poolname, ostname);
5601 OBD_ALLOC(canceled_label, label_sz);
5602 if (canceled_label == NULL)
5603 GOTO(out_label, rc = -ENOMEM);
5605 "rem %s.%s.%s", fsname, poolname, ostname);
5606 sprintf(canceled_label,
5607 "add %s.%s.%s", fsname, poolname, ostname);
5610 OBD_ALLOC(canceled_label, label_sz);
5611 if (canceled_label == NULL)
5612 GOTO(out_label, rc = -ENOMEM);
5614 "del %s.%s", fsname, poolname);
5615 sprintf(canceled_label,
5616 "new %s.%s", fsname, poolname);
5624 GOTO(out_cancel, rc = -ENOMEM);
5625 strncpy(mti->mti_svname, "lov pool", sizeof(mti->mti_svname));
5627 mutex_lock(&fsdb->fsdb_mutex);
5629 /* write pool def to all MDT logs */
5630 for (i = 0; i < INDEX_MAP_SIZE * 8; i++) {
5631 if (test_bit(i, fsdb->fsdb_mdt_index_map)) {
5632 rc = name_create_mdt_and_lov(&logname, &lovname,
5637 if (!checked && (canceled_label == NULL)) {
5638 rc = mgs_check_marker(env, mgs, fsdb, mti,
5639 logname, lovname, label);
5641 name_destroy(&logname);
5642 name_destroy(&lovname);
5644 rc = (rc == LLOG_PROC_BREAK ?
5649 if (canceled_label != NULL)
5650 rc = mgs_modify(env, mgs, fsdb, mti, logname,
5651 lovname, canceled_label,
5655 rc = mgs_write_log_pool(env, mgs, logname,
5659 name_destroy(&logname);
5660 name_destroy(&lovname);
5666 rc = name_create(&logname, fsname, "-client");
5670 if (!checked && (canceled_label == NULL)) {
5671 rc = mgs_check_marker(env, mgs, fsdb, mti, logname,
5672 fsdb->fsdb_clilov, label);
5674 name_destroy(&logname);
5675 GOTO(out_mti, rc = (rc == LLOG_PROC_BREAK ?
5679 if (canceled_label != NULL) {
5680 rc = mgs_modify(env, mgs, fsdb, mti, logname,
5681 fsdb->fsdb_clilov, canceled_label, CM_SKIP);
5683 name_destroy(&logname);
5688 rc = mgs_write_log_pool(env, mgs, logname, fsdb, fsdb->fsdb_clilov,
5689 cmd, fsname, poolname, ostname, label);
5690 mutex_unlock(&fsdb->fsdb_mutex);
5692 name_destroy(&logname);
5693 /* request for update */
5694 mgs_revoke_lock(mgs, fsdb, CONFIG_T_CONFIG);
5700 mutex_unlock(&fsdb->fsdb_mutex);
5704 if (canceled_label != NULL)
5705 OBD_FREE(canceled_label, label_sz);
5707 OBD_FREE(label, label_sz);
5710 mgs_unlink_fsdb(mgs, fsdb);
5711 mgs_put_fsdb(mgs, fsdb);