4 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License version 2 only,
8 * as published by the Free Software Foundation.
10 * This program is distributed in the hope that it will be useful, but
11 * WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * General Public License version 2 for more details (a copy is included
14 * in the LICENSE file that accompanied this code).
16 * You should have received a copy of the GNU General Public License
17 * version 2 along with this program; If not, see
18 * http://www.gnu.org/licenses/gpl-2.0.html
23 * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved.
24 * Use is subject to license terms.
26 * Copyright (c) 2011, 2017, Intel Corporation.
29 * This file is part of Lustre, http://www.lustre.org/
30 * Lustre is a trademark of Sun Microsystems, Inc.
32 * lustre/mgs/mgs_llog.c
34 * Lustre Management Server (mgs) config llog creation
36 * Author: Nathan Rutman <nathan@clusterfs.com>
37 * Author: Alex Zhuravlev <bzzz@whamcloud.com>
38 * Author: Mikhail Pershin <tappro@whamcloud.com>
41 #define DEBUG_SUBSYSTEM S_MGS
42 #define D_MGS D_CONFIG
45 #include <uapi/linux/lustre/lustre_ioctl.h>
46 #include <uapi/linux/lustre/lustre_param.h>
47 #include <lustre_sec.h>
48 #include <lustre_quota.h>
49 #include <lustre_sec.h>
51 #include "mgs_internal.h"
53 /********************** Class functions ********************/
56 * Find all logs in CONFIG directory and link then into list.
58 * \param[in] env pointer to the thread context
59 * \param[in] mgs pointer to the mgs device
60 * \param[out] log_list the list to hold the found llog name entry
62 * \retval 0 for success
63 * \retval negative error number on failure
65 int class_dentry_readdir(const struct lu_env *env, struct mgs_device *mgs,
66 struct list_head *log_list)
68 struct dt_object *dir = mgs->mgs_configs_dir;
69 const struct dt_it_ops *iops;
71 struct mgs_direntry *de;
75 INIT_LIST_HEAD(log_list);
78 LASSERT(dir->do_index_ops);
80 iops = &dir->do_index_ops->dio_it;
81 it = iops->init(env, dir, LUDA_64BITHASH);
85 rc = iops->load(env, it, 0);
91 key = (void *)iops->key(env, it);
93 CERROR("%s: key failed when listing %s: rc = %d\n",
94 mgs->mgs_obd->obd_name, MOUNT_CONFIGS_DIR,
98 key_sz = iops->key_size(env, it);
101 /* filter out "." and ".." entries */
105 if (key_sz == 2 && key[1] == '.')
109 /* filter out backup files */
110 if (lu_name_is_backup_file(key, key_sz, NULL)) {
111 CDEBUG(D_MGS, "Skipping backup file %.*s\n",
116 de = mgs_direntry_alloc(key_sz + 1);
122 memcpy(de->mde_name, key, key_sz);
123 de->mde_name[key_sz] = 0;
125 list_add(&de->mde_list, log_list);
128 rc = iops->next(env, it);
138 struct mgs_direntry *n;
140 CERROR("%s: key failed when listing %s: rc = %d\n",
141 mgs->mgs_obd->obd_name, MOUNT_CONFIGS_DIR, rc);
143 list_for_each_entry_safe(de, n, log_list, mde_list) {
144 list_del_init(&de->mde_list);
145 mgs_direntry_free(de);
152 /******************** DB functions *********************/
154 static inline int name_create(char **newname, char *prefix, char *suffix)
157 OBD_ALLOC(*newname, strlen(prefix) + strlen(suffix) + 1);
160 sprintf(*newname, "%s%s", prefix, suffix);
164 static inline void name_destroy(char **name)
167 OBD_FREE(*name, strlen(*name) + 1);
171 struct mgs_fsdb_handler_data
177 /* from the (client) config log, figure out:
178 1. which ost's/mdt's are configured (by index)
179 2. what the last config step is
180 3. COMPAT_18 osc name
182 /* It might be better to have a separate db file, instead of parsing the info
183 out of the client log. This is slow and potentially error-prone. */
184 static int mgs_fsdb_handler(const struct lu_env *env, struct llog_handle *llh,
185 struct llog_rec_hdr *rec, void *data)
187 struct mgs_fsdb_handler_data *d = data;
188 struct fs_db *fsdb = d->fsdb;
189 int cfg_len = rec->lrh_len;
190 char *cfg_buf = (char*) (rec + 1);
191 struct lustre_cfg *lcfg;
196 if (rec->lrh_type != OBD_CFG_REC) {
197 CERROR("unhandled lrh_type: %#x\n", rec->lrh_type);
201 rc = lustre_cfg_sanity_check(cfg_buf, cfg_len);
203 CERROR("Insane cfg\n");
207 lcfg = (struct lustre_cfg *)cfg_buf;
209 CDEBUG(D_INFO, "cmd %x %s %s\n", lcfg->lcfg_command,
210 lustre_cfg_string(lcfg, 0), lustre_cfg_string(lcfg, 1));
212 /* Figure out ost indicies */
213 /* lov_modify_tgts add 0:lov1 1:ost1_UUID 2(index):0 3(gen):1 */
214 if (lcfg->lcfg_command == LCFG_LOV_ADD_OBD ||
215 lcfg->lcfg_command == LCFG_LOV_DEL_OBD) {
216 rc = kstrtouint(lustre_cfg_string(lcfg, 2), 10, &index);
220 CDEBUG(D_MGS, "OST index for %s is %u (%s)\n",
221 lustre_cfg_string(lcfg, 1), index,
222 lustre_cfg_string(lcfg, 2));
223 set_bit(index, fsdb->fsdb_ost_index_map);
226 /* Figure out mdt indicies */
227 /* attach 0:MDC_uml1_mdsA_MNT_client 1:mdc 2:1d834_MNT_client_03f */
228 if ((lcfg->lcfg_command == LCFG_ATTACH) &&
229 (strcmp(lustre_cfg_string(lcfg, 1), LUSTRE_MDC_NAME) == 0)) {
230 rc = server_name2index(lustre_cfg_string(lcfg, 0),
232 if (rc != LDD_F_SV_TYPE_MDT) {
233 CWARN("Unparsable MDC name %s, assuming index 0\n",
234 lustre_cfg_string(lcfg, 0));
238 CDEBUG(D_MGS, "MDT index is %u\n", index);
239 if (!test_bit(index, fsdb->fsdb_mdt_index_map)) {
240 set_bit(index, fsdb->fsdb_mdt_index_map);
241 fsdb->fsdb_mdt_count++;
246 * figure out the old config. fsdb_gen = 0 means old log
247 * It is obsoleted and not supported anymore
249 if (fsdb->fsdb_gen == 0) {
250 CERROR("Old config format is not supported\n");
255 * compat to 1.8, check osc name used by MDT0 to OSTs, bz18548.
257 if (!test_bit(FSDB_OSCNAME18, &fsdb->fsdb_flags) &&
258 lcfg->lcfg_command == LCFG_ATTACH &&
259 strcmp(lustre_cfg_string(lcfg, 1), LUSTRE_OSC_NAME) == 0) {
260 if (OBD_OCD_VERSION_MAJOR(d->ver) == 1 &&
261 OBD_OCD_VERSION_MINOR(d->ver) <= 8) {
262 CWARN("MDT using 1.8 OSC name scheme\n");
263 set_bit(FSDB_OSCNAME18, &fsdb->fsdb_flags);
267 if (lcfg->lcfg_command == LCFG_MARKER) {
268 struct cfg_marker *marker;
269 marker = lustre_cfg_buf(lcfg, 1);
271 d->ver = marker->cm_vers;
273 /* Keep track of the latest marker step */
274 fsdb->fsdb_gen = max(fsdb->fsdb_gen, marker->cm_step);
280 /* fsdb->fsdb_mutex is already held in mgs_find_or_make_fsdb*/
281 static int mgs_get_fsdb_from_llog(const struct lu_env *env,
282 struct mgs_device *mgs,
286 struct llog_handle *loghandle;
287 struct llog_ctxt *ctxt;
288 struct mgs_fsdb_handler_data d = {
295 ctxt = llog_get_context(mgs->mgs_obd, LLOG_CONFIG_ORIG_CTXT);
296 LASSERT(ctxt != NULL);
297 rc = name_create(&logname, fsdb->fsdb_name, "-client");
300 rc = llog_open_create(env, ctxt, &loghandle, NULL, logname);
304 rc = llog_init_handle(env, loghandle, LLOG_F_IS_PLAIN, NULL);
308 if (llog_get_size(loghandle) <= 1)
309 set_bit(FSDB_LOG_EMPTY, &fsdb->fsdb_flags);
311 rc = llog_process(env, loghandle, mgs_fsdb_handler, (void *)&d, NULL);
312 CDEBUG(D_INFO, "get_db = %d\n", rc);
314 llog_close(env, loghandle);
316 name_destroy(&logname);
323 static void mgs_free_fsdb_srpc(struct fs_db *fsdb)
325 struct mgs_tgt_srpc_conf *tgtconf;
327 /* free target-specific rules */
328 while (fsdb->fsdb_srpc_tgt) {
329 tgtconf = fsdb->fsdb_srpc_tgt;
330 fsdb->fsdb_srpc_tgt = tgtconf->mtsc_next;
332 LASSERT(tgtconf->mtsc_tgt);
334 sptlrpc_rule_set_free(&tgtconf->mtsc_rset);
335 OBD_FREE(tgtconf->mtsc_tgt, strlen(tgtconf->mtsc_tgt) + 1);
336 OBD_FREE_PTR(tgtconf);
339 /* free general rules */
340 sptlrpc_rule_set_free(&fsdb->fsdb_srpc_gen);
343 static void mgs_unlink_fsdb(struct mgs_device *mgs, struct fs_db *fsdb)
345 mutex_lock(&mgs->mgs_mutex);
346 if (likely(!list_empty(&fsdb->fsdb_list))) {
347 LASSERTF(atomic_read(&fsdb->fsdb_ref) >= 2,
348 "Invalid ref %d on %s\n",
349 atomic_read(&fsdb->fsdb_ref),
352 list_del_init(&fsdb->fsdb_list);
353 /* Drop the reference on the list.*/
354 mgs_put_fsdb(mgs, fsdb);
356 mutex_unlock(&mgs->mgs_mutex);
359 /* The caller must hold mgs->mgs_mutex. */
360 static inline struct fs_db *
361 mgs_find_fsdb_noref(struct mgs_device *mgs, const char *fsname)
364 struct list_head *tmp;
366 list_for_each(tmp, &mgs->mgs_fs_db_list) {
367 fsdb = list_entry(tmp, struct fs_db, fsdb_list);
368 if (strcmp(fsdb->fsdb_name, fsname) == 0)
375 /* The caller must hold mgs->mgs_mutex. */
376 static void mgs_remove_fsdb_by_name(struct mgs_device *mgs, const char *name)
380 fsdb = mgs_find_fsdb_noref(mgs, name);
382 list_del_init(&fsdb->fsdb_list);
383 /* Drop the reference on the list.*/
384 mgs_put_fsdb(mgs, fsdb);
388 /* The caller must hold mgs->mgs_mutex. */
389 struct fs_db *mgs_find_fsdb(struct mgs_device *mgs, const char *fsname)
393 fsdb = mgs_find_fsdb_noref(mgs, fsname);
395 atomic_inc(&fsdb->fsdb_ref);
400 /* The caller must hold mgs->mgs_mutex. */
401 static struct fs_db *mgs_new_fsdb(const struct lu_env *env,
402 struct mgs_device *mgs, char *fsname)
408 if (strlen(fsname) >= sizeof(fsdb->fsdb_name)) {
409 CERROR("fsname %s is too long\n", fsname);
411 RETURN(ERR_PTR(-EINVAL));
416 RETURN(ERR_PTR(-ENOMEM));
418 strncpy(fsdb->fsdb_name, fsname, sizeof(fsdb->fsdb_name));
419 mutex_init(&fsdb->fsdb_mutex);
420 INIT_LIST_HEAD(&fsdb->fsdb_list);
421 set_bit(FSDB_UDESC, &fsdb->fsdb_flags);
423 INIT_LIST_HEAD(&fsdb->fsdb_clients);
424 atomic_set(&fsdb->fsdb_notify_phase, 0);
425 init_waitqueue_head(&fsdb->fsdb_notify_waitq);
426 init_completion(&fsdb->fsdb_notify_comp);
428 if (strcmp(fsname, MGSSELF_NAME) == 0) {
429 set_bit(FSDB_MGS_SELF, &fsdb->fsdb_flags);
430 fsdb->fsdb_mgs = mgs;
431 if (logname_is_barrier(fsname))
434 OBD_ALLOC(fsdb->fsdb_mdt_index_map, INDEX_MAP_SIZE);
435 if (!fsdb->fsdb_mdt_index_map) {
436 CERROR("No memory for MDT index maps\n");
438 GOTO(err, rc = -ENOMEM);
441 OBD_ALLOC(fsdb->fsdb_ost_index_map, INDEX_MAP_SIZE);
442 if (!fsdb->fsdb_ost_index_map) {
443 CERROR("No memory for OST index maps\n");
445 GOTO(err, rc = -ENOMEM);
448 if (logname_is_barrier(fsname))
451 rc = name_create(&fsdb->fsdb_clilov, fsname, "-clilov");
455 rc = name_create(&fsdb->fsdb_clilmv, fsname, "-clilmv");
459 /* initialise data for NID table */
460 mgs_ir_init_fs(env, mgs, fsdb);
461 lproc_mgs_add_live(mgs, fsdb);
464 if (!test_bit(FSDB_MGS_SELF, &fsdb->fsdb_flags) &&
465 strcmp(PARAMS_FILENAME, fsname) != 0) {
466 /* populate the db from the client llog */
467 rc = mgs_get_fsdb_from_llog(env, mgs, fsdb);
469 CERROR("Can't get db from client log %d\n", rc);
475 /* populate srpc rules from params llog */
476 rc = mgs_get_fsdb_srpc_from_llog(env, mgs, fsdb);
478 CERROR("Can't get db from params log %d\n", rc);
484 /* One ref is for the fsdb on the list.
485 * The other ref is for the caller. */
486 atomic_set(&fsdb->fsdb_ref, 2);
487 list_add(&fsdb->fsdb_list, &mgs->mgs_fs_db_list);
492 atomic_set(&fsdb->fsdb_ref, 1);
493 mgs_put_fsdb(mgs, fsdb);
498 static void mgs_free_fsdb(struct mgs_device *mgs, struct fs_db *fsdb)
500 LASSERT(list_empty(&fsdb->fsdb_list));
502 lproc_mgs_del_live(mgs, fsdb);
504 /* deinitialize fsr */
506 mgs_ir_fini_fs(mgs, fsdb);
508 if (fsdb->fsdb_ost_index_map)
509 OBD_FREE(fsdb->fsdb_ost_index_map, INDEX_MAP_SIZE);
510 if (fsdb->fsdb_mdt_index_map)
511 OBD_FREE(fsdb->fsdb_mdt_index_map, INDEX_MAP_SIZE);
512 name_destroy(&fsdb->fsdb_clilov);
513 name_destroy(&fsdb->fsdb_clilmv);
514 mgs_free_fsdb_srpc(fsdb);
518 void mgs_put_fsdb(struct mgs_device *mgs, struct fs_db *fsdb)
520 if (atomic_dec_and_test(&fsdb->fsdb_ref))
521 mgs_free_fsdb(mgs, fsdb);
524 int mgs_init_fsdb_list(struct mgs_device *mgs)
526 INIT_LIST_HEAD(&mgs->mgs_fs_db_list);
530 int mgs_cleanup_fsdb_list(struct mgs_device *mgs)
533 struct list_head *tmp, *tmp2;
535 mutex_lock(&mgs->mgs_mutex);
536 list_for_each_safe(tmp, tmp2, &mgs->mgs_fs_db_list) {
537 fsdb = list_entry(tmp, struct fs_db, fsdb_list);
538 list_del_init(&fsdb->fsdb_list);
539 mgs_put_fsdb(mgs, fsdb);
541 mutex_unlock(&mgs->mgs_mutex);
545 /* The caller must hold mgs->mgs_mutex. */
546 int mgs_find_or_make_fsdb_nolock(const struct lu_env *env,
547 struct mgs_device *mgs,
548 char *name, struct fs_db **dbh)
554 fsdb = mgs_find_fsdb(mgs, name);
556 fsdb = mgs_new_fsdb(env, mgs, name);
560 CDEBUG(D_MGS, "Created new db: rc = %d\n", rc);
569 int mgs_find_or_make_fsdb(const struct lu_env *env, struct mgs_device *mgs,
570 char *name, struct fs_db **dbh)
575 mutex_lock(&mgs->mgs_mutex);
576 rc = mgs_find_or_make_fsdb_nolock(env, mgs, name, dbh);
577 mutex_unlock(&mgs->mgs_mutex);
584 -1= empty client log */
585 int mgs_check_index(const struct lu_env *env,
586 struct mgs_device *mgs,
587 struct mgs_target_info *mti)
594 LASSERT(!(mti->mti_flags & LDD_F_NEED_INDEX));
596 rc = mgs_find_or_make_fsdb(env, mgs, mti->mti_fsname, &fsdb);
598 CERROR("Can't get db for %s\n", mti->mti_fsname);
602 if (test_bit(FSDB_LOG_EMPTY, &fsdb->fsdb_flags))
605 if (mti->mti_flags & LDD_F_SV_TYPE_OST)
606 imap = fsdb->fsdb_ost_index_map;
607 else if (mti->mti_flags & LDD_F_SV_TYPE_MDT)
608 imap = fsdb->fsdb_mdt_index_map;
610 GOTO(out, rc = -EINVAL);
612 if (test_bit(mti->mti_stripe_index, imap))
618 mgs_put_fsdb(mgs, fsdb);
622 static __inline__ int next_index(void *index_map, int map_len)
625 for (i = 0; i < map_len * 8; i++)
626 if (!test_bit(i, index_map)) {
629 CERROR("max index %d exceeded.\n", i);
633 /* Make the mdt/ost server obd name based on the filesystem name */
634 static bool server_make_name(u32 flags, u16 index, const char *fs,
635 char *name_buf, size_t name_buf_size)
637 bool invalid_flag = false;
639 if (flags & (LDD_F_SV_TYPE_MDT | LDD_F_SV_TYPE_OST)) {
640 if (!(flags & LDD_F_SV_ALL))
641 snprintf(name_buf, name_buf_size, "%.8s%c%s%04x", fs,
642 (flags & LDD_F_VIRGIN) ? ':' :
643 ((flags & LDD_F_WRITECONF) ? '=' : '-'),
644 (flags & LDD_F_SV_TYPE_MDT) ? "MDT" : "OST",
646 } else if (flags & LDD_F_SV_TYPE_MGS) {
647 snprintf(name_buf, name_buf_size, "MGS");
649 CERROR("unknown server type %#x\n", flags);
656 0 newly marked as in use
658 +EALREADY for update of an old index */
659 static int mgs_set_index(const struct lu_env *env,
660 struct mgs_device *mgs,
661 struct mgs_target_info *mti)
668 rc = mgs_find_or_make_fsdb(env, mgs, mti->mti_fsname, &fsdb);
670 CERROR("Can't get db for %s\n", mti->mti_fsname);
674 mutex_lock(&fsdb->fsdb_mutex);
675 if (mti->mti_flags & LDD_F_SV_TYPE_OST) {
676 imap = fsdb->fsdb_ost_index_map;
677 } else if (mti->mti_flags & LDD_F_SV_TYPE_MDT) {
678 imap = fsdb->fsdb_mdt_index_map;
680 GOTO(out_up, rc = -EINVAL);
683 if (mti->mti_flags & LDD_F_NEED_INDEX) {
684 rc = next_index(imap, INDEX_MAP_SIZE);
686 GOTO(out_up, rc = -ERANGE);
687 mti->mti_stripe_index = rc;
690 /* the last index(0xffff) is reserved for default value. */
691 if (mti->mti_stripe_index >= INDEX_MAP_SIZE * 8 - 1) {
692 LCONSOLE_ERROR_MSG(0x13f, "Server %s requested index %u, "
693 "but index must be less than %u.\n",
694 mti->mti_svname, mti->mti_stripe_index,
695 INDEX_MAP_SIZE * 8 - 1);
696 GOTO(out_up, rc = -ERANGE);
699 if (test_bit(mti->mti_stripe_index, imap)) {
700 if ((mti->mti_flags & LDD_F_VIRGIN) &&
701 !(mti->mti_flags & LDD_F_WRITECONF)) {
702 LCONSOLE_ERROR_MSG(0x140, "Server %s requested index "
703 "%d, but that index is already in "
704 "use. Use --writeconf to force\n",
706 mti->mti_stripe_index);
707 GOTO(out_up, rc = -EADDRINUSE);
709 CDEBUG(D_MGS, "Server %s updating index %d\n",
710 mti->mti_svname, mti->mti_stripe_index);
711 GOTO(out_up, rc = EALREADY);
714 set_bit(mti->mti_stripe_index, imap);
715 if (mti->mti_flags & LDD_F_SV_TYPE_MDT)
716 fsdb->fsdb_mdt_count++;
719 set_bit(mti->mti_stripe_index, imap);
720 clear_bit(FSDB_LOG_EMPTY, &fsdb->fsdb_flags);
721 if (server_make_name(mti->mti_flags & ~(LDD_F_VIRGIN | LDD_F_WRITECONF),
722 mti->mti_stripe_index, mti->mti_fsname,
723 mti->mti_svname, sizeof(mti->mti_svname))) {
724 CERROR("unknown server type %#x\n", mti->mti_flags);
725 GOTO(out_up, rc = -EINVAL);
728 CDEBUG(D_MGS, "Set index for %s to %d\n", mti->mti_svname,
729 mti->mti_stripe_index);
731 GOTO(out_up, rc = 0);
734 mutex_unlock(&fsdb->fsdb_mutex);
735 mgs_put_fsdb(mgs, fsdb);
739 struct mgs_modify_lookup {
740 struct cfg_marker mml_marker;
744 static int mgs_check_record_match(const struct lu_env *env,
745 struct llog_handle *llh,
746 struct llog_rec_hdr *rec, void *data)
748 struct cfg_marker *mc_marker = data;
749 struct cfg_marker *marker;
750 struct lustre_cfg *lcfg = REC_DATA(rec);
751 int cfg_len = REC_DATA_LEN(rec);
756 if (rec->lrh_type != OBD_CFG_REC) {
757 CDEBUG(D_ERROR, "Unhandled lrh_type: %#x\n", rec->lrh_type);
761 rc = lustre_cfg_sanity_check(lcfg, cfg_len);
763 CDEBUG(D_ERROR, "Insane cfg\n");
767 /* We only care about markers */
768 if (lcfg->lcfg_command != LCFG_MARKER)
771 marker = lustre_cfg_buf(lcfg, 1);
773 if (marker->cm_flags & CM_SKIP)
776 if ((strcmp(mc_marker->cm_comment, marker->cm_comment) == 0) &&
777 (strcmp(mc_marker->cm_tgtname, marker->cm_tgtname) == 0)) {
778 /* Found a non-skipped marker match */
779 CDEBUG(D_MGS, "Matched rec %u marker %d flag %x %s %s\n",
780 rec->lrh_index, marker->cm_step,
781 marker->cm_flags, marker->cm_tgtname,
783 rc = LLOG_PROC_BREAK;
790 * Check an existing config log record with matching comment and device
792 * 0 - checked successfully,
793 * LLOG_PROC_BREAK - record matches
796 static int mgs_check_marker(const struct lu_env *env, struct mgs_device *mgs,
797 struct fs_db *fsdb, struct mgs_target_info *mti,
798 char *logname, char *devname, char *comment)
800 struct llog_handle *loghandle;
801 struct llog_ctxt *ctxt;
802 struct cfg_marker *mc_marker;
807 LASSERT(mutex_is_locked(&fsdb->fsdb_mutex));
808 CDEBUG(D_MGS, "mgs check %s/%s/%s\n", logname, devname, comment);
810 ctxt = llog_get_context(mgs->mgs_obd, LLOG_CONFIG_ORIG_CTXT);
811 LASSERT(ctxt != NULL);
812 rc = llog_open(env, ctxt, &loghandle, NULL, logname, LLOG_OPEN_EXISTS);
819 rc = llog_init_handle(env, loghandle, LLOG_F_IS_PLAIN, NULL);
823 if (llog_get_size(loghandle) <= 1)
824 GOTO(out_close, rc = 0);
826 OBD_ALLOC_PTR(mc_marker);
828 GOTO(out_close, rc = -ENOMEM);
829 if (strlcpy(mc_marker->cm_comment, comment,
830 sizeof(mc_marker->cm_comment)) >=
831 sizeof(mc_marker->cm_comment))
832 GOTO(out_free, rc = -E2BIG);
833 if (strlcpy(mc_marker->cm_tgtname, devname,
834 sizeof(mc_marker->cm_tgtname)) >=
835 sizeof(mc_marker->cm_tgtname))
836 GOTO(out_free, rc = -E2BIG);
838 rc = llog_process(env, loghandle, mgs_check_record_match,
839 (void *)mc_marker, NULL);
842 OBD_FREE_PTR(mc_marker);
845 llog_close(env, loghandle);
847 if (rc && rc != LLOG_PROC_BREAK)
848 CDEBUG(D_ERROR, "%s: mgs check %s/%s failed: rc = %d\n",
849 mgs->mgs_obd->obd_name, mti->mti_svname, comment, rc);
854 static int mgs_modify_handler(const struct lu_env *env,
855 struct llog_handle *llh,
856 struct llog_rec_hdr *rec, void *data)
858 struct mgs_modify_lookup *mml = data;
859 struct cfg_marker *marker;
860 struct lustre_cfg *lcfg = REC_DATA(rec);
861 int cfg_len = REC_DATA_LEN(rec);
865 if (rec->lrh_type != OBD_CFG_REC) {
866 CERROR("unhandled lrh_type: %#x\n", rec->lrh_type);
870 rc = lustre_cfg_sanity_check(lcfg, cfg_len);
872 CERROR("Insane cfg\n");
876 /* We only care about markers */
877 if (lcfg->lcfg_command != LCFG_MARKER)
880 marker = lustre_cfg_buf(lcfg, 1);
881 if ((strcmp(mml->mml_marker.cm_comment, marker->cm_comment) == 0) &&
882 (strcmp(mml->mml_marker.cm_tgtname, marker->cm_tgtname) == 0) &&
883 !(marker->cm_flags & CM_SKIP)) {
884 /* Found a non-skipped marker match */
885 CDEBUG(D_MGS, "Changing rec %u marker %d %x->%x: %s %s\n",
886 rec->lrh_index, marker->cm_step,
887 marker->cm_flags, mml->mml_marker.cm_flags,
888 marker->cm_tgtname, marker->cm_comment);
889 /* Overwrite the old marker llog entry */
890 marker->cm_flags &= ~CM_EXCLUDE; /* in case we're unexcluding */
891 marker->cm_flags |= mml->mml_marker.cm_flags;
892 marker->cm_canceltime = mml->mml_marker.cm_canceltime;
893 rc = llog_write(env, llh, rec, rec->lrh_index);
902 * Modify an existing config log record (for CM_SKIP or CM_EXCLUDE)
904 * 0 - modified successfully,
905 * 1 - no modification was done
908 static int mgs_modify(const struct lu_env *env, struct mgs_device *mgs,
909 struct fs_db *fsdb, struct mgs_target_info *mti,
910 char *logname, char *devname, char *comment, int flags)
912 struct llog_handle *loghandle;
913 struct llog_ctxt *ctxt;
914 struct mgs_modify_lookup *mml;
919 LASSERT(mutex_is_locked(&fsdb->fsdb_mutex));
920 CDEBUG(D_MGS, "modify %s/%s/%s fl=%x\n", logname, devname, comment,
923 ctxt = llog_get_context(mgs->mgs_obd, LLOG_CONFIG_ORIG_CTXT);
924 LASSERT(ctxt != NULL);
925 rc = llog_open(env, ctxt, &loghandle, NULL, logname, LLOG_OPEN_EXISTS);
932 rc = llog_init_handle(env, loghandle, LLOG_F_IS_PLAIN, NULL);
936 if (llog_get_size(loghandle) <= 1)
937 GOTO(out_close, rc = 0);
941 GOTO(out_close, rc = -ENOMEM);
942 if (strlcpy(mml->mml_marker.cm_comment, comment,
943 sizeof(mml->mml_marker.cm_comment)) >=
944 sizeof(mml->mml_marker.cm_comment))
945 GOTO(out_free, rc = -E2BIG);
946 if (strlcpy(mml->mml_marker.cm_tgtname, devname,
947 sizeof(mml->mml_marker.cm_tgtname)) >=
948 sizeof(mml->mml_marker.cm_tgtname))
949 GOTO(out_free, rc = -E2BIG);
950 /* Modify mostly means cancel */
951 mml->mml_marker.cm_flags = flags;
952 mml->mml_marker.cm_canceltime = flags ? ktime_get_real_seconds() : 0;
953 mml->mml_modified = 0;
954 rc = llog_process(env, loghandle, mgs_modify_handler, (void *)mml,
956 if (!rc && !mml->mml_modified)
963 llog_close(env, loghandle);
966 CERROR("%s: modify %s/%s failed: rc = %d\n",
967 mgs->mgs_obd->obd_name, mti->mti_svname, comment, rc);
980 /** This structure is passed to mgs_replace_handler */
981 struct mgs_replace_data {
982 /* Nids are replaced for this target device */
983 struct mgs_target_info target;
984 /* Temporary modified llog */
985 struct llog_handle *temp_llh;
986 enum replace_state state;
992 * Check: a) if block should be skipped
993 * b) is it target block
998 * \retval 0 should not to be skipped
999 * \retval 1 should to be skipped
1001 static int check_markers(struct lustre_cfg *lcfg,
1002 struct mgs_replace_data *mrd)
1004 struct cfg_marker *marker;
1006 /* Track markers. Find given device */
1007 if (lcfg->lcfg_command == LCFG_MARKER) {
1008 marker = lustre_cfg_buf(lcfg, 1);
1009 /* Clean llog from records marked as CM_SKIP.
1010 CM_EXCLUDE records are used for "active" command
1011 and can be restored if needed */
1012 if ((marker->cm_flags & (CM_SKIP | CM_START)) ==
1013 (CM_SKIP | CM_START)) {
1014 mrd->state = REPLACE_SKIP;
1018 if ((marker->cm_flags & (CM_SKIP | CM_END)) ==
1019 (CM_SKIP | CM_END)) {
1020 mrd->state = REPLACE_COPY;
1024 if (strcmp(mrd->target.mti_svname, marker->cm_tgtname) == 0) {
1025 LASSERT(!(marker->cm_flags & CM_START) ||
1026 !(marker->cm_flags & CM_END));
1027 if (marker->cm_flags & CM_START) {
1028 mrd->state = REPLACE_UUID;
1029 mrd->failover = NULL;
1030 } else if (marker->cm_flags & CM_END)
1031 mrd->state = REPLACE_COPY;
1038 static int record_base(const struct lu_env *env, struct llog_handle *llh,
1039 char *cfgname, lnet_nid_t nid, int cmd,
1040 char *s1, char *s2, char *s3, char *s4)
1042 struct mgs_thread_info *mgi = mgs_env_info(env);
1043 struct llog_cfg_rec *lcr;
1046 CDEBUG(D_MGS, "lcfg %s %#x %s %s %s %s\n", cfgname,
1047 cmd, s1, s2, s3, s4);
1049 lustre_cfg_bufs_reset(&mgi->mgi_bufs, cfgname);
1051 lustre_cfg_bufs_set_string(&mgi->mgi_bufs, 1, s1);
1053 lustre_cfg_bufs_set_string(&mgi->mgi_bufs, 2, s2);
1055 lustre_cfg_bufs_set_string(&mgi->mgi_bufs, 3, s3);
1057 lustre_cfg_bufs_set_string(&mgi->mgi_bufs, 4, s4);
1059 lcr = lustre_cfg_rec_new(cmd, &mgi->mgi_bufs);
1063 lcr->lcr_cfg.lcfg_nid = nid;
1064 rc = llog_write(env, llh, &lcr->lcr_hdr, LLOG_NEXT_IDX);
1066 lustre_cfg_rec_free(lcr);
1070 "failed to write lcfg %s %#x %s %s %s %s: rc = %d\n",
1071 cfgname, cmd, s1, s2, s3, s4, rc);
1075 static inline int record_add_uuid(const struct lu_env *env,
1076 struct llog_handle *llh,
1077 uint64_t nid, char *uuid)
1079 return record_base(env, llh, NULL, nid, LCFG_ADD_UUID, uuid,
1083 static inline int record_add_conn(const struct lu_env *env,
1084 struct llog_handle *llh,
1085 char *devname, char *uuid)
1087 return record_base(env, llh, devname, 0, LCFG_ADD_CONN, uuid,
1091 static inline int record_attach(const struct lu_env *env,
1092 struct llog_handle *llh, char *devname,
1093 char *type, char *uuid)
1095 return record_base(env, llh, devname, 0, LCFG_ATTACH, type, uuid,
1099 static inline int record_setup(const struct lu_env *env,
1100 struct llog_handle *llh, char *devname,
1101 char *s1, char *s2, char *s3, char *s4)
1103 return record_base(env, llh, devname, 0, LCFG_SETUP, s1, s2, s3, s4);
1107 * \retval <0 record processing error
1108 * \retval n record is processed. No need copy original one.
1109 * \retval 0 record is not processed.
1111 static int process_command(const struct lu_env *env, struct lustre_cfg *lcfg,
1112 struct mgs_replace_data *mrd)
1119 if (mrd->state == REPLACE_UUID &&
1120 lcfg->lcfg_command == LCFG_ADD_UUID) {
1121 /* LCFG_ADD_UUID command found. Let's skip original command
1122 and add passed nids */
1123 ptr = mrd->target.mti_params;
1124 while (class_parse_nid(ptr, &nid, &ptr) == 0) {
1125 if (!mrd->nodeuuid) {
1126 rc = name_create(&mrd->nodeuuid,
1127 libcfs_nid2str(nid), "");
1129 CERROR("Can't create uuid for "
1130 "nid %s, device %s\n",
1131 libcfs_nid2str(nid),
1132 mrd->target.mti_svname);
1136 CDEBUG(D_MGS, "add nid %s with uuid %s, "
1137 "device %s\n", libcfs_nid2str(nid),
1138 mrd->target.mti_params,
1140 rc = record_add_uuid(env,
1147 mrd->failover = ptr;
1152 if (nids_added == 0) {
1153 CERROR("No new nids were added, nid %s with uuid %s, "
1154 "device %s\n", libcfs_nid2str(nid),
1155 mrd->nodeuuid ? mrd->nodeuuid : "NULL",
1156 mrd->target.mti_svname);
1157 name_destroy(&mrd->nodeuuid);
1160 mrd->state = REPLACE_SETUP;
1166 if (mrd->state == REPLACE_SETUP && lcfg->lcfg_command == LCFG_SETUP) {
1167 /* LCFG_SETUP command found. UUID should be changed */
1168 rc = record_setup(env,
1170 /* devname the same */
1171 lustre_cfg_string(lcfg, 0),
1172 /* s1 is not changed */
1173 lustre_cfg_string(lcfg, 1),
1175 /* s3 is not changed */
1176 lustre_cfg_string(lcfg, 3),
1177 /* s4 is not changed */
1178 lustre_cfg_string(lcfg, 4));
1180 name_destroy(&mrd->nodeuuid);
1184 if (mrd->failover) {
1185 ptr = mrd->failover;
1186 while (class_parse_nid(ptr, &nid, &ptr) == 0) {
1187 if (mrd->nodeuuid == NULL) {
1188 rc = name_create(&mrd->nodeuuid,
1189 libcfs_nid2str(nid),
1195 CDEBUG(D_MGS, "add nid %s for failover %s\n",
1196 libcfs_nid2str(nid), mrd->nodeuuid);
1197 rc = record_add_uuid(env, mrd->temp_llh, nid,
1200 name_destroy(&mrd->nodeuuid);
1204 rc = record_add_conn(env,
1206 lustre_cfg_string(lcfg, 0),
1208 name_destroy(&mrd->nodeuuid);
1213 if (mrd->nodeuuid) {
1214 rc = record_add_conn(env, mrd->temp_llh,
1215 lustre_cfg_string(lcfg, 0),
1217 name_destroy(&mrd->nodeuuid);
1222 mrd->state = REPLACE_DONE;
1226 /* Another commands in target device block */
1231 * Handler that called for every record in llog.
1232 * Records are processed in order they placed in llog.
1234 * \param[in] llh log to be processed
1235 * \param[in] rec current record
1236 * \param[in] data mgs_replace_data structure
1240 static int mgs_replace_nids_handler(const struct lu_env *env,
1241 struct llog_handle *llh,
1242 struct llog_rec_hdr *rec,
1245 struct mgs_replace_data *mrd;
1246 struct lustre_cfg *lcfg = REC_DATA(rec);
1247 int cfg_len = REC_DATA_LEN(rec);
1251 mrd = (struct mgs_replace_data *)data;
1253 if (rec->lrh_type != OBD_CFG_REC) {
1254 CERROR("unhandled lrh_type: %#x, cmd %x %s %s\n",
1255 rec->lrh_type, lcfg->lcfg_command,
1256 lustre_cfg_string(lcfg, 0),
1257 lustre_cfg_string(lcfg, 1));
1261 rc = lustre_cfg_sanity_check(lcfg, cfg_len);
1263 /* Do not copy any invalidated records */
1264 GOTO(skip_out, rc = 0);
1267 rc = check_markers(lcfg, mrd);
1268 if (rc || mrd->state == REPLACE_SKIP)
1269 GOTO(skip_out, rc = 0);
1271 /* Write to new log all commands outside target device block */
1272 if (mrd->state == REPLACE_COPY)
1273 GOTO(copy_out, rc = 0);
1275 if (mrd->state == REPLACE_DONE &&
1276 (lcfg->lcfg_command == LCFG_ADD_UUID ||
1277 lcfg->lcfg_command == LCFG_ADD_CONN)) {
1279 CWARN("Previous failover is deleted, but new one is "
1280 "not set. This means you configure system "
1281 "without failover or passed wrong replace_nids "
1282 "command parameters. Device %s, passed nids %s\n",
1283 mrd->target.mti_svname, mrd->target.mti_params);
1284 GOTO(skip_out, rc = 0);
1287 rc = process_command(env, lcfg, mrd);
1294 /* Record is placed in temporary llog as is */
1295 rc = llog_write(env, mrd->temp_llh, rec, LLOG_NEXT_IDX);
1297 CDEBUG(D_MGS, "Copied idx=%d, rc=%d, len=%d, cmd %x %s %s\n",
1298 rec->lrh_index, rc, rec->lrh_len, lcfg->lcfg_command,
1299 lustre_cfg_string(lcfg, 0), lustre_cfg_string(lcfg, 1));
1303 CDEBUG(D_MGS, "Skipped idx=%d, rc=%d, len=%d, cmd %x %s %s\n",
1304 rec->lrh_index, rc, rec->lrh_len, lcfg->lcfg_command,
1305 lustre_cfg_string(lcfg, 0), lustre_cfg_string(lcfg, 1));
1309 static int mgs_log_is_empty(const struct lu_env *env,
1310 struct mgs_device *mgs, char *name)
1312 struct llog_ctxt *ctxt;
1315 ctxt = llog_get_context(mgs->mgs_obd, LLOG_CONFIG_ORIG_CTXT);
1316 LASSERT(ctxt != NULL);
1318 rc = llog_is_empty(env, ctxt, name);
1319 llog_ctxt_put(ctxt);
1323 static int mgs_replace_log(const struct lu_env *env,
1324 struct obd_device *mgs,
1325 char *logname, char *devname,
1326 llog_cb_t replace_handler, void *data)
1328 struct llog_handle *orig_llh, *backup_llh;
1329 struct llog_ctxt *ctxt;
1330 struct mgs_replace_data *mrd;
1331 struct mgs_device *mgs_dev = lu2mgs_dev(mgs->obd_lu_dev);
1332 static struct obd_uuid cfg_uuid = { .uuid = "config_uuid" };
1334 int rc, rc2, buf_size;
1338 ctxt = llog_get_context(mgs, LLOG_CONFIG_ORIG_CTXT);
1339 LASSERT(ctxt != NULL);
1341 if (mgs_log_is_empty(env, mgs_dev, logname)) {
1342 /* Log is empty. Nothing to replace */
1343 GOTO(out_put, rc = 0);
1346 now = ktime_get_real_seconds();
1348 /* max time64_t in decimal fits into 20 bytes long string */
1349 buf_size = strlen(logname) + 1 + 20 + 1 + strlen(".bak") + 1;
1350 OBD_ALLOC(backup, buf_size);
1352 GOTO(out_put, rc = -ENOMEM);
1354 snprintf(backup, buf_size, "%s.%llu.bak", logname, now);
1356 rc = llog_backup(env, mgs, ctxt, ctxt, logname, backup);
1358 /* Now erase original log file. Connections are not allowed.
1359 Backup is already saved */
1360 rc = llog_erase(env, ctxt, NULL, logname);
1363 } else if (rc != -ENOENT) {
1364 CERROR("%s: can't make backup for %s: rc = %d\n",
1365 mgs->obd_name, logname, rc);
1369 /* open local log */
1370 rc = llog_open_create(env, ctxt, &orig_llh, NULL, logname);
1372 GOTO(out_restore, rc);
1374 rc = llog_init_handle(env, orig_llh, LLOG_F_IS_PLAIN, &cfg_uuid);
1376 GOTO(out_closel, rc);
1378 /* open backup llog */
1379 rc = llog_open(env, ctxt, &backup_llh, NULL, backup,
1382 GOTO(out_closel, rc);
1384 rc = llog_init_handle(env, backup_llh, LLOG_F_IS_PLAIN, NULL);
1386 GOTO(out_close, rc);
1388 if (llog_get_size(backup_llh) <= 1)
1389 GOTO(out_close, rc = 0);
1393 GOTO(out_close, rc = -ENOMEM);
1394 /* devname is only needed information to replace UUID records */
1396 strlcpy(mrd->target.mti_svname, devname,
1397 sizeof(mrd->target.mti_svname));
1398 /* data is parsed in llog callback */
1400 strlcpy(mrd->target.mti_params, data,
1401 sizeof(mrd->target.mti_params));
1402 /* Copy records to this temporary llog */
1403 mrd->temp_llh = orig_llh;
1405 rc = llog_process(env, backup_llh, replace_handler,
1409 rc2 = llog_close(NULL, backup_llh);
1413 rc2 = llog_close(NULL, orig_llh);
1419 CERROR("%s: llog should be restored: rc = %d\n",
1421 rc2 = llog_backup(env, mgs, ctxt, ctxt, backup,
1424 CERROR("%s: can't restore backup %s: rc = %d\n",
1425 mgs->obd_name, logname, rc2);
1429 OBD_FREE(backup, buf_size);
1432 llog_ctxt_put(ctxt);
1435 CERROR("%s: failed to replace log %s: rc = %d\n",
1436 mgs->obd_name, logname, rc);
1441 static int mgs_replace_nids_log(const struct lu_env *env,
1442 struct obd_device *obd,
1443 char *logname, char *devname, char *nids)
1445 CDEBUG(D_MGS, "Replace NIDs for %s in %s\n", devname, logname);
1446 return mgs_replace_log(env, obd, logname, devname,
1447 mgs_replace_nids_handler, nids);
1451 * Parse device name and get file system name and/or device index
1453 * @devname device name (ex. lustre-MDT0000)
1454 * @fsname file system name extracted from @devname and returned
1455 * to the caller (optional)
1456 * @index device index extracted from @devname and returned to
1457 * the caller (optional)
1459 * RETURN 0 success if we are only interested in
1460 * extracting fsname from devname.
1463 * LDD_F_SV_TYPE_* Besides extracting the fsname the
1464 * user also wants the index. Report to
1465 * the user the type of obd device the
1466 * returned index belongs too.
1468 * -EINVAL The obd device name is improper so
1469 * fsname could not be extracted.
1471 * -ENXIO Failed to extract the index out of
1472 * the obd device name. Most likely an
1473 * invalid obd device name
1475 static int mgs_parse_devname(char *devname, char *fsname, u32 *index)
1480 /* Extract fsname */
1482 rc = server_name2fsname(devname, fsname, NULL);
1484 CDEBUG(D_MGS, "Device name %s without fsname\n",
1491 rc = server_name2index(devname, index, NULL);
1493 CDEBUG(D_MGS, "Device name %s with wrong index\n",
1499 /* server_name2index can return LDD_F_SV_TYPE_* so always return rc */
1503 /* This is only called during replace_nids */
1504 static int only_mgs_is_running(struct obd_device *mgs_obd)
1506 /* TDB: Is global variable with devices count exists? */
1507 int num_devices = get_devices_count();
1508 int num_exports = 0;
1509 struct obd_export *exp;
1511 spin_lock(&mgs_obd->obd_dev_lock);
1512 list_for_each_entry(exp, &mgs_obd->obd_exports, exp_obd_chain) {
1513 /* skip self export */
1514 if (exp == mgs_obd->obd_self_export)
1519 if (num_exports > 1)
1520 CERROR("%s: node %s still connected during replace_nids connect_flags:%llx\n",
1522 libcfs_nid2str(exp->exp_nid_stats->nid),
1523 exp_connect_flags(exp));
1525 spin_unlock(&mgs_obd->obd_dev_lock);
1527 /* osd, MGS and MGC + MGC export (nosvc starts MGC)
1528 * (wc -l /proc/fs/lustre/devices <= 3) && (non self exports == 1)
1530 return (num_devices <= 3) && (num_exports <= 1);
1533 static int name_create_mdt(char **logname, char *fsname, int mdt_idx)
1537 if (mdt_idx > INDEX_MAP_MAX_VALUE)
1540 snprintf(postfix, sizeof(postfix), "-MDT%04x", mdt_idx);
1541 return name_create(logname, fsname, postfix);
1545 * Replace nids for \a device to \a nids values
1547 * \param obd MGS obd device
1548 * \param devname nids need to be replaced for this device
1549 * (ex. lustre-OST0000)
1550 * \param nids nids list (ex. nid1,nid2,nid3)
1554 int mgs_replace_nids(const struct lu_env *env,
1555 struct mgs_device *mgs,
1556 char *devname, char *nids)
1558 /* Assume fsname is part of device name */
1559 char fsname[MTI_NAME_MAXLEN];
1563 struct fs_db *fsdb = NULL;
1566 struct obd_device *mgs_obd = mgs->mgs_obd;
1569 /* We can only change NIDs if no other nodes are connected */
1570 spin_lock(&mgs_obd->obd_dev_lock);
1571 conn_state = mgs_obd->obd_no_conn;
1572 mgs_obd->obd_no_conn = 1;
1573 spin_unlock(&mgs_obd->obd_dev_lock);
1575 /* We can not change nids if not only MGS is started */
1576 if (!only_mgs_is_running(mgs_obd)) {
1577 CERROR("Only MGS is allowed to be started\n");
1578 GOTO(out, rc = -EINPROGRESS);
1581 /* Get fsname and index */
1582 rc = mgs_parse_devname(devname, fsname, &index);
1586 rc = mgs_find_or_make_fsdb(env, mgs, fsname, &fsdb);
1588 CERROR("%s: can't find fsdb: rc = %d\n", fsname, rc);
1592 /* Process client llogs */
1593 rc = name_create(&logname, fsname, "-client");
1596 rc = mgs_replace_nids_log(env, mgs_obd, logname, devname, nids);
1597 name_destroy(&logname);
1599 CERROR("%s: error while replacing NIDs for %s: rc = %d\n",
1600 fsname, devname, rc);
1604 /* Process MDT llogs */
1605 for (i = 0; i < INDEX_MAP_SIZE * 8; i++) {
1606 if (!test_bit(i, fsdb->fsdb_mdt_index_map))
1608 rc = name_create_mdt(&logname, fsname, i);
1611 rc = mgs_replace_nids_log(env, mgs_obd, logname, devname, nids);
1612 name_destroy(&logname);
1618 spin_lock(&mgs_obd->obd_dev_lock);
1619 mgs_obd->obd_no_conn = conn_state;
1620 spin_unlock(&mgs_obd->obd_dev_lock);
1623 mgs_put_fsdb(mgs, fsdb);
1629 * This is called for every record in llog. Some of records are
1630 * skipped, others are copied to new log as is.
1631 * Records to be skipped are
1632 * marker records marked SKIP
1633 * records enclosed between SKIP markers
1635 * \param[in] llh log to be processed
1636 * \param[in] rec current record
1637 * \param[in] data mgs_replace_data structure
1641 static int mgs_clear_config_handler(const struct lu_env *env,
1642 struct llog_handle *llh,
1643 struct llog_rec_hdr *rec, void *data)
1645 struct mgs_replace_data *mrd;
1646 struct lustre_cfg *lcfg = REC_DATA(rec);
1647 int cfg_len = REC_DATA_LEN(rec);
1652 mrd = (struct mgs_replace_data *)data;
1654 if (rec->lrh_type != OBD_CFG_REC) {
1655 CDEBUG(D_MGS, "Config llog Name=%s, Record Index=%u, "
1656 "Unhandled Record Type=%#x\n", llh->lgh_name,
1657 rec->lrh_index, rec->lrh_type);
1661 rc = lustre_cfg_sanity_check(lcfg, cfg_len);
1663 CDEBUG(D_MGS, "Config llog Name=%s, Invalid config file.",
1668 if (lcfg->lcfg_command == LCFG_MARKER) {
1669 struct cfg_marker *marker;
1671 marker = lustre_cfg_buf(lcfg, 1);
1672 if (marker->cm_flags & CM_SKIP) {
1673 if (marker->cm_flags & CM_START)
1674 mrd->state = REPLACE_SKIP;
1675 if (marker->cm_flags & CM_END)
1676 mrd->state = REPLACE_COPY;
1677 /* SKIP section started or finished */
1678 CDEBUG(D_MGS, "Skip idx=%d, rc=%d, len=%d, "
1679 "cmd %x %s %s\n", rec->lrh_index, rc,
1680 rec->lrh_len, lcfg->lcfg_command,
1681 lustre_cfg_string(lcfg, 0),
1682 lustre_cfg_string(lcfg, 1));
1686 if (mrd->state == REPLACE_SKIP) {
1687 /* record enclosed between SKIP markers, skip it */
1688 CDEBUG(D_MGS, "Skip idx=%d, rc=%d, len=%d, "
1689 "cmd %x %s %s\n", rec->lrh_index, rc,
1690 rec->lrh_len, lcfg->lcfg_command,
1691 lustre_cfg_string(lcfg, 0),
1692 lustre_cfg_string(lcfg, 1));
1697 /* Record is placed in temporary llog as is */
1698 rc = llog_write(env, mrd->temp_llh, rec, LLOG_NEXT_IDX);
1700 CDEBUG(D_MGS, "Copied idx=%d, rc=%d, len=%d, cmd %x %s %s\n",
1701 rec->lrh_index, rc, rec->lrh_len, lcfg->lcfg_command,
1702 lustre_cfg_string(lcfg, 0), lustre_cfg_string(lcfg, 1));
1707 * Directory CONFIGS/ may contain files which are not config logs to
1708 * be cleared. Skip any llogs with a non-alphanumeric character after
1709 * the last '-'. For example, fsname-MDT0000.sav, fsname-MDT0000.bak,
1710 * fsname-MDT0000.orig, fsname-MDT0000~, fsname-MDT0000.20150516, etc.
1712 static bool config_to_clear(const char *logname)
1717 str = strrchr(logname, '-');
1722 while (isalnum(str[++i]));
1723 return str[i] == '\0';
1727 * Clear config logs for \a name
1730 * \param mgs MGS device
1731 * \param name name of device or of filesystem
1732 * (ex. lustre-OST0000 or lustre) in later case all logs
1737 int mgs_clear_configs(const struct lu_env *env,
1738 struct mgs_device *mgs, const char *name)
1740 struct list_head dentry_list;
1741 struct mgs_direntry *dirent, *n;
1744 struct obd_device *mgs_obd = mgs->mgs_obd;
1749 /* Prevent clients and servers from connecting to mgs */
1750 spin_lock(&mgs_obd->obd_dev_lock);
1751 conn_state = mgs_obd->obd_no_conn;
1752 mgs_obd->obd_no_conn = 1;
1753 spin_unlock(&mgs_obd->obd_dev_lock);
1756 * config logs cannot be cleaned if anything other than
1759 if (!only_mgs_is_running(mgs_obd)) {
1760 CERROR("Only MGS is allowed to be started\n");
1761 GOTO(out, rc = -EBUSY);
1764 /* Find all the logs in the CONFIGS directory */
1765 rc = class_dentry_readdir(env, mgs, &dentry_list);
1767 CERROR("%s: cannot read config directory '%s': rc = %d\n",
1768 mgs_obd->obd_name, MOUNT_CONFIGS_DIR, rc);
1772 if (list_empty(&dentry_list)) {
1773 CERROR("%s: list empty reading config dir '%s': rc = %d\n",
1774 mgs_obd->obd_name, MOUNT_CONFIGS_DIR, -ENOENT);
1775 GOTO(out, rc = -ENOENT);
1778 OBD_ALLOC(namedash, strlen(name) + 2);
1779 if (namedash == NULL)
1780 GOTO(out, rc = -ENOMEM);
1781 snprintf(namedash, strlen(name) + 2, "%s-", name);
1783 list_for_each_entry(dirent, &dentry_list, mde_list) {
1784 if (strcmp(name, dirent->mde_name) &&
1785 strncmp(namedash, dirent->mde_name, strlen(namedash)))
1787 if (!config_to_clear(dirent->mde_name))
1789 CDEBUG(D_MGS, "%s: Clear config log %s\n",
1790 mgs_obd->obd_name, dirent->mde_name);
1791 rc = mgs_replace_log(env, mgs_obd, dirent->mde_name, NULL,
1792 mgs_clear_config_handler, NULL);
1797 list_for_each_entry_safe(dirent, n, &dentry_list, mde_list) {
1798 list_del_init(&dirent->mde_list);
1799 mgs_direntry_free(dirent);
1801 OBD_FREE(namedash, strlen(name) + 2);
1803 spin_lock(&mgs_obd->obd_dev_lock);
1804 mgs_obd->obd_no_conn = conn_state;
1805 spin_unlock(&mgs_obd->obd_dev_lock);
1810 static int record_lov_setup(const struct lu_env *env, struct llog_handle *llh,
1811 char *devname, struct lov_desc *desc)
1813 struct mgs_thread_info *mgi = mgs_env_info(env);
1814 struct llog_cfg_rec *lcr;
1817 lustre_cfg_bufs_reset(&mgi->mgi_bufs, devname);
1818 lustre_cfg_bufs_set(&mgi->mgi_bufs, 1, desc, sizeof(*desc));
1819 lcr = lustre_cfg_rec_new(LCFG_SETUP, &mgi->mgi_bufs);
1823 rc = llog_write(env, llh, &lcr->lcr_hdr, LLOG_NEXT_IDX);
1824 lustre_cfg_rec_free(lcr);
1828 static int record_lmv_setup(const struct lu_env *env, struct llog_handle *llh,
1829 char *devname, struct lmv_desc *desc)
1831 struct mgs_thread_info *mgi = mgs_env_info(env);
1832 struct llog_cfg_rec *lcr;
1835 lustre_cfg_bufs_reset(&mgi->mgi_bufs, devname);
1836 lustre_cfg_bufs_set(&mgi->mgi_bufs, 1, desc, sizeof(*desc));
1837 lcr = lustre_cfg_rec_new(LCFG_SETUP, &mgi->mgi_bufs);
1841 rc = llog_write(env, llh, &lcr->lcr_hdr, LLOG_NEXT_IDX);
1842 lustre_cfg_rec_free(lcr);
1846 static inline int record_mdc_add(const struct lu_env *env,
1847 struct llog_handle *llh,
1848 char *logname, char *mdcuuid,
1849 char *mdtuuid, char *index,
1852 return record_base(env,llh,logname,0,LCFG_ADD_MDC,
1853 mdtuuid,index,gen,mdcuuid);
1856 static inline int record_lov_add(const struct lu_env *env,
1857 struct llog_handle *llh,
1858 char *lov_name, char *ost_uuid,
1859 char *index, char *gen)
1861 return record_base(env, llh, lov_name, 0, LCFG_LOV_ADD_OBD,
1862 ost_uuid, index, gen, NULL);
1865 static inline int record_mount_opt(const struct lu_env *env,
1866 struct llog_handle *llh,
1867 char *profile, char *lov_name,
1870 return record_base(env, llh, NULL, 0, LCFG_MOUNTOPT,
1871 profile, lov_name, mdc_name, NULL);
1874 static int record_marker(const struct lu_env *env,
1875 struct llog_handle *llh,
1876 struct fs_db *fsdb, __u32 flags,
1877 char *tgtname, char *comment)
1879 struct mgs_thread_info *mgi = mgs_env_info(env);
1880 struct llog_cfg_rec *lcr;
1884 if (flags & CM_START)
1886 mgi->mgi_marker.cm_step = fsdb->fsdb_gen;
1887 mgi->mgi_marker.cm_flags = flags;
1888 mgi->mgi_marker.cm_vers = LUSTRE_VERSION_CODE;
1889 cplen = strlcpy(mgi->mgi_marker.cm_tgtname, tgtname,
1890 sizeof(mgi->mgi_marker.cm_tgtname));
1891 if (cplen >= sizeof(mgi->mgi_marker.cm_tgtname))
1893 cplen = strlcpy(mgi->mgi_marker.cm_comment, comment,
1894 sizeof(mgi->mgi_marker.cm_comment));
1895 if (cplen >= sizeof(mgi->mgi_marker.cm_comment))
1897 mgi->mgi_marker.cm_createtime = ktime_get_real_seconds();
1898 mgi->mgi_marker.cm_canceltime = 0;
1899 lustre_cfg_bufs_reset(&mgi->mgi_bufs, NULL);
1900 lustre_cfg_bufs_set(&mgi->mgi_bufs, 1, &mgi->mgi_marker,
1901 sizeof(mgi->mgi_marker));
1902 lcr = lustre_cfg_rec_new(LCFG_MARKER, &mgi->mgi_bufs);
1906 rc = llog_write(env, llh, &lcr->lcr_hdr, LLOG_NEXT_IDX);
1907 lustre_cfg_rec_free(lcr);
1911 static int record_start_log(const struct lu_env *env, struct mgs_device *mgs,
1912 struct llog_handle **llh, char *name)
1914 static struct obd_uuid cfg_uuid = { .uuid = "config_uuid" };
1915 struct llog_ctxt *ctxt;
1920 GOTO(out, rc = -EBUSY);
1922 ctxt = llog_get_context(mgs->mgs_obd, LLOG_CONFIG_ORIG_CTXT);
1924 GOTO(out, rc = -ENODEV);
1925 LASSERT(ctxt->loc_obd == mgs->mgs_obd);
1927 rc = llog_open_create(env, ctxt, llh, NULL, name);
1930 rc = llog_init_handle(env, *llh, LLOG_F_IS_PLAIN, &cfg_uuid);
1932 llog_close(env, *llh);
1934 llog_ctxt_put(ctxt);
1937 CERROR("%s: can't start log %s: rc = %d\n",
1938 mgs->mgs_obd->obd_name, name, rc);
1944 static int record_end_log(const struct lu_env *env, struct llog_handle **llh)
1948 rc = llog_close(env, *llh);
1954 /******************** config "macros" *********************/
1956 /* write an lcfg directly into a log (with markers) */
1957 static int mgs_write_log_direct(const struct lu_env *env,
1958 struct mgs_device *mgs, struct fs_db *fsdb,
1959 char *logname, struct llog_cfg_rec *lcr,
1960 char *devname, char *comment)
1962 struct llog_handle *llh = NULL;
1967 rc = record_start_log(env, mgs, &llh, logname);
1971 /* FIXME These should be a single journal transaction */
1972 rc = record_marker(env, llh, fsdb, CM_START, devname, comment);
1975 rc = llog_write(env, llh, &lcr->lcr_hdr, LLOG_NEXT_IDX);
1978 rc = record_marker(env, llh, fsdb, CM_END, devname, comment);
1982 record_end_log(env, &llh);
1986 /* write the lcfg in all logs for the given fs */
1987 static int mgs_write_log_direct_all(const struct lu_env *env,
1988 struct mgs_device *mgs,
1990 struct mgs_target_info *mti,
1991 struct llog_cfg_rec *lcr, char *devname,
1992 char *comment, int server_only)
1994 struct list_head log_list;
1995 struct mgs_direntry *dirent, *n;
1996 char *fsname = mti->mti_fsname;
1997 int rc = 0, len = strlen(fsname);
2000 /* Find all the logs in the CONFIGS directory */
2001 rc = class_dentry_readdir(env, mgs, &log_list);
2005 /* Could use fsdb index maps instead of directory listing */
2006 list_for_each_entry_safe(dirent, n, &log_list, mde_list) {
2007 list_del_init(&dirent->mde_list);
2008 /* don't write to sptlrpc rule log */
2009 if (strstr(dirent->mde_name, "-sptlrpc") != NULL)
2012 /* caller wants write server logs only */
2013 if (server_only && strstr(dirent->mde_name, "-client") != NULL)
2016 if (strlen(dirent->mde_name) <= len ||
2017 strncmp(fsname, dirent->mde_name, len) != 0 ||
2018 dirent->mde_name[len] != '-')
2021 CDEBUG(D_MGS, "Changing log %s\n", dirent->mde_name);
2022 /* Erase any old settings of this same parameter */
2023 rc = mgs_modify(env, mgs, fsdb, mti, dirent->mde_name,
2024 devname, comment, CM_SKIP);
2026 CERROR("%s: Can't modify llog %s: rc = %d\n",
2027 mgs->mgs_obd->obd_name, dirent->mde_name, rc);
2030 /* Write the new one */
2031 rc = mgs_write_log_direct(env, mgs, fsdb, dirent->mde_name,
2032 lcr, devname, comment);
2034 CERROR("%s: writing log %s: rc = %d\n",
2035 mgs->mgs_obd->obd_name, dirent->mde_name, rc);
2037 mgs_direntry_free(dirent);
2043 static int mgs_write_log_osp_to_mdt(const struct lu_env *env,
2044 struct mgs_device *mgs,
2046 struct mgs_target_info *mti,
2047 int index, char *logname);
2048 static int mgs_write_log_osc_to_lov(const struct lu_env *env,
2049 struct mgs_device *mgs,
2051 struct mgs_target_info *mti,
2052 char *logname, char *suffix, char *lovname,
2053 enum lustre_sec_part sec_part, int flags);
2054 static int name_create_mdt_and_lov(char **logname, char **lovname,
2055 struct fs_db *fsdb, int i);
2057 static int add_param(char *params, char *key, char *val)
2059 char *start = params + strlen(params);
2060 char *end = params + sizeof(((struct mgs_target_info *)0)->mti_params);
2064 keylen = strlen(key);
2065 if (start + 1 + keylen + strlen(val) >= end) {
2066 CERROR("params are too long: %s %s%s\n",
2067 params, key != NULL ? key : "", val);
2071 sprintf(start, " %s%s", key != NULL ? key : "", val);
2076 * Walk through client config log record and convert the related records
2079 static int mgs_steal_client_llog_handler(const struct lu_env *env,
2080 struct llog_handle *llh,
2081 struct llog_rec_hdr *rec, void *data)
2083 struct mgs_device *mgs;
2084 struct obd_device *obd;
2085 struct mgs_target_info *mti, *tmti;
2087 int cfg_len = rec->lrh_len;
2088 char *cfg_buf = (char*) (rec + 1);
2089 struct lustre_cfg *lcfg;
2091 struct llog_handle *mdt_llh = NULL;
2092 static int got_an_osc_or_mdc = 0;
2093 /* 0: not found any osc/mdc;
2097 static int last_step = -1;
2102 mti = ((struct temp_comp*)data)->comp_mti;
2103 tmti = ((struct temp_comp*)data)->comp_tmti;
2104 fsdb = ((struct temp_comp*)data)->comp_fsdb;
2105 obd = ((struct temp_comp *)data)->comp_obd;
2106 mgs = lu2mgs_dev(obd->obd_lu_dev);
2109 if (rec->lrh_type != OBD_CFG_REC) {
2110 CERROR("unhandled lrh_type: %#x\n", rec->lrh_type);
2114 rc = lustre_cfg_sanity_check(cfg_buf, cfg_len);
2116 CERROR("Insane cfg\n");
2120 lcfg = (struct lustre_cfg *)cfg_buf;
2122 if (lcfg->lcfg_command == LCFG_MARKER) {
2123 struct cfg_marker *marker;
2124 marker = lustre_cfg_buf(lcfg, 1);
2125 if (!strncmp(marker->cm_comment, "add osc", 7) &&
2126 (marker->cm_flags & CM_START) &&
2127 !(marker->cm_flags & CM_SKIP)) {
2128 got_an_osc_or_mdc = 1;
2129 cplen = strlcpy(tmti->mti_svname, marker->cm_tgtname,
2130 sizeof(tmti->mti_svname));
2131 if (cplen >= sizeof(tmti->mti_svname))
2133 rc = record_start_log(env, mgs, &mdt_llh,
2137 rc = record_marker(env, mdt_llh, fsdb, CM_START,
2138 mti->mti_svname, "add osc(copied)");
2139 record_end_log(env, &mdt_llh);
2140 last_step = marker->cm_step;
2143 if (!strncmp(marker->cm_comment, "add osc", 7) &&
2144 (marker->cm_flags & CM_END) &&
2145 !(marker->cm_flags & CM_SKIP)) {
2146 LASSERT(last_step == marker->cm_step);
2148 got_an_osc_or_mdc = 0;
2149 memset(tmti, 0, sizeof(*tmti));
2150 rc = record_start_log(env, mgs, &mdt_llh,
2154 rc = record_marker(env, mdt_llh, fsdb, CM_END,
2155 mti->mti_svname, "add osc(copied)");
2156 record_end_log(env, &mdt_llh);
2159 if (!strncmp(marker->cm_comment, "add mdc", 7) &&
2160 (marker->cm_flags & CM_START) &&
2161 !(marker->cm_flags & CM_SKIP)) {
2162 got_an_osc_or_mdc = 2;
2163 last_step = marker->cm_step;
2164 memcpy(tmti->mti_svname, marker->cm_tgtname,
2165 strlen(marker->cm_tgtname));
2169 if (!strncmp(marker->cm_comment, "add mdc", 7) &&
2170 (marker->cm_flags & CM_END) &&
2171 !(marker->cm_flags & CM_SKIP)) {
2172 LASSERT(last_step == marker->cm_step);
2174 got_an_osc_or_mdc = 0;
2175 memset(tmti, 0, sizeof(*tmti));
2180 if (got_an_osc_or_mdc == 0 || last_step < 0)
2183 if (lcfg->lcfg_command == LCFG_ADD_UUID) {
2184 __u64 nodenid = lcfg->lcfg_nid;
2186 if (strlen(tmti->mti_uuid) == 0) {
2187 /* target uuid not set, this config record is before
2188 * LCFG_SETUP, this nid is one of target node nid.
2190 tmti->mti_nids[tmti->mti_nid_count] = nodenid;
2191 tmti->mti_nid_count++;
2193 char nidstr[LNET_NIDSTR_SIZE];
2195 /* failover node nid */
2196 libcfs_nid2str_r(nodenid, nidstr, sizeof(nidstr));
2197 rc = add_param(tmti->mti_params, PARAM_FAILNODE,
2204 if (lcfg->lcfg_command == LCFG_SETUP) {
2207 target = lustre_cfg_string(lcfg, 1);
2208 memcpy(tmti->mti_uuid, target, strlen(target));
2212 /* ignore client side sptlrpc_conf_log */
2213 if (lcfg->lcfg_command == LCFG_SPTLRPC_CONF)
2216 if (lcfg->lcfg_command == LCFG_ADD_MDC &&
2217 strstr(lustre_cfg_string(lcfg, 0), "-clilmv") != NULL) {
2220 if (sscanf(lustre_cfg_buf(lcfg, 2), "%d", &index) != 1)
2223 memcpy(tmti->mti_fsname, mti->mti_fsname,
2224 strlen(mti->mti_fsname));
2225 tmti->mti_stripe_index = index;
2227 rc = mgs_write_log_osp_to_mdt(env, mgs, fsdb, tmti,
2228 mti->mti_stripe_index,
2230 memset(tmti, 0, sizeof(*tmti));
2234 if (lcfg->lcfg_command == LCFG_LOV_ADD_OBD) {
2237 char *logname, *lovname;
2239 rc = name_create_mdt_and_lov(&logname, &lovname, fsdb,
2240 mti->mti_stripe_index);
2243 sprintf(mdt_index, "-MDT%04x", mti->mti_stripe_index);
2245 if (sscanf(lustre_cfg_buf(lcfg, 2), "%d", &index) != 1) {
2246 name_destroy(&logname);
2247 name_destroy(&lovname);
2251 tmti->mti_stripe_index = index;
2252 rc = mgs_write_log_osc_to_lov(env, mgs, fsdb, tmti, logname,
2255 name_destroy(&logname);
2256 name_destroy(&lovname);
2262 /* fsdb->fsdb_mutex is already held in mgs_write_log_target*/
2263 /* stealed from mgs_get_fsdb_from_llog*/
2264 static int mgs_steal_llog_for_mdt_from_client(const struct lu_env *env,
2265 struct mgs_device *mgs,
2267 struct temp_comp* comp)
2269 struct llog_handle *loghandle;
2270 struct mgs_target_info *tmti;
2271 struct llog_ctxt *ctxt;
2276 ctxt = llog_get_context(mgs->mgs_obd, LLOG_CONFIG_ORIG_CTXT);
2277 LASSERT(ctxt != NULL);
2279 OBD_ALLOC_PTR(tmti);
2281 GOTO(out_ctxt, rc = -ENOMEM);
2283 comp->comp_tmti = tmti;
2284 comp->comp_obd = mgs->mgs_obd;
2286 rc = llog_open(env, ctxt, &loghandle, NULL, client_name,
2294 rc = llog_init_handle(env, loghandle, LLOG_F_IS_PLAIN, NULL);
2296 GOTO(out_close, rc);
2298 rc = llog_process_or_fork(env, loghandle, mgs_steal_client_llog_handler,
2299 (void *)comp, NULL, false);
2300 CDEBUG(D_MGS, "steal llog re = %d\n", rc);
2302 llog_close(env, loghandle);
2306 llog_ctxt_put(ctxt);
2310 /* lmv is the second thing for client logs */
2311 /* copied from mgs_write_log_lov. Please refer to that. */
2312 static int mgs_write_log_lmv(const struct lu_env *env,
2313 struct mgs_device *mgs,
2315 struct mgs_target_info *mti,
2316 char *logname, char *lmvname)
2318 struct llog_handle *llh = NULL;
2319 struct lmv_desc *lmvdesc;
2324 CDEBUG(D_MGS, "Writing lmv(%s) log for %s\n", lmvname,logname);
2326 OBD_ALLOC_PTR(lmvdesc);
2327 if (lmvdesc == NULL)
2329 lmvdesc->ld_active_tgt_count = 0;
2330 lmvdesc->ld_tgt_count = 0;
2331 sprintf((char*)lmvdesc->ld_uuid.uuid, "%s_UUID", lmvname);
2332 uuid = (char *)lmvdesc->ld_uuid.uuid;
2334 rc = record_start_log(env, mgs, &llh, logname);
2337 rc = record_marker(env, llh, fsdb, CM_START, lmvname, "lmv setup");
2340 rc = record_attach(env, llh, lmvname, "lmv", uuid);
2343 rc = record_lmv_setup(env, llh, lmvname, lmvdesc);
2346 rc = record_marker(env, llh, fsdb, CM_END, lmvname, "lmv setup");
2350 record_end_log(env, &llh);
2352 OBD_FREE_PTR(lmvdesc);
2356 /* lov is the first thing in the mdt and client logs */
2357 static int mgs_write_log_lov(const struct lu_env *env, struct mgs_device *mgs,
2358 struct fs_db *fsdb, struct mgs_target_info *mti,
2359 char *logname, char *lovname)
2361 struct llog_handle *llh = NULL;
2362 struct lov_desc *lovdesc;
2367 CDEBUG(D_MGS, "Writing lov(%s) log for %s\n", lovname, logname);
2370 #01 L attach 0:lov_mdsA 1:lov 2:71ccb_lov_mdsA_19f961a9e1
2371 #02 L lov_setup 0:lov_mdsA 1:(struct lov_desc)
2372 uuid=lov1_UUID, stripe count=1, size=1048576, offset=0, pattern=0
2375 /* FIXME just make lov_setup accept empty desc (put uuid in buf 2) */
2376 OBD_ALLOC_PTR(lovdesc);
2377 if (lovdesc == NULL)
2379 lovdesc->ld_magic = LOV_DESC_MAGIC;
2380 lovdesc->ld_tgt_count = 0;
2381 /* Defaults. Can be changed later by lcfg config_param */
2382 lovdesc->ld_default_stripe_count = 1;
2383 lovdesc->ld_pattern = LOV_PATTERN_RAID0;
2384 lovdesc->ld_default_stripe_size = LOV_DESC_STRIPE_SIZE_DEFAULT;
2385 lovdesc->ld_default_stripe_offset = -1;
2386 lovdesc->ld_qos_maxage = LOV_DESC_QOS_MAXAGE_DEFAULT;
2387 sprintf((char*)lovdesc->ld_uuid.uuid, "%s_UUID", lovname);
2388 /* can these be the same? */
2389 uuid = (char *)lovdesc->ld_uuid.uuid;
2391 /* This should always be the first entry in a log.
2392 rc = mgs_clear_log(obd, logname); */
2393 rc = record_start_log(env, mgs, &llh, logname);
2396 /* FIXME these should be a single journal transaction */
2397 rc = record_marker(env, llh, fsdb, CM_START, lovname, "lov setup");
2400 rc = record_attach(env, llh, lovname, "lov", uuid);
2403 rc = record_lov_setup(env, llh, lovname, lovdesc);
2406 rc = record_marker(env, llh, fsdb, CM_END, lovname, "lov setup");
2411 record_end_log(env, &llh);
2413 OBD_FREE_PTR(lovdesc);
2417 /* add failnids to open log */
2418 static int mgs_write_log_failnids(const struct lu_env *env,
2419 struct mgs_target_info *mti,
2420 struct llog_handle *llh,
2423 char *failnodeuuid = NULL;
2424 char *ptr = mti->mti_params;
2429 #03 L add_uuid nid=uml1@tcp(0x20000c0a80201) nal=90 0: 1:uml1_UUID
2430 #04 L add_uuid nid=1@elan(0x1000000000001) nal=90 0: 1:uml1_UUID
2431 #05 L setup 0:OSC_uml1_ost1_mdsA 1:ost1_UUID 2:uml1_UUID
2432 #06 L add_uuid nid=uml2@tcp(0x20000c0a80202) nal=90 0: 1:uml2_UUID
2433 #0x L add_uuid nid=2@elan(0x1000000000002) nal=90 0: 1:uml2_UUID
2434 #07 L add_conn 0:OSC_uml1_ost1_mdsA 1:uml2_UUID
2438 * Pull failnid info out of params string, which may contain something
2439 * like "<nid1>,<nid2>:<nid3>,<nid4>". class_parse_nid() does not
2440 * complain about abnormal inputs like ",:<nid1>", "<nid1>:,<nid2>",
2441 * etc. However, convert_hostnames() should have caught those.
2443 while (class_find_param(ptr, PARAM_FAILNODE, &ptr) == 0) {
2444 while (class_parse_nid(ptr, &nid, &ptr) == 0) {
2445 char nidstr[LNET_NIDSTR_SIZE];
2447 if (failnodeuuid == NULL) {
2448 /* We don't know the failover node name,
2449 * so just use the first nid as the uuid */
2450 libcfs_nid2str_r(nid, nidstr, sizeof(nidstr));
2451 rc = name_create(&failnodeuuid, nidstr, "");
2455 CDEBUG(D_MGS, "add nid %s for failover uuid %s, "
2457 libcfs_nid2str_r(nid, nidstr, sizeof(nidstr)),
2458 failnodeuuid, cliname);
2459 rc = record_add_uuid(env, llh, nid, failnodeuuid);
2461 * If *ptr is ':', we have added all NIDs for
2465 rc = record_add_conn(env, llh, cliname,
2467 name_destroy(&failnodeuuid);
2468 failnodeuuid = NULL;
2472 rc = record_add_conn(env, llh, cliname, failnodeuuid);
2473 name_destroy(&failnodeuuid);
2474 failnodeuuid = NULL;
2481 static int mgs_write_log_mdc_to_lmv(const struct lu_env *env,
2482 struct mgs_device *mgs,
2484 struct mgs_target_info *mti,
2485 char *logname, char *lmvname)
2487 struct llog_handle *llh = NULL;
2488 char *mdcname = NULL;
2489 char *nodeuuid = NULL;
2490 char *mdcuuid = NULL;
2491 char *lmvuuid = NULL;
2493 char nidstr[LNET_NIDSTR_SIZE];
2497 if (mgs_log_is_empty(env, mgs, logname)) {
2498 CERROR("log is empty! Logical error\n");
2502 CDEBUG(D_MGS, "adding mdc for %s to log %s:lmv(%s)\n",
2503 mti->mti_svname, logname, lmvname);
2505 libcfs_nid2str_r(mti->mti_nids[0], nidstr, sizeof(nidstr));
2506 rc = name_create(&nodeuuid, nidstr, "");
2509 rc = name_create(&mdcname, mti->mti_svname, "-mdc");
2512 rc = name_create(&mdcuuid, mdcname, "_UUID");
2515 rc = name_create(&lmvuuid, lmvname, "_UUID");
2519 rc = record_start_log(env, mgs, &llh, logname);
2522 rc = record_marker(env, llh, fsdb, CM_START, mti->mti_svname,
2526 for (i = 0; i < mti->mti_nid_count; i++) {
2527 CDEBUG(D_MGS, "add nid %s for mdt\n",
2528 libcfs_nid2str_r(mti->mti_nids[i],
2529 nidstr, sizeof(nidstr)));
2531 rc = record_add_uuid(env, llh, mti->mti_nids[i], nodeuuid);
2536 rc = record_attach(env, llh, mdcname, LUSTRE_MDC_NAME, lmvuuid);
2539 rc = record_setup(env, llh, mdcname, mti->mti_uuid, nodeuuid,
2543 rc = mgs_write_log_failnids(env, mti, llh, mdcname);
2546 snprintf(index, sizeof(index), "%d", mti->mti_stripe_index);
2547 rc = record_mdc_add(env, llh, lmvname, mdcuuid, mti->mti_uuid,
2551 rc = record_marker(env, llh, fsdb, CM_END, mti->mti_svname,
2556 record_end_log(env, &llh);
2558 name_destroy(&lmvuuid);
2559 name_destroy(&mdcuuid);
2560 name_destroy(&mdcname);
2561 name_destroy(&nodeuuid);
2565 static inline int name_create_lov(char **lovname, char *mdtname,
2566 struct fs_db *fsdb, int index)
2569 if (index == 0 && test_bit(FSDB_OSCNAME18, &fsdb->fsdb_flags))
2570 return name_create(lovname, fsdb->fsdb_name, "-mdtlov");
2572 return name_create(lovname, mdtname, "-mdtlov");
2575 static int name_create_mdt_and_lov(char **logname, char **lovname,
2576 struct fs_db *fsdb, int i)
2580 rc = name_create_mdt(logname, fsdb->fsdb_name, i);
2584 if (i == 0 && test_bit(FSDB_OSCNAME18, &fsdb->fsdb_flags))
2585 rc = name_create(lovname, fsdb->fsdb_name, "-mdtlov");
2587 rc = name_create(lovname, *logname, "-mdtlov");
2589 name_destroy(logname);
2595 static inline int name_create_mdt_osc(char **oscname, char *ostname,
2596 struct fs_db *fsdb, int i)
2600 if (i == 0 && test_bit(FSDB_OSCNAME18, &fsdb->fsdb_flags))
2601 sprintf(suffix, "-osc");
2603 sprintf(suffix, "-osc-MDT%04x", i);
2604 return name_create(oscname, ostname, suffix);
2607 /* add new mdc to already existent MDS */
2608 static int mgs_write_log_osp_to_mdt(const struct lu_env *env,
2609 struct mgs_device *mgs,
2611 struct mgs_target_info *mti,
2612 int mdt_index, char *logname)
2614 struct llog_handle *llh = NULL;
2615 char *nodeuuid = NULL;
2616 char *ospname = NULL;
2617 char *lovuuid = NULL;
2618 char *mdtuuid = NULL;
2619 char *svname = NULL;
2620 char *mdtname = NULL;
2621 char *lovname = NULL;
2623 char nidstr[LNET_NIDSTR_SIZE];
2627 if (mgs_log_is_empty(env, mgs, mti->mti_svname)) {
2628 CERROR("log is empty! Logical error\n");
2632 CDEBUG(D_MGS, "adding osp index %d to %s\n", mti->mti_stripe_index,
2635 rc = name_create_mdt(&mdtname, fsdb->fsdb_name, mti->mti_stripe_index);
2639 libcfs_nid2str_r(mti->mti_nids[0], nidstr, sizeof(nidstr));
2640 rc = name_create(&nodeuuid, nidstr, "");
2642 GOTO(out_destory, rc);
2644 rc = name_create(&svname, mdtname, "-osp");
2646 GOTO(out_destory, rc);
2648 sprintf(index_str, "-MDT%04x", mdt_index);
2649 rc = name_create(&ospname, svname, index_str);
2651 GOTO(out_destory, rc);
2653 rc = name_create_lov(&lovname, logname, fsdb, mdt_index);
2655 GOTO(out_destory, rc);
2657 rc = name_create(&lovuuid, lovname, "_UUID");
2659 GOTO(out_destory, rc);
2661 rc = name_create(&mdtuuid, mdtname, "_UUID");
2663 GOTO(out_destory, rc);
2665 rc = record_start_log(env, mgs, &llh, logname);
2667 GOTO(out_destory, rc);
2669 rc = record_marker(env, llh, fsdb, CM_START, mti->mti_svname,
2672 GOTO(out_destory, rc);
2674 for (i = 0; i < mti->mti_nid_count; i++) {
2675 CDEBUG(D_MGS, "add nid %s for mdt\n",
2676 libcfs_nid2str_r(mti->mti_nids[i],
2677 nidstr, sizeof(nidstr)));
2678 rc = record_add_uuid(env, llh, mti->mti_nids[i], nodeuuid);
2683 rc = record_attach(env, llh, ospname, LUSTRE_OSP_NAME, lovuuid);
2687 rc = record_setup(env, llh, ospname, mti->mti_uuid, nodeuuid,
2692 rc = mgs_write_log_failnids(env, mti, llh, ospname);
2696 /* Add mdc(osp) to lod */
2697 snprintf(index_str, sizeof(index_str), "%d", mti->mti_stripe_index);
2698 rc = record_base(env, llh, lovname, 0, LCFG_ADD_MDC, mti->mti_uuid,
2699 index_str, "1", NULL);
2703 rc = record_marker(env, llh, fsdb, CM_END, mti->mti_svname, "add osp");
2708 record_end_log(env, &llh);
2711 name_destroy(&mdtuuid);
2712 name_destroy(&lovuuid);
2713 name_destroy(&lovname);
2714 name_destroy(&ospname);
2715 name_destroy(&svname);
2716 name_destroy(&nodeuuid);
2717 name_destroy(&mdtname);
2721 static int mgs_write_log_mdt0(const struct lu_env *env,
2722 struct mgs_device *mgs,
2724 struct mgs_target_info *mti)
2726 char *log = mti->mti_svname;
2727 struct llog_handle *llh = NULL;
2728 struct obd_uuid *uuid;
2731 char *ptr = mti->mti_params;
2732 int rc = 0, failout = 0;
2735 OBD_ALLOC_PTR(uuid);
2739 if (class_find_param(ptr, PARAM_FAILMODE, &ptr) == 0)
2740 failout = (strncmp(ptr, "failout", 7) == 0);
2742 rc = name_create(&lovname, log, "-mdtlov");
2745 if (mgs_log_is_empty(env, mgs, log)) {
2746 rc = mgs_write_log_lov(env, mgs, fsdb, mti, log, lovname);
2751 sprintf(mdt_index, "%d", mti->mti_stripe_index);
2753 rc = record_start_log(env, mgs, &llh, log);
2757 /* add MDT itself */
2759 /* FIXME this whole fn should be a single journal transaction */
2760 sprintf(uuid->uuid, "%s_UUID", log);
2761 rc = record_marker(env, llh, fsdb, CM_START, log, "add mdt");
2764 rc = record_attach(env, llh, log, LUSTRE_MDT_NAME, uuid->uuid);
2767 rc = record_mount_opt(env, llh, log, lovname, NULL);
2770 rc = record_setup(env, llh, log, uuid->uuid, mdt_index, lovname,
2771 failout ? "n" : "f");
2774 rc = record_marker(env, llh, fsdb, CM_END, log, "add mdt");
2778 record_end_log(env, &llh);
2780 name_destroy(&lovname);
2786 /* envelope method for all layers log */
2787 static int mgs_write_log_mdt(const struct lu_env *env,
2788 struct mgs_device *mgs,
2790 struct mgs_target_info *mti)
2792 struct mgs_thread_info *mgi = mgs_env_info(env);
2793 struct llog_handle *llh = NULL;
2798 CDEBUG(D_MGS, "writing new mdt %s\n", mti->mti_svname);
2800 if (mti->mti_uuid[0] == '\0') {
2801 /* Make up our own uuid */
2802 snprintf(mti->mti_uuid, sizeof(mti->mti_uuid),
2803 "%s_UUID", mti->mti_svname);
2807 rc = mgs_write_log_mdt0(env, mgs, fsdb, mti);
2810 /* Append the mdt info to the client log */
2811 rc = name_create(&cliname, mti->mti_fsname, "-client");
2815 if (mgs_log_is_empty(env, mgs, cliname)) {
2816 /* Start client log */
2817 rc = mgs_write_log_lov(env, mgs, fsdb, mti, cliname,
2821 rc = mgs_write_log_lmv(env, mgs, fsdb, mti, cliname,
2828 #09 L add_uuid nid=uml1@tcp(0x20000c0a80201) 0: 1:uml1_UUID
2829 #10 L attach 0:MDC_uml1_mdsA_MNT_client 1:mdc 2:1d834_MNT_client_03f
2830 #11 L setup 0:MDC_uml1_mdsA_MNT_client 1:mdsA_UUID 2:uml1_UUID
2831 #12 L add_uuid nid=uml2@tcp(0x20000c0a80202) 0: 1:uml2_UUID
2832 #13 L add_conn 0:MDC_uml1_mdsA_MNT_client 1:uml2_UUID
2833 #14 L mount_option 0: 1:client 2:lov1 3:MDC_uml1_mdsA_MNT_client
2836 /* copy client info about lov/lmv */
2837 mgi->mgi_comp.comp_mti = mti;
2838 mgi->mgi_comp.comp_fsdb = fsdb;
2840 rc = mgs_steal_llog_for_mdt_from_client(env, mgs, cliname,
2844 rc = mgs_write_log_mdc_to_lmv(env, mgs, fsdb, mti, cliname,
2850 rc = record_start_log(env, mgs, &llh, cliname);
2854 rc = record_marker(env, llh, fsdb, CM_START, cliname, "mount opts");
2857 rc = record_mount_opt(env, llh, cliname, fsdb->fsdb_clilov,
2861 rc = record_marker(env, llh, fsdb, CM_END, cliname, "mount opts");
2865 /* for_all_existing_mdt except current one */
2866 for (i = 0; i < INDEX_MAP_SIZE * 8; i++) {
2867 if (i != mti->mti_stripe_index &&
2868 test_bit(i, fsdb->fsdb_mdt_index_map)) {
2871 rc = name_create_mdt(&logname, fsdb->fsdb_name, i);
2875 /* NB: If the log for the MDT is empty, it means
2876 * the MDT is only added to the index
2877 * map, and not being process yet, i.e. this
2878 * is an unregistered MDT, see mgs_write_log_target().
2879 * so we should skip it. Otherwise
2881 * 1. MGS get register request for MDT1 and MDT2.
2883 * 2. Then both MDT1 and MDT2 are added into
2884 * fsdb_mdt_index_map. (see mgs_set_index()).
2886 * 3. Then MDT1 get the lock of fsdb_mutex, then
2887 * generate the config log, here, it will regard MDT2
2888 * as an existent MDT, and generate "add osp" for
2889 * lustre-MDT0001-osp-MDT0002. Note: at the moment
2890 * MDT0002 config log is still empty, so it will
2891 * add "add osp" even before "lov setup", which
2892 * will definitly cause trouble.
2894 * 4. MDT1 registeration finished, fsdb_mutex is
2895 * released, then MDT2 get in, then in above
2896 * mgs_steal_llog_for_mdt_from_client(), it will
2897 * add another osp log for lustre-MDT0001-osp-MDT0002,
2898 * which will cause another trouble.*/
2899 if (!mgs_log_is_empty(env, mgs, logname))
2900 rc = mgs_write_log_osp_to_mdt(env, mgs, fsdb,
2903 name_destroy(&logname);
2909 record_end_log(env, &llh);
2911 name_destroy(&cliname);
2915 /* Add the ost info to the client/mdt lov */
2916 static int mgs_write_log_osc_to_lov(const struct lu_env *env,
2917 struct mgs_device *mgs, struct fs_db *fsdb,
2918 struct mgs_target_info *mti,
2919 char *logname, char *suffix, char *lovname,
2920 enum lustre_sec_part sec_part, int flags)
2922 struct llog_handle *llh = NULL;
2923 char *nodeuuid = NULL;
2924 char *oscname = NULL;
2925 char *oscuuid = NULL;
2926 char *lovuuid = NULL;
2927 char *svname = NULL;
2929 char nidstr[LNET_NIDSTR_SIZE];
2933 CDEBUG(D_INFO, "adding osc for %s to log %s\n",
2934 mti->mti_svname, logname);
2936 if (mgs_log_is_empty(env, mgs, logname)) {
2937 CERROR("log is empty! Logical error\n");
2941 libcfs_nid2str_r(mti->mti_nids[0], nidstr, sizeof(nidstr));
2942 rc = name_create(&nodeuuid, nidstr, "");
2945 rc = name_create(&svname, mti->mti_svname, "-osc");
2949 /* for the system upgraded from old 1.8, keep using the old osc naming
2950 * style for mdt, see name_create_mdt_osc(). LU-1257 */
2951 if (test_bit(FSDB_OSCNAME18, &fsdb->fsdb_flags))
2952 rc = name_create(&oscname, svname, "");
2954 rc = name_create(&oscname, svname, suffix);
2958 rc = name_create(&oscuuid, oscname, "_UUID");
2961 rc = name_create(&lovuuid, lovname, "_UUID");
2967 #03 L add_uuid nid=uml1@tcp(0x20000c0a80201) 0: 1:uml1_UUID
2969 #04 L add_uuid nid=1@elan(0x1000000000001) nal=90 0: 1:uml1_UUID
2970 #04 L attach 0:OSC_uml1_ost1_MNT_client 1:osc 2:89070_lov1_a41dff51a
2971 #05 L setup 0:OSC_uml1_ost1_MNT_client 1:ost1_UUID 2:uml1_UUID
2973 #06 L add_uuid nid=uml2@tcp(0x20000c0a80202) 0: 1:uml2_UUID
2974 #07 L add_conn 0:OSC_uml1_ost1_MNT_client 1:uml2_UUID
2975 #08 L lov_modify_tgts add 0:lov1 1:ost1_UUID 2(index):0 3(gen):1
2978 rc = record_start_log(env, mgs, &llh, logname);
2982 /* FIXME these should be a single journal transaction */
2983 rc = record_marker(env, llh, fsdb, CM_START | flags, mti->mti_svname,
2988 /* NB: don't change record order, because upon MDT steal OSC config
2989 * from client, it treats all nids before LCFG_SETUP as target nids
2990 * (multiple interfaces), while nids after as failover node nids.
2991 * See mgs_steal_client_llog_handler() LCFG_ADD_UUID.
2993 for (i = 0; i < mti->mti_nid_count; i++) {
2994 CDEBUG(D_MGS, "add nid %s\n",
2995 libcfs_nid2str_r(mti->mti_nids[i],
2996 nidstr, sizeof(nidstr)));
2997 rc = record_add_uuid(env, llh, mti->mti_nids[i], nodeuuid);
3001 rc = record_attach(env, llh, oscname, LUSTRE_OSC_NAME, lovuuid);
3004 rc = record_setup(env, llh, oscname, mti->mti_uuid, nodeuuid,
3008 rc = mgs_write_log_failnids(env, mti, llh, oscname);
3012 snprintf(index, sizeof(index), "%d", mti->mti_stripe_index);
3014 rc = record_lov_add(env, llh, lovname, mti->mti_uuid, index, "1");
3017 rc = record_marker(env, llh, fsdb, CM_END | flags, mti->mti_svname,
3022 record_end_log(env, &llh);
3024 name_destroy(&lovuuid);
3025 name_destroy(&oscuuid);
3026 name_destroy(&oscname);
3027 name_destroy(&svname);
3028 name_destroy(&nodeuuid);
3032 static int mgs_write_log_ost(const struct lu_env *env,
3033 struct mgs_device *mgs, struct fs_db *fsdb,
3034 struct mgs_target_info *mti)
3036 struct llog_handle *llh = NULL;
3037 char *logname, *lovname;
3038 char *ptr = mti->mti_params;
3039 int rc, flags = 0, failout = 0, i;
3042 CDEBUG(D_MGS, "writing new ost %s\n", mti->mti_svname);
3044 /* The ost startup log */
3046 /* If the ost log already exists, that means that someone reformatted
3047 the ost and it called target_add again. */
3048 if (!mgs_log_is_empty(env, mgs, mti->mti_svname)) {
3049 LCONSOLE_ERROR_MSG(0x141, "The config log for %s already "
3050 "exists, yet the server claims it never "
3051 "registered. It may have been reformatted, "
3052 "or the index changed. writeconf the MDT to "
3053 "regenerate all logs.\n", mti->mti_svname);
3058 attach obdfilter ost1 ost1_UUID
3059 setup /dev/loop2 ldiskfs f|n errors=remount-ro,user_xattr
3061 if (class_find_param(ptr, PARAM_FAILMODE, &ptr) == 0)
3062 failout = (strncmp(ptr, "failout", 7) == 0);
3063 rc = record_start_log(env, mgs, &llh, mti->mti_svname);
3066 /* FIXME these should be a single journal transaction */
3067 rc = record_marker(env, llh, fsdb, CM_START, mti->mti_svname,"add ost");
3070 if (*mti->mti_uuid == '\0')
3071 snprintf(mti->mti_uuid, sizeof(mti->mti_uuid),
3072 "%s_UUID", mti->mti_svname);
3073 rc = record_attach(env, llh, mti->mti_svname,
3074 "obdfilter"/*LUSTRE_OST_NAME*/, mti->mti_uuid);
3077 rc = record_setup(env, llh, mti->mti_svname,
3078 "dev"/*ignored*/, "type"/*ignored*/,
3079 failout ? "n" : "f", NULL/*options*/);
3082 rc = record_marker(env, llh, fsdb, CM_END, mti->mti_svname, "add ost");
3086 record_end_log(env, &llh);
3089 /* We also have to update the other logs where this osc is part of
3092 if (test_bit(FSDB_OLDLOG14, &fsdb->fsdb_flags)) {
3093 /* If we're upgrading, the old mdt log already has our
3094 entry. Let's do a fake one for fun. */
3095 /* Note that we can't add any new failnids, since we don't
3096 know the old osc names. */
3097 flags = CM_SKIP | CM_UPGRADE146;
3099 } else if ((mti->mti_flags & LDD_F_UPDATE) != LDD_F_UPDATE) {
3100 /* If the update flag isn't set, don't update client/mdt
3103 LCONSOLE_WARN("Client log for %s was not updated; writeconf "
3104 "the MDT first to regenerate it.\n",
3108 /* Add ost to all MDT lov defs */
3109 for (i = 0; i < INDEX_MAP_SIZE * 8; i++){
3110 if (test_bit(i, fsdb->fsdb_mdt_index_map)) {
3113 rc = name_create_mdt_and_lov(&logname, &lovname, fsdb,
3118 snprintf(mdt_index, sizeof(mdt_index), "-MDT%04x", i);
3119 rc = mgs_write_log_osc_to_lov(env, mgs, fsdb, mti,
3121 lovname, LUSTRE_SP_MDT,
3123 name_destroy(&logname);
3124 name_destroy(&lovname);
3130 /* Append ost info to the client log */
3131 rc = name_create(&logname, mti->mti_fsname, "-client");
3134 if (mgs_log_is_empty(env, mgs, logname)) {
3135 /* Start client log */
3136 rc = mgs_write_log_lov(env, mgs, fsdb, mti, logname,
3140 rc = mgs_write_log_lmv(env, mgs, fsdb, mti, logname,
3145 rc = mgs_write_log_osc_to_lov(env, mgs, fsdb, mti, logname, "",
3146 fsdb->fsdb_clilov, LUSTRE_SP_CLI, flags);
3148 name_destroy(&logname);
3152 static __inline__ int mgs_param_empty(char *ptr)
3156 if ((tmp = strchr(ptr, '=')) && (*(++tmp) == '\0'))
3161 static int mgs_write_log_failnid_internal(const struct lu_env *env,
3162 struct mgs_device *mgs,
3164 struct mgs_target_info *mti,
3165 char *logname, char *cliname)
3168 struct llog_handle *llh = NULL;
3170 if (mgs_param_empty(mti->mti_params)) {
3171 /* Remove _all_ failnids */
3172 rc = mgs_modify(env, mgs, fsdb, mti, logname,
3173 mti->mti_svname, "add failnid", CM_SKIP);
3174 return rc < 0 ? rc : 0;
3177 /* Otherwise failover nids are additive */
3178 rc = record_start_log(env, mgs, &llh, logname);
3181 /* FIXME this should be a single journal transaction */
3182 rc = record_marker(env, llh, fsdb, CM_START, mti->mti_svname,
3186 rc = mgs_write_log_failnids(env, mti, llh, cliname);
3189 rc = record_marker(env, llh, fsdb, CM_END,
3190 mti->mti_svname, "add failnid");
3192 record_end_log(env, &llh);
3197 /* Add additional failnids to an existing log.
3198 The mdc/osc must have been added to logs first */
3199 /* tcp nids must be in dotted-quad ascii -
3200 we can't resolve hostnames from the kernel. */
3201 static int mgs_write_log_add_failnid(const struct lu_env *env,
3202 struct mgs_device *mgs,
3204 struct mgs_target_info *mti)
3206 char *logname, *cliname;
3210 /* FIXME we currently can't erase the failnids
3211 * given when a target first registers, since they aren't part of
3212 * an "add uuid" stanza
3215 /* Verify that we know about this target */
3216 if (mgs_log_is_empty(env, mgs, mti->mti_svname)) {
3217 LCONSOLE_ERROR_MSG(0x142, "The target %s has not registered "
3218 "yet. It must be started before failnids "
3219 "can be added.\n", mti->mti_svname);
3223 /* Create mdc/osc client name (e.g. lustre-OST0001-osc) */
3224 if (mti->mti_flags & LDD_F_SV_TYPE_MDT) {
3225 rc = name_create(&cliname, mti->mti_svname, "-mdc");
3226 } else if (mti->mti_flags & LDD_F_SV_TYPE_OST) {
3227 rc = name_create(&cliname, mti->mti_svname, "-osc");
3234 /* Add failover nids to the client log */
3235 rc = name_create(&logname, mti->mti_fsname, "-client");
3237 name_destroy(&cliname);
3241 rc = mgs_write_log_failnid_internal(env, mgs, fsdb,mti,logname,cliname);
3242 name_destroy(&logname);
3243 name_destroy(&cliname);
3247 if (mti->mti_flags & LDD_F_SV_TYPE_OST) {
3248 /* Add OST failover nids to the MDT logs as well */
3251 for (i = 0; i < INDEX_MAP_SIZE * 8; i++) {
3252 if (!test_bit(i, fsdb->fsdb_mdt_index_map))
3254 rc = name_create_mdt(&logname, mti->mti_fsname, i);
3257 rc = name_create_mdt_osc(&cliname, mti->mti_svname,
3260 name_destroy(&logname);
3263 rc = mgs_write_log_failnid_internal(env, mgs, fsdb,
3266 name_destroy(&cliname);
3267 name_destroy(&logname);
3276 static int mgs_wlp_lcfg(const struct lu_env *env,
3277 struct mgs_device *mgs, struct fs_db *fsdb,
3278 struct mgs_target_info *mti,
3279 char *logname, struct lustre_cfg_bufs *bufs,
3280 char *tgtname, char *ptr)
3282 char comment[MTI_NAME_MAXLEN];
3284 struct llog_cfg_rec *lcr;
3287 /* Erase any old settings of this same parameter */
3288 strlcpy(comment, ptr, sizeof(comment));
3289 /* But don't try to match the value. */
3290 tmp = strchr(comment, '=');
3293 /* FIXME we should skip settings that are the same as old values */
3294 rc = mgs_modify(env, mgs, fsdb, mti, logname, tgtname, comment,CM_SKIP);
3297 del = mgs_param_empty(ptr);
3299 LCONSOLE_INFO("%s parameter %s.%s in log %s\n", del ? "Disabling" : rc ?
3300 "Setting" : "Modifying", tgtname, comment, logname);
3302 /* mgs_modify() will return 1 if nothing had to be done */
3308 lustre_cfg_bufs_reset(bufs, tgtname);
3309 lustre_cfg_bufs_set_string(bufs, 1, ptr);
3310 if (mti->mti_flags & LDD_F_PARAM2)
3311 lustre_cfg_bufs_set_string(bufs, 2, LCTL_UPCALL);
3313 lcr = lustre_cfg_rec_new((mti->mti_flags & LDD_F_PARAM2) ?
3314 LCFG_SET_PARAM : LCFG_PARAM, bufs);
3318 rc = mgs_write_log_direct(env, mgs, fsdb, logname, lcr, tgtname,
3320 lustre_cfg_rec_free(lcr);
3324 /* write global variable settings into log */
3325 static int mgs_write_log_sys(const struct lu_env *env,
3326 struct mgs_device *mgs, struct fs_db *fsdb,
3327 struct mgs_target_info *mti, char *sys, char *ptr)
3329 struct mgs_thread_info *mgi = mgs_env_info(env);
3330 struct lustre_cfg *lcfg;
3331 struct llog_cfg_rec *lcr;
3333 int rc, cmd, convert = 1;
3335 if (class_match_param(ptr, PARAM_TIMEOUT, &tmp) == 0) {
3336 cmd = LCFG_SET_TIMEOUT;
3337 } else if (class_match_param(ptr, PARAM_LDLM_TIMEOUT, &tmp) == 0) {
3338 cmd = LCFG_SET_LDLM_TIMEOUT;
3339 /* Check for known params here so we can return error to lctl */
3340 } else if ((class_match_param(ptr, PARAM_AT_MIN, &tmp) == 0) ||
3341 (class_match_param(ptr, PARAM_AT_MAX, &tmp) == 0) ||
3342 (class_match_param(ptr, PARAM_AT_EXTRA, &tmp) == 0) ||
3343 (class_match_param(ptr, PARAM_AT_EARLY_MARGIN, &tmp) == 0) ||
3344 (class_match_param(ptr, PARAM_AT_HISTORY, &tmp) == 0)) {
3346 } else if (class_match_param(ptr, PARAM_JOBID_VAR, &tmp) == 0) {
3347 convert = 0; /* Don't convert string value to integer */
3353 if (mgs_param_empty(ptr))
3354 CDEBUG(D_MGS, "global '%s' removed\n", sys);
3356 CDEBUG(D_MGS, "global '%s' val=%s\n", sys, tmp);
3358 lustre_cfg_bufs_reset(&mgi->mgi_bufs, NULL);
3359 lustre_cfg_bufs_set_string(&mgi->mgi_bufs, 1, sys);
3360 if (!convert && *tmp != '\0')
3361 lustre_cfg_bufs_set_string(&mgi->mgi_bufs, 2, tmp);
3362 lcr = lustre_cfg_rec_new(cmd, &mgi->mgi_bufs);
3366 lcfg = &lcr->lcr_cfg;
3368 rc = kstrtouint(tmp, 0, &lcfg->lcfg_num);
3370 GOTO(out_rec_free, rc);
3375 /* truncate the comment to the parameter name */
3379 /* modify all servers and clients */
3380 rc = mgs_write_log_direct_all(env, mgs, fsdb, mti,
3381 *tmp == '\0' ? NULL : lcr,
3382 mti->mti_fsname, sys, 0);
3383 if (rc == 0 && *tmp != '\0') {
3385 case LCFG_SET_TIMEOUT:
3386 if (!obd_timeout_set || lcfg->lcfg_num > obd_timeout)
3387 class_process_config(lcfg);
3389 case LCFG_SET_LDLM_TIMEOUT:
3390 if (!ldlm_timeout_set || lcfg->lcfg_num > ldlm_timeout)
3391 class_process_config(lcfg);
3399 lustre_cfg_rec_free(lcr);
3403 /* write quota settings into log */
3404 static int mgs_write_log_quota(const struct lu_env *env, struct mgs_device *mgs,
3405 struct fs_db *fsdb, struct mgs_target_info *mti,
3406 char *quota, char *ptr)
3408 struct mgs_thread_info *mgi = mgs_env_info(env);
3409 struct llog_cfg_rec *lcr;
3412 int rc, cmd = LCFG_PARAM;
3414 /* support only 'meta' and 'data' pools so far */
3415 if (class_match_param(ptr, QUOTA_METAPOOL_NAME, &tmp) != 0 &&
3416 class_match_param(ptr, QUOTA_DATAPOOL_NAME, &tmp) != 0) {
3417 CERROR("parameter quota.%s isn't supported (only quota.mdt "
3418 "& quota.ost are)\n", ptr);
3423 CDEBUG(D_MGS, "global '%s' removed\n", quota);
3425 CDEBUG(D_MGS, "global '%s'\n", quota);
3427 if (strchr(tmp, 'u') == NULL && strchr(tmp, 'g') == NULL &&
3428 strchr(tmp, 'p') == NULL &&
3429 strcmp(tmp, "none") != 0) {
3430 CERROR("enable option(%s) isn't supported\n", tmp);
3435 lustre_cfg_bufs_reset(&mgi->mgi_bufs, mti->mti_fsname);
3436 lustre_cfg_bufs_set_string(&mgi->mgi_bufs, 1, quota);
3437 lcr = lustre_cfg_rec_new(cmd, &mgi->mgi_bufs);
3441 /* truncate the comment to the parameter name */
3446 /* XXX we duplicated quota enable information in all server
3447 * config logs, it should be moved to a separate config
3448 * log once we cleanup the config log for global param. */
3449 /* modify all servers */
3450 rc = mgs_write_log_direct_all(env, mgs, fsdb, mti,
3451 *tmp == '\0' ? NULL : lcr,
3452 mti->mti_fsname, quota, 1);
3454 lustre_cfg_rec_free(lcr);
3455 return rc < 0 ? rc : 0;
3458 static int mgs_srpc_set_param_disk(const struct lu_env *env,
3459 struct mgs_device *mgs,
3461 struct mgs_target_info *mti,
3464 struct mgs_thread_info *mgi = mgs_env_info(env);
3465 struct llog_cfg_rec *lcr;
3466 struct llog_handle *llh = NULL;
3468 char *comment, *ptr;
3474 ptr = strchr(param, '=');
3475 LASSERT(ptr != NULL);
3478 OBD_ALLOC(comment, len + 1);
3479 if (comment == NULL)
3481 strncpy(comment, param, len);
3482 comment[len] = '\0';
3485 lustre_cfg_bufs_reset(&mgi->mgi_bufs, mti->mti_svname);
3486 lustre_cfg_bufs_set_string(&mgi->mgi_bufs, 1, param);
3487 lcr = lustre_cfg_rec_new(LCFG_SPTLRPC_CONF, &mgi->mgi_bufs);
3489 GOTO(out_comment, rc = -ENOMEM);
3491 /* construct log name */
3492 rc = name_create(&logname, mti->mti_fsname, "-sptlrpc");
3496 if (mgs_log_is_empty(env, mgs, logname)) {
3497 rc = record_start_log(env, mgs, &llh, logname);
3500 record_end_log(env, &llh);
3503 /* obsolete old one */
3504 rc = mgs_modify(env, mgs, fsdb, mti, logname, mti->mti_svname,
3508 /* write the new one */
3509 rc = mgs_write_log_direct(env, mgs, fsdb, logname, lcr,
3510 mti->mti_svname, comment);
3512 CERROR("%s: error writing log %s: rc = %d\n",
3513 mgs->mgs_obd->obd_name, logname, rc);
3515 name_destroy(&logname);
3517 lustre_cfg_rec_free(lcr);
3519 OBD_FREE(comment, len + 1);
3523 static int mgs_srpc_set_param_udesc_mem(struct fs_db *fsdb,
3528 /* disable the adjustable udesc parameter for now, i.e. use default
3529 * setting that client always ship udesc to MDT if possible. to enable
3530 * it simply remove the following line */
3533 ptr = strchr(param, '=');
3538 if (strcmp(param, PARAM_SRPC_UDESC))
3541 if (strcmp(ptr, "yes") == 0) {
3542 set_bit(FSDB_UDESC, &fsdb->fsdb_flags);
3543 CWARN("Enable user descriptor shipping from client to MDT\n");
3544 } else if (strcmp(ptr, "no") == 0) {
3545 clear_bit(FSDB_UDESC, &fsdb->fsdb_flags);
3546 CWARN("Disable user descriptor shipping from client to MDT\n");
3554 CERROR("Invalid param: %s\n", param);
3558 static int mgs_srpc_set_param_mem(struct fs_db *fsdb,
3562 struct sptlrpc_rule rule;
3563 struct sptlrpc_rule_set *rset;
3567 if (strncmp(param, PARAM_SRPC, sizeof(PARAM_SRPC) - 1) != 0) {
3568 CERROR("Invalid sptlrpc parameter: %s\n", param);
3572 if (strncmp(param, PARAM_SRPC_UDESC,
3573 sizeof(PARAM_SRPC_UDESC) - 1) == 0) {
3574 RETURN(mgs_srpc_set_param_udesc_mem(fsdb, param));
3577 if (strncmp(param, PARAM_SRPC_FLVR, sizeof(PARAM_SRPC_FLVR) - 1) != 0) {
3578 CERROR("Invalid sptlrpc flavor parameter: %s\n", param);
3582 param += sizeof(PARAM_SRPC_FLVR) - 1;
3584 rc = sptlrpc_parse_rule(param, &rule);
3588 /* mgs rules implies must be mgc->mgs */
3589 if (test_bit(FSDB_MGS_SELF, &fsdb->fsdb_flags)) {
3590 if ((rule.sr_from != LUSTRE_SP_MGC &&
3591 rule.sr_from != LUSTRE_SP_ANY) ||
3592 (rule.sr_to != LUSTRE_SP_MGS &&
3593 rule.sr_to != LUSTRE_SP_ANY))
3597 /* preapre room for this coming rule. svcname format should be:
3598 * - fsname: general rule
3599 * - fsname-tgtname: target-specific rule
3601 if (strchr(svname, '-')) {
3602 struct mgs_tgt_srpc_conf *tgtconf;
3605 for (tgtconf = fsdb->fsdb_srpc_tgt; tgtconf != NULL;
3606 tgtconf = tgtconf->mtsc_next) {
3607 if (!strcmp(tgtconf->mtsc_tgt, svname)) {
3616 OBD_ALLOC_PTR(tgtconf);
3617 if (tgtconf == NULL)
3620 name_len = strlen(svname);
3622 OBD_ALLOC(tgtconf->mtsc_tgt, name_len + 1);
3623 if (tgtconf->mtsc_tgt == NULL) {
3624 OBD_FREE_PTR(tgtconf);
3627 memcpy(tgtconf->mtsc_tgt, svname, name_len);
3629 tgtconf->mtsc_next = fsdb->fsdb_srpc_tgt;
3630 fsdb->fsdb_srpc_tgt = tgtconf;
3633 rset = &tgtconf->mtsc_rset;
3634 } else if (strcmp(svname, MGSSELF_NAME) == 0) {
3635 /* put _mgs related srpc rule directly in mgs ruleset */
3636 rset = &fsdb->fsdb_mgs->mgs_lut.lut_sptlrpc_rset;
3638 rset = &fsdb->fsdb_srpc_gen;
3641 rc = sptlrpc_rule_set_merge(rset, &rule);
3646 static int mgs_srpc_set_param(const struct lu_env *env,
3647 struct mgs_device *mgs,
3649 struct mgs_target_info *mti,
3659 /* keep a copy of original param, which could be destroied
3661 copy_size = strlen(param) + 1;
3662 OBD_ALLOC(copy, copy_size);
3665 memcpy(copy, param, copy_size);
3667 rc = mgs_srpc_set_param_mem(fsdb, mti->mti_svname, param);
3671 /* previous steps guaranteed the syntax is correct */
3672 rc = mgs_srpc_set_param_disk(env, mgs, fsdb, mti, copy);
3676 if (test_bit(FSDB_MGS_SELF, &fsdb->fsdb_flags)) {
3678 * for mgs rules, make them effective immediately.
3680 LASSERT(fsdb->fsdb_srpc_tgt == NULL);
3681 sptlrpc_target_update_exp_flavor(mgs->mgs_obd,
3682 &fsdb->fsdb_srpc_gen);
3686 OBD_FREE(copy, copy_size);
3690 struct mgs_srpc_read_data {
3691 struct fs_db *msrd_fsdb;
3695 static int mgs_srpc_read_handler(const struct lu_env *env,
3696 struct llog_handle *llh,
3697 struct llog_rec_hdr *rec, void *data)
3699 struct mgs_srpc_read_data *msrd = data;
3700 struct cfg_marker *marker;
3701 struct lustre_cfg *lcfg = REC_DATA(rec);
3702 char *svname, *param;
3706 if (rec->lrh_type != OBD_CFG_REC) {
3707 CERROR("unhandled lrh_type: %#x\n", rec->lrh_type);
3711 cfg_len = REC_DATA_LEN(rec);
3713 rc = lustre_cfg_sanity_check(lcfg, cfg_len);
3715 CERROR("Insane cfg\n");
3719 if (lcfg->lcfg_command == LCFG_MARKER) {
3720 marker = lustre_cfg_buf(lcfg, 1);
3722 if (marker->cm_flags & CM_START &&
3723 marker->cm_flags & CM_SKIP)
3724 msrd->msrd_skip = 1;
3725 if (marker->cm_flags & CM_END)
3726 msrd->msrd_skip = 0;
3731 if (msrd->msrd_skip)
3734 if (lcfg->lcfg_command != LCFG_SPTLRPC_CONF) {
3735 CERROR("invalid command (%x)\n", lcfg->lcfg_command);
3739 svname = lustre_cfg_string(lcfg, 0);
3740 if (svname == NULL) {
3741 CERROR("svname is empty\n");
3745 param = lustre_cfg_string(lcfg, 1);
3746 if (param == NULL) {
3747 CERROR("param is empty\n");
3751 rc = mgs_srpc_set_param_mem(msrd->msrd_fsdb, svname, param);
3753 CERROR("read sptlrpc record error (%d): %s\n", rc, param);
3758 int mgs_get_fsdb_srpc_from_llog(const struct lu_env *env,
3759 struct mgs_device *mgs,
3762 struct llog_handle *llh = NULL;
3763 struct llog_ctxt *ctxt;
3765 struct mgs_srpc_read_data msrd;
3769 /* construct log name */
3770 rc = name_create(&logname, fsdb->fsdb_name, "-sptlrpc");
3774 ctxt = llog_get_context(mgs->mgs_obd, LLOG_CONFIG_ORIG_CTXT);
3775 LASSERT(ctxt != NULL);
3777 if (mgs_log_is_empty(env, mgs, logname))
3780 rc = llog_open(env, ctxt, &llh, NULL, logname,
3788 rc = llog_init_handle(env, llh, LLOG_F_IS_PLAIN, NULL);
3790 GOTO(out_close, rc);
3792 if (llog_get_size(llh) <= 1)
3793 GOTO(out_close, rc = 0);
3795 msrd.msrd_fsdb = fsdb;
3798 rc = llog_process(env, llh, mgs_srpc_read_handler, (void *)&msrd,
3802 llog_close(env, llh);
3804 llog_ctxt_put(ctxt);
3805 name_destroy(&logname);
3808 CERROR("failed to read sptlrpc config database: %d\n", rc);
3812 static int mgs_write_log_param2(const struct lu_env *env,
3813 struct mgs_device *mgs,
3815 struct mgs_target_info *mti, char *ptr)
3817 struct lustre_cfg_bufs bufs;
3821 CDEBUG(D_MGS, "next param '%s'\n", ptr);
3823 /* PARAM_MGSNODE and PARAM_NETWORK are set only when formating
3824 * or during the inital mount. It can never change after that.
3826 if (!class_match_param(ptr, PARAM_MGSNODE, NULL) ||
3827 !class_match_param(ptr, PARAM_NETWORK, NULL)) {
3832 /* Processed in mgs_write_log_ost. Another value that can't
3833 * be changed by lctl set_param -P.
3835 if (!class_match_param(ptr, PARAM_FAILMODE, NULL)) {
3836 LCONSOLE_ERROR_MSG(0x169,
3837 "%s can only be changed with tunefs.lustre and --writeconf\n",
3843 /* FIXME !!! Support for sptlrpc is incomplete. Currently the change
3844 * doesn't transmit to the client. See LU-7183.
3846 if (!class_match_param(ptr, PARAM_SRPC, NULL)) {
3847 rc = mgs_srpc_set_param(env, mgs, fsdb, mti, ptr);
3851 /* Can't use class_match_param since ptr doesn't start with
3852 * PARAM_FAILNODE. So we look for PARAM_FAILNODE contained in ptr.
3854 if (strstr(ptr, PARAM_FAILNODE)) {
3855 /* Add a failover nidlist. We already processed failovers
3856 * params for new targets in mgs_write_log_target.
3860 /* can't use wildcards with failover.node */
3861 if (strchr(ptr, '*')) {
3866 param = strstr(ptr, PARAM_FAILNODE);
3867 if (strlcpy(mti->mti_params, param, sizeof(mti->mti_params)) >=
3868 sizeof(mti->mti_params)) {
3873 CDEBUG(D_MGS, "Adding failnode with param %s\n",
3875 rc = mgs_write_log_add_failnid(env, mgs, fsdb, mti);
3879 rc = mgs_wlp_lcfg(env, mgs, fsdb, mti, PARAMS_FILENAME, &bufs,
3880 mti->mti_svname, ptr);
3885 /* Permanent settings of all parameters by writing into the appropriate
3886 * configuration logs.
3887 * A parameter with null value ("<param>='\0'") means to erase it out of
3890 static int mgs_write_log_param(const struct lu_env *env,
3891 struct mgs_device *mgs, struct fs_db *fsdb,
3892 struct mgs_target_info *mti, char *ptr)
3894 struct mgs_thread_info *mgi = mgs_env_info(env);
3900 /* For various parameter settings, we have to figure out which logs
3901 care about them (e.g. both mdt and client for lov settings) */
3902 CDEBUG(D_MGS, "next param '%s'\n", ptr);
3904 /* The params are stored in MOUNT_DATA_FILE and modified via
3905 tunefs.lustre, or set using lctl conf_param */
3907 /* Processed in lustre_start_mgc */
3908 if (class_match_param(ptr, PARAM_MGSNODE, NULL) == 0)
3911 /* Processed in ost/mdt */
3912 if (class_match_param(ptr, PARAM_NETWORK, NULL) == 0)
3915 /* Processed in mgs_write_log_ost */
3916 if (class_match_param(ptr, PARAM_FAILMODE, NULL) == 0) {
3917 if (mti->mti_flags & LDD_F_PARAM) {
3918 LCONSOLE_ERROR_MSG(0x169,
3919 "%s can only be changed with tunefs.lustre and --writeconf\n",
3926 if (class_match_param(ptr, PARAM_SRPC, NULL) == 0) {
3927 rc = mgs_srpc_set_param(env, mgs, fsdb, mti, ptr);
3931 if (class_match_param(ptr, PARAM_FAILNODE, NULL) == 0) {
3932 /* Add a failover nidlist */
3934 /* We already processed failovers params for new
3935 targets in mgs_write_log_target */
3936 if (mti->mti_flags & LDD_F_PARAM) {
3937 CDEBUG(D_MGS, "Adding failnode\n");
3938 rc = mgs_write_log_add_failnid(env, mgs, fsdb, mti);
3943 if (class_match_param(ptr, PARAM_SYS, &tmp) == 0) {
3944 rc = mgs_write_log_sys(env, mgs, fsdb, mti, ptr, tmp);
3948 if (class_match_param(ptr, PARAM_QUOTA, &tmp) == 0) {
3949 rc = mgs_write_log_quota(env, mgs, fsdb, mti, ptr, tmp);
3953 if (class_match_param(ptr, PARAM_OSC PARAM_ACTIVE, &tmp) == 0 ||
3954 class_match_param(ptr, PARAM_MDC PARAM_ACTIVE, &tmp) == 0) {
3955 /* active=0 means off, anything else means on */
3956 int flag = (*tmp == '0') ? CM_EXCLUDE : 0;
3957 bool deactive_osc = memcmp(ptr, PARAM_OSC PARAM_ACTIVE,
3958 strlen(PARAM_OSC PARAM_ACTIVE)) == 0;
3961 if (!deactive_osc) {
3964 rc = server_name2index(mti->mti_svname, &index, NULL);
3969 LCONSOLE_ERROR_MSG(0x144, "%s: MDC0 can not be"
3970 " (de)activated.\n",
3972 GOTO(end, rc = -EPERM);
3976 LCONSOLE_WARN("Permanently %sactivating %s\n",
3977 flag ? "de" : "re", mti->mti_svname);
3979 rc = name_create(&logname, mti->mti_fsname, "-client");
3982 rc = mgs_modify(env, mgs, fsdb, mti, logname,
3984 deactive_osc ? "add osc" : "add mdc", flag);
3985 name_destroy(&logname);
3990 /* Add to all MDT logs for DNE */
3991 for (i = 0; i < INDEX_MAP_SIZE * 8; i++) {
3992 if (!test_bit(i, fsdb->fsdb_mdt_index_map))
3994 rc = name_create_mdt(&logname, mti->mti_fsname, i);
3997 rc = mgs_modify(env, mgs, fsdb, mti, logname,
3999 deactive_osc ? "add osc" : "add osp",
4001 name_destroy(&logname);
4007 LCONSOLE_ERROR_MSG(0x145,
4008 "Couldn't find %s in log (%d). No permanent changes were made to the config log.\n",
4009 mti->mti_svname, rc);
4010 if (test_bit(FSDB_OLDLOG14, &fsdb->fsdb_flags))
4011 LCONSOLE_ERROR_MSG(0x146,
4012 "This may be because the log is in the old 1.4 style. Consider --writeconf to update the logs.\n");
4015 /* Fall through to osc/mdc proc for deactivating live
4016 OSC/OSP on running MDT / clients. */
4018 /* Below here, let obd's XXX_process_config methods handle it */
4020 /* All lov. in proc */
4021 if (class_match_param(ptr, PARAM_LOV, NULL) == 0) {
4024 CDEBUG(D_MGS, "lov param %s\n", ptr);
4025 if (!(mti->mti_flags & LDD_F_SV_TYPE_MDT)) {
4026 LCONSOLE_ERROR_MSG(0x147, "LOV params must be "
4027 "set on the MDT, not %s. "
4034 if (mgs_log_is_empty(env, mgs, mti->mti_svname))
4035 GOTO(end, rc = -ENODEV);
4037 rc = name_create_mdt_and_lov(&logname, &mdtlovname, fsdb,
4038 mti->mti_stripe_index);
4041 rc = mgs_wlp_lcfg(env, mgs, fsdb, mti, mti->mti_svname,
4042 &mgi->mgi_bufs, mdtlovname, ptr);
4043 name_destroy(&logname);
4044 name_destroy(&mdtlovname);
4049 rc = name_create(&logname, mti->mti_fsname, "-client");
4052 rc = mgs_wlp_lcfg(env, mgs, fsdb, mti, logname, &mgi->mgi_bufs,
4053 fsdb->fsdb_clilov, ptr);
4054 name_destroy(&logname);
4058 /* All osc., mdc., llite. params in proc */
4059 if ((class_match_param(ptr, PARAM_OSC, NULL) == 0) ||
4060 (class_match_param(ptr, PARAM_MDC, NULL) == 0) ||
4061 (class_match_param(ptr, PARAM_LLITE, NULL) == 0)) {
4064 if (test_bit(FSDB_OLDLOG14, &fsdb->fsdb_flags)) {
4065 LCONSOLE_ERROR_MSG(0x148, "Upgraded client logs for %s"
4066 " cannot be modified. Consider"
4067 " updating the configuration with"
4070 GOTO(end, rc = -EINVAL);
4072 if (memcmp(ptr, PARAM_LLITE, strlen(PARAM_LLITE)) == 0) {
4073 rc = name_create(&cname, mti->mti_fsname, "-client");
4074 /* Add the client type to match the obdname in
4075 class_config_llog_handler */
4076 } else if (mti->mti_flags & LDD_F_SV_TYPE_MDT) {
4077 rc = name_create(&cname, mti->mti_svname, "-mdc");
4078 } else if (mti->mti_flags & LDD_F_SV_TYPE_OST) {
4079 rc = name_create(&cname, mti->mti_svname, "-osc");
4081 GOTO(end, rc = -EINVAL);
4086 /* Forbid direct update of llite root squash parameters.
4087 * These parameters are indirectly set via the MDT settings.
4089 if ((class_match_param(ptr, PARAM_LLITE, &tmp) == 0) &&
4090 ((memcmp(tmp, "root_squash=", 12) == 0) ||
4091 (memcmp(tmp, "nosquash_nids=", 14) == 0))) {
4092 LCONSOLE_ERROR("%s: root squash parameters can only "
4093 "be updated through MDT component\n",
4095 name_destroy(&cname);
4096 GOTO(end, rc = -EINVAL);
4099 CDEBUG(D_MGS, "%.3s param %s\n", ptr, ptr + 4);
4102 rc = name_create(&logname, mti->mti_fsname, "-client");
4104 name_destroy(&cname);
4107 rc = mgs_wlp_lcfg(env, mgs, fsdb, mti, logname, &mgi->mgi_bufs,
4110 /* osc params affect the MDT as well */
4111 if (!rc && (mti->mti_flags & LDD_F_SV_TYPE_OST)) {
4114 for (i = 0; i < INDEX_MAP_SIZE * 8; i++){
4115 if (!test_bit(i, fsdb->fsdb_mdt_index_map))
4117 name_destroy(&cname);
4118 rc = name_create_mdt_osc(&cname, mti->mti_svname,
4120 name_destroy(&logname);
4123 rc = name_create_mdt(&logname,
4124 mti->mti_fsname, i);
4127 if (!mgs_log_is_empty(env, mgs, logname)) {
4128 rc = mgs_wlp_lcfg(env, mgs, fsdb,
4138 /* For mdc activate/deactivate, it affects OSP on MDT as well */
4139 if (class_match_param(ptr, PARAM_MDC PARAM_ACTIVE, &tmp) == 0 &&
4142 char *lodname = NULL;
4143 char *param_str = NULL;
4147 /* replace mdc with osp */
4148 memcpy(ptr, PARAM_OSP, strlen(PARAM_OSP));
4149 rc = server_name2index(mti->mti_svname, &index, NULL);
4151 memcpy(ptr, PARAM_MDC, strlen(PARAM_MDC));
4155 for (i = 0; i < INDEX_MAP_SIZE * 8; i++) {
4156 if (!test_bit(i, fsdb->fsdb_mdt_index_map))
4162 name_destroy(&logname);
4163 rc = name_create_mdt(&logname, mti->mti_fsname,
4168 if (mgs_log_is_empty(env, mgs, logname))
4171 snprintf(suffix, sizeof(suffix), "-osp-MDT%04x",
4173 name_destroy(&cname);
4174 rc = name_create(&cname, mti->mti_svname,
4179 rc = mgs_wlp_lcfg(env, mgs, fsdb, mti, logname,
4180 &mgi->mgi_bufs, cname, ptr);
4184 /* Add configuration log for noitfying LOD
4185 * to active/deactive the OSP. */
4186 name_destroy(¶m_str);
4187 rc = name_create(¶m_str, cname,
4188 (*tmp == '0') ? ".active=0" :
4193 name_destroy(&lodname);
4194 rc = name_create(&lodname, logname, "-mdtlov");
4198 rc = mgs_wlp_lcfg(env, mgs, fsdb, mti, logname,
4199 &mgi->mgi_bufs, lodname,
4204 memcpy(ptr, PARAM_MDC, strlen(PARAM_MDC));
4205 name_destroy(&lodname);
4206 name_destroy(¶m_str);
4209 name_destroy(&logname);
4210 name_destroy(&cname);
4214 /* All mdt. params in proc */
4215 if (class_match_param(ptr, PARAM_MDT, &tmp) == 0) {
4219 CDEBUG(D_MGS, "%.3s param %s\n", ptr, ptr + 4);
4220 if (strncmp(mti->mti_svname, mti->mti_fsname,
4221 MTI_NAME_MAXLEN) == 0)
4222 /* device is unspecified completely? */
4223 rc = LDD_F_SV_TYPE_MDT | LDD_F_SV_ALL;
4225 rc = server_name2index(mti->mti_svname, &idx, NULL);
4228 if ((rc & LDD_F_SV_TYPE_MDT) == 0)
4230 if (rc & LDD_F_SV_ALL) {
4231 for (i = 0; i < INDEX_MAP_SIZE * 8; i++) {
4233 fsdb->fsdb_mdt_index_map))
4235 rc = name_create_mdt(&logname,
4236 mti->mti_fsname, i);
4239 rc = mgs_wlp_lcfg(env, mgs, fsdb, mti,
4240 logname, &mgi->mgi_bufs,
4242 name_destroy(&logname);
4247 if ((memcmp(tmp, "root_squash=", 12) == 0) ||
4248 (memcmp(tmp, "nosquash_nids=", 14) == 0)) {
4249 LCONSOLE_ERROR("%s: root squash parameters "
4250 "cannot be applied to a single MDT\n",
4252 GOTO(end, rc = -EINVAL);
4254 rc = mgs_wlp_lcfg(env, mgs, fsdb, mti,
4255 mti->mti_svname, &mgi->mgi_bufs,
4256 mti->mti_svname, ptr);
4261 /* root squash settings are also applied to llite
4262 * config log (see LU-1778) */
4264 ((memcmp(tmp, "root_squash=", 12) == 0) ||
4265 (memcmp(tmp, "nosquash_nids=", 14) == 0))) {
4269 rc = name_create(&cname, mti->mti_fsname, "-client");
4272 rc = name_create(&logname, mti->mti_fsname, "-client");
4274 name_destroy(&cname);
4277 rc = name_create(&ptr2, PARAM_LLITE, tmp);
4279 name_destroy(&cname);
4280 name_destroy(&logname);
4283 rc = mgs_wlp_lcfg(env, mgs, fsdb, mti, logname,
4284 &mgi->mgi_bufs, cname, ptr2);
4285 name_destroy(&ptr2);
4286 name_destroy(&logname);
4287 name_destroy(&cname);
4292 /* All mdd., ost. and osd. params in proc */
4293 if ((class_match_param(ptr, PARAM_MDD, NULL) == 0) ||
4294 (class_match_param(ptr, PARAM_LOD, NULL) == 0) ||
4295 (class_match_param(ptr, PARAM_OST, NULL) == 0) ||
4296 (class_match_param(ptr, PARAM_OSD, NULL) == 0)) {
4297 CDEBUG(D_MGS, "%.3s param %s\n", ptr, ptr + 4);
4298 if (mgs_log_is_empty(env, mgs, mti->mti_svname))
4299 GOTO(end, rc = -ENODEV);
4301 rc = mgs_wlp_lcfg(env, mgs, fsdb, mti, mti->mti_svname,
4302 &mgi->mgi_bufs, mti->mti_svname, ptr);
4306 LCONSOLE_WARN("Ignoring unrecognized param '%s'\n", ptr);
4310 CERROR("err %d on param '%s'\n", rc, ptr);
4315 int mgs_write_log_target(const struct lu_env *env, struct mgs_device *mgs,
4316 struct mgs_target_info *mti, struct fs_db *fsdb)
4323 /* set/check the new target index */
4324 rc = mgs_set_index(env, mgs, mti);
4328 if (rc == EALREADY) {
4329 LCONSOLE_WARN("Found index %d for %s, updating log\n",
4330 mti->mti_stripe_index, mti->mti_svname);
4331 /* We would like to mark old log sections as invalid
4332 and add new log sections in the client and mdt logs.
4333 But if we add new sections, then live clients will
4334 get repeat setup instructions for already running
4335 osc's. So don't update the client/mdt logs. */
4336 mti->mti_flags &= ~LDD_F_UPDATE;
4340 OBD_FAIL_TIMEOUT(OBD_FAIL_MGS_WRITE_TARGET_DELAY, cfs_fail_val > 0 ?
4343 mutex_lock(&fsdb->fsdb_mutex);
4345 if (mti->mti_flags & (LDD_F_VIRGIN | LDD_F_WRITECONF)) {
4346 /* Generate a log from scratch */
4347 if (mti->mti_flags & LDD_F_SV_TYPE_MDT) {
4348 rc = mgs_write_log_mdt(env, mgs, fsdb, mti);
4349 } else if (mti->mti_flags & LDD_F_SV_TYPE_OST) {
4350 rc = mgs_write_log_ost(env, mgs, fsdb, mti);
4352 CERROR("Unknown target type %#x, can't create log for %s\n",
4353 mti->mti_flags, mti->mti_svname);
4356 CERROR("Can't write logs for %s (%d)\n",
4357 mti->mti_svname, rc);
4361 /* Just update the params from tunefs in mgs_write_log_params */
4362 CDEBUG(D_MGS, "Update params for %s\n", mti->mti_svname);
4363 mti->mti_flags |= LDD_F_PARAM;
4366 /* allocate temporary buffer, where class_get_next_param will
4367 make copy of a current parameter */
4368 OBD_ALLOC(buf, strlen(mti->mti_params) + 1);
4370 GOTO(out_up, rc = -ENOMEM);
4371 params = mti->mti_params;
4372 while (params != NULL) {
4373 rc = class_get_next_param(¶ms, buf);
4376 /* there is no next parameter, that is
4381 CDEBUG(D_MGS, "remaining string: '%s', param: '%s'\n",
4383 rc = mgs_write_log_param(env, mgs, fsdb, mti, buf);
4388 OBD_FREE(buf, strlen(mti->mti_params) + 1);
4391 mutex_unlock(&fsdb->fsdb_mutex);
4395 int mgs_erase_log(const struct lu_env *env, struct mgs_device *mgs, char *name)
4397 struct llog_ctxt *ctxt;
4400 ctxt = llog_get_context(mgs->mgs_obd, LLOG_CONFIG_ORIG_CTXT);
4402 CERROR("%s: MGS config context doesn't exist\n",
4403 mgs->mgs_obd->obd_name);
4406 rc = llog_erase(env, ctxt, NULL, name);
4407 /* llog may not exist */
4410 llog_ctxt_put(ctxt);
4414 CERROR("%s: failed to clear log %s: %d\n",
4415 mgs->mgs_obd->obd_name, name, rc);
4420 /* erase all logs for the given fs */
4421 int mgs_erase_logs(const struct lu_env *env, struct mgs_device *mgs,
4424 struct list_head log_list;
4425 struct mgs_direntry *dirent, *n;
4426 char barrier_name[20] = {};
4429 int rc, len = strlen(fsname);
4432 mutex_lock(&mgs->mgs_mutex);
4434 /* Find all the logs in the CONFIGS directory */
4435 rc = class_dentry_readdir(env, mgs, &log_list);
4437 mutex_unlock(&mgs->mgs_mutex);
4441 if (list_empty(&log_list)) {
4442 mutex_unlock(&mgs->mgs_mutex);
4446 snprintf(barrier_name, sizeof(barrier_name) - 1, "%s-%s",
4447 fsname, BARRIER_FILENAME);
4448 /* Delete the barrier fsdb */
4449 mgs_remove_fsdb_by_name(mgs, barrier_name);
4450 /* Delete the fs db */
4451 mgs_remove_fsdb_by_name(mgs, fsname);
4452 mutex_unlock(&mgs->mgs_mutex);
4454 list_for_each_entry_safe(dirent, n, &log_list, mde_list) {
4455 list_del_init(&dirent->mde_list);
4456 suffix = strrchr(dirent->mde_name, '-');
4457 if (suffix != NULL) {
4458 if ((len == suffix - dirent->mde_name) &&
4459 (strncmp(fsname, dirent->mde_name, len) == 0)) {
4460 CDEBUG(D_MGS, "Removing log %s\n",
4462 mgs_erase_log(env, mgs, dirent->mde_name);
4466 mgs_direntry_free(dirent);
4475 /* list all logs for the given fs */
4476 int mgs_list_logs(const struct lu_env *env, struct mgs_device *mgs,
4477 struct obd_ioctl_data *data)
4479 struct list_head log_list;
4480 struct mgs_direntry *dirent, *n;
4481 char *out, *suffix, prefix[] = "config_log: ";
4482 int prefix_len = strlen(prefix);
4483 int l, remains, start = 0, rc;
4487 /* Find all the logs in the CONFIGS directory */
4488 rc = class_dentry_readdir(env, mgs, &log_list);
4492 out = data->ioc_bulk;
4493 remains = data->ioc_inllen1;
4494 /* OBD_FAIL: fetch the config_log records from the specified one */
4495 if (OBD_FAIL_CHECK(OBD_FAIL_CATLIST))
4496 data->ioc_count = cfs_fail_val;
4498 list_for_each_entry_safe(dirent, n, &log_list, mde_list) {
4499 list_del_init(&dirent->mde_list);
4500 suffix = strrchr(dirent->mde_name, '-');
4501 if (suffix != NULL) {
4502 l = prefix_len + dirent->mde_len + 1;
4503 if (remains - 1 < 0) {
4504 /* No enough space for this record */
4505 mgs_direntry_free(dirent);
4509 if (start < data->ioc_count) {
4510 mgs_direntry_free(dirent);
4513 l = scnprintf(out, remains, "%s%s\n", prefix,
4518 mgs_direntry_free(dirent);
4526 data->ioc_count = start;
4530 struct mgs_lcfg_fork_data {
4531 struct lustre_cfg_bufs mlfd_bufs;
4532 struct mgs_device *mlfd_mgs;
4533 struct llog_handle *mlfd_llh;
4534 const char *mlfd_oldname;
4535 const char *mlfd_newname;
4539 static bool contain_valid_fsname(char *buf, const char *fsname,
4540 int buflen, int namelen)
4542 if (buflen < namelen)
4545 if (memcmp(buf, fsname, namelen) != 0)
4548 if (buf[namelen] != '\0' && buf[namelen] != '-')
4554 static int mgs_lcfg_fork_handler(const struct lu_env *env,
4555 struct llog_handle *o_llh,
4556 struct llog_rec_hdr *o_rec, void *data)
4558 struct mgs_lcfg_fork_data *mlfd = data;
4559 struct lustre_cfg_bufs *n_bufs = &mlfd->mlfd_bufs;
4560 struct lustre_cfg *o_lcfg = (struct lustre_cfg *)(o_rec + 1);
4561 struct llog_cfg_rec *lcr;
4563 char *n_buf = mlfd->mlfd_data;
4565 int o_namelen = strlen(mlfd->mlfd_oldname);
4566 int n_namelen = strlen(mlfd->mlfd_newname);
4567 int diff = n_namelen - o_namelen;
4568 __u32 cmd = o_lcfg->lcfg_command;
4569 __u32 cnt = o_lcfg->lcfg_bufcount;
4575 o_buf = lustre_cfg_buf(o_lcfg, 0);
4576 o_buflen = o_lcfg->lcfg_buflens[0];
4577 if (contain_valid_fsname(o_buf, mlfd->mlfd_oldname, o_buflen,
4579 memcpy(n_buf, mlfd->mlfd_newname, n_namelen);
4580 memcpy(n_buf + n_namelen, o_buf + o_namelen,
4581 o_buflen - o_namelen);
4582 lustre_cfg_bufs_reset(n_bufs, n_buf);
4583 n_buf += cfs_size_round(o_buflen + diff);
4585 lustre_cfg_bufs_reset(n_bufs, o_buflen != 0 ? o_buf : NULL);
4590 struct cfg_marker *o_marker;
4591 struct cfg_marker *n_marker;
4595 CDEBUG(D_MGS, "Unknown cfg marker entry with %d "
4600 /* buf[1] is marker */
4601 o_buf = lustre_cfg_buf(o_lcfg, 1);
4602 o_buflen = o_lcfg->lcfg_buflens[1];
4603 o_marker = (struct cfg_marker *)o_buf;
4604 if (!contain_valid_fsname(o_marker->cm_tgtname,
4606 sizeof(o_marker->cm_tgtname),
4608 lustre_cfg_bufs_set(n_bufs, 1, o_marker,
4613 n_marker = (struct cfg_marker *)n_buf;
4614 *n_marker = *o_marker;
4615 memcpy(n_marker->cm_tgtname, mlfd->mlfd_newname, n_namelen);
4616 tgt_namelen = strlen(o_marker->cm_tgtname);
4617 if (tgt_namelen > o_namelen)
4618 memcpy(n_marker->cm_tgtname + n_namelen,
4619 o_marker->cm_tgtname + o_namelen,
4620 tgt_namelen - o_namelen);
4621 n_marker->cm_tgtname[tgt_namelen + diff] = '\0';
4622 lustre_cfg_bufs_set(n_bufs, 1, n_marker, sizeof(*n_marker));
4626 case LCFG_SET_PARAM: {
4627 for (i = 1; i < cnt; i++)
4628 /* buf[i] is the param value, reuse it directly */
4629 lustre_cfg_bufs_set(n_bufs, i,
4630 lustre_cfg_buf(o_lcfg, i),
4631 o_lcfg->lcfg_buflens[i]);
4637 case LCFG_POOL_DEL: {
4638 if (cnt < 3 || cnt > 4) {
4639 CDEBUG(D_MGS, "Unknown cfg pool (%x) entry with %d "
4640 "buffers\n", cmd, cnt);
4644 /* buf[1] is fsname */
4645 o_buf = lustre_cfg_buf(o_lcfg, 1);
4646 o_buflen = o_lcfg->lcfg_buflens[1];
4647 memcpy(n_buf, mlfd->mlfd_newname, n_namelen);
4648 memcpy(n_buf + n_namelen, o_buf + o_namelen,
4649 o_buflen - o_namelen);
4650 lustre_cfg_bufs_set(n_bufs, 1, n_buf, o_buflen + diff);
4651 n_buf += cfs_size_round(o_buflen + diff);
4653 /* buf[2] is the pool name, reuse it directly */
4654 lustre_cfg_bufs_set(n_bufs, 2, lustre_cfg_buf(o_lcfg, 2),
4655 o_lcfg->lcfg_buflens[2]);
4660 /* buf[3] is ostname */
4661 o_buf = lustre_cfg_buf(o_lcfg, 3);
4662 o_buflen = o_lcfg->lcfg_buflens[3];
4663 memcpy(n_buf, mlfd->mlfd_newname, n_namelen);
4664 memcpy(n_buf + n_namelen, o_buf + o_namelen,
4665 o_buflen - o_namelen);
4666 lustre_cfg_bufs_set(n_bufs, 3, n_buf, o_buflen + diff);
4671 o_buflen = o_lcfg->lcfg_buflens[1];
4672 if (o_buflen == sizeof(struct lov_desc) ||
4673 o_buflen == sizeof(struct lmv_desc)) {
4679 o_buf = lustre_cfg_buf(o_lcfg, 1);
4680 if (o_buflen == sizeof(struct lov_desc)) {
4681 struct lov_desc *o_desc =
4682 (struct lov_desc *)o_buf;
4683 struct lov_desc *n_desc =
4684 (struct lov_desc *)n_buf;
4687 o_uuid = o_desc->ld_uuid.uuid;
4688 n_uuid = n_desc->ld_uuid.uuid;
4689 uuid_len = sizeof(o_desc->ld_uuid.uuid);
4691 struct lmv_desc *o_desc =
4692 (struct lmv_desc *)o_buf;
4693 struct lmv_desc *n_desc =
4694 (struct lmv_desc *)n_buf;
4697 o_uuid = o_desc->ld_uuid.uuid;
4698 n_uuid = n_desc->ld_uuid.uuid;
4699 uuid_len = sizeof(o_desc->ld_uuid.uuid);
4702 if (unlikely(!contain_valid_fsname(o_uuid,
4703 mlfd->mlfd_oldname, uuid_len,
4705 lustre_cfg_bufs_set(n_bufs, 1, o_buf,
4710 memcpy(n_uuid, mlfd->mlfd_newname, n_namelen);
4711 uuid_len = strlen(o_uuid);
4712 if (uuid_len > o_namelen)
4713 memcpy(n_uuid + n_namelen,
4715 uuid_len - o_namelen);
4716 n_uuid[uuid_len + diff] = '\0';
4717 lustre_cfg_bufs_set(n_bufs, 1, n_buf, o_buflen);
4719 } /* else case fall through */
4720 } /* else case fall through */
4724 for (i = 1; i < cnt; i++) {
4725 o_buflen = o_lcfg->lcfg_buflens[i];
4729 o_buf = lustre_cfg_buf(o_lcfg, i);
4730 if (!contain_valid_fsname(o_buf, mlfd->mlfd_oldname,
4731 o_buflen, o_namelen)) {
4732 lustre_cfg_bufs_set(n_bufs, i, o_buf, o_buflen);
4736 memcpy(n_buf, mlfd->mlfd_newname, n_namelen);
4737 if (o_buflen == o_namelen) {
4738 lustre_cfg_bufs_set(n_bufs, i, n_buf,
4740 n_buf += cfs_size_round(n_namelen);
4744 memcpy(n_buf + n_namelen, o_buf + o_namelen,
4745 o_buflen - o_namelen);
4746 lustre_cfg_bufs_set(n_bufs, i, n_buf, o_buflen + diff);
4747 n_buf += cfs_size_round(o_buflen + diff);
4753 lcr = lustre_cfg_rec_new(cmd, n_bufs);
4757 lcr->lcr_cfg = *o_lcfg;
4758 rc = llog_write(env, mlfd->mlfd_llh, &lcr->lcr_hdr, LLOG_NEXT_IDX);
4759 lustre_cfg_rec_free(lcr);
4764 static int mgs_lcfg_fork_one(const struct lu_env *env, struct mgs_device *mgs,
4765 struct mgs_direntry *mde, const char *oldname,
4766 const char *newname)
4768 struct llog_handle *old_llh = NULL;
4769 struct llog_handle *new_llh = NULL;
4770 struct llog_ctxt *ctxt = NULL;
4771 struct mgs_lcfg_fork_data *mlfd = NULL;
4772 char *name_buf = NULL;
4774 int old_namelen = strlen(oldname);
4775 int new_namelen = strlen(newname);
4779 name_buflen = mde->mde_len + new_namelen - old_namelen;
4780 OBD_ALLOC(name_buf, name_buflen);
4784 memcpy(name_buf, newname, new_namelen);
4785 memcpy(name_buf + new_namelen, mde->mde_name + old_namelen,
4786 mde->mde_len - old_namelen);
4788 CDEBUG(D_MGS, "Fork the config-log from %s to %s\n",
4789 mde->mde_name, name_buf);
4791 ctxt = llog_get_context(mgs->mgs_obd, LLOG_CONFIG_ORIG_CTXT);
4794 rc = llog_open_create(env, ctxt, &new_llh, NULL, name_buf);
4798 rc = llog_init_handle(env, new_llh, LLOG_F_IS_PLAIN, NULL);
4802 if (unlikely(mgs_log_is_empty(env, mgs, mde->mde_name)))
4805 rc = llog_open(env, ctxt, &old_llh, NULL, mde->mde_name,
4810 rc = llog_init_handle(env, old_llh, LLOG_F_IS_PLAIN, NULL);
4814 new_llh->lgh_hdr->llh_tgtuuid = old_llh->lgh_hdr->llh_tgtuuid;
4816 OBD_ALLOC(mlfd, LLOG_MIN_CHUNK_SIZE);
4818 GOTO(out, rc = -ENOMEM);
4820 mlfd->mlfd_mgs = mgs;
4821 mlfd->mlfd_llh = new_llh;
4822 mlfd->mlfd_oldname = oldname;
4823 mlfd->mlfd_newname = newname;
4825 rc = llog_process(env, old_llh, mgs_lcfg_fork_handler, mlfd, NULL);
4826 OBD_FREE(mlfd, LLOG_MIN_CHUNK_SIZE);
4832 llog_close(env, old_llh);
4834 llog_close(env, new_llh);
4836 OBD_FREE(name_buf, name_buflen);
4838 llog_ctxt_put(ctxt);
4843 int mgs_lcfg_fork(const struct lu_env *env, struct mgs_device *mgs,
4844 const char *oldname, const char *newname)
4846 struct list_head log_list;
4847 struct mgs_direntry *dirent, *n;
4848 int olen = strlen(oldname);
4849 int nlen = strlen(newname);
4854 if (unlikely(!oldname || oldname[0] == '\0' ||
4855 !newname || newname[0] == '\0'))
4858 if (strcmp(oldname, newname) == 0)
4861 /* lock it to prevent fork/erase/register in parallel. */
4862 mutex_lock(&mgs->mgs_mutex);
4864 rc = class_dentry_readdir(env, mgs, &log_list);
4866 mutex_unlock(&mgs->mgs_mutex);
4870 if (list_empty(&log_list)) {
4871 mutex_unlock(&mgs->mgs_mutex);
4875 list_for_each_entry_safe(dirent, n, &log_list, mde_list) {
4878 ptr = strrchr(dirent->mde_name, '-');
4880 int tlen = ptr - dirent->mde_name;
4883 strncmp(newname, dirent->mde_name, tlen) == 0)
4884 GOTO(out, rc = -EEXIST);
4887 strncmp(oldname, dirent->mde_name, tlen) == 0)
4891 list_del_init(&dirent->mde_list);
4892 mgs_direntry_free(dirent);
4895 if (list_empty(&log_list)) {
4896 mutex_unlock(&mgs->mgs_mutex);
4900 list_for_each_entry(dirent, &log_list, mde_list) {
4901 rc = mgs_lcfg_fork_one(env, mgs, dirent, oldname, newname);
4909 mutex_unlock(&mgs->mgs_mutex);
4911 list_for_each_entry_safe(dirent, n, &log_list, mde_list) {
4912 list_del_init(&dirent->mde_list);
4913 mgs_direntry_free(dirent);
4916 if (rc && count > 0)
4917 mgs_erase_logs(env, mgs, newname);
4922 int mgs_lcfg_erase(const struct lu_env *env, struct mgs_device *mgs,
4928 if (unlikely(!fsname || fsname[0] == '\0'))
4931 rc = mgs_erase_logs(env, mgs, fsname);
4936 static int mgs_xattr_del(const struct lu_env *env, struct dt_object *obj)
4938 struct dt_device *dev;
4939 struct thandle *th = NULL;
4944 dev = container_of(obj->do_lu.lo_dev, struct dt_device, dd_lu_dev);
4945 th = dt_trans_create(env, dev);
4947 RETURN(PTR_ERR(th));
4949 rc = dt_declare_xattr_del(env, obj, XATTR_TARGET_RENAME, th);
4953 rc = dt_trans_start_local(env, dev, th);
4957 dt_write_lock(env, obj, 0);
4958 rc = dt_xattr_del(env, obj, XATTR_TARGET_RENAME, th);
4963 dt_write_unlock(env, obj);
4966 dt_trans_stop(env, dev, th);
4971 int mgs_lcfg_rename(const struct lu_env *env, struct mgs_device *mgs)
4973 struct list_head log_list;
4974 struct mgs_direntry *dirent, *n;
4976 struct lu_buf buf = {
4978 .lb_len = sizeof(fsname)
4984 rc = class_dentry_readdir(env, mgs, &log_list);
4988 if (list_empty(&log_list))
4991 list_for_each_entry_safe(dirent, n, &log_list, mde_list) {
4992 struct dt_object *o = NULL;
4997 list_del_init(&dirent->mde_list);
4998 ptr = strrchr(dirent->mde_name, '-');
5002 len = ptr - dirent->mde_name;
5003 if (unlikely(len >= sizeof(oldname))) {
5004 CDEBUG(D_MGS, "Skip invalid configuration file %s\n",
5009 o = local_file_find(env, mgs->mgs_los, mgs->mgs_configs_dir,
5013 CDEBUG(D_MGS, "Fail to locate file %s: rc = %d\n",
5014 dirent->mde_name, rc);
5018 rc = dt_xattr_get(env, o, &buf, XATTR_TARGET_RENAME);
5024 "Fail to get EA for %s: rc = %d\n",
5025 dirent->mde_name, rc);
5029 if (unlikely(rc == len &&
5030 memcmp(fsname, dirent->mde_name, len) == 0)) {
5031 /* The new fsname is the same as the old one. */
5032 rc = mgs_xattr_del(env, o);
5036 memcpy(oldname, dirent->mde_name, len);
5037 oldname[len] = '\0';
5039 rc = mgs_lcfg_fork_one(env, mgs, dirent, oldname, fsname);
5040 if (rc && rc != -EEXIST) {
5041 CDEBUG(D_MGS, "Fail to fork %s: rc = %d\n",
5042 dirent->mde_name, rc);
5046 rc = mgs_erase_log(env, mgs, dirent->mde_name);
5048 CDEBUG(D_MGS, "Fail to erase old %s: rc = %d\n",
5049 dirent->mde_name, rc);
5050 /* keep it there if failed to remove it. */
5055 if (o && !IS_ERR(o))
5056 lu_object_put(env, &o->do_lu);
5058 mgs_direntry_free(dirent);
5063 list_for_each_entry_safe(dirent, n, &log_list, mde_list) {
5064 list_del_init(&dirent->mde_list);
5065 mgs_direntry_free(dirent);
5071 /* Setup _mgs fsdb and log
5073 int mgs__mgs_fsdb_setup(const struct lu_env *env, struct mgs_device *mgs)
5075 struct fs_db *fsdb = NULL;
5079 rc = mgs_find_or_make_fsdb(env, mgs, MGSSELF_NAME, &fsdb);
5081 mgs_put_fsdb(mgs, fsdb);
5086 /* Setup params fsdb and log
5088 int mgs_params_fsdb_setup(const struct lu_env *env, struct mgs_device *mgs)
5090 struct fs_db *fsdb = NULL;
5091 struct llog_handle *params_llh = NULL;
5095 rc = mgs_find_or_make_fsdb(env, mgs, PARAMS_FILENAME, &fsdb);
5097 mutex_lock(&fsdb->fsdb_mutex);
5098 rc = record_start_log(env, mgs, ¶ms_llh, PARAMS_FILENAME);
5100 rc = record_end_log(env, ¶ms_llh);
5101 mutex_unlock(&fsdb->fsdb_mutex);
5102 mgs_put_fsdb(mgs, fsdb);
5108 /* Cleanup params fsdb and log
5110 int mgs_params_fsdb_cleanup(const struct lu_env *env, struct mgs_device *mgs)
5114 rc = mgs_erase_logs(env, mgs, PARAMS_FILENAME);
5115 return rc == -ENOENT ? 0 : rc;
5119 * Fill in the mgs_target_info based on data devname and param provide.
5121 * @env thread context
5123 * @mti mgs target info. We want to set this based other paramters
5124 * passed to this function. Once setup we write it to the config
5126 * @devname optional OBD device name
5127 * @param string that contains both what tunable to set and the value to
5130 * RETURN 0 for success
5131 * negative error number on failure
5133 static int mgs_set_conf_param(const struct lu_env *env, struct mgs_device *mgs,
5134 struct mgs_target_info *mti, const char *devname,
5137 struct fs_db *fsdb = NULL;
5142 /* lustre, lustre-mdtlov, lustre-client, lustre-MDT0000 */
5146 /* We have two possible cases here:
5148 * 1) the device name embedded in the param:
5149 * lustre-OST0000.osc.max_dirty_mb=32
5151 * 2) the file system name is embedded in
5152 * the param: lustre.sys.at.min=0
5154 len = strcspn(param, ".=");
5155 if (!len || param[len] == '=')
5158 if (len >= sizeof(mti->mti_svname))
5161 snprintf(mti->mti_svname, sizeof(mti->mti_svname),
5162 "%.*s", (int)len, param);
5165 if (strlcpy(mti->mti_svname, devname, sizeof(mti->mti_svname)) >=
5166 sizeof(mti->mti_svname))
5170 if (!strlen(mti->mti_svname)) {
5171 LCONSOLE_ERROR_MSG(0x14d, "No target specified: %s\n", param);
5175 dev_type = mgs_parse_devname(mti->mti_svname, mti->mti_fsname,
5176 &mti->mti_stripe_index);
5178 /* For this case we have an invalid obd device name */
5180 CDEBUG(D_MGS, "%s don't contain an index\n", mti->mti_svname);
5181 strlcpy(mti->mti_fsname, mti->mti_svname, MTI_NAME_MAXLEN);
5184 /* Not an obd device, assume devname is the fsname.
5185 * User might of only provided fsname and not obd device
5188 CDEBUG(D_MGS, "%s is seen as a file system name\n", mti->mti_svname);
5189 strlcpy(mti->mti_fsname, mti->mti_svname, MTI_NAME_MAXLEN);
5194 GOTO(out, rc = dev_type);
5196 /* param related to llite isn't allowed to set by OST or MDT */
5197 if (dev_type & LDD_F_SV_TYPE_OST ||
5198 dev_type & LDD_F_SV_TYPE_MDT) {
5199 /* param related to llite isn't allowed to set by OST
5202 if (!strncmp(param, PARAM_LLITE,
5203 sizeof(PARAM_LLITE) - 1))
5204 GOTO(out, rc = -EINVAL);
5206 /* Strip -osc or -mdc suffix from svname */
5207 if (server_make_name(dev_type, mti->mti_stripe_index,
5208 mti->mti_fsname, mti->mti_svname,
5209 sizeof(mti->mti_svname)))
5210 GOTO(out, rc = -EINVAL);
5215 if (strlcpy(mti->mti_params, param, sizeof(mti->mti_params)) >=
5216 sizeof(mti->mti_params))
5217 GOTO(out, rc = -E2BIG);
5219 CDEBUG(D_MGS, "set_conf_param fs='%s' device='%s' param='%s'\n",
5220 mti->mti_fsname, mti->mti_svname, mti->mti_params);
5222 rc = mgs_find_or_make_fsdb(env, mgs, mti->mti_fsname, &fsdb);
5226 if (!test_bit(FSDB_MGS_SELF, &fsdb->fsdb_flags) &&
5227 test_bit(FSDB_LOG_EMPTY, &fsdb->fsdb_flags)) {
5228 CERROR("No filesystem targets for %s. cfg_device from lctl "
5229 "is '%s'\n", mti->mti_fsname, mti->mti_svname);
5230 mgs_unlink_fsdb(mgs, fsdb);
5231 GOTO(out, rc = -EINVAL);
5235 * Revoke lock so everyone updates. Should be alright if
5236 * someone was already reading while we were updating the logs,
5237 * so we don't really need to hold the lock while we're
5240 mti->mti_flags = dev_type | LDD_F_PARAM;
5241 mutex_lock(&fsdb->fsdb_mutex);
5242 rc = mgs_write_log_param(env, mgs, fsdb, mti, mti->mti_params);
5243 mutex_unlock(&fsdb->fsdb_mutex);
5244 mgs_revoke_lock(mgs, fsdb, CONFIG_T_CONFIG);
5248 mgs_put_fsdb(mgs, fsdb);
5253 static int mgs_set_param2(const struct lu_env *env, struct mgs_device *mgs,
5254 struct mgs_target_info *mti, const char *param)
5256 struct fs_db *fsdb = NULL;
5261 if (strlcpy(mti->mti_params, param, sizeof(mti->mti_params)) >=
5262 sizeof(mti->mti_params))
5263 GOTO(out, rc = -E2BIG);
5265 len = strcspn(param, ".=");
5266 if (len && param[len] != '=') {
5267 struct list_head *tmp;
5271 ptr = strchr(param, '.');
5273 len = strlen(param);
5276 if (len >= sizeof(mti->mti_svname))
5277 GOTO(out, rc = -E2BIG);
5279 snprintf(mti->mti_svname, sizeof(mti->mti_svname), "%.*s",
5282 mutex_lock(&mgs->mgs_mutex);
5283 if (unlikely(list_empty(&mgs->mgs_fs_db_list))) {
5284 mutex_unlock(&mgs->mgs_mutex);
5285 GOTO(out, rc = -ENODEV);
5288 list_for_each(tmp, &mgs->mgs_fs_db_list) {
5289 fsdb = list_entry(tmp, struct fs_db, fsdb_list);
5290 if (fsdb->fsdb_has_lproc_entry &&
5291 strcmp(fsdb->fsdb_name, "params") != 0 &&
5292 strstr(param, fsdb->fsdb_name)) {
5293 snprintf(mti->mti_svname,
5294 sizeof(mti->mti_svname), "%s",
5302 snprintf(mti->mti_svname, sizeof(mti->mti_svname),
5305 mutex_unlock(&mgs->mgs_mutex);
5307 snprintf(mti->mti_svname, sizeof(mti->mti_svname), "general");
5310 CDEBUG(D_MGS, "set_param2 fs='%s' device='%s' param='%s'\n",
5311 mti->mti_fsname, mti->mti_svname, mti->mti_params);
5313 /* The return value should be the device type i.e LDD_F_SV_TYPE_XXX.
5314 * A returned error tells us we don't have a target obd device.
5316 dev_type = server_name2index(mti->mti_svname, &mti->mti_stripe_index,
5321 /* the return value should be the device type i.e LDD_F_SV_TYPE_XXX.
5322 * Strip -osc or -mdc suffix from svname
5324 if ((dev_type & LDD_F_SV_TYPE_OST || dev_type & LDD_F_SV_TYPE_MDT) &&
5325 server_make_name(dev_type, mti->mti_stripe_index,
5326 mti->mti_fsname, mti->mti_svname,
5327 sizeof(mti->mti_svname)))
5328 GOTO(out, rc = -EINVAL);
5330 rc = mgs_find_or_make_fsdb(env, mgs, PARAMS_FILENAME, &fsdb);
5334 * Revoke lock so everyone updates. Should be alright if
5335 * someone was already reading while we were updating the logs,
5336 * so we don't really need to hold the lock while we're
5339 mti->mti_flags = dev_type | LDD_F_PARAM2;
5340 mutex_lock(&fsdb->fsdb_mutex);
5341 rc = mgs_write_log_param2(env, mgs, fsdb, mti, mti->mti_params);
5342 mutex_unlock(&fsdb->fsdb_mutex);
5343 mgs_revoke_lock(mgs, fsdb, CONFIG_T_PARAMS);
5344 mgs_put_fsdb(mgs, fsdb);
5349 /* Set a permanent (config log) param for a target or fs
5351 * @lcfg buf0 may contain the device (testfs-MDT0000) name
5352 * buf1 contains the single parameter
5354 int mgs_set_param(const struct lu_env *env, struct mgs_device *mgs,
5355 struct lustre_cfg *lcfg)
5357 const char *param = lustre_cfg_string(lcfg, 1);
5358 struct mgs_target_info *mti;
5361 /* Create a fake mti to hold everything */
5366 print_lustre_cfg(lcfg);
5368 if (lcfg->lcfg_command == LCFG_PARAM) {
5369 /* For the case of lctl conf_param devname can be
5370 * lustre, lustre-mdtlov, lustre-client, lustre-MDT0000
5372 const char *devname = lustre_cfg_string(lcfg, 0);
5374 rc = mgs_set_conf_param(env, mgs, mti, devname, param);
5376 /* In the case of lctl set_param -P lcfg[0] will always
5377 * be 'general'. At least for now.
5379 rc = mgs_set_param2(env, mgs, mti, param);
5387 static int mgs_write_log_pool(const struct lu_env *env,
5388 struct mgs_device *mgs, char *logname,
5389 struct fs_db *fsdb, char *tgtname,
5390 enum lcfg_command_type cmd,
5391 char *fsname, char *poolname,
5392 char *ostname, char *comment)
5394 struct llog_handle *llh = NULL;
5397 rc = record_start_log(env, mgs, &llh, logname);
5400 rc = record_marker(env, llh, fsdb, CM_START, tgtname, comment);
5403 rc = record_base(env, llh, tgtname, 0, cmd,
5404 fsname, poolname, ostname, NULL);
5407 rc = record_marker(env, llh, fsdb, CM_END, tgtname, comment);
5409 record_end_log(env, &llh);
5413 int mgs_nodemap_cmd(const struct lu_env *env, struct mgs_device *mgs,
5414 enum lcfg_command_type cmd, const char *nodemap_name,
5425 case LCFG_NODEMAP_ADD:
5426 rc = nodemap_add(nodemap_name);
5428 case LCFG_NODEMAP_DEL:
5429 rc = nodemap_del(nodemap_name);
5431 case LCFG_NODEMAP_ADD_RANGE:
5432 rc = nodemap_parse_range(param, nid);
5435 rc = nodemap_add_range(nodemap_name, nid);
5437 case LCFG_NODEMAP_DEL_RANGE:
5438 rc = nodemap_parse_range(param, nid);
5441 rc = nodemap_del_range(nodemap_name, nid);
5443 case LCFG_NODEMAP_ADMIN:
5444 rc = kstrtobool(param, &bool_switch);
5447 rc = nodemap_set_allow_root(nodemap_name, bool_switch);
5449 case LCFG_NODEMAP_DENY_UNKNOWN:
5450 rc = kstrtobool(param, &bool_switch);
5453 rc = nodemap_set_deny_unknown(nodemap_name, bool_switch);
5455 case LCFG_NODEMAP_AUDIT_MODE:
5456 rc = kstrtobool(param, &bool_switch);
5458 rc = nodemap_set_audit_mode(nodemap_name, bool_switch);
5460 case LCFG_NODEMAP_FORBID_ENCRYPT:
5461 rc = kstrtobool(param, &bool_switch);
5463 rc = nodemap_set_forbid_encryption(nodemap_name,
5466 case LCFG_NODEMAP_MAP_MODE:
5467 if (strcmp("both", param) == 0)
5468 rc = nodemap_set_mapping_mode(nodemap_name,
5470 else if (strcmp("uid_only", param) == 0)
5471 rc = nodemap_set_mapping_mode(nodemap_name,
5472 NODEMAP_MAP_UID_ONLY);
5473 else if (strcmp("gid_only", param) == 0)
5474 rc = nodemap_set_mapping_mode(nodemap_name,
5475 NODEMAP_MAP_GID_ONLY);
5479 case LCFG_NODEMAP_TRUSTED:
5480 rc = kstrtobool(param, &bool_switch);
5483 rc = nodemap_set_trust_client_ids(nodemap_name, bool_switch);
5485 case LCFG_NODEMAP_SQUASH_UID:
5486 rc = kstrtouint(param, 10, &int_id);
5489 rc = nodemap_set_squash_uid(nodemap_name, int_id);
5491 case LCFG_NODEMAP_SQUASH_GID:
5492 rc = kstrtouint(param, 10, &int_id);
5495 rc = nodemap_set_squash_gid(nodemap_name, int_id);
5497 case LCFG_NODEMAP_ADD_UIDMAP:
5498 case LCFG_NODEMAP_ADD_GIDMAP:
5499 rc = nodemap_parse_idmap(param, idmap);
5502 if (cmd == LCFG_NODEMAP_ADD_UIDMAP)
5503 rc = nodemap_add_idmap(nodemap_name, NODEMAP_UID,
5506 rc = nodemap_add_idmap(nodemap_name, NODEMAP_GID,
5509 case LCFG_NODEMAP_DEL_UIDMAP:
5510 case LCFG_NODEMAP_DEL_GIDMAP:
5511 rc = nodemap_parse_idmap(param, idmap);
5514 if (cmd == LCFG_NODEMAP_DEL_UIDMAP)
5515 rc = nodemap_del_idmap(nodemap_name, NODEMAP_UID,
5518 rc = nodemap_del_idmap(nodemap_name, NODEMAP_GID,
5521 case LCFG_NODEMAP_SET_FILESET:
5522 rc = nodemap_set_fileset(nodemap_name, param);
5524 case LCFG_NODEMAP_SET_SEPOL:
5525 rc = nodemap_set_sepol(nodemap_name, param);
5534 int mgs_pool_cmd(const struct lu_env *env, struct mgs_device *mgs,
5535 enum lcfg_command_type cmd, char *fsname,
5536 char *poolname, char *ostname)
5541 char *label = NULL, *canceled_label = NULL;
5543 struct mgs_target_info *mti = NULL;
5544 bool checked = false;
5545 bool locked = false;
5550 rc = mgs_find_or_make_fsdb(env, mgs, fsname, &fsdb);
5552 CERROR("Can't get db for %s\n", fsname);
5555 if (test_bit(FSDB_LOG_EMPTY, &fsdb->fsdb_flags)) {
5556 CERROR("%s is not defined\n", fsname);
5558 GOTO(out_fsdb, rc = -EINVAL);
5561 label_sz = 10 + strlen(fsname) + strlen(poolname);
5563 /* check if ostname match fsname */
5564 if (ostname != NULL) {
5567 ptr = strrchr(ostname, '-');
5568 if ((ptr == NULL) ||
5569 (strncmp(fsname, ostname, ptr-ostname) != 0))
5571 label_sz += strlen(ostname);
5574 OBD_ALLOC(label, label_sz);
5576 GOTO(out_fsdb, rc = -ENOMEM);
5581 "new %s.%s", fsname, poolname);
5585 "add %s.%s.%s", fsname, poolname, ostname);
5588 OBD_ALLOC(canceled_label, label_sz);
5589 if (canceled_label == NULL)
5590 GOTO(out_label, rc = -ENOMEM);
5592 "rem %s.%s.%s", fsname, poolname, ostname);
5593 sprintf(canceled_label,
5594 "add %s.%s.%s", fsname, poolname, ostname);
5597 OBD_ALLOC(canceled_label, label_sz);
5598 if (canceled_label == NULL)
5599 GOTO(out_label, rc = -ENOMEM);
5601 "del %s.%s", fsname, poolname);
5602 sprintf(canceled_label,
5603 "new %s.%s", fsname, poolname);
5611 GOTO(out_cancel, rc = -ENOMEM);
5612 strncpy(mti->mti_svname, "lov pool", sizeof(mti->mti_svname));
5614 mutex_lock(&fsdb->fsdb_mutex);
5616 /* write pool def to all MDT logs */
5617 for (i = 0; i < INDEX_MAP_SIZE * 8; i++) {
5618 if (test_bit(i, fsdb->fsdb_mdt_index_map)) {
5619 rc = name_create_mdt_and_lov(&logname, &lovname,
5624 if (!checked && (canceled_label == NULL)) {
5625 rc = mgs_check_marker(env, mgs, fsdb, mti,
5626 logname, lovname, label);
5628 name_destroy(&logname);
5629 name_destroy(&lovname);
5631 rc = (rc == LLOG_PROC_BREAK ?
5636 if (canceled_label != NULL)
5637 rc = mgs_modify(env, mgs, fsdb, mti, logname,
5638 lovname, canceled_label,
5642 rc = mgs_write_log_pool(env, mgs, logname,
5646 name_destroy(&logname);
5647 name_destroy(&lovname);
5653 rc = name_create(&logname, fsname, "-client");
5657 if (!checked && (canceled_label == NULL)) {
5658 rc = mgs_check_marker(env, mgs, fsdb, mti, logname,
5659 fsdb->fsdb_clilov, label);
5661 name_destroy(&logname);
5662 GOTO(out_mti, rc = (rc == LLOG_PROC_BREAK ?
5666 if (canceled_label != NULL) {
5667 rc = mgs_modify(env, mgs, fsdb, mti, logname,
5668 fsdb->fsdb_clilov, canceled_label, CM_SKIP);
5670 name_destroy(&logname);
5675 rc = mgs_write_log_pool(env, mgs, logname, fsdb, fsdb->fsdb_clilov,
5676 cmd, fsname, poolname, ostname, label);
5677 mutex_unlock(&fsdb->fsdb_mutex);
5679 name_destroy(&logname);
5680 /* request for update */
5681 mgs_revoke_lock(mgs, fsdb, CONFIG_T_CONFIG);
5687 mutex_unlock(&fsdb->fsdb_mutex);
5691 if (canceled_label != NULL)
5692 OBD_FREE(canceled_label, label_sz);
5694 OBD_FREE(label, label_sz);
5697 mgs_unlink_fsdb(mgs, fsdb);
5698 mgs_put_fsdb(mgs, fsdb);