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 if (!strncmp(marker->cm_comment,
1029 "add failnid", 11)) {
1030 mrd->state = REPLACE_SKIP;
1032 mrd->state = REPLACE_UUID;
1033 mrd->failover = NULL;
1035 } else if (marker->cm_flags & CM_END)
1036 mrd->state = REPLACE_COPY;
1038 if (!strncmp(marker->cm_comment,
1047 static int record_base(const struct lu_env *env, struct llog_handle *llh,
1048 char *cfgname, lnet_nid_t nid, int cmd,
1049 char *s1, char *s2, char *s3, char *s4)
1051 struct mgs_thread_info *mgi = mgs_env_info(env);
1052 struct llog_cfg_rec *lcr;
1055 CDEBUG(D_MGS, "lcfg %s %#x %s %s %s %s\n", cfgname,
1056 cmd, s1, s2, s3, s4);
1058 lustre_cfg_bufs_reset(&mgi->mgi_bufs, cfgname);
1060 lustre_cfg_bufs_set_string(&mgi->mgi_bufs, 1, s1);
1062 lustre_cfg_bufs_set_string(&mgi->mgi_bufs, 2, s2);
1064 lustre_cfg_bufs_set_string(&mgi->mgi_bufs, 3, s3);
1066 lustre_cfg_bufs_set_string(&mgi->mgi_bufs, 4, s4);
1068 lcr = lustre_cfg_rec_new(cmd, &mgi->mgi_bufs);
1072 lcr->lcr_cfg.lcfg_nid = nid;
1073 rc = llog_write(env, llh, &lcr->lcr_hdr, LLOG_NEXT_IDX);
1075 lustre_cfg_rec_free(lcr);
1079 "failed to write lcfg %s %#x %s %s %s %s: rc = %d\n",
1080 cfgname, cmd, s1, s2, s3, s4, rc);
1084 static inline int record_add_uuid(const struct lu_env *env,
1085 struct llog_handle *llh,
1086 uint64_t nid, char *uuid)
1088 return record_base(env, llh, NULL, nid, LCFG_ADD_UUID, uuid,
1092 static inline int record_add_conn(const struct lu_env *env,
1093 struct llog_handle *llh,
1094 char *devname, char *uuid)
1096 return record_base(env, llh, devname, 0, LCFG_ADD_CONN, uuid,
1100 static inline int record_attach(const struct lu_env *env,
1101 struct llog_handle *llh, char *devname,
1102 char *type, char *uuid)
1104 return record_base(env, llh, devname, 0, LCFG_ATTACH, type, uuid,
1108 static inline int record_setup(const struct lu_env *env,
1109 struct llog_handle *llh, char *devname,
1110 char *s1, char *s2, char *s3, char *s4)
1112 return record_base(env, llh, devname, 0, LCFG_SETUP, s1, s2, s3, s4);
1116 * \retval <0 record processing error
1117 * \retval n record is processed. No need copy original one.
1118 * \retval 0 record is not processed.
1120 static int process_command(const struct lu_env *env, struct lustre_cfg *lcfg,
1121 struct mgs_replace_data *mrd)
1128 if (mrd->state == REPLACE_UUID &&
1129 lcfg->lcfg_command == LCFG_ADD_UUID) {
1130 /* LCFG_ADD_UUID command found. Let's skip original command
1131 and add passed nids */
1132 ptr = mrd->target.mti_params;
1133 while (class_parse_nid(ptr, &nid, &ptr) == 0) {
1134 if (!mrd->nodeuuid) {
1135 rc = name_create(&mrd->nodeuuid,
1136 libcfs_nid2str(nid), "");
1138 CERROR("Can't create uuid for "
1139 "nid %s, device %s\n",
1140 libcfs_nid2str(nid),
1141 mrd->target.mti_svname);
1145 CDEBUG(D_MGS, "add nid %s with uuid %s, "
1146 "device %s\n", libcfs_nid2str(nid),
1147 mrd->target.mti_params,
1149 rc = record_add_uuid(env,
1156 mrd->failover = ptr;
1161 if (nids_added == 0) {
1162 CERROR("No new nids were added, nid %s with uuid %s, "
1163 "device %s\n", libcfs_nid2str(nid),
1164 mrd->nodeuuid ? mrd->nodeuuid : "NULL",
1165 mrd->target.mti_svname);
1166 name_destroy(&mrd->nodeuuid);
1169 mrd->state = REPLACE_SETUP;
1175 if (mrd->state == REPLACE_SETUP && lcfg->lcfg_command == LCFG_SETUP) {
1176 /* LCFG_SETUP command found. UUID should be changed */
1177 rc = record_setup(env,
1179 /* devname the same */
1180 lustre_cfg_string(lcfg, 0),
1181 /* s1 is not changed */
1182 lustre_cfg_string(lcfg, 1),
1184 /* s3 is not changed */
1185 lustre_cfg_string(lcfg, 3),
1186 /* s4 is not changed */
1187 lustre_cfg_string(lcfg, 4));
1189 name_destroy(&mrd->nodeuuid);
1193 if (mrd->failover) {
1194 ptr = mrd->failover;
1195 while (class_parse_nid(ptr, &nid, &ptr) == 0) {
1196 if (mrd->nodeuuid == NULL) {
1197 rc = name_create(&mrd->nodeuuid,
1198 libcfs_nid2str(nid),
1204 CDEBUG(D_MGS, "add nid %s for failover %s\n",
1205 libcfs_nid2str(nid), mrd->nodeuuid);
1206 rc = record_add_uuid(env, mrd->temp_llh, nid,
1209 name_destroy(&mrd->nodeuuid);
1213 rc = record_add_conn(env,
1215 lustre_cfg_string(lcfg, 0),
1217 name_destroy(&mrd->nodeuuid);
1222 if (mrd->nodeuuid) {
1223 rc = record_add_conn(env, mrd->temp_llh,
1224 lustre_cfg_string(lcfg, 0),
1226 name_destroy(&mrd->nodeuuid);
1231 mrd->state = REPLACE_DONE;
1235 /* All new UUID are added. Skip. */
1236 if (mrd->state == REPLACE_SETUP &&
1237 lcfg->lcfg_command == LCFG_ADD_UUID)
1240 /* Another commands in target device block */
1245 * Handler that called for every record in llog.
1246 * Records are processed in order they placed in llog.
1248 * \param[in] llh log to be processed
1249 * \param[in] rec current record
1250 * \param[in] data mgs_replace_data structure
1254 static int mgs_replace_nids_handler(const struct lu_env *env,
1255 struct llog_handle *llh,
1256 struct llog_rec_hdr *rec,
1259 struct mgs_replace_data *mrd;
1260 struct lustre_cfg *lcfg = REC_DATA(rec);
1261 int cfg_len = REC_DATA_LEN(rec);
1265 mrd = (struct mgs_replace_data *)data;
1267 if (rec->lrh_type != OBD_CFG_REC) {
1268 CERROR("unhandled lrh_type: %#x, cmd %x %s %s\n",
1269 rec->lrh_type, lcfg->lcfg_command,
1270 lustre_cfg_string(lcfg, 0),
1271 lustre_cfg_string(lcfg, 1));
1275 rc = lustre_cfg_sanity_check(lcfg, cfg_len);
1277 /* Do not copy any invalidated records */
1278 GOTO(skip_out, rc = 0);
1281 rc = check_markers(lcfg, mrd);
1282 if (rc || mrd->state == REPLACE_SKIP)
1283 GOTO(skip_out, rc = 0);
1285 /* Write to new log all commands outside target device block */
1286 if (mrd->state == REPLACE_COPY)
1287 GOTO(copy_out, rc = 0);
1289 if (mrd->state == REPLACE_DONE &&
1290 (lcfg->lcfg_command == LCFG_ADD_UUID ||
1291 lcfg->lcfg_command == LCFG_ADD_CONN)) {
1293 CWARN("Previous failover is deleted, but new one is "
1294 "not set. This means you configure system "
1295 "without failover or passed wrong replace_nids "
1296 "command parameters. Device %s, passed nids %s\n",
1297 mrd->target.mti_svname, mrd->target.mti_params);
1298 GOTO(skip_out, rc = 0);
1301 rc = process_command(env, lcfg, mrd);
1308 /* Record is placed in temporary llog as is */
1309 rc = llog_write(env, mrd->temp_llh, rec, LLOG_NEXT_IDX);
1311 CDEBUG(D_MGS, "Copied idx=%d, rc=%d, len=%d, cmd %x %s %s\n",
1312 rec->lrh_index, rc, rec->lrh_len, lcfg->lcfg_command,
1313 lustre_cfg_string(lcfg, 0), lustre_cfg_string(lcfg, 1));
1317 CDEBUG(D_MGS, "Skipped idx=%d, rc=%d, len=%d, cmd %x %s %s\n",
1318 rec->lrh_index, rc, rec->lrh_len, lcfg->lcfg_command,
1319 lustre_cfg_string(lcfg, 0), lustre_cfg_string(lcfg, 1));
1323 static int mgs_log_is_empty(const struct lu_env *env,
1324 struct mgs_device *mgs, char *name)
1326 struct llog_ctxt *ctxt;
1329 ctxt = llog_get_context(mgs->mgs_obd, LLOG_CONFIG_ORIG_CTXT);
1330 LASSERT(ctxt != NULL);
1332 rc = llog_is_empty(env, ctxt, name);
1333 llog_ctxt_put(ctxt);
1337 static int mgs_replace_log(const struct lu_env *env,
1338 struct obd_device *mgs,
1339 char *logname, char *devname,
1340 llog_cb_t replace_handler, void *data)
1342 struct llog_handle *orig_llh, *backup_llh;
1343 struct llog_ctxt *ctxt;
1344 struct mgs_replace_data *mrd;
1345 struct mgs_device *mgs_dev = lu2mgs_dev(mgs->obd_lu_dev);
1346 static struct obd_uuid cfg_uuid = { .uuid = "config_uuid" };
1348 int rc, rc2, buf_size;
1352 ctxt = llog_get_context(mgs, LLOG_CONFIG_ORIG_CTXT);
1353 LASSERT(ctxt != NULL);
1355 if (mgs_log_is_empty(env, mgs_dev, logname)) {
1356 /* Log is empty. Nothing to replace */
1357 GOTO(out_put, rc = 0);
1360 now = ktime_get_real_seconds();
1362 /* max time64_t in decimal fits into 20 bytes long string */
1363 buf_size = strlen(logname) + 1 + 20 + 1 + strlen(".bak") + 1;
1364 OBD_ALLOC(backup, buf_size);
1366 GOTO(out_put, rc = -ENOMEM);
1368 snprintf(backup, buf_size, "%s.%llu.bak", logname, now);
1370 rc = llog_backup(env, mgs, ctxt, ctxt, logname, backup);
1372 /* Now erase original log file. Connections are not allowed.
1373 Backup is already saved */
1374 rc = llog_erase(env, ctxt, NULL, logname);
1377 } else if (rc != -ENOENT) {
1378 CERROR("%s: can't make backup for %s: rc = %d\n",
1379 mgs->obd_name, logname, rc);
1383 /* open local log */
1384 rc = llog_open_create(env, ctxt, &orig_llh, NULL, logname);
1386 GOTO(out_restore, rc);
1388 rc = llog_init_handle(env, orig_llh, LLOG_F_IS_PLAIN, &cfg_uuid);
1390 GOTO(out_closel, rc);
1392 /* open backup llog */
1393 rc = llog_open(env, ctxt, &backup_llh, NULL, backup,
1396 GOTO(out_closel, rc);
1398 rc = llog_init_handle(env, backup_llh, LLOG_F_IS_PLAIN, NULL);
1400 GOTO(out_close, rc);
1402 if (llog_get_size(backup_llh) <= 1)
1403 GOTO(out_close, rc = 0);
1407 GOTO(out_close, rc = -ENOMEM);
1408 /* devname is only needed information to replace UUID records */
1410 strlcpy(mrd->target.mti_svname, devname,
1411 sizeof(mrd->target.mti_svname));
1412 /* data is parsed in llog callback */
1414 strlcpy(mrd->target.mti_params, data,
1415 sizeof(mrd->target.mti_params));
1416 /* Copy records to this temporary llog */
1417 mrd->temp_llh = orig_llh;
1419 rc = llog_process(env, backup_llh, replace_handler,
1423 rc2 = llog_close(NULL, backup_llh);
1427 rc2 = llog_close(NULL, orig_llh);
1433 CERROR("%s: llog should be restored: rc = %d\n",
1435 rc2 = llog_backup(env, mgs, ctxt, ctxt, backup,
1438 CERROR("%s: can't restore backup %s: rc = %d\n",
1439 mgs->obd_name, logname, rc2);
1443 OBD_FREE(backup, buf_size);
1446 llog_ctxt_put(ctxt);
1449 CERROR("%s: failed to replace log %s: rc = %d\n",
1450 mgs->obd_name, logname, rc);
1455 static int mgs_replace_nids_log(const struct lu_env *env,
1456 struct obd_device *obd,
1457 char *logname, char *devname, char *nids)
1459 CDEBUG(D_MGS, "Replace NIDs for %s in %s\n", devname, logname);
1460 return mgs_replace_log(env, obd, logname, devname,
1461 mgs_replace_nids_handler, nids);
1465 * Parse device name and get file system name and/or device index
1467 * @devname device name (ex. lustre-MDT0000)
1468 * @fsname file system name extracted from @devname and returned
1469 * to the caller (optional)
1470 * @index device index extracted from @devname and returned to
1471 * the caller (optional)
1473 * RETURN 0 success if we are only interested in
1474 * extracting fsname from devname.
1477 * LDD_F_SV_TYPE_* Besides extracting the fsname the
1478 * user also wants the index. Report to
1479 * the user the type of obd device the
1480 * returned index belongs too.
1482 * -EINVAL The obd device name is improper so
1483 * fsname could not be extracted.
1485 * -ENXIO Failed to extract the index out of
1486 * the obd device name. Most likely an
1487 * invalid obd device name
1489 static int mgs_parse_devname(char *devname, char *fsname, u32 *index)
1494 /* Extract fsname */
1496 rc = server_name2fsname(devname, fsname, NULL);
1498 CDEBUG(D_MGS, "Device name %s without fsname\n",
1505 rc = server_name2index(devname, index, NULL);
1507 CDEBUG(D_MGS, "Device name %s with wrong index\n",
1513 /* server_name2index can return LDD_F_SV_TYPE_* so always return rc */
1517 /* This is only called during replace_nids */
1518 static int only_mgs_is_running(struct obd_device *mgs_obd)
1520 /* TDB: Is global variable with devices count exists? */
1521 int num_devices = get_devices_count();
1522 int num_exports = 0;
1523 struct obd_export *exp;
1525 spin_lock(&mgs_obd->obd_dev_lock);
1526 list_for_each_entry(exp, &mgs_obd->obd_exports, exp_obd_chain) {
1527 /* skip self export */
1528 if (exp == mgs_obd->obd_self_export)
1533 if (num_exports > 1)
1534 CERROR("%s: node %s still connected during replace_nids connect_flags:%llx\n",
1536 libcfs_nid2str(exp->exp_nid_stats->nid),
1537 exp_connect_flags(exp));
1539 spin_unlock(&mgs_obd->obd_dev_lock);
1541 /* osd, MGS and MGC + MGC export (nosvc starts MGC)
1542 * (wc -l /proc/fs/lustre/devices <= 3) && (non self exports == 1)
1544 return (num_devices <= 3) && (num_exports <= 1);
1547 static int name_create_mdt(char **logname, char *fsname, int mdt_idx)
1551 if (mdt_idx > INDEX_MAP_MAX_VALUE)
1554 snprintf(postfix, sizeof(postfix), "-MDT%04x", mdt_idx);
1555 return name_create(logname, fsname, postfix);
1559 * Replace nids for \a device to \a nids values
1561 * \param obd MGS obd device
1562 * \param devname nids need to be replaced for this device
1563 * (ex. lustre-OST0000)
1564 * \param nids nids list (ex. nid1,nid2,nid3)
1568 int mgs_replace_nids(const struct lu_env *env,
1569 struct mgs_device *mgs,
1570 char *devname, char *nids)
1572 /* Assume fsname is part of device name */
1573 char fsname[MTI_NAME_MAXLEN];
1577 struct fs_db *fsdb = NULL;
1580 struct obd_device *mgs_obd = mgs->mgs_obd;
1583 /* We can only change NIDs if no other nodes are connected */
1584 spin_lock(&mgs_obd->obd_dev_lock);
1585 conn_state = mgs_obd->obd_no_conn;
1586 mgs_obd->obd_no_conn = 1;
1587 spin_unlock(&mgs_obd->obd_dev_lock);
1589 /* We can not change nids if not only MGS is started */
1590 if (!only_mgs_is_running(mgs_obd)) {
1591 CERROR("Only MGS is allowed to be started\n");
1592 GOTO(out, rc = -EINPROGRESS);
1595 /* Get fsname and index */
1596 rc = mgs_parse_devname(devname, fsname, &index);
1600 rc = mgs_find_or_make_fsdb(env, mgs, fsname, &fsdb);
1602 CERROR("%s: can't find fsdb: rc = %d\n", fsname, rc);
1606 /* Process client llogs */
1607 rc = name_create(&logname, fsname, "-client");
1610 rc = mgs_replace_nids_log(env, mgs_obd, logname, devname, nids);
1611 name_destroy(&logname);
1613 CERROR("%s: error while replacing NIDs for %s: rc = %d\n",
1614 fsname, devname, rc);
1618 /* Process MDT llogs */
1619 for (i = 0; i < INDEX_MAP_SIZE * 8; i++) {
1620 if (!test_bit(i, fsdb->fsdb_mdt_index_map))
1622 rc = name_create_mdt(&logname, fsname, i);
1625 rc = mgs_replace_nids_log(env, mgs_obd, logname, devname, nids);
1626 name_destroy(&logname);
1632 spin_lock(&mgs_obd->obd_dev_lock);
1633 mgs_obd->obd_no_conn = conn_state;
1634 spin_unlock(&mgs_obd->obd_dev_lock);
1637 mgs_put_fsdb(mgs, fsdb);
1643 * This is called for every record in llog. Some of records are
1644 * skipped, others are copied to new log as is.
1645 * Records to be skipped are
1646 * marker records marked SKIP
1647 * records enclosed between SKIP markers
1649 * \param[in] llh log to be processed
1650 * \param[in] rec current record
1651 * \param[in] data mgs_replace_data structure
1655 static int mgs_clear_config_handler(const struct lu_env *env,
1656 struct llog_handle *llh,
1657 struct llog_rec_hdr *rec, void *data)
1659 struct mgs_replace_data *mrd;
1660 struct lustre_cfg *lcfg = REC_DATA(rec);
1661 int cfg_len = REC_DATA_LEN(rec);
1666 mrd = (struct mgs_replace_data *)data;
1668 if (rec->lrh_type != OBD_CFG_REC) {
1669 CDEBUG(D_MGS, "Config llog Name=%s, Record Index=%u, "
1670 "Unhandled Record Type=%#x\n", llh->lgh_name,
1671 rec->lrh_index, rec->lrh_type);
1675 rc = lustre_cfg_sanity_check(lcfg, cfg_len);
1677 CDEBUG(D_MGS, "Config llog Name=%s, Invalid config file.",
1682 if (lcfg->lcfg_command == LCFG_MARKER) {
1683 struct cfg_marker *marker;
1685 marker = lustre_cfg_buf(lcfg, 1);
1686 if (marker->cm_flags & CM_SKIP) {
1687 if (marker->cm_flags & CM_START)
1688 mrd->state = REPLACE_SKIP;
1689 if (marker->cm_flags & CM_END)
1690 mrd->state = REPLACE_COPY;
1691 /* SKIP section started or finished */
1692 CDEBUG(D_MGS, "Skip idx=%d, rc=%d, len=%d, "
1693 "cmd %x %s %s\n", rec->lrh_index, rc,
1694 rec->lrh_len, lcfg->lcfg_command,
1695 lustre_cfg_string(lcfg, 0),
1696 lustre_cfg_string(lcfg, 1));
1700 if (mrd->state == REPLACE_SKIP) {
1701 /* record enclosed between SKIP markers, skip it */
1702 CDEBUG(D_MGS, "Skip idx=%d, rc=%d, len=%d, "
1703 "cmd %x %s %s\n", rec->lrh_index, rc,
1704 rec->lrh_len, lcfg->lcfg_command,
1705 lustre_cfg_string(lcfg, 0),
1706 lustre_cfg_string(lcfg, 1));
1711 /* Record is placed in temporary llog as is */
1712 rc = llog_write(env, mrd->temp_llh, rec, LLOG_NEXT_IDX);
1714 CDEBUG(D_MGS, "Copied idx=%d, rc=%d, len=%d, cmd %x %s %s\n",
1715 rec->lrh_index, rc, rec->lrh_len, lcfg->lcfg_command,
1716 lustre_cfg_string(lcfg, 0), lustre_cfg_string(lcfg, 1));
1721 * Directory CONFIGS/ may contain files which are not config logs to
1722 * be cleared. Skip any llogs with a non-alphanumeric character after
1723 * the last '-'. For example, fsname-MDT0000.sav, fsname-MDT0000.bak,
1724 * fsname-MDT0000.orig, fsname-MDT0000~, fsname-MDT0000.20150516, etc.
1726 static bool config_to_clear(const char *logname)
1731 str = strrchr(logname, '-');
1736 while (isalnum(str[++i]));
1737 return str[i] == '\0';
1741 * Clear config logs for \a name
1744 * \param mgs MGS device
1745 * \param name name of device or of filesystem
1746 * (ex. lustre-OST0000 or lustre) in later case all logs
1751 int mgs_clear_configs(const struct lu_env *env,
1752 struct mgs_device *mgs, const char *name)
1754 struct list_head dentry_list;
1755 struct mgs_direntry *dirent, *n;
1758 struct obd_device *mgs_obd = mgs->mgs_obd;
1763 /* Prevent clients and servers from connecting to mgs */
1764 spin_lock(&mgs_obd->obd_dev_lock);
1765 conn_state = mgs_obd->obd_no_conn;
1766 mgs_obd->obd_no_conn = 1;
1767 spin_unlock(&mgs_obd->obd_dev_lock);
1770 * config logs cannot be cleaned if anything other than
1773 if (!only_mgs_is_running(mgs_obd)) {
1774 CERROR("Only MGS is allowed to be started\n");
1775 GOTO(out, rc = -EBUSY);
1778 /* Find all the logs in the CONFIGS directory */
1779 rc = class_dentry_readdir(env, mgs, &dentry_list);
1781 CERROR("%s: cannot read config directory '%s': rc = %d\n",
1782 mgs_obd->obd_name, MOUNT_CONFIGS_DIR, rc);
1786 if (list_empty(&dentry_list)) {
1787 CERROR("%s: list empty reading config dir '%s': rc = %d\n",
1788 mgs_obd->obd_name, MOUNT_CONFIGS_DIR, -ENOENT);
1789 GOTO(out, rc = -ENOENT);
1792 OBD_ALLOC(namedash, strlen(name) + 2);
1793 if (namedash == NULL)
1794 GOTO(out, rc = -ENOMEM);
1795 snprintf(namedash, strlen(name) + 2, "%s-", name);
1797 list_for_each_entry(dirent, &dentry_list, mde_list) {
1798 if (strcmp(name, dirent->mde_name) &&
1799 strncmp(namedash, dirent->mde_name, strlen(namedash)))
1801 if (!config_to_clear(dirent->mde_name))
1803 CDEBUG(D_MGS, "%s: Clear config log %s\n",
1804 mgs_obd->obd_name, dirent->mde_name);
1805 rc = mgs_replace_log(env, mgs_obd, dirent->mde_name, NULL,
1806 mgs_clear_config_handler, NULL);
1811 list_for_each_entry_safe(dirent, n, &dentry_list, mde_list) {
1812 list_del_init(&dirent->mde_list);
1813 mgs_direntry_free(dirent);
1815 OBD_FREE(namedash, strlen(name) + 2);
1817 spin_lock(&mgs_obd->obd_dev_lock);
1818 mgs_obd->obd_no_conn = conn_state;
1819 spin_unlock(&mgs_obd->obd_dev_lock);
1824 static int record_lov_setup(const struct lu_env *env, struct llog_handle *llh,
1825 char *devname, struct lov_desc *desc)
1827 struct mgs_thread_info *mgi = mgs_env_info(env);
1828 struct llog_cfg_rec *lcr;
1831 lustre_cfg_bufs_reset(&mgi->mgi_bufs, devname);
1832 lustre_cfg_bufs_set(&mgi->mgi_bufs, 1, desc, sizeof(*desc));
1833 lcr = lustre_cfg_rec_new(LCFG_SETUP, &mgi->mgi_bufs);
1837 rc = llog_write(env, llh, &lcr->lcr_hdr, LLOG_NEXT_IDX);
1838 lustre_cfg_rec_free(lcr);
1842 static int record_lmv_setup(const struct lu_env *env, struct llog_handle *llh,
1843 char *devname, struct lmv_desc *desc)
1845 struct mgs_thread_info *mgi = mgs_env_info(env);
1846 struct llog_cfg_rec *lcr;
1849 lustre_cfg_bufs_reset(&mgi->mgi_bufs, devname);
1850 lustre_cfg_bufs_set(&mgi->mgi_bufs, 1, desc, sizeof(*desc));
1851 lcr = lustre_cfg_rec_new(LCFG_SETUP, &mgi->mgi_bufs);
1855 rc = llog_write(env, llh, &lcr->lcr_hdr, LLOG_NEXT_IDX);
1856 lustre_cfg_rec_free(lcr);
1860 static inline int record_mdc_add(const struct lu_env *env,
1861 struct llog_handle *llh,
1862 char *logname, char *mdcuuid,
1863 char *mdtuuid, char *index,
1866 return record_base(env,llh,logname,0,LCFG_ADD_MDC,
1867 mdtuuid,index,gen,mdcuuid);
1870 static inline int record_lov_add(const struct lu_env *env,
1871 struct llog_handle *llh,
1872 char *lov_name, char *ost_uuid,
1873 char *index, char *gen)
1875 return record_base(env, llh, lov_name, 0, LCFG_LOV_ADD_OBD,
1876 ost_uuid, index, gen, NULL);
1879 static inline int record_mount_opt(const struct lu_env *env,
1880 struct llog_handle *llh,
1881 char *profile, char *lov_name,
1884 return record_base(env, llh, NULL, 0, LCFG_MOUNTOPT,
1885 profile, lov_name, mdc_name, NULL);
1888 static int record_marker(const struct lu_env *env,
1889 struct llog_handle *llh,
1890 struct fs_db *fsdb, __u32 flags,
1891 char *tgtname, char *comment)
1893 struct mgs_thread_info *mgi = mgs_env_info(env);
1894 struct llog_cfg_rec *lcr;
1898 if (flags & CM_START)
1900 mgi->mgi_marker.cm_step = fsdb->fsdb_gen;
1901 mgi->mgi_marker.cm_flags = flags;
1902 mgi->mgi_marker.cm_vers = LUSTRE_VERSION_CODE;
1903 cplen = strlcpy(mgi->mgi_marker.cm_tgtname, tgtname,
1904 sizeof(mgi->mgi_marker.cm_tgtname));
1905 if (cplen >= sizeof(mgi->mgi_marker.cm_tgtname))
1907 cplen = strlcpy(mgi->mgi_marker.cm_comment, comment,
1908 sizeof(mgi->mgi_marker.cm_comment));
1909 if (cplen >= sizeof(mgi->mgi_marker.cm_comment))
1911 mgi->mgi_marker.cm_createtime = ktime_get_real_seconds();
1912 mgi->mgi_marker.cm_canceltime = 0;
1913 lustre_cfg_bufs_reset(&mgi->mgi_bufs, NULL);
1914 lustre_cfg_bufs_set(&mgi->mgi_bufs, 1, &mgi->mgi_marker,
1915 sizeof(mgi->mgi_marker));
1916 lcr = lustre_cfg_rec_new(LCFG_MARKER, &mgi->mgi_bufs);
1920 rc = llog_write(env, llh, &lcr->lcr_hdr, LLOG_NEXT_IDX);
1921 lustre_cfg_rec_free(lcr);
1925 static int record_start_log(const struct lu_env *env, struct mgs_device *mgs,
1926 struct llog_handle **llh, char *name)
1928 static struct obd_uuid cfg_uuid = { .uuid = "config_uuid" };
1929 struct llog_ctxt *ctxt;
1934 GOTO(out, rc = -EBUSY);
1936 ctxt = llog_get_context(mgs->mgs_obd, LLOG_CONFIG_ORIG_CTXT);
1938 GOTO(out, rc = -ENODEV);
1939 LASSERT(ctxt->loc_obd == mgs->mgs_obd);
1941 rc = llog_open_create(env, ctxt, llh, NULL, name);
1944 rc = llog_init_handle(env, *llh, LLOG_F_IS_PLAIN, &cfg_uuid);
1946 llog_close(env, *llh);
1948 llog_ctxt_put(ctxt);
1951 CERROR("%s: can't start log %s: rc = %d\n",
1952 mgs->mgs_obd->obd_name, name, rc);
1958 static int record_end_log(const struct lu_env *env, struct llog_handle **llh)
1962 rc = llog_close(env, *llh);
1968 /******************** config "macros" *********************/
1970 /* write an lcfg directly into a log (with markers) */
1971 static int mgs_write_log_direct(const struct lu_env *env,
1972 struct mgs_device *mgs, struct fs_db *fsdb,
1973 char *logname, struct llog_cfg_rec *lcr,
1974 char *devname, char *comment)
1976 struct llog_handle *llh = NULL;
1981 rc = record_start_log(env, mgs, &llh, logname);
1985 /* FIXME These should be a single journal transaction */
1986 rc = record_marker(env, llh, fsdb, CM_START, devname, comment);
1989 rc = llog_write(env, llh, &lcr->lcr_hdr, LLOG_NEXT_IDX);
1992 rc = record_marker(env, llh, fsdb, CM_END, devname, comment);
1996 record_end_log(env, &llh);
2000 /* write the lcfg in all logs for the given fs */
2001 static int mgs_write_log_direct_all(const struct lu_env *env,
2002 struct mgs_device *mgs,
2004 struct mgs_target_info *mti,
2005 struct llog_cfg_rec *lcr, char *devname,
2006 char *comment, int server_only)
2008 struct list_head log_list;
2009 struct mgs_direntry *dirent, *n;
2010 char *fsname = mti->mti_fsname;
2011 int rc = 0, len = strlen(fsname);
2014 /* Find all the logs in the CONFIGS directory */
2015 rc = class_dentry_readdir(env, mgs, &log_list);
2019 /* Could use fsdb index maps instead of directory listing */
2020 list_for_each_entry_safe(dirent, n, &log_list, mde_list) {
2021 list_del_init(&dirent->mde_list);
2022 /* don't write to sptlrpc rule log */
2023 if (strstr(dirent->mde_name, "-sptlrpc") != NULL)
2026 /* caller wants write server logs only */
2027 if (server_only && strstr(dirent->mde_name, "-client") != NULL)
2030 if (strlen(dirent->mde_name) <= len ||
2031 strncmp(fsname, dirent->mde_name, len) != 0 ||
2032 dirent->mde_name[len] != '-')
2035 CDEBUG(D_MGS, "Changing log %s\n", dirent->mde_name);
2036 /* Erase any old settings of this same parameter */
2037 rc = mgs_modify(env, mgs, fsdb, mti, dirent->mde_name,
2038 devname, comment, CM_SKIP);
2040 CERROR("%s: Can't modify llog %s: rc = %d\n",
2041 mgs->mgs_obd->obd_name, dirent->mde_name, rc);
2044 /* Write the new one */
2045 rc = mgs_write_log_direct(env, mgs, fsdb, dirent->mde_name,
2046 lcr, devname, comment);
2048 CERROR("%s: writing log %s: rc = %d\n",
2049 mgs->mgs_obd->obd_name, dirent->mde_name, rc);
2051 mgs_direntry_free(dirent);
2057 static int mgs_write_log_osp_to_mdt(const struct lu_env *env,
2058 struct mgs_device *mgs,
2060 struct mgs_target_info *mti,
2061 int index, char *logname);
2062 static int mgs_write_log_osc_to_lov(const struct lu_env *env,
2063 struct mgs_device *mgs,
2065 struct mgs_target_info *mti,
2066 char *logname, char *suffix, char *lovname,
2067 enum lustre_sec_part sec_part, int flags);
2068 static int name_create_mdt_and_lov(char **logname, char **lovname,
2069 struct fs_db *fsdb, int i);
2071 static int add_param(char *params, char *key, char *val)
2073 char *start = params + strlen(params);
2074 char *end = params + sizeof(((struct mgs_target_info *)0)->mti_params);
2078 keylen = strlen(key);
2079 if (start + 1 + keylen + strlen(val) >= end) {
2080 CERROR("params are too long: %s %s%s\n",
2081 params, key != NULL ? key : "", val);
2085 sprintf(start, " %s%s", key != NULL ? key : "", val);
2090 * Walk through client config log record and convert the related records
2093 static int mgs_steal_client_llog_handler(const struct lu_env *env,
2094 struct llog_handle *llh,
2095 struct llog_rec_hdr *rec, void *data)
2097 struct mgs_device *mgs;
2098 struct obd_device *obd;
2099 struct mgs_target_info *mti, *tmti;
2101 int cfg_len = rec->lrh_len;
2102 char *cfg_buf = (char*) (rec + 1);
2103 struct lustre_cfg *lcfg;
2105 struct llog_handle *mdt_llh = NULL;
2106 static int got_an_osc_or_mdc = 0;
2107 /* 0: not found any osc/mdc;
2111 static int last_step = -1;
2116 mti = ((struct temp_comp*)data)->comp_mti;
2117 tmti = ((struct temp_comp*)data)->comp_tmti;
2118 fsdb = ((struct temp_comp*)data)->comp_fsdb;
2119 obd = ((struct temp_comp *)data)->comp_obd;
2120 mgs = lu2mgs_dev(obd->obd_lu_dev);
2123 if (rec->lrh_type != OBD_CFG_REC) {
2124 CERROR("unhandled lrh_type: %#x\n", rec->lrh_type);
2128 rc = lustre_cfg_sanity_check(cfg_buf, cfg_len);
2130 CERROR("Insane cfg\n");
2134 lcfg = (struct lustre_cfg *)cfg_buf;
2136 if (lcfg->lcfg_command == LCFG_MARKER) {
2137 struct cfg_marker *marker;
2138 marker = lustre_cfg_buf(lcfg, 1);
2139 if (!strncmp(marker->cm_comment, "add osc", 7) &&
2140 (marker->cm_flags & CM_START) &&
2141 !(marker->cm_flags & CM_SKIP)) {
2142 got_an_osc_or_mdc = 1;
2143 cplen = strlcpy(tmti->mti_svname, marker->cm_tgtname,
2144 sizeof(tmti->mti_svname));
2145 if (cplen >= sizeof(tmti->mti_svname))
2147 rc = record_start_log(env, mgs, &mdt_llh,
2151 rc = record_marker(env, mdt_llh, fsdb, CM_START,
2152 mti->mti_svname, "add osc(copied)");
2153 record_end_log(env, &mdt_llh);
2154 last_step = marker->cm_step;
2157 if (!strncmp(marker->cm_comment, "add osc", 7) &&
2158 (marker->cm_flags & CM_END) &&
2159 !(marker->cm_flags & CM_SKIP)) {
2160 LASSERT(last_step == marker->cm_step);
2162 got_an_osc_or_mdc = 0;
2163 memset(tmti, 0, sizeof(*tmti));
2164 rc = record_start_log(env, mgs, &mdt_llh,
2168 rc = record_marker(env, mdt_llh, fsdb, CM_END,
2169 mti->mti_svname, "add osc(copied)");
2170 record_end_log(env, &mdt_llh);
2173 if (!strncmp(marker->cm_comment, "add mdc", 7) &&
2174 (marker->cm_flags & CM_START) &&
2175 !(marker->cm_flags & CM_SKIP)) {
2176 got_an_osc_or_mdc = 2;
2177 last_step = marker->cm_step;
2178 memcpy(tmti->mti_svname, marker->cm_tgtname,
2179 strlen(marker->cm_tgtname));
2183 if (!strncmp(marker->cm_comment, "add mdc", 7) &&
2184 (marker->cm_flags & CM_END) &&
2185 !(marker->cm_flags & CM_SKIP)) {
2186 LASSERT(last_step == marker->cm_step);
2188 got_an_osc_or_mdc = 0;
2189 memset(tmti, 0, sizeof(*tmti));
2194 if (got_an_osc_or_mdc == 0 || last_step < 0)
2197 if (lcfg->lcfg_command == LCFG_ADD_UUID) {
2198 __u64 nodenid = lcfg->lcfg_nid;
2200 if (strlen(tmti->mti_uuid) == 0) {
2201 /* target uuid not set, this config record is before
2202 * LCFG_SETUP, this nid is one of target node nid.
2204 tmti->mti_nids[tmti->mti_nid_count] = nodenid;
2205 tmti->mti_nid_count++;
2207 char nidstr[LNET_NIDSTR_SIZE];
2209 /* failover node nid */
2210 libcfs_nid2str_r(nodenid, nidstr, sizeof(nidstr));
2211 rc = add_param(tmti->mti_params, PARAM_FAILNODE,
2218 if (lcfg->lcfg_command == LCFG_SETUP) {
2221 target = lustre_cfg_string(lcfg, 1);
2222 memcpy(tmti->mti_uuid, target, strlen(target));
2226 /* ignore client side sptlrpc_conf_log */
2227 if (lcfg->lcfg_command == LCFG_SPTLRPC_CONF)
2230 if (lcfg->lcfg_command == LCFG_ADD_MDC &&
2231 strstr(lustre_cfg_string(lcfg, 0), "-clilmv") != NULL) {
2234 if (sscanf(lustre_cfg_buf(lcfg, 2), "%d", &index) != 1)
2237 memcpy(tmti->mti_fsname, mti->mti_fsname,
2238 strlen(mti->mti_fsname));
2239 tmti->mti_stripe_index = index;
2241 rc = mgs_write_log_osp_to_mdt(env, mgs, fsdb, tmti,
2242 mti->mti_stripe_index,
2244 memset(tmti, 0, sizeof(*tmti));
2248 if (lcfg->lcfg_command == LCFG_LOV_ADD_OBD) {
2251 char *logname, *lovname;
2253 rc = name_create_mdt_and_lov(&logname, &lovname, fsdb,
2254 mti->mti_stripe_index);
2257 sprintf(mdt_index, "-MDT%04x", mti->mti_stripe_index);
2259 if (sscanf(lustre_cfg_buf(lcfg, 2), "%d", &index) != 1) {
2260 name_destroy(&logname);
2261 name_destroy(&lovname);
2265 tmti->mti_stripe_index = index;
2266 rc = mgs_write_log_osc_to_lov(env, mgs, fsdb, tmti, logname,
2269 name_destroy(&logname);
2270 name_destroy(&lovname);
2276 /* fsdb->fsdb_mutex is already held in mgs_write_log_target*/
2277 /* stealed from mgs_get_fsdb_from_llog*/
2278 static int mgs_steal_llog_for_mdt_from_client(const struct lu_env *env,
2279 struct mgs_device *mgs,
2281 struct temp_comp* comp)
2283 struct llog_handle *loghandle;
2284 struct mgs_target_info *tmti;
2285 struct llog_ctxt *ctxt;
2290 ctxt = llog_get_context(mgs->mgs_obd, LLOG_CONFIG_ORIG_CTXT);
2291 LASSERT(ctxt != NULL);
2293 OBD_ALLOC_PTR(tmti);
2295 GOTO(out_ctxt, rc = -ENOMEM);
2297 comp->comp_tmti = tmti;
2298 comp->comp_obd = mgs->mgs_obd;
2300 rc = llog_open(env, ctxt, &loghandle, NULL, client_name,
2308 rc = llog_init_handle(env, loghandle, LLOG_F_IS_PLAIN, NULL);
2310 GOTO(out_close, rc);
2312 rc = llog_process_or_fork(env, loghandle, mgs_steal_client_llog_handler,
2313 (void *)comp, NULL, false);
2314 CDEBUG(D_MGS, "steal llog re = %d\n", rc);
2316 llog_close(env, loghandle);
2320 llog_ctxt_put(ctxt);
2324 /* lmv is the second thing for client logs */
2325 /* copied from mgs_write_log_lov. Please refer to that. */
2326 static int mgs_write_log_lmv(const struct lu_env *env,
2327 struct mgs_device *mgs,
2329 struct mgs_target_info *mti,
2330 char *logname, char *lmvname)
2332 struct llog_handle *llh = NULL;
2333 struct lmv_desc *lmvdesc;
2338 CDEBUG(D_MGS, "Writing lmv(%s) log for %s\n", lmvname,logname);
2340 OBD_ALLOC_PTR(lmvdesc);
2341 if (lmvdesc == NULL)
2343 lmvdesc->ld_active_tgt_count = 0;
2344 lmvdesc->ld_tgt_count = 0;
2345 sprintf((char*)lmvdesc->ld_uuid.uuid, "%s_UUID", lmvname);
2346 uuid = (char *)lmvdesc->ld_uuid.uuid;
2348 rc = record_start_log(env, mgs, &llh, logname);
2351 rc = record_marker(env, llh, fsdb, CM_START, lmvname, "lmv setup");
2354 rc = record_attach(env, llh, lmvname, "lmv", uuid);
2357 rc = record_lmv_setup(env, llh, lmvname, lmvdesc);
2360 rc = record_marker(env, llh, fsdb, CM_END, lmvname, "lmv setup");
2364 record_end_log(env, &llh);
2366 OBD_FREE_PTR(lmvdesc);
2370 /* lov is the first thing in the mdt and client logs */
2371 static int mgs_write_log_lov(const struct lu_env *env, struct mgs_device *mgs,
2372 struct fs_db *fsdb, struct mgs_target_info *mti,
2373 char *logname, char *lovname)
2375 struct llog_handle *llh = NULL;
2376 struct lov_desc *lovdesc;
2381 CDEBUG(D_MGS, "Writing lov(%s) log for %s\n", lovname, logname);
2384 #01 L attach 0:lov_mdsA 1:lov 2:71ccb_lov_mdsA_19f961a9e1
2385 #02 L lov_setup 0:lov_mdsA 1:(struct lov_desc)
2386 uuid=lov1_UUID, stripe count=1, size=1048576, offset=0, pattern=0
2389 /* FIXME just make lov_setup accept empty desc (put uuid in buf 2) */
2390 OBD_ALLOC_PTR(lovdesc);
2391 if (lovdesc == NULL)
2393 lovdesc->ld_magic = LOV_DESC_MAGIC;
2394 lovdesc->ld_tgt_count = 0;
2395 /* Defaults. Can be changed later by lcfg config_param */
2396 lovdesc->ld_default_stripe_count = 1;
2397 lovdesc->ld_pattern = LOV_PATTERN_RAID0;
2398 lovdesc->ld_default_stripe_size = LOV_DESC_STRIPE_SIZE_DEFAULT;
2399 lovdesc->ld_default_stripe_offset = -1;
2400 lovdesc->ld_qos_maxage = LOV_DESC_QOS_MAXAGE_DEFAULT;
2401 sprintf((char*)lovdesc->ld_uuid.uuid, "%s_UUID", lovname);
2402 /* can these be the same? */
2403 uuid = (char *)lovdesc->ld_uuid.uuid;
2405 /* This should always be the first entry in a log.
2406 rc = mgs_clear_log(obd, logname); */
2407 rc = record_start_log(env, mgs, &llh, logname);
2410 /* FIXME these should be a single journal transaction */
2411 rc = record_marker(env, llh, fsdb, CM_START, lovname, "lov setup");
2414 rc = record_attach(env, llh, lovname, "lov", uuid);
2417 rc = record_lov_setup(env, llh, lovname, lovdesc);
2420 rc = record_marker(env, llh, fsdb, CM_END, lovname, "lov setup");
2425 record_end_log(env, &llh);
2427 OBD_FREE_PTR(lovdesc);
2431 /* add failnids to open log */
2432 static int mgs_write_log_failnids(const struct lu_env *env,
2433 struct mgs_target_info *mti,
2434 struct llog_handle *llh,
2437 char *failnodeuuid = NULL;
2438 char *ptr = mti->mti_params;
2443 #03 L add_uuid nid=uml1@tcp(0x20000c0a80201) nal=90 0: 1:uml1_UUID
2444 #04 L add_uuid nid=1@elan(0x1000000000001) nal=90 0: 1:uml1_UUID
2445 #05 L setup 0:OSC_uml1_ost1_mdsA 1:ost1_UUID 2:uml1_UUID
2446 #06 L add_uuid nid=uml2@tcp(0x20000c0a80202) nal=90 0: 1:uml2_UUID
2447 #0x L add_uuid nid=2@elan(0x1000000000002) nal=90 0: 1:uml2_UUID
2448 #07 L add_conn 0:OSC_uml1_ost1_mdsA 1:uml2_UUID
2452 * Pull failnid info out of params string, which may contain something
2453 * like "<nid1>,<nid2>:<nid3>,<nid4>". class_parse_nid() does not
2454 * complain about abnormal inputs like ",:<nid1>", "<nid1>:,<nid2>",
2455 * etc. However, convert_hostnames() should have caught those.
2457 while (class_find_param(ptr, PARAM_FAILNODE, &ptr) == 0) {
2458 while (class_parse_nid(ptr, &nid, &ptr) == 0) {
2459 char nidstr[LNET_NIDSTR_SIZE];
2461 if (failnodeuuid == NULL) {
2462 /* We don't know the failover node name,
2463 * so just use the first nid as the uuid */
2464 libcfs_nid2str_r(nid, nidstr, sizeof(nidstr));
2465 rc = name_create(&failnodeuuid, nidstr, "");
2469 CDEBUG(D_MGS, "add nid %s for failover uuid %s, "
2471 libcfs_nid2str_r(nid, nidstr, sizeof(nidstr)),
2472 failnodeuuid, cliname);
2473 rc = record_add_uuid(env, llh, nid, failnodeuuid);
2475 * If *ptr is ':', we have added all NIDs for
2479 rc = record_add_conn(env, llh, cliname,
2481 name_destroy(&failnodeuuid);
2482 failnodeuuid = NULL;
2486 rc = record_add_conn(env, llh, cliname, failnodeuuid);
2487 name_destroy(&failnodeuuid);
2488 failnodeuuid = NULL;
2495 static int mgs_write_log_mdc_to_lmv(const struct lu_env *env,
2496 struct mgs_device *mgs,
2498 struct mgs_target_info *mti,
2499 char *logname, char *lmvname)
2501 struct llog_handle *llh = NULL;
2502 char *mdcname = NULL;
2503 char *nodeuuid = NULL;
2504 char *mdcuuid = NULL;
2505 char *lmvuuid = NULL;
2507 char nidstr[LNET_NIDSTR_SIZE];
2511 if (mgs_log_is_empty(env, mgs, logname)) {
2512 CERROR("log is empty! Logical error\n");
2516 CDEBUG(D_MGS, "adding mdc for %s to log %s:lmv(%s)\n",
2517 mti->mti_svname, logname, lmvname);
2519 libcfs_nid2str_r(mti->mti_nids[0], nidstr, sizeof(nidstr));
2520 rc = name_create(&nodeuuid, nidstr, "");
2523 rc = name_create(&mdcname, mti->mti_svname, "-mdc");
2526 rc = name_create(&mdcuuid, mdcname, "_UUID");
2529 rc = name_create(&lmvuuid, lmvname, "_UUID");
2533 rc = record_start_log(env, mgs, &llh, logname);
2536 rc = record_marker(env, llh, fsdb, CM_START, mti->mti_svname,
2540 for (i = 0; i < mti->mti_nid_count; i++) {
2541 CDEBUG(D_MGS, "add nid %s for mdt\n",
2542 libcfs_nid2str_r(mti->mti_nids[i],
2543 nidstr, sizeof(nidstr)));
2545 rc = record_add_uuid(env, llh, mti->mti_nids[i], nodeuuid);
2550 rc = record_attach(env, llh, mdcname, LUSTRE_MDC_NAME, lmvuuid);
2553 rc = record_setup(env, llh, mdcname, mti->mti_uuid, nodeuuid,
2557 rc = mgs_write_log_failnids(env, mti, llh, mdcname);
2560 snprintf(index, sizeof(index), "%d", mti->mti_stripe_index);
2561 rc = record_mdc_add(env, llh, lmvname, mdcuuid, mti->mti_uuid,
2565 rc = record_marker(env, llh, fsdb, CM_END, mti->mti_svname,
2570 record_end_log(env, &llh);
2572 name_destroy(&lmvuuid);
2573 name_destroy(&mdcuuid);
2574 name_destroy(&mdcname);
2575 name_destroy(&nodeuuid);
2579 static inline int name_create_lov(char **lovname, char *mdtname,
2580 struct fs_db *fsdb, int index)
2583 if (index == 0 && test_bit(FSDB_OSCNAME18, &fsdb->fsdb_flags))
2584 return name_create(lovname, fsdb->fsdb_name, "-mdtlov");
2586 return name_create(lovname, mdtname, "-mdtlov");
2589 static int name_create_mdt_and_lov(char **logname, char **lovname,
2590 struct fs_db *fsdb, int i)
2594 rc = name_create_mdt(logname, fsdb->fsdb_name, i);
2598 if (i == 0 && test_bit(FSDB_OSCNAME18, &fsdb->fsdb_flags))
2599 rc = name_create(lovname, fsdb->fsdb_name, "-mdtlov");
2601 rc = name_create(lovname, *logname, "-mdtlov");
2603 name_destroy(logname);
2609 static inline int name_create_mdt_osc(char **oscname, char *ostname,
2610 struct fs_db *fsdb, int i)
2614 if (i == 0 && test_bit(FSDB_OSCNAME18, &fsdb->fsdb_flags))
2615 sprintf(suffix, "-osc");
2617 sprintf(suffix, "-osc-MDT%04x", i);
2618 return name_create(oscname, ostname, suffix);
2621 /* add new mdc to already existent MDS */
2622 static int mgs_write_log_osp_to_mdt(const struct lu_env *env,
2623 struct mgs_device *mgs,
2625 struct mgs_target_info *mti,
2626 int mdt_index, char *logname)
2628 struct llog_handle *llh = NULL;
2629 char *nodeuuid = NULL;
2630 char *ospname = NULL;
2631 char *lovuuid = NULL;
2632 char *mdtuuid = NULL;
2633 char *svname = NULL;
2634 char *mdtname = NULL;
2635 char *lovname = NULL;
2637 char nidstr[LNET_NIDSTR_SIZE];
2641 if (mgs_log_is_empty(env, mgs, mti->mti_svname)) {
2642 CERROR("log is empty! Logical error\n");
2646 CDEBUG(D_MGS, "adding osp index %d to %s\n", mti->mti_stripe_index,
2649 rc = name_create_mdt(&mdtname, fsdb->fsdb_name, mti->mti_stripe_index);
2653 libcfs_nid2str_r(mti->mti_nids[0], nidstr, sizeof(nidstr));
2654 rc = name_create(&nodeuuid, nidstr, "");
2656 GOTO(out_destory, rc);
2658 rc = name_create(&svname, mdtname, "-osp");
2660 GOTO(out_destory, rc);
2662 sprintf(index_str, "-MDT%04x", mdt_index);
2663 rc = name_create(&ospname, svname, index_str);
2665 GOTO(out_destory, rc);
2667 rc = name_create_lov(&lovname, logname, fsdb, mdt_index);
2669 GOTO(out_destory, rc);
2671 rc = name_create(&lovuuid, lovname, "_UUID");
2673 GOTO(out_destory, rc);
2675 rc = name_create(&mdtuuid, mdtname, "_UUID");
2677 GOTO(out_destory, rc);
2679 rc = record_start_log(env, mgs, &llh, logname);
2681 GOTO(out_destory, rc);
2683 rc = record_marker(env, llh, fsdb, CM_START, mti->mti_svname,
2686 GOTO(out_destory, rc);
2688 for (i = 0; i < mti->mti_nid_count; i++) {
2689 CDEBUG(D_MGS, "add nid %s for mdt\n",
2690 libcfs_nid2str_r(mti->mti_nids[i],
2691 nidstr, sizeof(nidstr)));
2692 rc = record_add_uuid(env, llh, mti->mti_nids[i], nodeuuid);
2697 rc = record_attach(env, llh, ospname, LUSTRE_OSP_NAME, lovuuid);
2701 rc = record_setup(env, llh, ospname, mti->mti_uuid, nodeuuid,
2706 rc = mgs_write_log_failnids(env, mti, llh, ospname);
2710 /* Add mdc(osp) to lod */
2711 snprintf(index_str, sizeof(index_str), "%d", mti->mti_stripe_index);
2712 rc = record_base(env, llh, lovname, 0, LCFG_ADD_MDC, mti->mti_uuid,
2713 index_str, "1", NULL);
2717 rc = record_marker(env, llh, fsdb, CM_END, mti->mti_svname, "add osp");
2722 record_end_log(env, &llh);
2725 name_destroy(&mdtuuid);
2726 name_destroy(&lovuuid);
2727 name_destroy(&lovname);
2728 name_destroy(&ospname);
2729 name_destroy(&svname);
2730 name_destroy(&nodeuuid);
2731 name_destroy(&mdtname);
2735 static int mgs_write_log_mdt0(const struct lu_env *env,
2736 struct mgs_device *mgs,
2738 struct mgs_target_info *mti)
2740 char *log = mti->mti_svname;
2741 struct llog_handle *llh = NULL;
2742 struct obd_uuid *uuid;
2745 char *ptr = mti->mti_params;
2746 int rc = 0, failout = 0;
2749 OBD_ALLOC_PTR(uuid);
2753 if (class_find_param(ptr, PARAM_FAILMODE, &ptr) == 0)
2754 failout = (strncmp(ptr, "failout", 7) == 0);
2756 rc = name_create(&lovname, log, "-mdtlov");
2759 if (mgs_log_is_empty(env, mgs, log)) {
2760 rc = mgs_write_log_lov(env, mgs, fsdb, mti, log, lovname);
2765 sprintf(mdt_index, "%d", mti->mti_stripe_index);
2767 rc = record_start_log(env, mgs, &llh, log);
2771 /* add MDT itself */
2773 /* FIXME this whole fn should be a single journal transaction */
2774 sprintf(uuid->uuid, "%s_UUID", log);
2775 rc = record_marker(env, llh, fsdb, CM_START, log, "add mdt");
2778 rc = record_attach(env, llh, log, LUSTRE_MDT_NAME, uuid->uuid);
2781 rc = record_mount_opt(env, llh, log, lovname, NULL);
2784 rc = record_setup(env, llh, log, uuid->uuid, mdt_index, lovname,
2785 failout ? "n" : "f");
2788 rc = record_marker(env, llh, fsdb, CM_END, log, "add mdt");
2792 record_end_log(env, &llh);
2794 name_destroy(&lovname);
2800 /* envelope method for all layers log */
2801 static int mgs_write_log_mdt(const struct lu_env *env,
2802 struct mgs_device *mgs,
2804 struct mgs_target_info *mti)
2806 struct mgs_thread_info *mgi = mgs_env_info(env);
2807 struct llog_handle *llh = NULL;
2812 CDEBUG(D_MGS, "writing new mdt %s\n", mti->mti_svname);
2814 if (mti->mti_uuid[0] == '\0') {
2815 /* Make up our own uuid */
2816 snprintf(mti->mti_uuid, sizeof(mti->mti_uuid),
2817 "%s_UUID", mti->mti_svname);
2821 rc = mgs_write_log_mdt0(env, mgs, fsdb, mti);
2824 /* Append the mdt info to the client log */
2825 rc = name_create(&cliname, mti->mti_fsname, "-client");
2829 if (mgs_log_is_empty(env, mgs, cliname)) {
2830 /* Start client log */
2831 rc = mgs_write_log_lov(env, mgs, fsdb, mti, cliname,
2835 rc = mgs_write_log_lmv(env, mgs, fsdb, mti, cliname,
2842 #09 L add_uuid nid=uml1@tcp(0x20000c0a80201) 0: 1:uml1_UUID
2843 #10 L attach 0:MDC_uml1_mdsA_MNT_client 1:mdc 2:1d834_MNT_client_03f
2844 #11 L setup 0:MDC_uml1_mdsA_MNT_client 1:mdsA_UUID 2:uml1_UUID
2845 #12 L add_uuid nid=uml2@tcp(0x20000c0a80202) 0: 1:uml2_UUID
2846 #13 L add_conn 0:MDC_uml1_mdsA_MNT_client 1:uml2_UUID
2847 #14 L mount_option 0: 1:client 2:lov1 3:MDC_uml1_mdsA_MNT_client
2850 /* copy client info about lov/lmv */
2851 mgi->mgi_comp.comp_mti = mti;
2852 mgi->mgi_comp.comp_fsdb = fsdb;
2854 rc = mgs_steal_llog_for_mdt_from_client(env, mgs, cliname,
2858 rc = mgs_write_log_mdc_to_lmv(env, mgs, fsdb, mti, cliname,
2864 rc = record_start_log(env, mgs, &llh, cliname);
2868 rc = record_marker(env, llh, fsdb, CM_START, cliname, "mount opts");
2871 rc = record_mount_opt(env, llh, cliname, fsdb->fsdb_clilov,
2875 rc = record_marker(env, llh, fsdb, CM_END, cliname, "mount opts");
2879 /* for_all_existing_mdt except current one */
2880 for (i = 0; i < INDEX_MAP_SIZE * 8; i++) {
2881 if (i != mti->mti_stripe_index &&
2882 test_bit(i, fsdb->fsdb_mdt_index_map)) {
2885 rc = name_create_mdt(&logname, fsdb->fsdb_name, i);
2889 /* NB: If the log for the MDT is empty, it means
2890 * the MDT is only added to the index
2891 * map, and not being process yet, i.e. this
2892 * is an unregistered MDT, see mgs_write_log_target().
2893 * so we should skip it. Otherwise
2895 * 1. MGS get register request for MDT1 and MDT2.
2897 * 2. Then both MDT1 and MDT2 are added into
2898 * fsdb_mdt_index_map. (see mgs_set_index()).
2900 * 3. Then MDT1 get the lock of fsdb_mutex, then
2901 * generate the config log, here, it will regard MDT2
2902 * as an existent MDT, and generate "add osp" for
2903 * lustre-MDT0001-osp-MDT0002. Note: at the moment
2904 * MDT0002 config log is still empty, so it will
2905 * add "add osp" even before "lov setup", which
2906 * will definitly cause trouble.
2908 * 4. MDT1 registeration finished, fsdb_mutex is
2909 * released, then MDT2 get in, then in above
2910 * mgs_steal_llog_for_mdt_from_client(), it will
2911 * add another osp log for lustre-MDT0001-osp-MDT0002,
2912 * which will cause another trouble.*/
2913 if (!mgs_log_is_empty(env, mgs, logname))
2914 rc = mgs_write_log_osp_to_mdt(env, mgs, fsdb,
2917 name_destroy(&logname);
2923 record_end_log(env, &llh);
2925 name_destroy(&cliname);
2929 /* Add the ost info to the client/mdt lov */
2930 static int mgs_write_log_osc_to_lov(const struct lu_env *env,
2931 struct mgs_device *mgs, struct fs_db *fsdb,
2932 struct mgs_target_info *mti,
2933 char *logname, char *suffix, char *lovname,
2934 enum lustre_sec_part sec_part, int flags)
2936 struct llog_handle *llh = NULL;
2937 char *nodeuuid = NULL;
2938 char *oscname = NULL;
2939 char *oscuuid = NULL;
2940 char *lovuuid = NULL;
2941 char *svname = NULL;
2943 char nidstr[LNET_NIDSTR_SIZE];
2947 CDEBUG(D_INFO, "adding osc for %s to log %s\n",
2948 mti->mti_svname, logname);
2950 if (mgs_log_is_empty(env, mgs, logname)) {
2951 CERROR("log is empty! Logical error\n");
2955 libcfs_nid2str_r(mti->mti_nids[0], nidstr, sizeof(nidstr));
2956 rc = name_create(&nodeuuid, nidstr, "");
2959 rc = name_create(&svname, mti->mti_svname, "-osc");
2963 /* for the system upgraded from old 1.8, keep using the old osc naming
2964 * style for mdt, see name_create_mdt_osc(). LU-1257 */
2965 if (test_bit(FSDB_OSCNAME18, &fsdb->fsdb_flags))
2966 rc = name_create(&oscname, svname, "");
2968 rc = name_create(&oscname, svname, suffix);
2972 rc = name_create(&oscuuid, oscname, "_UUID");
2975 rc = name_create(&lovuuid, lovname, "_UUID");
2981 #03 L add_uuid nid=uml1@tcp(0x20000c0a80201) 0: 1:uml1_UUID
2983 #04 L add_uuid nid=1@elan(0x1000000000001) nal=90 0: 1:uml1_UUID
2984 #04 L attach 0:OSC_uml1_ost1_MNT_client 1:osc 2:89070_lov1_a41dff51a
2985 #05 L setup 0:OSC_uml1_ost1_MNT_client 1:ost1_UUID 2:uml1_UUID
2987 #06 L add_uuid nid=uml2@tcp(0x20000c0a80202) 0: 1:uml2_UUID
2988 #07 L add_conn 0:OSC_uml1_ost1_MNT_client 1:uml2_UUID
2989 #08 L lov_modify_tgts add 0:lov1 1:ost1_UUID 2(index):0 3(gen):1
2992 rc = record_start_log(env, mgs, &llh, logname);
2996 /* FIXME these should be a single journal transaction */
2997 rc = record_marker(env, llh, fsdb, CM_START | flags, mti->mti_svname,
3002 /* NB: don't change record order, because upon MDT steal OSC config
3003 * from client, it treats all nids before LCFG_SETUP as target nids
3004 * (multiple interfaces), while nids after as failover node nids.
3005 * See mgs_steal_client_llog_handler() LCFG_ADD_UUID.
3007 for (i = 0; i < mti->mti_nid_count; i++) {
3008 CDEBUG(D_MGS, "add nid %s\n",
3009 libcfs_nid2str_r(mti->mti_nids[i],
3010 nidstr, sizeof(nidstr)));
3011 rc = record_add_uuid(env, llh, mti->mti_nids[i], nodeuuid);
3015 rc = record_attach(env, llh, oscname, LUSTRE_OSC_NAME, lovuuid);
3018 rc = record_setup(env, llh, oscname, mti->mti_uuid, nodeuuid,
3022 rc = mgs_write_log_failnids(env, mti, llh, oscname);
3026 snprintf(index, sizeof(index), "%d", mti->mti_stripe_index);
3028 rc = record_lov_add(env, llh, lovname, mti->mti_uuid, index, "1");
3031 rc = record_marker(env, llh, fsdb, CM_END | flags, mti->mti_svname,
3036 record_end_log(env, &llh);
3038 name_destroy(&lovuuid);
3039 name_destroy(&oscuuid);
3040 name_destroy(&oscname);
3041 name_destroy(&svname);
3042 name_destroy(&nodeuuid);
3046 static int mgs_write_log_ost(const struct lu_env *env,
3047 struct mgs_device *mgs, struct fs_db *fsdb,
3048 struct mgs_target_info *mti)
3050 struct llog_handle *llh = NULL;
3051 char *logname, *lovname;
3052 char *ptr = mti->mti_params;
3053 int rc, flags = 0, failout = 0, i;
3056 CDEBUG(D_MGS, "writing new ost %s\n", mti->mti_svname);
3058 /* The ost startup log */
3060 /* If the ost log already exists, that means that someone reformatted
3061 the ost and it called target_add again. */
3062 if (!mgs_log_is_empty(env, mgs, mti->mti_svname)) {
3063 LCONSOLE_ERROR_MSG(0x141, "The config log for %s already "
3064 "exists, yet the server claims it never "
3065 "registered. It may have been reformatted, "
3066 "or the index changed. writeconf the MDT to "
3067 "regenerate all logs.\n", mti->mti_svname);
3072 attach obdfilter ost1 ost1_UUID
3073 setup /dev/loop2 ldiskfs f|n errors=remount-ro,user_xattr
3075 if (class_find_param(ptr, PARAM_FAILMODE, &ptr) == 0)
3076 failout = (strncmp(ptr, "failout", 7) == 0);
3077 rc = record_start_log(env, mgs, &llh, mti->mti_svname);
3080 /* FIXME these should be a single journal transaction */
3081 rc = record_marker(env, llh, fsdb, CM_START, mti->mti_svname,"add ost");
3084 if (*mti->mti_uuid == '\0')
3085 snprintf(mti->mti_uuid, sizeof(mti->mti_uuid),
3086 "%s_UUID", mti->mti_svname);
3087 rc = record_attach(env, llh, mti->mti_svname,
3088 "obdfilter"/*LUSTRE_OST_NAME*/, mti->mti_uuid);
3091 rc = record_setup(env, llh, mti->mti_svname,
3092 "dev"/*ignored*/, "type"/*ignored*/,
3093 failout ? "n" : "f", NULL/*options*/);
3096 rc = record_marker(env, llh, fsdb, CM_END, mti->mti_svname, "add ost");
3100 record_end_log(env, &llh);
3103 /* We also have to update the other logs where this osc is part of
3106 if (test_bit(FSDB_OLDLOG14, &fsdb->fsdb_flags)) {
3107 /* If we're upgrading, the old mdt log already has our
3108 entry. Let's do a fake one for fun. */
3109 /* Note that we can't add any new failnids, since we don't
3110 know the old osc names. */
3111 flags = CM_SKIP | CM_UPGRADE146;
3113 } else if ((mti->mti_flags & LDD_F_UPDATE) != LDD_F_UPDATE) {
3114 /* If the update flag isn't set, don't update client/mdt
3117 LCONSOLE_WARN("Client log for %s was not updated; writeconf "
3118 "the MDT first to regenerate it.\n",
3122 /* Add ost to all MDT lov defs */
3123 for (i = 0; i < INDEX_MAP_SIZE * 8; i++){
3124 if (test_bit(i, fsdb->fsdb_mdt_index_map)) {
3127 rc = name_create_mdt_and_lov(&logname, &lovname, fsdb,
3132 snprintf(mdt_index, sizeof(mdt_index), "-MDT%04x", i);
3133 rc = mgs_write_log_osc_to_lov(env, mgs, fsdb, mti,
3135 lovname, LUSTRE_SP_MDT,
3137 name_destroy(&logname);
3138 name_destroy(&lovname);
3144 /* Append ost info to the client log */
3145 rc = name_create(&logname, mti->mti_fsname, "-client");
3148 if (mgs_log_is_empty(env, mgs, logname)) {
3149 /* Start client log */
3150 rc = mgs_write_log_lov(env, mgs, fsdb, mti, logname,
3154 rc = mgs_write_log_lmv(env, mgs, fsdb, mti, logname,
3159 rc = mgs_write_log_osc_to_lov(env, mgs, fsdb, mti, logname, "",
3160 fsdb->fsdb_clilov, LUSTRE_SP_CLI, flags);
3162 name_destroy(&logname);
3166 static __inline__ int mgs_param_empty(char *ptr)
3170 if ((tmp = strchr(ptr, '=')) && (*(++tmp) == '\0'))
3175 static int mgs_write_log_failnid_internal(const struct lu_env *env,
3176 struct mgs_device *mgs,
3178 struct mgs_target_info *mti,
3179 char *logname, char *cliname)
3182 struct llog_handle *llh = NULL;
3184 if (mgs_param_empty(mti->mti_params)) {
3185 /* Remove _all_ failnids */
3186 rc = mgs_modify(env, mgs, fsdb, mti, logname,
3187 mti->mti_svname, "add failnid", CM_SKIP);
3188 return rc < 0 ? rc : 0;
3191 /* Otherwise failover nids are additive */
3192 rc = record_start_log(env, mgs, &llh, logname);
3195 /* FIXME this should be a single journal transaction */
3196 rc = record_marker(env, llh, fsdb, CM_START, mti->mti_svname,
3200 rc = mgs_write_log_failnids(env, mti, llh, cliname);
3203 rc = record_marker(env, llh, fsdb, CM_END,
3204 mti->mti_svname, "add failnid");
3206 record_end_log(env, &llh);
3211 /* Add additional failnids to an existing log.
3212 The mdc/osc must have been added to logs first */
3213 /* tcp nids must be in dotted-quad ascii -
3214 we can't resolve hostnames from the kernel. */
3215 static int mgs_write_log_add_failnid(const struct lu_env *env,
3216 struct mgs_device *mgs,
3218 struct mgs_target_info *mti)
3220 char *logname, *cliname;
3224 /* FIXME we currently can't erase the failnids
3225 * given when a target first registers, since they aren't part of
3226 * an "add uuid" stanza
3229 /* Verify that we know about this target */
3230 if (mgs_log_is_empty(env, mgs, mti->mti_svname)) {
3231 LCONSOLE_ERROR_MSG(0x142, "The target %s has not registered "
3232 "yet. It must be started before failnids "
3233 "can be added.\n", mti->mti_svname);
3237 /* Create mdc/osc client name (e.g. lustre-OST0001-osc) */
3238 if (mti->mti_flags & LDD_F_SV_TYPE_MDT) {
3239 rc = name_create(&cliname, mti->mti_svname, "-mdc");
3240 } else if (mti->mti_flags & LDD_F_SV_TYPE_OST) {
3241 rc = name_create(&cliname, mti->mti_svname, "-osc");
3248 /* Add failover nids to the client log */
3249 rc = name_create(&logname, mti->mti_fsname, "-client");
3251 name_destroy(&cliname);
3255 rc = mgs_write_log_failnid_internal(env, mgs, fsdb,mti,logname,cliname);
3256 name_destroy(&logname);
3257 name_destroy(&cliname);
3261 if (mti->mti_flags & LDD_F_SV_TYPE_OST) {
3262 /* Add OST failover nids to the MDT logs as well */
3265 for (i = 0; i < INDEX_MAP_SIZE * 8; i++) {
3266 if (!test_bit(i, fsdb->fsdb_mdt_index_map))
3268 rc = name_create_mdt(&logname, mti->mti_fsname, i);
3271 rc = name_create_mdt_osc(&cliname, mti->mti_svname,
3274 name_destroy(&logname);
3277 rc = mgs_write_log_failnid_internal(env, mgs, fsdb,
3280 name_destroy(&cliname);
3281 name_destroy(&logname);
3290 static int mgs_wlp_lcfg(const struct lu_env *env,
3291 struct mgs_device *mgs, struct fs_db *fsdb,
3292 struct mgs_target_info *mti,
3293 char *logname, struct lustre_cfg_bufs *bufs,
3294 char *tgtname, char *ptr)
3296 char comment[MTI_NAME_MAXLEN];
3298 struct llog_cfg_rec *lcr;
3301 /* Erase any old settings of this same parameter */
3302 strlcpy(comment, ptr, sizeof(comment));
3303 /* But don't try to match the value. */
3304 tmp = strchr(comment, '=');
3307 /* FIXME we should skip settings that are the same as old values */
3308 rc = mgs_modify(env, mgs, fsdb, mti, logname, tgtname, comment,CM_SKIP);
3311 del = mgs_param_empty(ptr);
3313 LCONSOLE_INFO("%s parameter %s.%s in log %s\n", del ? "Disabling" : rc ?
3314 "Setting" : "Modifying", tgtname, comment, logname);
3316 /* mgs_modify() will return 1 if nothing had to be done */
3322 lustre_cfg_bufs_reset(bufs, tgtname);
3323 lustre_cfg_bufs_set_string(bufs, 1, ptr);
3324 if (mti->mti_flags & LDD_F_PARAM2)
3325 lustre_cfg_bufs_set_string(bufs, 2, LCTL_UPCALL);
3327 lcr = lustre_cfg_rec_new((mti->mti_flags & LDD_F_PARAM2) ?
3328 LCFG_SET_PARAM : LCFG_PARAM, bufs);
3332 rc = mgs_write_log_direct(env, mgs, fsdb, logname, lcr, tgtname,
3334 lustre_cfg_rec_free(lcr);
3338 /* write global variable settings into log */
3339 static int mgs_write_log_sys(const struct lu_env *env,
3340 struct mgs_device *mgs, struct fs_db *fsdb,
3341 struct mgs_target_info *mti, char *sys, char *ptr)
3343 struct mgs_thread_info *mgi = mgs_env_info(env);
3344 struct lustre_cfg *lcfg;
3345 struct llog_cfg_rec *lcr;
3347 int rc, cmd, convert = 1;
3349 if (class_match_param(ptr, PARAM_TIMEOUT, &tmp) == 0) {
3350 cmd = LCFG_SET_TIMEOUT;
3351 } else if (class_match_param(ptr, PARAM_LDLM_TIMEOUT, &tmp) == 0) {
3352 cmd = LCFG_SET_LDLM_TIMEOUT;
3353 /* Check for known params here so we can return error to lctl */
3354 } else if ((class_match_param(ptr, PARAM_AT_MIN, &tmp) == 0) ||
3355 (class_match_param(ptr, PARAM_AT_MAX, &tmp) == 0) ||
3356 (class_match_param(ptr, PARAM_AT_EXTRA, &tmp) == 0) ||
3357 (class_match_param(ptr, PARAM_AT_EARLY_MARGIN, &tmp) == 0) ||
3358 (class_match_param(ptr, PARAM_AT_HISTORY, &tmp) == 0)) {
3360 } else if (class_match_param(ptr, PARAM_JOBID_VAR, &tmp) == 0) {
3361 convert = 0; /* Don't convert string value to integer */
3367 if (mgs_param_empty(ptr))
3368 CDEBUG(D_MGS, "global '%s' removed\n", sys);
3370 CDEBUG(D_MGS, "global '%s' val=%s\n", sys, tmp);
3372 lustre_cfg_bufs_reset(&mgi->mgi_bufs, NULL);
3373 lustre_cfg_bufs_set_string(&mgi->mgi_bufs, 1, sys);
3374 if (!convert && *tmp != '\0')
3375 lustre_cfg_bufs_set_string(&mgi->mgi_bufs, 2, tmp);
3376 lcr = lustre_cfg_rec_new(cmd, &mgi->mgi_bufs);
3380 lcfg = &lcr->lcr_cfg;
3382 rc = kstrtouint(tmp, 0, &lcfg->lcfg_num);
3384 GOTO(out_rec_free, rc);
3389 /* truncate the comment to the parameter name */
3393 /* modify all servers and clients */
3394 rc = mgs_write_log_direct_all(env, mgs, fsdb, mti,
3395 *tmp == '\0' ? NULL : lcr,
3396 mti->mti_fsname, sys, 0);
3397 if (rc == 0 && *tmp != '\0') {
3399 case LCFG_SET_TIMEOUT:
3400 if (!obd_timeout_set || lcfg->lcfg_num > obd_timeout)
3401 class_process_config(lcfg);
3403 case LCFG_SET_LDLM_TIMEOUT:
3404 if (!ldlm_timeout_set || lcfg->lcfg_num > ldlm_timeout)
3405 class_process_config(lcfg);
3413 lustre_cfg_rec_free(lcr);
3417 /* write quota settings into log */
3418 static int mgs_write_log_quota(const struct lu_env *env, struct mgs_device *mgs,
3419 struct fs_db *fsdb, struct mgs_target_info *mti,
3420 char *quota, char *ptr)
3422 struct mgs_thread_info *mgi = mgs_env_info(env);
3423 struct llog_cfg_rec *lcr;
3426 int rc, cmd = LCFG_PARAM;
3428 /* support only 'meta' and 'data' pools so far */
3429 if (class_match_param(ptr, QUOTA_METAPOOL_NAME, &tmp) != 0 &&
3430 class_match_param(ptr, QUOTA_DATAPOOL_NAME, &tmp) != 0) {
3431 CERROR("parameter quota.%s isn't supported (only quota.mdt "
3432 "& quota.ost are)\n", ptr);
3437 CDEBUG(D_MGS, "global '%s' removed\n", quota);
3439 CDEBUG(D_MGS, "global '%s'\n", quota);
3441 if (strchr(tmp, 'u') == NULL && strchr(tmp, 'g') == NULL &&
3442 strchr(tmp, 'p') == NULL &&
3443 strcmp(tmp, "none") != 0) {
3444 CERROR("enable option(%s) isn't supported\n", tmp);
3449 lustre_cfg_bufs_reset(&mgi->mgi_bufs, mti->mti_fsname);
3450 lustre_cfg_bufs_set_string(&mgi->mgi_bufs, 1, quota);
3451 lcr = lustre_cfg_rec_new(cmd, &mgi->mgi_bufs);
3455 /* truncate the comment to the parameter name */
3460 /* XXX we duplicated quota enable information in all server
3461 * config logs, it should be moved to a separate config
3462 * log once we cleanup the config log for global param. */
3463 /* modify all servers */
3464 rc = mgs_write_log_direct_all(env, mgs, fsdb, mti,
3465 *tmp == '\0' ? NULL : lcr,
3466 mti->mti_fsname, quota, 1);
3468 lustre_cfg_rec_free(lcr);
3469 return rc < 0 ? rc : 0;
3472 static int mgs_srpc_set_param_disk(const struct lu_env *env,
3473 struct mgs_device *mgs,
3475 struct mgs_target_info *mti,
3478 struct mgs_thread_info *mgi = mgs_env_info(env);
3479 struct llog_cfg_rec *lcr;
3480 struct llog_handle *llh = NULL;
3482 char *comment, *ptr;
3488 ptr = strchr(param, '=');
3489 LASSERT(ptr != NULL);
3492 OBD_ALLOC(comment, len + 1);
3493 if (comment == NULL)
3495 strncpy(comment, param, len);
3496 comment[len] = '\0';
3499 lustre_cfg_bufs_reset(&mgi->mgi_bufs, mti->mti_svname);
3500 lustre_cfg_bufs_set_string(&mgi->mgi_bufs, 1, param);
3501 lcr = lustre_cfg_rec_new(LCFG_SPTLRPC_CONF, &mgi->mgi_bufs);
3503 GOTO(out_comment, rc = -ENOMEM);
3505 /* construct log name */
3506 rc = name_create(&logname, mti->mti_fsname, "-sptlrpc");
3510 if (mgs_log_is_empty(env, mgs, logname)) {
3511 rc = record_start_log(env, mgs, &llh, logname);
3514 record_end_log(env, &llh);
3517 /* obsolete old one */
3518 rc = mgs_modify(env, mgs, fsdb, mti, logname, mti->mti_svname,
3522 /* write the new one */
3523 rc = mgs_write_log_direct(env, mgs, fsdb, logname, lcr,
3524 mti->mti_svname, comment);
3526 CERROR("%s: error writing log %s: rc = %d\n",
3527 mgs->mgs_obd->obd_name, logname, rc);
3529 name_destroy(&logname);
3531 lustre_cfg_rec_free(lcr);
3533 OBD_FREE(comment, len + 1);
3537 static int mgs_srpc_set_param_udesc_mem(struct fs_db *fsdb,
3542 /* disable the adjustable udesc parameter for now, i.e. use default
3543 * setting that client always ship udesc to MDT if possible. to enable
3544 * it simply remove the following line */
3547 ptr = strchr(param, '=');
3552 if (strcmp(param, PARAM_SRPC_UDESC))
3555 if (strcmp(ptr, "yes") == 0) {
3556 set_bit(FSDB_UDESC, &fsdb->fsdb_flags);
3557 CWARN("Enable user descriptor shipping from client to MDT\n");
3558 } else if (strcmp(ptr, "no") == 0) {
3559 clear_bit(FSDB_UDESC, &fsdb->fsdb_flags);
3560 CWARN("Disable user descriptor shipping from client to MDT\n");
3568 CERROR("Invalid param: %s\n", param);
3572 static int mgs_srpc_set_param_mem(struct fs_db *fsdb,
3576 struct sptlrpc_rule rule;
3577 struct sptlrpc_rule_set *rset;
3581 if (strncmp(param, PARAM_SRPC, sizeof(PARAM_SRPC) - 1) != 0) {
3582 CERROR("Invalid sptlrpc parameter: %s\n", param);
3586 if (strncmp(param, PARAM_SRPC_UDESC,
3587 sizeof(PARAM_SRPC_UDESC) - 1) == 0) {
3588 RETURN(mgs_srpc_set_param_udesc_mem(fsdb, param));
3591 if (strncmp(param, PARAM_SRPC_FLVR, sizeof(PARAM_SRPC_FLVR) - 1) != 0) {
3592 CERROR("Invalid sptlrpc flavor parameter: %s\n", param);
3596 param += sizeof(PARAM_SRPC_FLVR) - 1;
3598 rc = sptlrpc_parse_rule(param, &rule);
3602 /* mgs rules implies must be mgc->mgs */
3603 if (test_bit(FSDB_MGS_SELF, &fsdb->fsdb_flags)) {
3604 if ((rule.sr_from != LUSTRE_SP_MGC &&
3605 rule.sr_from != LUSTRE_SP_ANY) ||
3606 (rule.sr_to != LUSTRE_SP_MGS &&
3607 rule.sr_to != LUSTRE_SP_ANY))
3611 /* preapre room for this coming rule. svcname format should be:
3612 * - fsname: general rule
3613 * - fsname-tgtname: target-specific rule
3615 if (strchr(svname, '-')) {
3616 struct mgs_tgt_srpc_conf *tgtconf;
3619 for (tgtconf = fsdb->fsdb_srpc_tgt; tgtconf != NULL;
3620 tgtconf = tgtconf->mtsc_next) {
3621 if (!strcmp(tgtconf->mtsc_tgt, svname)) {
3630 OBD_ALLOC_PTR(tgtconf);
3631 if (tgtconf == NULL)
3634 name_len = strlen(svname);
3636 OBD_ALLOC(tgtconf->mtsc_tgt, name_len + 1);
3637 if (tgtconf->mtsc_tgt == NULL) {
3638 OBD_FREE_PTR(tgtconf);
3641 memcpy(tgtconf->mtsc_tgt, svname, name_len);
3643 tgtconf->mtsc_next = fsdb->fsdb_srpc_tgt;
3644 fsdb->fsdb_srpc_tgt = tgtconf;
3647 rset = &tgtconf->mtsc_rset;
3648 } else if (strcmp(svname, MGSSELF_NAME) == 0) {
3649 /* put _mgs related srpc rule directly in mgs ruleset */
3650 rset = &fsdb->fsdb_mgs->mgs_lut.lut_sptlrpc_rset;
3652 rset = &fsdb->fsdb_srpc_gen;
3655 rc = sptlrpc_rule_set_merge(rset, &rule);
3660 static int mgs_srpc_set_param(const struct lu_env *env,
3661 struct mgs_device *mgs,
3663 struct mgs_target_info *mti,
3673 /* keep a copy of original param, which could be destroied
3675 copy_size = strlen(param) + 1;
3676 OBD_ALLOC(copy, copy_size);
3679 memcpy(copy, param, copy_size);
3681 rc = mgs_srpc_set_param_mem(fsdb, mti->mti_svname, param);
3685 /* previous steps guaranteed the syntax is correct */
3686 rc = mgs_srpc_set_param_disk(env, mgs, fsdb, mti, copy);
3690 if (test_bit(FSDB_MGS_SELF, &fsdb->fsdb_flags)) {
3692 * for mgs rules, make them effective immediately.
3694 LASSERT(fsdb->fsdb_srpc_tgt == NULL);
3695 sptlrpc_target_update_exp_flavor(mgs->mgs_obd,
3696 &fsdb->fsdb_srpc_gen);
3700 OBD_FREE(copy, copy_size);
3704 struct mgs_srpc_read_data {
3705 struct fs_db *msrd_fsdb;
3709 static int mgs_srpc_read_handler(const struct lu_env *env,
3710 struct llog_handle *llh,
3711 struct llog_rec_hdr *rec, void *data)
3713 struct mgs_srpc_read_data *msrd = data;
3714 struct cfg_marker *marker;
3715 struct lustre_cfg *lcfg = REC_DATA(rec);
3716 char *svname, *param;
3720 if (rec->lrh_type != OBD_CFG_REC) {
3721 CERROR("unhandled lrh_type: %#x\n", rec->lrh_type);
3725 cfg_len = REC_DATA_LEN(rec);
3727 rc = lustre_cfg_sanity_check(lcfg, cfg_len);
3729 CERROR("Insane cfg\n");
3733 if (lcfg->lcfg_command == LCFG_MARKER) {
3734 marker = lustre_cfg_buf(lcfg, 1);
3736 if (marker->cm_flags & CM_START &&
3737 marker->cm_flags & CM_SKIP)
3738 msrd->msrd_skip = 1;
3739 if (marker->cm_flags & CM_END)
3740 msrd->msrd_skip = 0;
3745 if (msrd->msrd_skip)
3748 if (lcfg->lcfg_command != LCFG_SPTLRPC_CONF) {
3749 CERROR("invalid command (%x)\n", lcfg->lcfg_command);
3753 svname = lustre_cfg_string(lcfg, 0);
3754 if (svname == NULL) {
3755 CERROR("svname is empty\n");
3759 param = lustre_cfg_string(lcfg, 1);
3760 if (param == NULL) {
3761 CERROR("param is empty\n");
3765 rc = mgs_srpc_set_param_mem(msrd->msrd_fsdb, svname, param);
3767 CERROR("read sptlrpc record error (%d): %s\n", rc, param);
3772 int mgs_get_fsdb_srpc_from_llog(const struct lu_env *env,
3773 struct mgs_device *mgs,
3776 struct llog_handle *llh = NULL;
3777 struct llog_ctxt *ctxt;
3779 struct mgs_srpc_read_data msrd;
3783 /* construct log name */
3784 rc = name_create(&logname, fsdb->fsdb_name, "-sptlrpc");
3788 ctxt = llog_get_context(mgs->mgs_obd, LLOG_CONFIG_ORIG_CTXT);
3789 LASSERT(ctxt != NULL);
3791 if (mgs_log_is_empty(env, mgs, logname))
3794 rc = llog_open(env, ctxt, &llh, NULL, logname,
3802 rc = llog_init_handle(env, llh, LLOG_F_IS_PLAIN, NULL);
3804 GOTO(out_close, rc);
3806 if (llog_get_size(llh) <= 1)
3807 GOTO(out_close, rc = 0);
3809 msrd.msrd_fsdb = fsdb;
3812 rc = llog_process(env, llh, mgs_srpc_read_handler, (void *)&msrd,
3816 llog_close(env, llh);
3818 llog_ctxt_put(ctxt);
3819 name_destroy(&logname);
3822 CERROR("failed to read sptlrpc config database: %d\n", rc);
3826 static int mgs_write_log_param2(const struct lu_env *env,
3827 struct mgs_device *mgs,
3829 struct mgs_target_info *mti, char *ptr)
3831 struct lustre_cfg_bufs bufs;
3835 CDEBUG(D_MGS, "next param '%s'\n", ptr);
3837 /* PARAM_MGSNODE and PARAM_NETWORK are set only when formating
3838 * or during the inital mount. It can never change after that.
3840 if (!class_match_param(ptr, PARAM_MGSNODE, NULL) ||
3841 !class_match_param(ptr, PARAM_NETWORK, NULL)) {
3846 /* Processed in mgs_write_log_ost. Another value that can't
3847 * be changed by lctl set_param -P.
3849 if (!class_match_param(ptr, PARAM_FAILMODE, NULL)) {
3850 LCONSOLE_ERROR_MSG(0x169,
3851 "%s can only be changed with tunefs.lustre and --writeconf\n",
3857 /* FIXME !!! Support for sptlrpc is incomplete. Currently the change
3858 * doesn't transmit to the client. See LU-7183.
3860 if (!class_match_param(ptr, PARAM_SRPC, NULL)) {
3861 rc = mgs_srpc_set_param(env, mgs, fsdb, mti, ptr);
3865 /* Can't use class_match_param since ptr doesn't start with
3866 * PARAM_FAILNODE. So we look for PARAM_FAILNODE contained in ptr.
3868 if (strstr(ptr, PARAM_FAILNODE)) {
3869 /* Add a failover nidlist. We already processed failovers
3870 * params for new targets in mgs_write_log_target.
3874 /* can't use wildcards with failover.node */
3875 if (strchr(ptr, '*')) {
3880 param = strstr(ptr, PARAM_FAILNODE);
3881 if (strlcpy(mti->mti_params, param, sizeof(mti->mti_params)) >=
3882 sizeof(mti->mti_params)) {
3887 CDEBUG(D_MGS, "Adding failnode with param %s\n",
3889 rc = mgs_write_log_add_failnid(env, mgs, fsdb, mti);
3893 rc = mgs_wlp_lcfg(env, mgs, fsdb, mti, PARAMS_FILENAME, &bufs,
3894 mti->mti_svname, ptr);
3899 /* Permanent settings of all parameters by writing into the appropriate
3900 * configuration logs.
3901 * A parameter with null value ("<param>='\0'") means to erase it out of
3904 static int mgs_write_log_param(const struct lu_env *env,
3905 struct mgs_device *mgs, struct fs_db *fsdb,
3906 struct mgs_target_info *mti, char *ptr)
3908 struct mgs_thread_info *mgi = mgs_env_info(env);
3914 /* For various parameter settings, we have to figure out which logs
3915 care about them (e.g. both mdt and client for lov settings) */
3916 CDEBUG(D_MGS, "next param '%s'\n", ptr);
3918 /* The params are stored in MOUNT_DATA_FILE and modified via
3919 tunefs.lustre, or set using lctl conf_param */
3921 /* Processed in lustre_start_mgc */
3922 if (class_match_param(ptr, PARAM_MGSNODE, NULL) == 0)
3925 /* Processed in ost/mdt */
3926 if (class_match_param(ptr, PARAM_NETWORK, NULL) == 0)
3929 /* Processed in mgs_write_log_ost */
3930 if (class_match_param(ptr, PARAM_FAILMODE, NULL) == 0) {
3931 if (mti->mti_flags & LDD_F_PARAM) {
3932 LCONSOLE_ERROR_MSG(0x169,
3933 "%s can only be changed with tunefs.lustre and --writeconf\n",
3940 if (class_match_param(ptr, PARAM_SRPC, NULL) == 0) {
3941 rc = mgs_srpc_set_param(env, mgs, fsdb, mti, ptr);
3945 if (class_match_param(ptr, PARAM_FAILNODE, NULL) == 0) {
3946 /* Add a failover nidlist */
3948 /* We already processed failovers params for new
3949 targets in mgs_write_log_target */
3950 if (mti->mti_flags & LDD_F_PARAM) {
3951 CDEBUG(D_MGS, "Adding failnode\n");
3952 rc = mgs_write_log_add_failnid(env, mgs, fsdb, mti);
3957 if (class_match_param(ptr, PARAM_SYS, &tmp) == 0) {
3958 rc = mgs_write_log_sys(env, mgs, fsdb, mti, ptr, tmp);
3962 if (class_match_param(ptr, PARAM_QUOTA, &tmp) == 0) {
3963 rc = mgs_write_log_quota(env, mgs, fsdb, mti, ptr, tmp);
3967 if (class_match_param(ptr, PARAM_OSC PARAM_ACTIVE, &tmp) == 0 ||
3968 class_match_param(ptr, PARAM_MDC PARAM_ACTIVE, &tmp) == 0) {
3969 /* active=0 means off, anything else means on */
3970 int flag = (*tmp == '0') ? CM_EXCLUDE : 0;
3971 bool deactive_osc = memcmp(ptr, PARAM_OSC PARAM_ACTIVE,
3972 strlen(PARAM_OSC PARAM_ACTIVE)) == 0;
3975 if (!deactive_osc) {
3978 rc = server_name2index(mti->mti_svname, &index, NULL);
3983 LCONSOLE_ERROR_MSG(0x144, "%s: MDC0 can not be"
3984 " (de)activated.\n",
3986 GOTO(end, rc = -EPERM);
3990 LCONSOLE_WARN("Permanently %sactivating %s\n",
3991 flag ? "de" : "re", mti->mti_svname);
3993 rc = name_create(&logname, mti->mti_fsname, "-client");
3996 rc = mgs_modify(env, mgs, fsdb, mti, logname,
3998 deactive_osc ? "add osc" : "add mdc", flag);
3999 name_destroy(&logname);
4004 /* Add to all MDT logs for DNE */
4005 for (i = 0; i < INDEX_MAP_SIZE * 8; i++) {
4006 if (!test_bit(i, fsdb->fsdb_mdt_index_map))
4008 rc = name_create_mdt(&logname, mti->mti_fsname, i);
4011 rc = mgs_modify(env, mgs, fsdb, mti, logname,
4013 deactive_osc ? "add osc" : "add osp",
4015 name_destroy(&logname);
4021 LCONSOLE_ERROR_MSG(0x145,
4022 "Couldn't find %s in log (%d). No permanent changes were made to the config log.\n",
4023 mti->mti_svname, rc);
4024 if (test_bit(FSDB_OLDLOG14, &fsdb->fsdb_flags))
4025 LCONSOLE_ERROR_MSG(0x146,
4026 "This may be because the log is in the old 1.4 style. Consider --writeconf to update the logs.\n");
4029 /* Fall through to osc/mdc proc for deactivating live
4030 OSC/OSP on running MDT / clients. */
4032 /* Below here, let obd's XXX_process_config methods handle it */
4034 /* All lov. in proc */
4035 if (class_match_param(ptr, PARAM_LOV, NULL) == 0) {
4038 CDEBUG(D_MGS, "lov param %s\n", ptr);
4039 if (!(mti->mti_flags & LDD_F_SV_TYPE_MDT)) {
4040 LCONSOLE_ERROR_MSG(0x147, "LOV params must be "
4041 "set on the MDT, not %s. "
4048 if (mgs_log_is_empty(env, mgs, mti->mti_svname))
4049 GOTO(end, rc = -ENODEV);
4051 rc = name_create_mdt_and_lov(&logname, &mdtlovname, fsdb,
4052 mti->mti_stripe_index);
4055 rc = mgs_wlp_lcfg(env, mgs, fsdb, mti, mti->mti_svname,
4056 &mgi->mgi_bufs, mdtlovname, ptr);
4057 name_destroy(&logname);
4058 name_destroy(&mdtlovname);
4063 rc = name_create(&logname, mti->mti_fsname, "-client");
4066 rc = mgs_wlp_lcfg(env, mgs, fsdb, mti, logname, &mgi->mgi_bufs,
4067 fsdb->fsdb_clilov, ptr);
4068 name_destroy(&logname);
4072 /* All osc., mdc., llite. params in proc */
4073 if ((class_match_param(ptr, PARAM_OSC, NULL) == 0) ||
4074 (class_match_param(ptr, PARAM_MDC, NULL) == 0) ||
4075 (class_match_param(ptr, PARAM_LLITE, NULL) == 0)) {
4078 if (test_bit(FSDB_OLDLOG14, &fsdb->fsdb_flags)) {
4079 LCONSOLE_ERROR_MSG(0x148, "Upgraded client logs for %s"
4080 " cannot be modified. Consider"
4081 " updating the configuration with"
4084 GOTO(end, rc = -EINVAL);
4086 if (memcmp(ptr, PARAM_LLITE, strlen(PARAM_LLITE)) == 0) {
4087 rc = name_create(&cname, mti->mti_fsname, "-client");
4088 /* Add the client type to match the obdname in
4089 class_config_llog_handler */
4090 } else if (mti->mti_flags & LDD_F_SV_TYPE_MDT) {
4091 rc = name_create(&cname, mti->mti_svname, "-mdc");
4092 } else if (mti->mti_flags & LDD_F_SV_TYPE_OST) {
4093 rc = name_create(&cname, mti->mti_svname, "-osc");
4095 GOTO(end, rc = -EINVAL);
4100 /* Forbid direct update of llite root squash parameters.
4101 * These parameters are indirectly set via the MDT settings.
4103 if ((class_match_param(ptr, PARAM_LLITE, &tmp) == 0) &&
4104 ((memcmp(tmp, "root_squash=", 12) == 0) ||
4105 (memcmp(tmp, "nosquash_nids=", 14) == 0))) {
4106 LCONSOLE_ERROR("%s: root squash parameters can only "
4107 "be updated through MDT component\n",
4109 name_destroy(&cname);
4110 GOTO(end, rc = -EINVAL);
4113 CDEBUG(D_MGS, "%.3s param %s\n", ptr, ptr + 4);
4116 rc = name_create(&logname, mti->mti_fsname, "-client");
4118 name_destroy(&cname);
4121 rc = mgs_wlp_lcfg(env, mgs, fsdb, mti, logname, &mgi->mgi_bufs,
4124 /* osc params affect the MDT as well */
4125 if (!rc && (mti->mti_flags & LDD_F_SV_TYPE_OST)) {
4128 for (i = 0; i < INDEX_MAP_SIZE * 8; i++){
4129 if (!test_bit(i, fsdb->fsdb_mdt_index_map))
4131 name_destroy(&cname);
4132 rc = name_create_mdt_osc(&cname, mti->mti_svname,
4134 name_destroy(&logname);
4137 rc = name_create_mdt(&logname,
4138 mti->mti_fsname, i);
4141 if (!mgs_log_is_empty(env, mgs, logname)) {
4142 rc = mgs_wlp_lcfg(env, mgs, fsdb,
4152 /* For mdc activate/deactivate, it affects OSP on MDT as well */
4153 if (class_match_param(ptr, PARAM_MDC PARAM_ACTIVE, &tmp) == 0 &&
4156 char *lodname = NULL;
4157 char *param_str = NULL;
4161 /* replace mdc with osp */
4162 memcpy(ptr, PARAM_OSP, strlen(PARAM_OSP));
4163 rc = server_name2index(mti->mti_svname, &index, NULL);
4165 memcpy(ptr, PARAM_MDC, strlen(PARAM_MDC));
4169 for (i = 0; i < INDEX_MAP_SIZE * 8; i++) {
4170 if (!test_bit(i, fsdb->fsdb_mdt_index_map))
4176 name_destroy(&logname);
4177 rc = name_create_mdt(&logname, mti->mti_fsname,
4182 if (mgs_log_is_empty(env, mgs, logname))
4185 snprintf(suffix, sizeof(suffix), "-osp-MDT%04x",
4187 name_destroy(&cname);
4188 rc = name_create(&cname, mti->mti_svname,
4193 rc = mgs_wlp_lcfg(env, mgs, fsdb, mti, logname,
4194 &mgi->mgi_bufs, cname, ptr);
4198 /* Add configuration log for noitfying LOD
4199 * to active/deactive the OSP. */
4200 name_destroy(¶m_str);
4201 rc = name_create(¶m_str, cname,
4202 (*tmp == '0') ? ".active=0" :
4207 name_destroy(&lodname);
4208 rc = name_create(&lodname, logname, "-mdtlov");
4212 rc = mgs_wlp_lcfg(env, mgs, fsdb, mti, logname,
4213 &mgi->mgi_bufs, lodname,
4218 memcpy(ptr, PARAM_MDC, strlen(PARAM_MDC));
4219 name_destroy(&lodname);
4220 name_destroy(¶m_str);
4223 name_destroy(&logname);
4224 name_destroy(&cname);
4228 /* All mdt. params in proc */
4229 if (class_match_param(ptr, PARAM_MDT, &tmp) == 0) {
4233 CDEBUG(D_MGS, "%.3s param %s\n", ptr, ptr + 4);
4234 if (strncmp(mti->mti_svname, mti->mti_fsname,
4235 MTI_NAME_MAXLEN) == 0)
4236 /* device is unspecified completely? */
4237 rc = LDD_F_SV_TYPE_MDT | LDD_F_SV_ALL;
4239 rc = server_name2index(mti->mti_svname, &idx, NULL);
4242 if ((rc & LDD_F_SV_TYPE_MDT) == 0)
4244 if (rc & LDD_F_SV_ALL) {
4245 for (i = 0; i < INDEX_MAP_SIZE * 8; i++) {
4247 fsdb->fsdb_mdt_index_map))
4249 rc = name_create_mdt(&logname,
4250 mti->mti_fsname, i);
4253 rc = mgs_wlp_lcfg(env, mgs, fsdb, mti,
4254 logname, &mgi->mgi_bufs,
4256 name_destroy(&logname);
4261 if ((memcmp(tmp, "root_squash=", 12) == 0) ||
4262 (memcmp(tmp, "nosquash_nids=", 14) == 0)) {
4263 LCONSOLE_ERROR("%s: root squash parameters "
4264 "cannot be applied to a single MDT\n",
4266 GOTO(end, rc = -EINVAL);
4268 rc = mgs_wlp_lcfg(env, mgs, fsdb, mti,
4269 mti->mti_svname, &mgi->mgi_bufs,
4270 mti->mti_svname, ptr);
4275 /* root squash settings are also applied to llite
4276 * config log (see LU-1778) */
4278 ((memcmp(tmp, "root_squash=", 12) == 0) ||
4279 (memcmp(tmp, "nosquash_nids=", 14) == 0))) {
4283 rc = name_create(&cname, mti->mti_fsname, "-client");
4286 rc = name_create(&logname, mti->mti_fsname, "-client");
4288 name_destroy(&cname);
4291 rc = name_create(&ptr2, PARAM_LLITE, tmp);
4293 name_destroy(&cname);
4294 name_destroy(&logname);
4297 rc = mgs_wlp_lcfg(env, mgs, fsdb, mti, logname,
4298 &mgi->mgi_bufs, cname, ptr2);
4299 name_destroy(&ptr2);
4300 name_destroy(&logname);
4301 name_destroy(&cname);
4306 /* All mdd., ost. and osd. params in proc */
4307 if ((class_match_param(ptr, PARAM_MDD, NULL) == 0) ||
4308 (class_match_param(ptr, PARAM_LOD, NULL) == 0) ||
4309 (class_match_param(ptr, PARAM_OST, NULL) == 0) ||
4310 (class_match_param(ptr, PARAM_OSD, NULL) == 0)) {
4311 CDEBUG(D_MGS, "%.3s param %s\n", ptr, ptr + 4);
4312 if (mgs_log_is_empty(env, mgs, mti->mti_svname))
4313 GOTO(end, rc = -ENODEV);
4315 rc = mgs_wlp_lcfg(env, mgs, fsdb, mti, mti->mti_svname,
4316 &mgi->mgi_bufs, mti->mti_svname, ptr);
4320 LCONSOLE_WARN("Ignoring unrecognized param '%s'\n", ptr);
4324 CERROR("err %d on param '%s'\n", rc, ptr);
4329 int mgs_write_log_target(const struct lu_env *env, struct mgs_device *mgs,
4330 struct mgs_target_info *mti, struct fs_db *fsdb)
4337 /* set/check the new target index */
4338 rc = mgs_set_index(env, mgs, mti);
4342 if (rc == EALREADY) {
4343 LCONSOLE_WARN("Found index %d for %s, updating log\n",
4344 mti->mti_stripe_index, mti->mti_svname);
4345 /* We would like to mark old log sections as invalid
4346 and add new log sections in the client and mdt logs.
4347 But if we add new sections, then live clients will
4348 get repeat setup instructions for already running
4349 osc's. So don't update the client/mdt logs. */
4350 mti->mti_flags &= ~LDD_F_UPDATE;
4354 OBD_FAIL_TIMEOUT(OBD_FAIL_MGS_WRITE_TARGET_DELAY, cfs_fail_val > 0 ?
4357 mutex_lock(&fsdb->fsdb_mutex);
4359 if (mti->mti_flags & (LDD_F_VIRGIN | LDD_F_WRITECONF)) {
4360 /* Generate a log from scratch */
4361 if (mti->mti_flags & LDD_F_SV_TYPE_MDT) {
4362 rc = mgs_write_log_mdt(env, mgs, fsdb, mti);
4363 } else if (mti->mti_flags & LDD_F_SV_TYPE_OST) {
4364 rc = mgs_write_log_ost(env, mgs, fsdb, mti);
4366 CERROR("Unknown target type %#x, can't create log for %s\n",
4367 mti->mti_flags, mti->mti_svname);
4370 CERROR("Can't write logs for %s (%d)\n",
4371 mti->mti_svname, rc);
4375 /* Just update the params from tunefs in mgs_write_log_params */
4376 CDEBUG(D_MGS, "Update params for %s\n", mti->mti_svname);
4377 mti->mti_flags |= LDD_F_PARAM;
4380 /* allocate temporary buffer, where class_get_next_param will
4381 make copy of a current parameter */
4382 OBD_ALLOC(buf, strlen(mti->mti_params) + 1);
4384 GOTO(out_up, rc = -ENOMEM);
4385 params = mti->mti_params;
4386 while (params != NULL) {
4387 rc = class_get_next_param(¶ms, buf);
4390 /* there is no next parameter, that is
4395 CDEBUG(D_MGS, "remaining string: '%s', param: '%s'\n",
4397 rc = mgs_write_log_param(env, mgs, fsdb, mti, buf);
4402 OBD_FREE(buf, strlen(mti->mti_params) + 1);
4405 mutex_unlock(&fsdb->fsdb_mutex);
4409 int mgs_erase_log(const struct lu_env *env, struct mgs_device *mgs, char *name)
4411 struct llog_ctxt *ctxt;
4414 ctxt = llog_get_context(mgs->mgs_obd, LLOG_CONFIG_ORIG_CTXT);
4416 CERROR("%s: MGS config context doesn't exist\n",
4417 mgs->mgs_obd->obd_name);
4420 rc = llog_erase(env, ctxt, NULL, name);
4421 /* llog may not exist */
4424 llog_ctxt_put(ctxt);
4428 CERROR("%s: failed to clear log %s: %d\n",
4429 mgs->mgs_obd->obd_name, name, rc);
4434 /* erase all logs for the given fs */
4435 int mgs_erase_logs(const struct lu_env *env, struct mgs_device *mgs,
4438 struct list_head log_list;
4439 struct mgs_direntry *dirent, *n;
4440 char barrier_name[20] = {};
4443 int rc, len = strlen(fsname);
4446 mutex_lock(&mgs->mgs_mutex);
4448 /* Find all the logs in the CONFIGS directory */
4449 rc = class_dentry_readdir(env, mgs, &log_list);
4451 mutex_unlock(&mgs->mgs_mutex);
4455 if (list_empty(&log_list)) {
4456 mutex_unlock(&mgs->mgs_mutex);
4460 snprintf(barrier_name, sizeof(barrier_name) - 1, "%s-%s",
4461 fsname, BARRIER_FILENAME);
4462 /* Delete the barrier fsdb */
4463 mgs_remove_fsdb_by_name(mgs, barrier_name);
4464 /* Delete the fs db */
4465 mgs_remove_fsdb_by_name(mgs, fsname);
4466 mutex_unlock(&mgs->mgs_mutex);
4468 list_for_each_entry_safe(dirent, n, &log_list, mde_list) {
4469 list_del_init(&dirent->mde_list);
4470 suffix = strrchr(dirent->mde_name, '-');
4471 if (suffix != NULL) {
4472 if ((len == suffix - dirent->mde_name) &&
4473 (strncmp(fsname, dirent->mde_name, len) == 0)) {
4474 CDEBUG(D_MGS, "Removing log %s\n",
4476 mgs_erase_log(env, mgs, dirent->mde_name);
4480 mgs_direntry_free(dirent);
4489 /* list all logs for the given fs */
4490 int mgs_list_logs(const struct lu_env *env, struct mgs_device *mgs,
4491 struct obd_ioctl_data *data)
4493 struct list_head log_list;
4494 struct mgs_direntry *dirent, *n;
4495 char *out, *suffix, prefix[] = "config_log: ";
4496 int prefix_len = strlen(prefix);
4497 int len, remains, start = 0, rc;
4501 /* Find all the logs in the CONFIGS directory */
4502 rc = class_dentry_readdir(env, mgs, &log_list);
4506 out = data->ioc_bulk;
4507 remains = data->ioc_inllen1;
4508 /* OBD_FAIL: fetch the config_log records from the specified one */
4509 if (OBD_FAIL_CHECK(OBD_FAIL_CATLIST))
4510 data->ioc_count = cfs_fail_val;
4512 list_for_each_entry_safe(dirent, n, &log_list, mde_list) {
4513 list_del_init(&dirent->mde_list);
4514 suffix = strrchr(dirent->mde_name, '-');
4515 if (suffix != NULL) {
4516 len = prefix_len + dirent->mde_len + 1;
4517 if (remains - len < 0) {
4518 /* No enough space for this record */
4519 mgs_direntry_free(dirent);
4523 if (start < data->ioc_count) {
4524 mgs_direntry_free(dirent);
4527 len = scnprintf(out, remains, "%s%s\n", prefix,
4532 mgs_direntry_free(dirent);
4540 data->ioc_count = start;
4544 struct mgs_lcfg_fork_data {
4545 struct lustre_cfg_bufs mlfd_bufs;
4546 struct mgs_device *mlfd_mgs;
4547 struct llog_handle *mlfd_llh;
4548 const char *mlfd_oldname;
4549 const char *mlfd_newname;
4553 static bool contain_valid_fsname(char *buf, const char *fsname,
4554 int buflen, int namelen)
4556 if (buflen < namelen)
4559 if (memcmp(buf, fsname, namelen) != 0)
4562 if (buf[namelen] != '\0' && buf[namelen] != '-')
4568 static int mgs_lcfg_fork_handler(const struct lu_env *env,
4569 struct llog_handle *o_llh,
4570 struct llog_rec_hdr *o_rec, void *data)
4572 struct mgs_lcfg_fork_data *mlfd = data;
4573 struct lustre_cfg_bufs *n_bufs = &mlfd->mlfd_bufs;
4574 struct lustre_cfg *o_lcfg = (struct lustre_cfg *)(o_rec + 1);
4575 struct llog_cfg_rec *lcr;
4577 char *n_buf = mlfd->mlfd_data;
4579 int o_namelen = strlen(mlfd->mlfd_oldname);
4580 int n_namelen = strlen(mlfd->mlfd_newname);
4581 int diff = n_namelen - o_namelen;
4582 __u32 cmd = o_lcfg->lcfg_command;
4583 __u32 cnt = o_lcfg->lcfg_bufcount;
4589 o_buf = lustre_cfg_buf(o_lcfg, 0);
4590 o_buflen = o_lcfg->lcfg_buflens[0];
4591 if (contain_valid_fsname(o_buf, mlfd->mlfd_oldname, o_buflen,
4593 memcpy(n_buf, mlfd->mlfd_newname, n_namelen);
4594 memcpy(n_buf + n_namelen, o_buf + o_namelen,
4595 o_buflen - o_namelen);
4596 lustre_cfg_bufs_reset(n_bufs, n_buf);
4597 n_buf += cfs_size_round(o_buflen + diff);
4599 lustre_cfg_bufs_reset(n_bufs, o_buflen != 0 ? o_buf : NULL);
4604 struct cfg_marker *o_marker;
4605 struct cfg_marker *n_marker;
4609 CDEBUG(D_MGS, "Unknown cfg marker entry with %d "
4614 /* buf[1] is marker */
4615 o_buf = lustre_cfg_buf(o_lcfg, 1);
4616 o_buflen = o_lcfg->lcfg_buflens[1];
4617 o_marker = (struct cfg_marker *)o_buf;
4618 if (!contain_valid_fsname(o_marker->cm_tgtname,
4620 sizeof(o_marker->cm_tgtname),
4622 lustre_cfg_bufs_set(n_bufs, 1, o_marker,
4627 n_marker = (struct cfg_marker *)n_buf;
4628 *n_marker = *o_marker;
4629 memcpy(n_marker->cm_tgtname, mlfd->mlfd_newname, n_namelen);
4630 tgt_namelen = strlen(o_marker->cm_tgtname);
4631 if (tgt_namelen > o_namelen)
4632 memcpy(n_marker->cm_tgtname + n_namelen,
4633 o_marker->cm_tgtname + o_namelen,
4634 tgt_namelen - o_namelen);
4635 n_marker->cm_tgtname[tgt_namelen + diff] = '\0';
4636 lustre_cfg_bufs_set(n_bufs, 1, n_marker, sizeof(*n_marker));
4640 case LCFG_SET_PARAM: {
4641 for (i = 1; i < cnt; i++)
4642 /* buf[i] is the param value, reuse it directly */
4643 lustre_cfg_bufs_set(n_bufs, i,
4644 lustre_cfg_buf(o_lcfg, i),
4645 o_lcfg->lcfg_buflens[i]);
4651 case LCFG_POOL_DEL: {
4652 if (cnt < 3 || cnt > 4) {
4653 CDEBUG(D_MGS, "Unknown cfg pool (%x) entry with %d "
4654 "buffers\n", cmd, cnt);
4658 /* buf[1] is fsname */
4659 o_buf = lustre_cfg_buf(o_lcfg, 1);
4660 o_buflen = o_lcfg->lcfg_buflens[1];
4661 memcpy(n_buf, mlfd->mlfd_newname, n_namelen);
4662 memcpy(n_buf + n_namelen, o_buf + o_namelen,
4663 o_buflen - o_namelen);
4664 lustre_cfg_bufs_set(n_bufs, 1, n_buf, o_buflen + diff);
4665 n_buf += cfs_size_round(o_buflen + diff);
4667 /* buf[2] is the pool name, reuse it directly */
4668 lustre_cfg_bufs_set(n_bufs, 2, lustre_cfg_buf(o_lcfg, 2),
4669 o_lcfg->lcfg_buflens[2]);
4674 /* buf[3] is ostname */
4675 o_buf = lustre_cfg_buf(o_lcfg, 3);
4676 o_buflen = o_lcfg->lcfg_buflens[3];
4677 memcpy(n_buf, mlfd->mlfd_newname, n_namelen);
4678 memcpy(n_buf + n_namelen, o_buf + o_namelen,
4679 o_buflen - o_namelen);
4680 lustre_cfg_bufs_set(n_bufs, 3, n_buf, o_buflen + diff);
4685 o_buflen = o_lcfg->lcfg_buflens[1];
4686 if (o_buflen == sizeof(struct lov_desc) ||
4687 o_buflen == sizeof(struct lmv_desc)) {
4693 o_buf = lustre_cfg_buf(o_lcfg, 1);
4694 if (o_buflen == sizeof(struct lov_desc)) {
4695 struct lov_desc *o_desc =
4696 (struct lov_desc *)o_buf;
4697 struct lov_desc *n_desc =
4698 (struct lov_desc *)n_buf;
4701 o_uuid = o_desc->ld_uuid.uuid;
4702 n_uuid = n_desc->ld_uuid.uuid;
4703 uuid_len = sizeof(o_desc->ld_uuid.uuid);
4705 struct lmv_desc *o_desc =
4706 (struct lmv_desc *)o_buf;
4707 struct lmv_desc *n_desc =
4708 (struct lmv_desc *)n_buf;
4711 o_uuid = o_desc->ld_uuid.uuid;
4712 n_uuid = n_desc->ld_uuid.uuid;
4713 uuid_len = sizeof(o_desc->ld_uuid.uuid);
4716 if (unlikely(!contain_valid_fsname(o_uuid,
4717 mlfd->mlfd_oldname, uuid_len,
4719 lustre_cfg_bufs_set(n_bufs, 1, o_buf,
4724 memcpy(n_uuid, mlfd->mlfd_newname, n_namelen);
4725 uuid_len = strlen(o_uuid);
4726 if (uuid_len > o_namelen)
4727 memcpy(n_uuid + n_namelen,
4729 uuid_len - o_namelen);
4730 n_uuid[uuid_len + diff] = '\0';
4731 lustre_cfg_bufs_set(n_bufs, 1, n_buf, o_buflen);
4733 } /* else case fall through */
4734 } /* else case fall through */
4738 for (i = 1; i < cnt; i++) {
4739 o_buflen = o_lcfg->lcfg_buflens[i];
4743 o_buf = lustre_cfg_buf(o_lcfg, i);
4744 if (!contain_valid_fsname(o_buf, mlfd->mlfd_oldname,
4745 o_buflen, o_namelen)) {
4746 lustre_cfg_bufs_set(n_bufs, i, o_buf, o_buflen);
4750 memcpy(n_buf, mlfd->mlfd_newname, n_namelen);
4751 if (o_buflen == o_namelen) {
4752 lustre_cfg_bufs_set(n_bufs, i, n_buf,
4754 n_buf += cfs_size_round(n_namelen);
4758 memcpy(n_buf + n_namelen, o_buf + o_namelen,
4759 o_buflen - o_namelen);
4760 lustre_cfg_bufs_set(n_bufs, i, n_buf, o_buflen + diff);
4761 n_buf += cfs_size_round(o_buflen + diff);
4767 lcr = lustre_cfg_rec_new(cmd, n_bufs);
4771 lcr->lcr_cfg = *o_lcfg;
4772 rc = llog_write(env, mlfd->mlfd_llh, &lcr->lcr_hdr, LLOG_NEXT_IDX);
4773 lustre_cfg_rec_free(lcr);
4778 static int mgs_lcfg_fork_one(const struct lu_env *env, struct mgs_device *mgs,
4779 struct mgs_direntry *mde, const char *oldname,
4780 const char *newname)
4782 struct llog_handle *old_llh = NULL;
4783 struct llog_handle *new_llh = NULL;
4784 struct llog_ctxt *ctxt = NULL;
4785 struct mgs_lcfg_fork_data *mlfd = NULL;
4786 char *name_buf = NULL;
4788 int old_namelen = strlen(oldname);
4789 int new_namelen = strlen(newname);
4793 name_buflen = mde->mde_len + new_namelen - old_namelen;
4794 OBD_ALLOC(name_buf, name_buflen);
4798 memcpy(name_buf, newname, new_namelen);
4799 memcpy(name_buf + new_namelen, mde->mde_name + old_namelen,
4800 mde->mde_len - old_namelen);
4802 CDEBUG(D_MGS, "Fork the config-log from %s to %s\n",
4803 mde->mde_name, name_buf);
4805 ctxt = llog_get_context(mgs->mgs_obd, LLOG_CONFIG_ORIG_CTXT);
4808 rc = llog_open_create(env, ctxt, &new_llh, NULL, name_buf);
4812 rc = llog_init_handle(env, new_llh, LLOG_F_IS_PLAIN, NULL);
4816 if (unlikely(mgs_log_is_empty(env, mgs, mde->mde_name)))
4819 rc = llog_open(env, ctxt, &old_llh, NULL, mde->mde_name,
4824 rc = llog_init_handle(env, old_llh, LLOG_F_IS_PLAIN, NULL);
4828 new_llh->lgh_hdr->llh_tgtuuid = old_llh->lgh_hdr->llh_tgtuuid;
4830 OBD_ALLOC(mlfd, LLOG_MIN_CHUNK_SIZE);
4832 GOTO(out, rc = -ENOMEM);
4834 mlfd->mlfd_mgs = mgs;
4835 mlfd->mlfd_llh = new_llh;
4836 mlfd->mlfd_oldname = oldname;
4837 mlfd->mlfd_newname = newname;
4839 rc = llog_process(env, old_llh, mgs_lcfg_fork_handler, mlfd, NULL);
4840 OBD_FREE(mlfd, LLOG_MIN_CHUNK_SIZE);
4846 llog_close(env, old_llh);
4848 llog_close(env, new_llh);
4850 OBD_FREE(name_buf, name_buflen);
4852 llog_ctxt_put(ctxt);
4857 int mgs_lcfg_fork(const struct lu_env *env, struct mgs_device *mgs,
4858 const char *oldname, const char *newname)
4860 struct list_head log_list;
4861 struct mgs_direntry *dirent, *n;
4862 int olen = strlen(oldname);
4863 int nlen = strlen(newname);
4868 if (unlikely(!oldname || oldname[0] == '\0' ||
4869 !newname || newname[0] == '\0'))
4872 if (strcmp(oldname, newname) == 0)
4875 /* lock it to prevent fork/erase/register in parallel. */
4876 mutex_lock(&mgs->mgs_mutex);
4878 rc = class_dentry_readdir(env, mgs, &log_list);
4880 mutex_unlock(&mgs->mgs_mutex);
4884 if (list_empty(&log_list)) {
4885 mutex_unlock(&mgs->mgs_mutex);
4889 list_for_each_entry_safe(dirent, n, &log_list, mde_list) {
4892 ptr = strrchr(dirent->mde_name, '-');
4894 int tlen = ptr - dirent->mde_name;
4897 strncmp(newname, dirent->mde_name, tlen) == 0)
4898 GOTO(out, rc = -EEXIST);
4901 strncmp(oldname, dirent->mde_name, tlen) == 0)
4905 list_del_init(&dirent->mde_list);
4906 mgs_direntry_free(dirent);
4909 if (list_empty(&log_list)) {
4910 mutex_unlock(&mgs->mgs_mutex);
4914 list_for_each_entry(dirent, &log_list, mde_list) {
4915 rc = mgs_lcfg_fork_one(env, mgs, dirent, oldname, newname);
4923 mutex_unlock(&mgs->mgs_mutex);
4925 list_for_each_entry_safe(dirent, n, &log_list, mde_list) {
4926 list_del_init(&dirent->mde_list);
4927 mgs_direntry_free(dirent);
4930 if (rc && count > 0)
4931 mgs_erase_logs(env, mgs, newname);
4936 int mgs_lcfg_erase(const struct lu_env *env, struct mgs_device *mgs,
4942 if (unlikely(!fsname || fsname[0] == '\0'))
4945 rc = mgs_erase_logs(env, mgs, fsname);
4950 static int mgs_xattr_del(const struct lu_env *env, struct dt_object *obj)
4952 struct dt_device *dev;
4953 struct thandle *th = NULL;
4958 dev = container_of(obj->do_lu.lo_dev, struct dt_device, dd_lu_dev);
4959 th = dt_trans_create(env, dev);
4961 RETURN(PTR_ERR(th));
4963 rc = dt_declare_xattr_del(env, obj, XATTR_TARGET_RENAME, th);
4967 rc = dt_trans_start_local(env, dev, th);
4971 dt_write_lock(env, obj, 0);
4972 rc = dt_xattr_del(env, obj, XATTR_TARGET_RENAME, th);
4977 dt_write_unlock(env, obj);
4980 dt_trans_stop(env, dev, th);
4985 int mgs_lcfg_rename(const struct lu_env *env, struct mgs_device *mgs)
4987 struct list_head log_list;
4988 struct mgs_direntry *dirent, *n;
4990 struct lu_buf buf = {
4992 .lb_len = sizeof(fsname)
4998 rc = class_dentry_readdir(env, mgs, &log_list);
5002 if (list_empty(&log_list))
5005 list_for_each_entry_safe(dirent, n, &log_list, mde_list) {
5006 struct dt_object *o = NULL;
5011 list_del_init(&dirent->mde_list);
5012 ptr = strrchr(dirent->mde_name, '-');
5016 len = ptr - dirent->mde_name;
5017 if (unlikely(len >= sizeof(oldname))) {
5018 CDEBUG(D_MGS, "Skip invalid configuration file %s\n",
5023 o = local_file_find(env, mgs->mgs_los, mgs->mgs_configs_dir,
5027 CDEBUG(D_MGS, "Fail to locate file %s: rc = %d\n",
5028 dirent->mde_name, rc);
5032 rc = dt_xattr_get(env, o, &buf, XATTR_TARGET_RENAME);
5038 "Fail to get EA for %s: rc = %d\n",
5039 dirent->mde_name, rc);
5043 if (unlikely(rc == len &&
5044 memcmp(fsname, dirent->mde_name, len) == 0)) {
5045 /* The new fsname is the same as the old one. */
5046 rc = mgs_xattr_del(env, o);
5050 memcpy(oldname, dirent->mde_name, len);
5051 oldname[len] = '\0';
5053 rc = mgs_lcfg_fork_one(env, mgs, dirent, oldname, fsname);
5054 if (rc && rc != -EEXIST) {
5055 CDEBUG(D_MGS, "Fail to fork %s: rc = %d\n",
5056 dirent->mde_name, rc);
5060 rc = mgs_erase_log(env, mgs, dirent->mde_name);
5062 CDEBUG(D_MGS, "Fail to erase old %s: rc = %d\n",
5063 dirent->mde_name, rc);
5064 /* keep it there if failed to remove it. */
5069 if (o && !IS_ERR(o))
5070 lu_object_put(env, &o->do_lu);
5072 mgs_direntry_free(dirent);
5077 list_for_each_entry_safe(dirent, n, &log_list, mde_list) {
5078 list_del_init(&dirent->mde_list);
5079 mgs_direntry_free(dirent);
5085 /* Setup _mgs fsdb and log
5087 int mgs__mgs_fsdb_setup(const struct lu_env *env, struct mgs_device *mgs)
5089 struct fs_db *fsdb = NULL;
5093 rc = mgs_find_or_make_fsdb(env, mgs, MGSSELF_NAME, &fsdb);
5095 mgs_put_fsdb(mgs, fsdb);
5100 /* Setup params fsdb and log
5102 int mgs_params_fsdb_setup(const struct lu_env *env, struct mgs_device *mgs)
5104 struct fs_db *fsdb = NULL;
5105 struct llog_handle *params_llh = NULL;
5109 rc = mgs_find_or_make_fsdb(env, mgs, PARAMS_FILENAME, &fsdb);
5111 mutex_lock(&fsdb->fsdb_mutex);
5112 rc = record_start_log(env, mgs, ¶ms_llh, PARAMS_FILENAME);
5114 rc = record_end_log(env, ¶ms_llh);
5115 mutex_unlock(&fsdb->fsdb_mutex);
5116 mgs_put_fsdb(mgs, fsdb);
5122 /* Cleanup params fsdb and log
5124 int mgs_params_fsdb_cleanup(const struct lu_env *env, struct mgs_device *mgs)
5128 rc = mgs_erase_logs(env, mgs, PARAMS_FILENAME);
5129 return rc == -ENOENT ? 0 : rc;
5133 * Fill in the mgs_target_info based on data devname and param provide.
5135 * @env thread context
5137 * @mti mgs target info. We want to set this based other paramters
5138 * passed to this function. Once setup we write it to the config
5140 * @devname optional OBD device name
5141 * @param string that contains both what tunable to set and the value to
5144 * RETURN 0 for success
5145 * negative error number on failure
5147 static int mgs_set_conf_param(const struct lu_env *env, struct mgs_device *mgs,
5148 struct mgs_target_info *mti, const char *devname,
5151 struct fs_db *fsdb = NULL;
5156 /* lustre, lustre-mdtlov, lustre-client, lustre-MDT0000 */
5160 /* We have two possible cases here:
5162 * 1) the device name embedded in the param:
5163 * lustre-OST0000.osc.max_dirty_mb=32
5165 * 2) the file system name is embedded in
5166 * the param: lustre.sys.at.min=0
5168 len = strcspn(param, ".=");
5169 if (!len || param[len] == '=')
5172 if (len >= sizeof(mti->mti_svname))
5175 snprintf(mti->mti_svname, sizeof(mti->mti_svname),
5176 "%.*s", (int)len, param);
5179 if (strlcpy(mti->mti_svname, devname, sizeof(mti->mti_svname)) >=
5180 sizeof(mti->mti_svname))
5184 if (!strlen(mti->mti_svname)) {
5185 LCONSOLE_ERROR_MSG(0x14d, "No target specified: %s\n", param);
5189 dev_type = mgs_parse_devname(mti->mti_svname, mti->mti_fsname,
5190 &mti->mti_stripe_index);
5192 /* For this case we have an invalid obd device name */
5194 CDEBUG(D_MGS, "%s don't contain an index\n", mti->mti_svname);
5195 strlcpy(mti->mti_fsname, mti->mti_svname, MTI_NAME_MAXLEN);
5198 /* Not an obd device, assume devname is the fsname.
5199 * User might of only provided fsname and not obd device
5202 CDEBUG(D_MGS, "%s is seen as a file system name\n", mti->mti_svname);
5203 strlcpy(mti->mti_fsname, mti->mti_svname, MTI_NAME_MAXLEN);
5208 GOTO(out, rc = dev_type);
5210 /* param related to llite isn't allowed to set by OST or MDT */
5211 if (dev_type & LDD_F_SV_TYPE_OST ||
5212 dev_type & LDD_F_SV_TYPE_MDT) {
5213 /* param related to llite isn't allowed to set by OST
5216 if (!strncmp(param, PARAM_LLITE,
5217 sizeof(PARAM_LLITE) - 1))
5218 GOTO(out, rc = -EINVAL);
5220 /* Strip -osc or -mdc suffix from svname */
5221 if (server_make_name(dev_type, mti->mti_stripe_index,
5222 mti->mti_fsname, mti->mti_svname,
5223 sizeof(mti->mti_svname)))
5224 GOTO(out, rc = -EINVAL);
5229 if (strlcpy(mti->mti_params, param, sizeof(mti->mti_params)) >=
5230 sizeof(mti->mti_params))
5231 GOTO(out, rc = -E2BIG);
5233 CDEBUG(D_MGS, "set_conf_param fs='%s' device='%s' param='%s'\n",
5234 mti->mti_fsname, mti->mti_svname, mti->mti_params);
5236 rc = mgs_find_or_make_fsdb(env, mgs, mti->mti_fsname, &fsdb);
5240 if (!test_bit(FSDB_MGS_SELF, &fsdb->fsdb_flags) &&
5241 test_bit(FSDB_LOG_EMPTY, &fsdb->fsdb_flags)) {
5242 CERROR("No filesystem targets for %s. cfg_device from lctl "
5243 "is '%s'\n", mti->mti_fsname, mti->mti_svname);
5244 mgs_unlink_fsdb(mgs, fsdb);
5245 GOTO(out, rc = -EINVAL);
5249 * Revoke lock so everyone updates. Should be alright if
5250 * someone was already reading while we were updating the logs,
5251 * so we don't really need to hold the lock while we're
5254 mti->mti_flags = dev_type | LDD_F_PARAM;
5255 mutex_lock(&fsdb->fsdb_mutex);
5256 rc = mgs_write_log_param(env, mgs, fsdb, mti, mti->mti_params);
5257 mutex_unlock(&fsdb->fsdb_mutex);
5258 mgs_revoke_lock(mgs, fsdb, CONFIG_T_CONFIG);
5262 mgs_put_fsdb(mgs, fsdb);
5267 static int mgs_set_param2(const struct lu_env *env, struct mgs_device *mgs,
5268 struct mgs_target_info *mti, const char *param)
5270 struct fs_db *fsdb = NULL;
5275 if (strlcpy(mti->mti_params, param, sizeof(mti->mti_params)) >=
5276 sizeof(mti->mti_params))
5277 GOTO(out, rc = -E2BIG);
5279 len = strcspn(param, ".=");
5280 if (len && param[len] != '=') {
5281 struct list_head *tmp;
5285 ptr = strchr(param, '.');
5287 len = strlen(param);
5290 if (len >= sizeof(mti->mti_svname))
5291 GOTO(out, rc = -E2BIG);
5293 snprintf(mti->mti_svname, sizeof(mti->mti_svname), "%.*s",
5296 mutex_lock(&mgs->mgs_mutex);
5297 if (unlikely(list_empty(&mgs->mgs_fs_db_list))) {
5298 mutex_unlock(&mgs->mgs_mutex);
5299 GOTO(out, rc = -ENODEV);
5302 list_for_each(tmp, &mgs->mgs_fs_db_list) {
5303 fsdb = list_entry(tmp, struct fs_db, fsdb_list);
5304 if (fsdb->fsdb_has_lproc_entry &&
5305 strcmp(fsdb->fsdb_name, "params") != 0 &&
5306 strstr(param, fsdb->fsdb_name)) {
5307 snprintf(mti->mti_svname,
5308 sizeof(mti->mti_svname), "%s",
5316 snprintf(mti->mti_svname, sizeof(mti->mti_svname),
5319 mutex_unlock(&mgs->mgs_mutex);
5321 snprintf(mti->mti_svname, sizeof(mti->mti_svname), "general");
5324 CDEBUG(D_MGS, "set_param2 fs='%s' device='%s' param='%s'\n",
5325 mti->mti_fsname, mti->mti_svname, mti->mti_params);
5327 /* The return value should be the device type i.e LDD_F_SV_TYPE_XXX.
5328 * A returned error tells us we don't have a target obd device.
5330 dev_type = server_name2index(mti->mti_svname, &mti->mti_stripe_index,
5335 /* the return value should be the device type i.e LDD_F_SV_TYPE_XXX.
5336 * Strip -osc or -mdc suffix from svname
5338 if ((dev_type & LDD_F_SV_TYPE_OST || dev_type & LDD_F_SV_TYPE_MDT) &&
5339 server_make_name(dev_type, mti->mti_stripe_index,
5340 mti->mti_fsname, mti->mti_svname,
5341 sizeof(mti->mti_svname)))
5342 GOTO(out, rc = -EINVAL);
5344 rc = mgs_find_or_make_fsdb(env, mgs, PARAMS_FILENAME, &fsdb);
5348 * Revoke lock so everyone updates. Should be alright if
5349 * someone was already reading while we were updating the logs,
5350 * so we don't really need to hold the lock while we're
5353 mti->mti_flags = dev_type | LDD_F_PARAM2;
5354 mutex_lock(&fsdb->fsdb_mutex);
5355 rc = mgs_write_log_param2(env, mgs, fsdb, mti, mti->mti_params);
5356 mutex_unlock(&fsdb->fsdb_mutex);
5357 mgs_revoke_lock(mgs, fsdb, CONFIG_T_PARAMS);
5358 mgs_put_fsdb(mgs, fsdb);
5363 /* Set a permanent (config log) param for a target or fs
5365 * @lcfg buf0 may contain the device (testfs-MDT0000) name
5366 * buf1 contains the single parameter
5368 int mgs_set_param(const struct lu_env *env, struct mgs_device *mgs,
5369 struct lustre_cfg *lcfg)
5371 const char *param = lustre_cfg_string(lcfg, 1);
5372 struct mgs_target_info *mti;
5375 /* Create a fake mti to hold everything */
5380 print_lustre_cfg(lcfg);
5382 if (lcfg->lcfg_command == LCFG_PARAM) {
5383 /* For the case of lctl conf_param devname can be
5384 * lustre, lustre-mdtlov, lustre-client, lustre-MDT0000
5386 const char *devname = lustre_cfg_string(lcfg, 0);
5388 rc = mgs_set_conf_param(env, mgs, mti, devname, param);
5390 /* In the case of lctl set_param -P lcfg[0] will always
5391 * be 'general'. At least for now.
5393 rc = mgs_set_param2(env, mgs, mti, param);
5401 static int mgs_write_log_pool(const struct lu_env *env,
5402 struct mgs_device *mgs, char *logname,
5403 struct fs_db *fsdb, char *tgtname,
5404 enum lcfg_command_type cmd,
5405 char *fsname, char *poolname,
5406 char *ostname, char *comment)
5408 struct llog_handle *llh = NULL;
5411 rc = record_start_log(env, mgs, &llh, logname);
5414 rc = record_marker(env, llh, fsdb, CM_START, tgtname, comment);
5417 rc = record_base(env, llh, tgtname, 0, cmd,
5418 fsname, poolname, ostname, NULL);
5421 rc = record_marker(env, llh, fsdb, CM_END, tgtname, comment);
5423 record_end_log(env, &llh);
5427 int mgs_nodemap_cmd(const struct lu_env *env, struct mgs_device *mgs,
5428 enum lcfg_command_type cmd, const char *nodemap_name,
5439 case LCFG_NODEMAP_ADD:
5440 rc = nodemap_add(nodemap_name);
5442 case LCFG_NODEMAP_DEL:
5443 rc = nodemap_del(nodemap_name);
5445 case LCFG_NODEMAP_ADD_RANGE:
5446 rc = nodemap_parse_range(param, nid);
5449 rc = nodemap_add_range(nodemap_name, nid);
5451 case LCFG_NODEMAP_DEL_RANGE:
5452 rc = nodemap_parse_range(param, nid);
5455 rc = nodemap_del_range(nodemap_name, nid);
5457 case LCFG_NODEMAP_ADMIN:
5458 rc = kstrtobool(param, &bool_switch);
5461 rc = nodemap_set_allow_root(nodemap_name, bool_switch);
5463 case LCFG_NODEMAP_DENY_UNKNOWN:
5464 rc = kstrtobool(param, &bool_switch);
5467 rc = nodemap_set_deny_unknown(nodemap_name, bool_switch);
5469 case LCFG_NODEMAP_AUDIT_MODE:
5470 rc = kstrtobool(param, &bool_switch);
5472 rc = nodemap_set_audit_mode(nodemap_name, bool_switch);
5474 case LCFG_NODEMAP_FORBID_ENCRYPT:
5475 rc = kstrtobool(param, &bool_switch);
5477 rc = nodemap_set_forbid_encryption(nodemap_name,
5480 case LCFG_NODEMAP_MAP_MODE:
5481 if (strcmp("both", param) == 0)
5482 rc = nodemap_set_mapping_mode(nodemap_name,
5484 else if (strcmp("uid_only", param) == 0)
5485 rc = nodemap_set_mapping_mode(nodemap_name,
5486 NODEMAP_MAP_UID_ONLY);
5487 else if (strcmp("gid_only", param) == 0)
5488 rc = nodemap_set_mapping_mode(nodemap_name,
5489 NODEMAP_MAP_GID_ONLY);
5493 case LCFG_NODEMAP_TRUSTED:
5494 rc = kstrtobool(param, &bool_switch);
5497 rc = nodemap_set_trust_client_ids(nodemap_name, bool_switch);
5499 case LCFG_NODEMAP_SQUASH_UID:
5500 rc = kstrtouint(param, 10, &int_id);
5503 rc = nodemap_set_squash_uid(nodemap_name, int_id);
5505 case LCFG_NODEMAP_SQUASH_GID:
5506 rc = kstrtouint(param, 10, &int_id);
5509 rc = nodemap_set_squash_gid(nodemap_name, int_id);
5511 case LCFG_NODEMAP_ADD_UIDMAP:
5512 case LCFG_NODEMAP_ADD_GIDMAP:
5513 rc = nodemap_parse_idmap(param, idmap);
5516 if (cmd == LCFG_NODEMAP_ADD_UIDMAP)
5517 rc = nodemap_add_idmap(nodemap_name, NODEMAP_UID,
5520 rc = nodemap_add_idmap(nodemap_name, NODEMAP_GID,
5523 case LCFG_NODEMAP_DEL_UIDMAP:
5524 case LCFG_NODEMAP_DEL_GIDMAP:
5525 rc = nodemap_parse_idmap(param, idmap);
5528 if (cmd == LCFG_NODEMAP_DEL_UIDMAP)
5529 rc = nodemap_del_idmap(nodemap_name, NODEMAP_UID,
5532 rc = nodemap_del_idmap(nodemap_name, NODEMAP_GID,
5535 case LCFG_NODEMAP_SET_FILESET:
5536 rc = nodemap_set_fileset(nodemap_name, param);
5538 case LCFG_NODEMAP_SET_SEPOL:
5539 rc = nodemap_set_sepol(nodemap_name, param);
5548 int mgs_pool_cmd(const struct lu_env *env, struct mgs_device *mgs,
5549 enum lcfg_command_type cmd, char *fsname,
5550 char *poolname, char *ostname)
5555 char *label = NULL, *canceled_label = NULL;
5557 struct mgs_target_info *mti = NULL;
5558 bool checked = false;
5559 bool locked = false;
5564 rc = mgs_find_or_make_fsdb(env, mgs, fsname, &fsdb);
5566 CERROR("Can't get db for %s\n", fsname);
5569 if (test_bit(FSDB_LOG_EMPTY, &fsdb->fsdb_flags)) {
5570 CERROR("%s is not defined\n", fsname);
5572 GOTO(out_fsdb, rc = -EINVAL);
5575 label_sz = 10 + strlen(fsname) + strlen(poolname);
5577 /* check if ostname match fsname */
5578 if (ostname != NULL) {
5581 ptr = strrchr(ostname, '-');
5582 if ((ptr == NULL) ||
5583 (strncmp(fsname, ostname, ptr-ostname) != 0))
5585 label_sz += strlen(ostname);
5588 OBD_ALLOC(label, label_sz);
5590 GOTO(out_fsdb, rc = -ENOMEM);
5595 "new %s.%s", fsname, poolname);
5599 "add %s.%s.%s", fsname, poolname, ostname);
5602 OBD_ALLOC(canceled_label, label_sz);
5603 if (canceled_label == NULL)
5604 GOTO(out_label, rc = -ENOMEM);
5606 "rem %s.%s.%s", fsname, poolname, ostname);
5607 sprintf(canceled_label,
5608 "add %s.%s.%s", fsname, poolname, ostname);
5611 OBD_ALLOC(canceled_label, label_sz);
5612 if (canceled_label == NULL)
5613 GOTO(out_label, rc = -ENOMEM);
5615 "del %s.%s", fsname, poolname);
5616 sprintf(canceled_label,
5617 "new %s.%s", fsname, poolname);
5625 GOTO(out_cancel, rc = -ENOMEM);
5626 strncpy(mti->mti_svname, "lov pool", sizeof(mti->mti_svname));
5628 mutex_lock(&fsdb->fsdb_mutex);
5630 /* write pool def to all MDT logs */
5631 for (i = 0; i < INDEX_MAP_SIZE * 8; i++) {
5632 if (test_bit(i, fsdb->fsdb_mdt_index_map)) {
5633 rc = name_create_mdt_and_lov(&logname, &lovname,
5638 if (!checked && (canceled_label == NULL)) {
5639 rc = mgs_check_marker(env, mgs, fsdb, mti,
5640 logname, lovname, label);
5642 name_destroy(&logname);
5643 name_destroy(&lovname);
5645 rc = (rc == LLOG_PROC_BREAK ?
5650 if (canceled_label != NULL)
5651 rc = mgs_modify(env, mgs, fsdb, mti, logname,
5652 lovname, canceled_label,
5656 rc = mgs_write_log_pool(env, mgs, logname,
5660 name_destroy(&logname);
5661 name_destroy(&lovname);
5667 rc = name_create(&logname, fsname, "-client");
5671 if (!checked && (canceled_label == NULL)) {
5672 rc = mgs_check_marker(env, mgs, fsdb, mti, logname,
5673 fsdb->fsdb_clilov, label);
5675 name_destroy(&logname);
5676 GOTO(out_mti, rc = (rc == LLOG_PROC_BREAK ?
5680 if (canceled_label != NULL) {
5681 rc = mgs_modify(env, mgs, fsdb, mti, logname,
5682 fsdb->fsdb_clilov, canceled_label, CM_SKIP);
5684 name_destroy(&logname);
5689 rc = mgs_write_log_pool(env, mgs, logname, fsdb, fsdb->fsdb_clilov,
5690 cmd, fsname, poolname, ostname, label);
5691 mutex_unlock(&fsdb->fsdb_mutex);
5693 name_destroy(&logname);
5694 /* request for update */
5695 mgs_revoke_lock(mgs, fsdb, CONFIG_T_CONFIG);
5701 mutex_unlock(&fsdb->fsdb_mutex);
5705 if (canceled_label != NULL)
5706 OBD_FREE(canceled_label, label_sz);
5708 OBD_FREE(label, label_sz);
5711 mgs_unlink_fsdb(mgs, fsdb);
5712 mgs_put_fsdb(mgs, fsdb);