4 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License version 2 only,
8 * as published by the Free Software Foundation.
10 * This program is distributed in the hope that it will be useful, but
11 * WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * General Public License version 2 for more details (a copy is included
14 * in the LICENSE file that accompanied this code).
16 * You should have received a copy of the GNU General Public License
17 * version 2 along with this program; If not, see
18 * http://www.gnu.org/licenses/gpl-2.0.html
23 * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved.
24 * Use is subject to license terms.
26 * Copyright (c) 2011, 2017, Intel Corporation.
29 * This file is part of Lustre, http://www.lustre.org/
31 * lustre/mgs/mgs_llog.c
33 * Lustre Management Server (mgs) config llog creation
35 * Author: Nathan Rutman <nathan@clusterfs.com>
36 * Author: Alex Zhuravlev <bzzz@whamcloud.com>
37 * Author: Mikhail Pershin <tappro@whamcloud.com>
40 #define DEBUG_SUBSYSTEM S_MGS
41 #define D_MGS D_CONFIG
44 #include <uapi/linux/lustre/lustre_ioctl.h>
45 #include <uapi/linux/lustre/lustre_param.h>
46 #include <lustre_sec.h>
47 #include <lustre_quota.h>
48 #include <lustre_sec.h>
50 #include "mgs_internal.h"
52 /********************** Class functions ********************/
55 * Find all logs in CONFIG directory and link then into list.
57 * \param[in] env pointer to the thread context
58 * \param[in] mgs pointer to the mgs device
59 * \param[out] log_list the list to hold the found llog name entry
61 * \retval 0 for success
62 * \retval negative error number on failure
64 int class_dentry_readdir(const struct lu_env *env, struct mgs_device *mgs,
65 struct list_head *log_list)
67 struct dt_object *dir = mgs->mgs_configs_dir;
68 const struct dt_it_ops *iops;
70 struct mgs_direntry *de;
74 INIT_LIST_HEAD(log_list);
77 LASSERT(dir->do_index_ops);
79 iops = &dir->do_index_ops->dio_it;
80 it = iops->init(env, dir, LUDA_64BITHASH);
84 rc = iops->load(env, it, 0);
90 key = (void *)iops->key(env, it);
92 CERROR("%s: key failed when listing %s: rc = %d\n",
93 mgs->mgs_obd->obd_name, MOUNT_CONFIGS_DIR,
97 key_sz = iops->key_size(env, it);
100 /* filter out "." and ".." entries */
104 if (key_sz == 2 && key[1] == '.')
108 /* filter out backup files */
109 if (lu_name_is_backup_file(key, key_sz, NULL)) {
110 CDEBUG(D_MGS, "Skipping backup file %.*s\n",
115 de = mgs_direntry_alloc(key_sz + 1);
121 memcpy(de->mde_name, key, key_sz);
122 de->mde_name[key_sz] = 0;
124 list_add(&de->mde_list, log_list);
127 rc = iops->next(env, it);
137 struct mgs_direntry *n;
139 CERROR("%s: key failed when listing %s: rc = %d\n",
140 mgs->mgs_obd->obd_name, MOUNT_CONFIGS_DIR, rc);
142 list_for_each_entry_safe(de, n, log_list, mde_list) {
143 list_del_init(&de->mde_list);
144 mgs_direntry_free(de);
151 /******************** DB functions *********************/
153 static inline int name_create(char **newname, char *prefix, char *suffix)
156 OBD_ALLOC(*newname, strlen(prefix) + strlen(suffix) + 1);
159 sprintf(*newname, "%s%s", prefix, suffix);
163 static inline void name_destroy(char **name)
166 OBD_FREE(*name, strlen(*name) + 1);
170 struct mgs_fsdb_handler_data
176 /* from the (client) config log, figure out:
177 1. which ost's/mdt's are configured (by index)
178 2. what the last config step is
179 3. COMPAT_18 osc name
181 /* It might be better to have a separate db file, instead of parsing the info
182 out of the client log. This is slow and potentially error-prone. */
183 static int mgs_fsdb_handler(const struct lu_env *env, struct llog_handle *llh,
184 struct llog_rec_hdr *rec, void *data)
186 struct mgs_fsdb_handler_data *d = data;
187 struct fs_db *fsdb = d->fsdb;
188 int cfg_len = rec->lrh_len;
189 char *cfg_buf = (char*) (rec + 1);
190 struct lustre_cfg *lcfg;
195 if (rec->lrh_type != OBD_CFG_REC) {
196 CERROR("unhandled lrh_type: %#x\n", rec->lrh_type);
200 rc = lustre_cfg_sanity_check(cfg_buf, cfg_len);
202 CERROR("Insane cfg\n");
206 lcfg = (struct lustre_cfg *)cfg_buf;
208 CDEBUG(D_INFO, "cmd %x %s %s\n", lcfg->lcfg_command,
209 lustre_cfg_string(lcfg, 0), lustre_cfg_string(lcfg, 1));
211 /* Figure out ost indicies */
212 /* lov_modify_tgts add 0:lov1 1:ost1_UUID 2(index):0 3(gen):1 */
213 if (lcfg->lcfg_command == LCFG_LOV_ADD_OBD ||
214 lcfg->lcfg_command == LCFG_LOV_DEL_OBD) {
215 rc = kstrtouint(lustre_cfg_string(lcfg, 2), 10, &index);
219 CDEBUG(D_MGS, "OST index for %s is %u (%s)\n",
220 lustre_cfg_string(lcfg, 1), index,
221 lustre_cfg_string(lcfg, 2));
222 set_bit(index, fsdb->fsdb_ost_index_map);
225 /* Figure out mdt indicies */
226 /* attach 0:MDC_uml1_mdsA_MNT_client 1:mdc 2:1d834_MNT_client_03f */
227 if ((lcfg->lcfg_command == LCFG_ATTACH) &&
228 (strcmp(lustre_cfg_string(lcfg, 1), LUSTRE_MDC_NAME) == 0)) {
229 rc = server_name2index(lustre_cfg_string(lcfg, 0),
231 if (rc != LDD_F_SV_TYPE_MDT) {
232 CWARN("Unparsable MDC name %s, assuming index 0\n",
233 lustre_cfg_string(lcfg, 0));
237 CDEBUG(D_MGS, "MDT index is %u\n", index);
238 if (!test_bit(index, fsdb->fsdb_mdt_index_map)) {
239 set_bit(index, fsdb->fsdb_mdt_index_map);
240 fsdb->fsdb_mdt_count++;
245 * figure out the old config. fsdb_gen = 0 means old log
246 * It is obsoleted and not supported anymore
248 if (fsdb->fsdb_gen == 0) {
249 CERROR("Old config format is not supported\n");
254 * compat to 1.8, check osc name used by MDT0 to OSTs, bz18548.
256 if (!test_bit(FSDB_OSCNAME18, &fsdb->fsdb_flags) &&
257 lcfg->lcfg_command == LCFG_ATTACH &&
258 strcmp(lustre_cfg_string(lcfg, 1), LUSTRE_OSC_NAME) == 0) {
259 if (OBD_OCD_VERSION_MAJOR(d->ver) == 1 &&
260 OBD_OCD_VERSION_MINOR(d->ver) <= 8) {
261 CWARN("MDT using 1.8 OSC name scheme\n");
262 set_bit(FSDB_OSCNAME18, &fsdb->fsdb_flags);
266 if (lcfg->lcfg_command == LCFG_MARKER) {
267 struct cfg_marker *marker;
268 marker = lustre_cfg_buf(lcfg, 1);
270 d->ver = marker->cm_vers;
272 /* Keep track of the latest marker step */
273 fsdb->fsdb_gen = max(fsdb->fsdb_gen, marker->cm_step);
279 /* fsdb->fsdb_mutex is already held in mgs_find_or_make_fsdb*/
280 static int mgs_get_fsdb_from_llog(const struct lu_env *env,
281 struct mgs_device *mgs,
285 struct llog_handle *loghandle;
286 struct llog_ctxt *ctxt;
287 struct mgs_fsdb_handler_data d = {
294 ctxt = llog_get_context(mgs->mgs_obd, LLOG_CONFIG_ORIG_CTXT);
295 LASSERT(ctxt != NULL);
296 rc = name_create(&logname, fsdb->fsdb_name, "-client");
299 rc = llog_open_create(env, ctxt, &loghandle, NULL, logname);
303 rc = llog_init_handle(env, loghandle, LLOG_F_IS_PLAIN, NULL);
307 if (llog_get_size(loghandle) <= 1)
308 set_bit(FSDB_LOG_EMPTY, &fsdb->fsdb_flags);
310 rc = llog_process(env, loghandle, mgs_fsdb_handler, (void *)&d, NULL);
311 CDEBUG(D_INFO, "get_db = %d\n", rc);
313 llog_close(env, loghandle);
315 name_destroy(&logname);
322 static void mgs_free_fsdb_srpc(struct fs_db *fsdb)
324 struct mgs_tgt_srpc_conf *tgtconf;
326 /* free target-specific rules */
327 while (fsdb->fsdb_srpc_tgt) {
328 tgtconf = fsdb->fsdb_srpc_tgt;
329 fsdb->fsdb_srpc_tgt = tgtconf->mtsc_next;
331 LASSERT(tgtconf->mtsc_tgt);
333 sptlrpc_rule_set_free(&tgtconf->mtsc_rset);
334 OBD_FREE(tgtconf->mtsc_tgt, strlen(tgtconf->mtsc_tgt) + 1);
335 OBD_FREE_PTR(tgtconf);
338 /* free general rules */
339 sptlrpc_rule_set_free(&fsdb->fsdb_srpc_gen);
342 static void mgs_unlink_fsdb(struct mgs_device *mgs, struct fs_db *fsdb)
344 mutex_lock(&mgs->mgs_mutex);
345 if (likely(!list_empty(&fsdb->fsdb_list))) {
346 LASSERTF(atomic_read(&fsdb->fsdb_ref) >= 2,
347 "Invalid ref %d on %s\n",
348 atomic_read(&fsdb->fsdb_ref),
351 list_del_init(&fsdb->fsdb_list);
352 /* Drop the reference on the list.*/
353 mgs_put_fsdb(mgs, fsdb);
355 mutex_unlock(&mgs->mgs_mutex);
358 /* The caller must hold mgs->mgs_mutex. */
359 static inline struct fs_db *
360 mgs_find_fsdb_noref(struct mgs_device *mgs, const char *fsname)
363 struct list_head *tmp;
365 list_for_each(tmp, &mgs->mgs_fs_db_list) {
366 fsdb = list_entry(tmp, struct fs_db, fsdb_list);
367 if (strcmp(fsdb->fsdb_name, fsname) == 0)
374 /* The caller must hold mgs->mgs_mutex. */
375 static void mgs_remove_fsdb_by_name(struct mgs_device *mgs, const char *name)
379 fsdb = mgs_find_fsdb_noref(mgs, name);
381 list_del_init(&fsdb->fsdb_list);
382 /* Drop the reference on the list.*/
383 mgs_put_fsdb(mgs, fsdb);
387 /* The caller must hold mgs->mgs_mutex. */
388 struct fs_db *mgs_find_fsdb(struct mgs_device *mgs, const char *fsname)
392 fsdb = mgs_find_fsdb_noref(mgs, fsname);
394 atomic_inc(&fsdb->fsdb_ref);
399 /* The caller must hold mgs->mgs_mutex. */
400 static struct fs_db *mgs_new_fsdb(const struct lu_env *env,
401 struct mgs_device *mgs, char *fsname)
407 if (strlen(fsname) >= sizeof(fsdb->fsdb_name)) {
408 CERROR("fsname %s is too long\n", fsname);
410 RETURN(ERR_PTR(-EINVAL));
415 RETURN(ERR_PTR(-ENOMEM));
417 strncpy(fsdb->fsdb_name, fsname, sizeof(fsdb->fsdb_name));
418 mutex_init(&fsdb->fsdb_mutex);
419 INIT_LIST_HEAD(&fsdb->fsdb_list);
420 set_bit(FSDB_UDESC, &fsdb->fsdb_flags);
422 INIT_LIST_HEAD(&fsdb->fsdb_clients);
423 atomic_set(&fsdb->fsdb_notify_phase, 0);
424 init_waitqueue_head(&fsdb->fsdb_notify_waitq);
425 init_completion(&fsdb->fsdb_notify_comp);
427 if (strcmp(fsname, MGSSELF_NAME) == 0) {
428 set_bit(FSDB_MGS_SELF, &fsdb->fsdb_flags);
429 fsdb->fsdb_mgs = mgs;
430 if (logname_is_barrier(fsname))
433 OBD_ALLOC(fsdb->fsdb_mdt_index_map, INDEX_MAP_SIZE);
434 if (!fsdb->fsdb_mdt_index_map) {
435 CERROR("No memory for MDT index maps\n");
437 GOTO(err, rc = -ENOMEM);
440 OBD_ALLOC(fsdb->fsdb_ost_index_map, INDEX_MAP_SIZE);
441 if (!fsdb->fsdb_ost_index_map) {
442 CERROR("No memory for OST index maps\n");
444 GOTO(err, rc = -ENOMEM);
447 if (logname_is_barrier(fsname))
450 rc = name_create(&fsdb->fsdb_clilov, fsname, "-clilov");
454 rc = name_create(&fsdb->fsdb_clilmv, fsname, "-clilmv");
458 /* initialise data for NID table */
459 mgs_ir_init_fs(env, mgs, fsdb);
460 lproc_mgs_add_live(mgs, fsdb);
463 if (!test_bit(FSDB_MGS_SELF, &fsdb->fsdb_flags) &&
464 strcmp(PARAMS_FILENAME, fsname) != 0) {
465 /* populate the db from the client llog */
466 rc = mgs_get_fsdb_from_llog(env, mgs, fsdb);
468 CERROR("Can't get db from client log %d\n", rc);
474 /* populate srpc rules from params llog */
475 rc = mgs_get_fsdb_srpc_from_llog(env, mgs, fsdb);
477 CERROR("Can't get db from params log %d\n", rc);
483 /* One ref is for the fsdb on the list.
484 * The other ref is for the caller. */
485 atomic_set(&fsdb->fsdb_ref, 2);
486 list_add(&fsdb->fsdb_list, &mgs->mgs_fs_db_list);
491 atomic_set(&fsdb->fsdb_ref, 1);
492 mgs_put_fsdb(mgs, fsdb);
497 static void mgs_free_fsdb(struct mgs_device *mgs, struct fs_db *fsdb)
499 LASSERT(list_empty(&fsdb->fsdb_list));
501 lproc_mgs_del_live(mgs, fsdb);
503 /* deinitialize fsr */
505 mgs_ir_fini_fs(mgs, fsdb);
507 if (fsdb->fsdb_ost_index_map)
508 OBD_FREE(fsdb->fsdb_ost_index_map, INDEX_MAP_SIZE);
509 if (fsdb->fsdb_mdt_index_map)
510 OBD_FREE(fsdb->fsdb_mdt_index_map, INDEX_MAP_SIZE);
511 name_destroy(&fsdb->fsdb_clilov);
512 name_destroy(&fsdb->fsdb_clilmv);
513 mgs_free_fsdb_srpc(fsdb);
517 void mgs_put_fsdb(struct mgs_device *mgs, struct fs_db *fsdb)
519 if (atomic_dec_and_test(&fsdb->fsdb_ref))
520 mgs_free_fsdb(mgs, fsdb);
523 int mgs_init_fsdb_list(struct mgs_device *mgs)
525 INIT_LIST_HEAD(&mgs->mgs_fs_db_list);
529 int mgs_cleanup_fsdb_list(struct mgs_device *mgs)
532 struct list_head *tmp, *tmp2;
534 mutex_lock(&mgs->mgs_mutex);
535 list_for_each_safe(tmp, tmp2, &mgs->mgs_fs_db_list) {
536 fsdb = list_entry(tmp, struct fs_db, fsdb_list);
537 list_del_init(&fsdb->fsdb_list);
538 mgs_put_fsdb(mgs, fsdb);
540 mutex_unlock(&mgs->mgs_mutex);
544 /* The caller must hold mgs->mgs_mutex. */
545 int mgs_find_or_make_fsdb_nolock(const struct lu_env *env,
546 struct mgs_device *mgs,
547 char *name, struct fs_db **dbh)
553 fsdb = mgs_find_fsdb(mgs, name);
555 fsdb = mgs_new_fsdb(env, mgs, name);
559 CDEBUG(D_MGS, "Created new db: rc = %d\n", rc);
568 int mgs_find_or_make_fsdb(const struct lu_env *env, struct mgs_device *mgs,
569 char *name, struct fs_db **dbh)
574 mutex_lock(&mgs->mgs_mutex);
575 rc = mgs_find_or_make_fsdb_nolock(env, mgs, name, dbh);
576 mutex_unlock(&mgs->mgs_mutex);
583 -1= empty client log */
584 int mgs_check_index(const struct lu_env *env,
585 struct mgs_device *mgs,
586 struct mgs_target_info *mti)
593 LASSERT(!(mti->mti_flags & LDD_F_NEED_INDEX));
595 rc = mgs_find_or_make_fsdb(env, mgs, mti->mti_fsname, &fsdb);
597 CERROR("Can't get db for %s\n", mti->mti_fsname);
601 if (test_bit(FSDB_LOG_EMPTY, &fsdb->fsdb_flags))
604 if (mti->mti_flags & LDD_F_SV_TYPE_OST)
605 imap = fsdb->fsdb_ost_index_map;
606 else if (mti->mti_flags & LDD_F_SV_TYPE_MDT)
607 imap = fsdb->fsdb_mdt_index_map;
609 GOTO(out, rc = -EINVAL);
611 if (test_bit(mti->mti_stripe_index, imap))
617 mgs_put_fsdb(mgs, fsdb);
621 static __inline__ int next_index(void *index_map, int map_len)
624 for (i = 0; i < map_len * 8; i++)
625 if (!test_bit(i, index_map)) {
628 CERROR("max index %d exceeded.\n", i);
632 /* Make the mdt/ost server obd name based on the filesystem name */
633 static bool server_make_name(u32 flags, u16 index, const char *fs,
634 char *name_buf, size_t name_buf_size)
636 bool invalid_flag = false;
638 if (flags & (LDD_F_SV_TYPE_MDT | LDD_F_SV_TYPE_OST)) {
639 if (!(flags & LDD_F_SV_ALL))
640 snprintf(name_buf, name_buf_size, "%.8s%c%s%04x", fs,
641 (flags & LDD_F_VIRGIN) ? ':' :
642 ((flags & LDD_F_WRITECONF) ? '=' : '-'),
643 (flags & LDD_F_SV_TYPE_MDT) ? "MDT" : "OST",
645 } else if (flags & LDD_F_SV_TYPE_MGS) {
646 snprintf(name_buf, name_buf_size, "MGS");
648 CERROR("unknown server type %#x\n", flags);
655 0 newly marked as in use
657 +EALREADY for update of an old index */
658 static int mgs_set_index(const struct lu_env *env,
659 struct mgs_device *mgs,
660 struct mgs_target_info *mti)
667 rc = mgs_find_or_make_fsdb(env, mgs, mti->mti_fsname, &fsdb);
669 CERROR("Can't get db for %s\n", mti->mti_fsname);
673 mutex_lock(&fsdb->fsdb_mutex);
674 if (mti->mti_flags & LDD_F_SV_TYPE_OST) {
675 imap = fsdb->fsdb_ost_index_map;
676 } else if (mti->mti_flags & LDD_F_SV_TYPE_MDT) {
677 imap = fsdb->fsdb_mdt_index_map;
679 GOTO(out_up, rc = -EINVAL);
682 if (mti->mti_flags & LDD_F_NEED_INDEX) {
683 rc = next_index(imap, INDEX_MAP_SIZE);
685 GOTO(out_up, rc = -ERANGE);
686 mti->mti_stripe_index = rc;
689 /* the last index(0xffff) is reserved for default value. */
690 if (mti->mti_stripe_index >= INDEX_MAP_SIZE * 8 - 1) {
691 LCONSOLE_ERROR_MSG(0x13f, "Server %s requested index %u, "
692 "but index must be less than %u.\n",
693 mti->mti_svname, mti->mti_stripe_index,
694 INDEX_MAP_SIZE * 8 - 1);
695 GOTO(out_up, rc = -ERANGE);
698 if (test_bit(mti->mti_stripe_index, imap)) {
699 if ((mti->mti_flags & LDD_F_VIRGIN) &&
700 !(mti->mti_flags & LDD_F_WRITECONF)) {
701 LCONSOLE_ERROR_MSG(0x140, "Server %s requested index "
702 "%d, but that index is already in "
703 "use. Use --writeconf to force\n",
705 mti->mti_stripe_index);
706 GOTO(out_up, rc = -EADDRINUSE);
708 CDEBUG(D_MGS, "Server %s updating index %d\n",
709 mti->mti_svname, mti->mti_stripe_index);
710 GOTO(out_up, rc = EALREADY);
713 set_bit(mti->mti_stripe_index, imap);
714 if (mti->mti_flags & LDD_F_SV_TYPE_MDT)
715 fsdb->fsdb_mdt_count++;
718 set_bit(mti->mti_stripe_index, imap);
719 clear_bit(FSDB_LOG_EMPTY, &fsdb->fsdb_flags);
720 if (server_make_name(mti->mti_flags & ~(LDD_F_VIRGIN | LDD_F_WRITECONF),
721 mti->mti_stripe_index, mti->mti_fsname,
722 mti->mti_svname, sizeof(mti->mti_svname))) {
723 CERROR("unknown server type %#x\n", mti->mti_flags);
724 GOTO(out_up, rc = -EINVAL);
727 CDEBUG(D_MGS, "Set index for %s to %d\n", mti->mti_svname,
728 mti->mti_stripe_index);
730 GOTO(out_up, rc = 0);
733 mutex_unlock(&fsdb->fsdb_mutex);
734 mgs_put_fsdb(mgs, fsdb);
738 struct mgs_modify_lookup {
739 struct cfg_marker mml_marker;
743 static int mgs_check_record_match(const struct lu_env *env,
744 struct llog_handle *llh,
745 struct llog_rec_hdr *rec, void *data)
747 struct cfg_marker *mc_marker = data;
748 struct cfg_marker *marker;
749 struct lustre_cfg *lcfg = REC_DATA(rec);
750 int cfg_len = REC_DATA_LEN(rec);
755 if (rec->lrh_type != OBD_CFG_REC) {
756 CDEBUG(D_ERROR, "Unhandled lrh_type: %#x\n", rec->lrh_type);
760 rc = lustre_cfg_sanity_check(lcfg, cfg_len);
762 CDEBUG(D_ERROR, "Insane cfg\n");
766 /* We only care about markers */
767 if (lcfg->lcfg_command != LCFG_MARKER)
770 marker = lustre_cfg_buf(lcfg, 1);
772 if (marker->cm_flags & CM_SKIP)
775 if ((strcmp(mc_marker->cm_comment, marker->cm_comment) == 0) &&
776 (strcmp(mc_marker->cm_tgtname, marker->cm_tgtname) == 0)) {
777 /* Found a non-skipped marker match */
778 CDEBUG(D_MGS, "Matched rec %u marker %d flag %x %s %s\n",
779 rec->lrh_index, marker->cm_step,
780 marker->cm_flags, marker->cm_tgtname,
782 rc = LLOG_PROC_BREAK;
789 * Check an existing config log record with matching comment and device
791 * 0 - checked successfully,
792 * LLOG_PROC_BREAK - record matches
795 static int mgs_check_marker(const struct lu_env *env, struct mgs_device *mgs,
796 struct fs_db *fsdb, struct mgs_target_info *mti,
797 char *logname, char *devname, char *comment)
799 struct llog_handle *loghandle;
800 struct llog_ctxt *ctxt;
801 struct cfg_marker *mc_marker;
806 LASSERT(mutex_is_locked(&fsdb->fsdb_mutex));
807 CDEBUG(D_MGS, "mgs check %s/%s/%s\n", logname, devname, comment);
809 ctxt = llog_get_context(mgs->mgs_obd, LLOG_CONFIG_ORIG_CTXT);
810 LASSERT(ctxt != NULL);
811 rc = llog_open(env, ctxt, &loghandle, NULL, logname, LLOG_OPEN_EXISTS);
818 rc = llog_init_handle(env, loghandle, LLOG_F_IS_PLAIN, NULL);
822 if (llog_get_size(loghandle) <= 1)
823 GOTO(out_close, rc = 0);
825 OBD_ALLOC_PTR(mc_marker);
827 GOTO(out_close, rc = -ENOMEM);
828 if (strlcpy(mc_marker->cm_comment, comment,
829 sizeof(mc_marker->cm_comment)) >=
830 sizeof(mc_marker->cm_comment))
831 GOTO(out_free, rc = -E2BIG);
832 if (strlcpy(mc_marker->cm_tgtname, devname,
833 sizeof(mc_marker->cm_tgtname)) >=
834 sizeof(mc_marker->cm_tgtname))
835 GOTO(out_free, rc = -E2BIG);
837 rc = llog_process(env, loghandle, mgs_check_record_match,
838 (void *)mc_marker, NULL);
841 OBD_FREE_PTR(mc_marker);
844 llog_close(env, loghandle);
846 if (rc && rc != LLOG_PROC_BREAK)
847 CDEBUG(D_ERROR, "%s: mgs check %s/%s failed: rc = %d\n",
848 mgs->mgs_obd->obd_name, mti->mti_svname, comment, rc);
853 static int mgs_modify_handler(const struct lu_env *env,
854 struct llog_handle *llh,
855 struct llog_rec_hdr *rec, void *data)
857 struct mgs_modify_lookup *mml = data;
858 struct cfg_marker *marker;
859 struct lustre_cfg *lcfg = REC_DATA(rec);
860 int cfg_len = REC_DATA_LEN(rec);
864 if (rec->lrh_type != OBD_CFG_REC) {
865 CERROR("unhandled lrh_type: %#x\n", rec->lrh_type);
869 rc = lustre_cfg_sanity_check(lcfg, cfg_len);
871 CERROR("Insane cfg\n");
875 /* We only care about markers */
876 if (lcfg->lcfg_command != LCFG_MARKER)
879 marker = lustre_cfg_buf(lcfg, 1);
880 if ((strcmp(mml->mml_marker.cm_comment, marker->cm_comment) == 0) &&
881 (strcmp(mml->mml_marker.cm_tgtname, marker->cm_tgtname) == 0) &&
882 !(marker->cm_flags & CM_SKIP)) {
883 /* Found a non-skipped marker match */
884 CDEBUG(D_MGS, "Changing rec %u marker %d %x->%x: %s %s\n",
885 rec->lrh_index, marker->cm_step,
886 marker->cm_flags, mml->mml_marker.cm_flags,
887 marker->cm_tgtname, marker->cm_comment);
888 /* Overwrite the old marker llog entry */
889 marker->cm_flags &= ~CM_EXCLUDE; /* in case we're unexcluding */
890 marker->cm_flags |= mml->mml_marker.cm_flags;
891 marker->cm_canceltime = mml->mml_marker.cm_canceltime;
892 rc = llog_write(env, llh, rec, rec->lrh_index);
901 * Modify an existing config log record (for CM_SKIP or CM_EXCLUDE)
903 * 0 - modified successfully,
904 * 1 - no modification was done
907 static int mgs_modify(const struct lu_env *env, struct mgs_device *mgs,
908 struct fs_db *fsdb, struct mgs_target_info *mti,
909 char *logname, char *devname, char *comment, int flags)
911 struct llog_handle *loghandle;
912 struct llog_ctxt *ctxt;
913 struct mgs_modify_lookup *mml;
918 LASSERT(mutex_is_locked(&fsdb->fsdb_mutex));
919 CDEBUG(D_MGS, "modify %s/%s/%s fl=%x\n", logname, devname, comment,
922 ctxt = llog_get_context(mgs->mgs_obd, LLOG_CONFIG_ORIG_CTXT);
923 LASSERT(ctxt != NULL);
924 rc = llog_open(env, ctxt, &loghandle, NULL, logname, LLOG_OPEN_EXISTS);
931 rc = llog_init_handle(env, loghandle, LLOG_F_IS_PLAIN, NULL);
935 if (llog_get_size(loghandle) <= 1)
936 GOTO(out_close, rc = 0);
940 GOTO(out_close, rc = -ENOMEM);
941 if (strlcpy(mml->mml_marker.cm_comment, comment,
942 sizeof(mml->mml_marker.cm_comment)) >=
943 sizeof(mml->mml_marker.cm_comment))
944 GOTO(out_free, rc = -E2BIG);
945 if (strlcpy(mml->mml_marker.cm_tgtname, devname,
946 sizeof(mml->mml_marker.cm_tgtname)) >=
947 sizeof(mml->mml_marker.cm_tgtname))
948 GOTO(out_free, rc = -E2BIG);
949 /* Modify mostly means cancel */
950 mml->mml_marker.cm_flags = flags;
951 mml->mml_marker.cm_canceltime = flags ? ktime_get_real_seconds() : 0;
952 mml->mml_modified = 0;
953 rc = llog_process(env, loghandle, mgs_modify_handler, (void *)mml,
955 if (!rc && !mml->mml_modified)
962 llog_close(env, loghandle);
965 CERROR("%s: modify %s/%s failed: rc = %d\n",
966 mgs->mgs_obd->obd_name, mti->mti_svname, comment, rc);
979 /** This structure is passed to mgs_replace_handler */
980 struct mgs_replace_data {
981 /* Nids are replaced for this target device */
982 struct mgs_target_info target;
983 /* Temporary modified llog */
984 struct llog_handle *temp_llh;
985 enum replace_state state;
991 * Check: a) if block should be skipped
992 * b) is it target block
997 * \retval 0 should not to be skipped
998 * \retval 1 should to be skipped
1000 static int check_markers(struct lustre_cfg *lcfg,
1001 struct mgs_replace_data *mrd)
1003 struct cfg_marker *marker;
1005 /* Track markers. Find given device */
1006 if (lcfg->lcfg_command == LCFG_MARKER) {
1007 marker = lustre_cfg_buf(lcfg, 1);
1008 /* Clean llog from records marked as CM_SKIP.
1009 CM_EXCLUDE records are used for "active" command
1010 and can be restored if needed */
1011 if ((marker->cm_flags & (CM_SKIP | CM_START)) ==
1012 (CM_SKIP | CM_START)) {
1013 mrd->state = REPLACE_SKIP;
1017 if ((marker->cm_flags & (CM_SKIP | CM_END)) ==
1018 (CM_SKIP | CM_END)) {
1019 mrd->state = REPLACE_COPY;
1023 if (strcmp(mrd->target.mti_svname, marker->cm_tgtname) == 0) {
1024 LASSERT(!(marker->cm_flags & CM_START) ||
1025 !(marker->cm_flags & CM_END));
1026 if (marker->cm_flags & CM_START) {
1027 if (!strncmp(marker->cm_comment,
1028 "add failnid", 11)) {
1029 mrd->state = REPLACE_SKIP;
1031 mrd->state = REPLACE_UUID;
1032 mrd->failover = NULL;
1034 } else if (marker->cm_flags & CM_END)
1035 mrd->state = REPLACE_COPY;
1037 if (!strncmp(marker->cm_comment,
1046 static int record_base(const struct lu_env *env, struct llog_handle *llh,
1047 char *cfgname, lnet_nid_t nid, int cmd,
1048 char *s1, char *s2, char *s3, char *s4)
1050 struct mgs_thread_info *mgi = mgs_env_info(env);
1051 struct llog_cfg_rec *lcr;
1054 CDEBUG(D_MGS, "lcfg %s %#x %s %s %s %s\n", cfgname,
1055 cmd, s1, s2, s3, s4);
1057 lustre_cfg_bufs_reset(&mgi->mgi_bufs, cfgname);
1059 lustre_cfg_bufs_set_string(&mgi->mgi_bufs, 1, s1);
1061 lustre_cfg_bufs_set_string(&mgi->mgi_bufs, 2, s2);
1063 lustre_cfg_bufs_set_string(&mgi->mgi_bufs, 3, s3);
1065 lustre_cfg_bufs_set_string(&mgi->mgi_bufs, 4, s4);
1067 lcr = lustre_cfg_rec_new(cmd, &mgi->mgi_bufs);
1071 lcr->lcr_cfg.lcfg_nid = nid;
1072 rc = llog_write(env, llh, &lcr->lcr_hdr, LLOG_NEXT_IDX);
1074 lustre_cfg_rec_free(lcr);
1078 "failed to write lcfg %s %#x %s %s %s %s: rc = %d\n",
1079 cfgname, cmd, s1, s2, s3, s4, rc);
1083 static inline int record_add_uuid(const struct lu_env *env,
1084 struct llog_handle *llh,
1085 uint64_t nid, char *uuid)
1087 return record_base(env, llh, NULL, nid, LCFG_ADD_UUID, uuid,
1091 static inline int record_add_conn(const struct lu_env *env,
1092 struct llog_handle *llh,
1093 char *devname, char *uuid)
1095 return record_base(env, llh, devname, 0, LCFG_ADD_CONN, uuid,
1099 static inline int record_attach(const struct lu_env *env,
1100 struct llog_handle *llh, char *devname,
1101 char *type, char *uuid)
1103 return record_base(env, llh, devname, 0, LCFG_ATTACH, type, uuid,
1107 static inline int record_setup(const struct lu_env *env,
1108 struct llog_handle *llh, char *devname,
1109 char *s1, char *s2, char *s3, char *s4)
1111 return record_base(env, llh, devname, 0, LCFG_SETUP, s1, s2, s3, s4);
1115 * \retval <0 record processing error
1116 * \retval n record is processed. No need copy original one.
1117 * \retval 0 record is not processed.
1119 static int process_command(const struct lu_env *env, struct lustre_cfg *lcfg,
1120 struct mgs_replace_data *mrd)
1127 if (mrd->state == REPLACE_UUID &&
1128 lcfg->lcfg_command == LCFG_ADD_UUID) {
1129 /* LCFG_ADD_UUID command found. Let's skip original command
1130 and add passed nids */
1131 ptr = mrd->target.mti_params;
1132 while (class_parse_nid(ptr, &nid, &ptr) == 0) {
1133 if (!mrd->nodeuuid) {
1134 rc = name_create(&mrd->nodeuuid,
1135 libcfs_nid2str(nid), "");
1137 CERROR("Can't create uuid for "
1138 "nid %s, device %s\n",
1139 libcfs_nid2str(nid),
1140 mrd->target.mti_svname);
1144 CDEBUG(D_MGS, "add nid %s with uuid %s, "
1145 "device %s\n", libcfs_nid2str(nid),
1146 mrd->target.mti_params,
1148 rc = record_add_uuid(env,
1152 CWARN("%s: Can't add nid %s for uuid %s :rc=%d\n",
1153 mrd->target.mti_svname,
1154 libcfs_nid2str(nid),
1160 mrd->failover = ptr;
1165 if (nids_added == 0) {
1166 CERROR("No new nids were added, nid %s with uuid %s, "
1167 "device %s\n", libcfs_nid2str(nid),
1168 mrd->nodeuuid ? mrd->nodeuuid : "NULL",
1169 mrd->target.mti_svname);
1170 name_destroy(&mrd->nodeuuid);
1173 mrd->state = REPLACE_SETUP;
1179 if (mrd->state == REPLACE_SETUP && lcfg->lcfg_command == LCFG_SETUP) {
1180 /* LCFG_SETUP command found. UUID should be changed */
1181 rc = record_setup(env,
1183 /* devname the same */
1184 lustre_cfg_string(lcfg, 0),
1185 /* s1 is not changed */
1186 lustre_cfg_string(lcfg, 1),
1188 /* s3 is not changed */
1189 lustre_cfg_string(lcfg, 3),
1190 /* s4 is not changed */
1191 lustre_cfg_string(lcfg, 4));
1193 name_destroy(&mrd->nodeuuid);
1197 if (mrd->failover) {
1198 ptr = mrd->failover;
1199 while (class_parse_nid(ptr, &nid, &ptr) == 0) {
1200 if (mrd->nodeuuid == NULL) {
1201 rc = name_create(&mrd->nodeuuid,
1202 libcfs_nid2str(nid),
1208 CDEBUG(D_MGS, "add nid %s for failover %s\n",
1209 libcfs_nid2str(nid), mrd->nodeuuid);
1210 rc = record_add_uuid(env, mrd->temp_llh, nid,
1213 CWARN("%s: Can't add nid %s for failover %s :rc = %d\n",
1214 mrd->target.mti_svname,
1215 libcfs_nid2str(nid),
1217 name_destroy(&mrd->nodeuuid);
1221 rc = record_add_conn(env,
1223 lustre_cfg_string(lcfg, 0),
1225 name_destroy(&mrd->nodeuuid);
1230 if (mrd->nodeuuid) {
1231 rc = record_add_conn(env, mrd->temp_llh,
1232 lustre_cfg_string(lcfg, 0),
1234 name_destroy(&mrd->nodeuuid);
1239 mrd->state = REPLACE_DONE;
1243 /* All new UUID are added. Skip. */
1244 if (mrd->state == REPLACE_SETUP &&
1245 lcfg->lcfg_command == LCFG_ADD_UUID)
1248 /* Another commands in target device block */
1253 * Handler that called for every record in llog.
1254 * Records are processed in order they placed in llog.
1256 * \param[in] llh log to be processed
1257 * \param[in] rec current record
1258 * \param[in] data mgs_replace_data structure
1262 static int mgs_replace_nids_handler(const struct lu_env *env,
1263 struct llog_handle *llh,
1264 struct llog_rec_hdr *rec,
1267 struct mgs_replace_data *mrd;
1268 struct lustre_cfg *lcfg = REC_DATA(rec);
1269 int cfg_len = REC_DATA_LEN(rec);
1273 mrd = (struct mgs_replace_data *)data;
1275 if (rec->lrh_type != OBD_CFG_REC) {
1276 CERROR("unhandled lrh_type: %#x, cmd %x %s %s\n",
1277 rec->lrh_type, lcfg->lcfg_command,
1278 lustre_cfg_string(lcfg, 0),
1279 lustre_cfg_string(lcfg, 1));
1283 rc = lustre_cfg_sanity_check(lcfg, cfg_len);
1285 /* Do not copy any invalidated records */
1286 GOTO(skip_out, rc = 0);
1289 rc = check_markers(lcfg, mrd);
1290 if (rc || mrd->state == REPLACE_SKIP)
1291 GOTO(skip_out, rc = 0);
1293 /* Write to new log all commands outside target device block */
1294 if (mrd->state == REPLACE_COPY)
1295 GOTO(copy_out, rc = 0);
1297 if (mrd->state == REPLACE_DONE &&
1298 (lcfg->lcfg_command == LCFG_ADD_UUID ||
1299 lcfg->lcfg_command == LCFG_ADD_CONN)) {
1301 CWARN("Previous failover is deleted, but new one is "
1302 "not set. This means you configure system "
1303 "without failover or passed wrong replace_nids "
1304 "command parameters. Device %s, passed nids %s\n",
1305 mrd->target.mti_svname, mrd->target.mti_params);
1306 GOTO(skip_out, rc = 0);
1309 rc = process_command(env, lcfg, mrd);
1316 /* Record is placed in temporary llog as is */
1317 rc = llog_write(env, mrd->temp_llh, rec, LLOG_NEXT_IDX);
1319 CDEBUG(D_MGS, "Copied idx=%d, rc=%d, len=%d, cmd %x %s %s\n",
1320 rec->lrh_index, rc, rec->lrh_len, lcfg->lcfg_command,
1321 lustre_cfg_string(lcfg, 0), lustre_cfg_string(lcfg, 1));
1325 CDEBUG(D_MGS, "Skipped idx=%d, rc=%d, len=%d, cmd %x %s %s\n",
1326 rec->lrh_index, rc, rec->lrh_len, lcfg->lcfg_command,
1327 lustre_cfg_string(lcfg, 0), lustre_cfg_string(lcfg, 1));
1331 static int mgs_log_is_empty(const struct lu_env *env,
1332 struct mgs_device *mgs, char *name)
1334 struct llog_ctxt *ctxt;
1337 ctxt = llog_get_context(mgs->mgs_obd, LLOG_CONFIG_ORIG_CTXT);
1338 LASSERT(ctxt != NULL);
1340 rc = llog_is_empty(env, ctxt, name);
1341 llog_ctxt_put(ctxt);
1345 static int mgs_replace_log(const struct lu_env *env,
1346 struct obd_device *mgs,
1347 char *logname, char *devname,
1348 llog_cb_t replace_handler, void *data)
1350 struct llog_handle *orig_llh, *backup_llh;
1351 struct llog_ctxt *ctxt;
1352 struct mgs_replace_data *mrd;
1353 struct mgs_device *mgs_dev = lu2mgs_dev(mgs->obd_lu_dev);
1354 static struct obd_uuid cfg_uuid = { .uuid = "config_uuid" };
1356 int rc, rc2, buf_size;
1360 ctxt = llog_get_context(mgs, LLOG_CONFIG_ORIG_CTXT);
1361 LASSERT(ctxt != NULL);
1363 if (mgs_log_is_empty(env, mgs_dev, logname)) {
1364 /* Log is empty. Nothing to replace */
1365 GOTO(out_put, rc = 0);
1368 now = ktime_get_real_seconds();
1370 /* max time64_t in decimal fits into 20 bytes long string */
1371 buf_size = strlen(logname) + 1 + 20 + 1 + strlen(".bak") + 1;
1372 OBD_ALLOC(backup, buf_size);
1374 GOTO(out_put, rc = -ENOMEM);
1376 snprintf(backup, buf_size, "%s.%llu.bak", logname, now);
1378 rc = llog_backup(env, mgs, ctxt, ctxt, logname, backup);
1380 /* Now erase original log file. Connections are not allowed.
1381 Backup is already saved */
1382 rc = llog_erase(env, ctxt, NULL, logname);
1385 } else if (rc != -ENOENT) {
1386 CERROR("%s: can't make backup for %s: rc = %d\n",
1387 mgs->obd_name, logname, rc);
1391 /* open local log */
1392 rc = llog_open_create(env, ctxt, &orig_llh, NULL, logname);
1394 GOTO(out_restore, rc);
1396 rc = llog_init_handle(env, orig_llh, LLOG_F_IS_PLAIN, &cfg_uuid);
1398 GOTO(out_closel, rc);
1400 /* open backup llog */
1401 rc = llog_open(env, ctxt, &backup_llh, NULL, backup,
1404 GOTO(out_closel, rc);
1406 rc = llog_init_handle(env, backup_llh, LLOG_F_IS_PLAIN, NULL);
1408 GOTO(out_close, rc);
1410 if (llog_get_size(backup_llh) <= 1)
1411 GOTO(out_close, rc = 0);
1415 GOTO(out_close, rc = -ENOMEM);
1416 /* devname is only needed information to replace UUID records */
1418 strlcpy(mrd->target.mti_svname, devname,
1419 sizeof(mrd->target.mti_svname));
1420 /* data is parsed in llog callback */
1422 strlcpy(mrd->target.mti_params, data,
1423 sizeof(mrd->target.mti_params));
1424 /* Copy records to this temporary llog */
1425 mrd->temp_llh = orig_llh;
1427 rc = llog_process(env, backup_llh, replace_handler,
1431 rc2 = llog_close(NULL, backup_llh);
1435 rc2 = llog_close(NULL, orig_llh);
1441 CERROR("%s: llog should be restored: rc = %d\n",
1443 rc2 = llog_backup(env, mgs, ctxt, ctxt, backup,
1446 CERROR("%s: can't restore backup %s: rc = %d\n",
1447 mgs->obd_name, logname, rc2);
1451 OBD_FREE(backup, buf_size);
1454 llog_ctxt_put(ctxt);
1457 CERROR("%s: failed to replace log %s: rc = %d\n",
1458 mgs->obd_name, logname, rc);
1463 static int mgs_replace_nids_log(const struct lu_env *env,
1464 struct obd_device *obd,
1465 char *logname, char *devname, char *nids)
1467 CDEBUG(D_MGS, "Replace NIDs for %s in %s\n", devname, logname);
1468 return mgs_replace_log(env, obd, logname, devname,
1469 mgs_replace_nids_handler, nids);
1473 * Parse device name and get file system name and/or device index
1475 * @devname device name (ex. lustre-MDT0000)
1476 * @fsname file system name extracted from @devname and returned
1477 * to the caller (optional)
1478 * @index device index extracted from @devname and returned to
1479 * the caller (optional)
1481 * RETURN 0 success if we are only interested in
1482 * extracting fsname from devname.
1485 * LDD_F_SV_TYPE_* Besides extracting the fsname the
1486 * user also wants the index. Report to
1487 * the user the type of obd device the
1488 * returned index belongs too.
1490 * -EINVAL The obd device name is improper so
1491 * fsname could not be extracted.
1493 * -ENXIO Failed to extract the index out of
1494 * the obd device name. Most likely an
1495 * invalid obd device name
1497 static int mgs_parse_devname(char *devname, char *fsname, u32 *index)
1502 /* Extract fsname */
1504 rc = server_name2fsname(devname, fsname, NULL);
1506 CDEBUG(D_MGS, "Device name %s without fsname\n",
1513 rc = server_name2index(devname, index, NULL);
1515 CDEBUG(D_MGS, "Device name %s with wrong index\n",
1521 /* server_name2index can return LDD_F_SV_TYPE_* so always return rc */
1525 /* This is only called during replace_nids */
1526 static int only_mgs_is_running(struct obd_device *mgs_obd)
1528 /* TDB: Is global variable with devices count exists? */
1529 int num_devices = get_devices_count();
1530 int num_exports = 0;
1531 struct obd_export *exp;
1533 spin_lock(&mgs_obd->obd_dev_lock);
1534 list_for_each_entry(exp, &mgs_obd->obd_exports, exp_obd_chain) {
1535 /* skip self export */
1536 if (exp == mgs_obd->obd_self_export)
1541 if (num_exports > 1)
1542 CERROR("%s: node %s still connected during replace_nids connect_flags:%llx\n",
1544 libcfs_nid2str(exp->exp_nid_stats->nid),
1545 exp_connect_flags(exp));
1547 spin_unlock(&mgs_obd->obd_dev_lock);
1549 /* osd, MGS and MGC + MGC export (nosvc starts MGC)
1550 * (wc -l /proc/fs/lustre/devices <= 3) && (non self exports == 1)
1552 return (num_devices <= 3) && (num_exports <= 1);
1555 static int name_create_mdt(char **logname, char *fsname, int mdt_idx)
1559 if (mdt_idx > INDEX_MAP_MAX_VALUE)
1562 snprintf(postfix, sizeof(postfix), "-MDT%04x", mdt_idx);
1563 return name_create(logname, fsname, postfix);
1567 * Replace nids for \a device to \a nids values
1569 * \param obd MGS obd device
1570 * \param devname nids need to be replaced for this device
1571 * (ex. lustre-OST0000)
1572 * \param nids nids list (ex. nid1,nid2,nid3)
1576 int mgs_replace_nids(const struct lu_env *env,
1577 struct mgs_device *mgs,
1578 char *devname, char *nids)
1580 /* Assume fsname is part of device name */
1581 char fsname[MTI_NAME_MAXLEN];
1585 struct fs_db *fsdb = NULL;
1588 struct obd_device *mgs_obd = mgs->mgs_obd;
1591 /* We can only change NIDs if no other nodes are connected */
1592 spin_lock(&mgs_obd->obd_dev_lock);
1593 conn_state = mgs_obd->obd_no_conn;
1594 mgs_obd->obd_no_conn = 1;
1595 spin_unlock(&mgs_obd->obd_dev_lock);
1597 /* We can not change nids if not only MGS is started */
1598 if (!only_mgs_is_running(mgs_obd)) {
1599 CERROR("Only MGS is allowed to be started\n");
1600 GOTO(out, rc = -EINPROGRESS);
1603 /* Get fsname and index */
1604 rc = mgs_parse_devname(devname, fsname, &index);
1608 rc = mgs_find_or_make_fsdb(env, mgs, fsname, &fsdb);
1610 CERROR("%s: can't find fsdb: rc = %d\n", fsname, rc);
1614 /* Process client llogs */
1615 rc = name_create(&logname, fsname, "-client");
1618 rc = mgs_replace_nids_log(env, mgs_obd, logname, devname, nids);
1619 name_destroy(&logname);
1621 CERROR("%s: error while replacing NIDs for %s: rc = %d\n",
1622 fsname, devname, rc);
1626 /* Process MDT llogs */
1627 for (i = 0; i < INDEX_MAP_SIZE * 8; i++) {
1628 if (!test_bit(i, fsdb->fsdb_mdt_index_map))
1630 rc = name_create_mdt(&logname, fsname, i);
1633 rc = mgs_replace_nids_log(env, mgs_obd, logname, devname, nids);
1634 name_destroy(&logname);
1640 spin_lock(&mgs_obd->obd_dev_lock);
1641 mgs_obd->obd_no_conn = conn_state;
1642 spin_unlock(&mgs_obd->obd_dev_lock);
1645 mgs_put_fsdb(mgs, fsdb);
1651 * This is called for every record in llog. Some of records are
1652 * skipped, others are copied to new log as is.
1653 * Records to be skipped are
1654 * marker records marked SKIP
1655 * records enclosed between SKIP markers
1657 * \param[in] llh log to be processed
1658 * \param[in] rec current record
1659 * \param[in] data mgs_replace_data structure
1663 static int mgs_clear_config_handler(const struct lu_env *env,
1664 struct llog_handle *llh,
1665 struct llog_rec_hdr *rec, void *data)
1667 struct mgs_replace_data *mrd;
1668 struct lustre_cfg *lcfg = REC_DATA(rec);
1669 int cfg_len = REC_DATA_LEN(rec);
1674 mrd = (struct mgs_replace_data *)data;
1676 if (rec->lrh_type != OBD_CFG_REC) {
1677 CDEBUG(D_MGS, "Config llog Name=%s, Record Index=%u, "
1678 "Unhandled Record Type=%#x\n", llh->lgh_name,
1679 rec->lrh_index, rec->lrh_type);
1683 rc = lustre_cfg_sanity_check(lcfg, cfg_len);
1685 CDEBUG(D_MGS, "Config llog Name=%s, Invalid config file.",
1690 if (lcfg->lcfg_command == LCFG_MARKER) {
1691 struct cfg_marker *marker;
1693 marker = lustre_cfg_buf(lcfg, 1);
1694 if (marker->cm_flags & CM_SKIP) {
1695 if (marker->cm_flags & CM_START)
1696 mrd->state = REPLACE_SKIP;
1697 if (marker->cm_flags & CM_END)
1698 mrd->state = REPLACE_COPY;
1699 /* SKIP section started or finished */
1700 CDEBUG(D_MGS, "Skip idx=%d, rc=%d, len=%d, "
1701 "cmd %x %s %s\n", rec->lrh_index, rc,
1702 rec->lrh_len, lcfg->lcfg_command,
1703 lustre_cfg_string(lcfg, 0),
1704 lustre_cfg_string(lcfg, 1));
1708 if (mrd->state == REPLACE_SKIP) {
1709 /* record enclosed between SKIP markers, skip it */
1710 CDEBUG(D_MGS, "Skip idx=%d, rc=%d, len=%d, "
1711 "cmd %x %s %s\n", rec->lrh_index, rc,
1712 rec->lrh_len, lcfg->lcfg_command,
1713 lustre_cfg_string(lcfg, 0),
1714 lustre_cfg_string(lcfg, 1));
1719 /* Record is placed in temporary llog as is */
1720 rc = llog_write(env, mrd->temp_llh, rec, LLOG_NEXT_IDX);
1722 CDEBUG(D_MGS, "Copied idx=%d, rc=%d, len=%d, cmd %x %s %s\n",
1723 rec->lrh_index, rc, rec->lrh_len, lcfg->lcfg_command,
1724 lustre_cfg_string(lcfg, 0), lustre_cfg_string(lcfg, 1));
1729 * Directory CONFIGS/ may contain files which are not config logs to
1730 * be cleared. Skip any llogs with a non-alphanumeric character after
1731 * the last '-'. For example, fsname-MDT0000.sav, fsname-MDT0000.bak,
1732 * fsname-MDT0000.orig, fsname-MDT0000~, fsname-MDT0000.20150516, etc.
1734 static bool config_to_clear(const char *logname)
1739 str = strrchr(logname, '-');
1744 while (isalnum(str[++i]));
1745 return str[i] == '\0';
1749 * Clear config logs for \a name
1752 * \param mgs MGS device
1753 * \param name name of device or of filesystem
1754 * (ex. lustre-OST0000 or lustre) in later case all logs
1759 int mgs_clear_configs(const struct lu_env *env,
1760 struct mgs_device *mgs, const char *name)
1762 struct list_head dentry_list;
1763 struct mgs_direntry *dirent, *n;
1766 struct obd_device *mgs_obd = mgs->mgs_obd;
1771 /* Prevent clients and servers from connecting to mgs */
1772 spin_lock(&mgs_obd->obd_dev_lock);
1773 conn_state = mgs_obd->obd_no_conn;
1774 mgs_obd->obd_no_conn = 1;
1775 spin_unlock(&mgs_obd->obd_dev_lock);
1778 * config logs cannot be cleaned if anything other than
1781 if (!only_mgs_is_running(mgs_obd)) {
1782 CERROR("Only MGS is allowed to be started\n");
1783 GOTO(out, rc = -EBUSY);
1786 /* Find all the logs in the CONFIGS directory */
1787 rc = class_dentry_readdir(env, mgs, &dentry_list);
1789 CERROR("%s: cannot read config directory '%s': rc = %d\n",
1790 mgs_obd->obd_name, MOUNT_CONFIGS_DIR, rc);
1794 if (list_empty(&dentry_list)) {
1795 CERROR("%s: list empty reading config dir '%s': rc = %d\n",
1796 mgs_obd->obd_name, MOUNT_CONFIGS_DIR, -ENOENT);
1797 GOTO(out, rc = -ENOENT);
1800 OBD_ALLOC(namedash, strlen(name) + 2);
1801 if (namedash == NULL)
1802 GOTO(out, rc = -ENOMEM);
1803 snprintf(namedash, strlen(name) + 2, "%s-", name);
1805 list_for_each_entry(dirent, &dentry_list, mde_list) {
1806 if (strcmp(name, dirent->mde_name) &&
1807 strncmp(namedash, dirent->mde_name, strlen(namedash)))
1809 if (!config_to_clear(dirent->mde_name))
1811 CDEBUG(D_MGS, "%s: Clear config log %s\n",
1812 mgs_obd->obd_name, dirent->mde_name);
1813 rc = mgs_replace_log(env, mgs_obd, dirent->mde_name, NULL,
1814 mgs_clear_config_handler, NULL);
1819 list_for_each_entry_safe(dirent, n, &dentry_list, mde_list) {
1820 list_del_init(&dirent->mde_list);
1821 mgs_direntry_free(dirent);
1823 OBD_FREE(namedash, strlen(name) + 2);
1825 spin_lock(&mgs_obd->obd_dev_lock);
1826 mgs_obd->obd_no_conn = conn_state;
1827 spin_unlock(&mgs_obd->obd_dev_lock);
1832 static int record_lov_setup(const struct lu_env *env, struct llog_handle *llh,
1833 char *devname, struct lov_desc *desc)
1835 struct mgs_thread_info *mgi = mgs_env_info(env);
1836 struct llog_cfg_rec *lcr;
1839 lustre_cfg_bufs_reset(&mgi->mgi_bufs, devname);
1840 lustre_cfg_bufs_set(&mgi->mgi_bufs, 1, desc, sizeof(*desc));
1841 lcr = lustre_cfg_rec_new(LCFG_SETUP, &mgi->mgi_bufs);
1845 rc = llog_write(env, llh, &lcr->lcr_hdr, LLOG_NEXT_IDX);
1846 lustre_cfg_rec_free(lcr);
1850 static int record_lmv_setup(const struct lu_env *env, struct llog_handle *llh,
1851 char *devname, struct lmv_desc *desc)
1853 struct mgs_thread_info *mgi = mgs_env_info(env);
1854 struct llog_cfg_rec *lcr;
1857 lustre_cfg_bufs_reset(&mgi->mgi_bufs, devname);
1858 lustre_cfg_bufs_set(&mgi->mgi_bufs, 1, desc, sizeof(*desc));
1859 lcr = lustre_cfg_rec_new(LCFG_SETUP, &mgi->mgi_bufs);
1863 rc = llog_write(env, llh, &lcr->lcr_hdr, LLOG_NEXT_IDX);
1864 lustre_cfg_rec_free(lcr);
1868 static inline int record_mdc_add(const struct lu_env *env,
1869 struct llog_handle *llh,
1870 char *logname, char *mdcuuid,
1871 char *mdtuuid, char *index,
1874 return record_base(env,llh,logname,0,LCFG_ADD_MDC,
1875 mdtuuid,index,gen,mdcuuid);
1878 static inline int record_lov_add(const struct lu_env *env,
1879 struct llog_handle *llh,
1880 char *lov_name, char *ost_uuid,
1881 char *index, char *gen)
1883 return record_base(env, llh, lov_name, 0, LCFG_LOV_ADD_OBD,
1884 ost_uuid, index, gen, NULL);
1887 static inline int record_mount_opt(const struct lu_env *env,
1888 struct llog_handle *llh,
1889 char *profile, char *lov_name,
1892 return record_base(env, llh, NULL, 0, LCFG_MOUNTOPT,
1893 profile, lov_name, mdc_name, NULL);
1896 static int record_marker(const struct lu_env *env,
1897 struct llog_handle *llh,
1898 struct fs_db *fsdb, __u32 flags,
1899 char *tgtname, char *comment)
1901 struct mgs_thread_info *mgi = mgs_env_info(env);
1902 struct llog_cfg_rec *lcr;
1906 if (flags & CM_START)
1908 mgi->mgi_marker.cm_step = fsdb->fsdb_gen;
1909 mgi->mgi_marker.cm_flags = flags;
1910 mgi->mgi_marker.cm_vers = LUSTRE_VERSION_CODE;
1911 cplen = strlcpy(mgi->mgi_marker.cm_tgtname, tgtname,
1912 sizeof(mgi->mgi_marker.cm_tgtname));
1913 if (cplen >= sizeof(mgi->mgi_marker.cm_tgtname))
1915 cplen = strlcpy(mgi->mgi_marker.cm_comment, comment,
1916 sizeof(mgi->mgi_marker.cm_comment));
1917 if (cplen >= sizeof(mgi->mgi_marker.cm_comment))
1919 mgi->mgi_marker.cm_createtime = ktime_get_real_seconds();
1920 mgi->mgi_marker.cm_canceltime = 0;
1921 lustre_cfg_bufs_reset(&mgi->mgi_bufs, NULL);
1922 lustre_cfg_bufs_set(&mgi->mgi_bufs, 1, &mgi->mgi_marker,
1923 sizeof(mgi->mgi_marker));
1924 lcr = lustre_cfg_rec_new(LCFG_MARKER, &mgi->mgi_bufs);
1928 rc = llog_write(env, llh, &lcr->lcr_hdr, LLOG_NEXT_IDX);
1929 lustre_cfg_rec_free(lcr);
1933 static int record_start_log(const struct lu_env *env, struct mgs_device *mgs,
1934 struct llog_handle **llh, char *name)
1936 static struct obd_uuid cfg_uuid = { .uuid = "config_uuid" };
1937 struct llog_ctxt *ctxt;
1942 GOTO(out, rc = -EBUSY);
1944 ctxt = llog_get_context(mgs->mgs_obd, LLOG_CONFIG_ORIG_CTXT);
1946 GOTO(out, rc = -ENODEV);
1947 LASSERT(ctxt->loc_obd == mgs->mgs_obd);
1949 rc = llog_open_create(env, ctxt, llh, NULL, name);
1952 rc = llog_init_handle(env, *llh, LLOG_F_IS_PLAIN, &cfg_uuid);
1954 llog_close(env, *llh);
1956 llog_ctxt_put(ctxt);
1959 CERROR("%s: can't start log %s: rc = %d\n",
1960 mgs->mgs_obd->obd_name, name, rc);
1966 static int record_end_log(const struct lu_env *env, struct llog_handle **llh)
1970 rc = llog_close(env, *llh);
1976 /******************** config "macros" *********************/
1978 /* write an lcfg directly into a log (with markers) */
1979 static int mgs_write_log_direct(const struct lu_env *env,
1980 struct mgs_device *mgs, struct fs_db *fsdb,
1981 char *logname, struct llog_cfg_rec *lcr,
1982 char *devname, char *comment)
1984 struct llog_handle *llh = NULL;
1989 rc = record_start_log(env, mgs, &llh, logname);
1993 /* FIXME These should be a single journal transaction */
1994 rc = record_marker(env, llh, fsdb, CM_START, devname, comment);
1997 rc = llog_write(env, llh, &lcr->lcr_hdr, LLOG_NEXT_IDX);
2000 rc = record_marker(env, llh, fsdb, CM_END, devname, comment);
2004 record_end_log(env, &llh);
2008 /* write the lcfg in all logs for the given fs */
2009 static int mgs_write_log_direct_all(const struct lu_env *env,
2010 struct mgs_device *mgs,
2012 struct mgs_target_info *mti,
2013 struct llog_cfg_rec *lcr, char *devname,
2014 char *comment, int server_only)
2016 struct list_head log_list;
2017 struct mgs_direntry *dirent, *n;
2018 char *fsname = mti->mti_fsname;
2019 int rc = 0, len = strlen(fsname);
2022 /* Find all the logs in the CONFIGS directory */
2023 rc = class_dentry_readdir(env, mgs, &log_list);
2027 /* Could use fsdb index maps instead of directory listing */
2028 list_for_each_entry_safe(dirent, n, &log_list, mde_list) {
2029 list_del_init(&dirent->mde_list);
2030 /* don't write to sptlrpc rule log */
2031 if (strstr(dirent->mde_name, "-sptlrpc") != NULL)
2034 /* caller wants write server logs only */
2035 if (server_only && strstr(dirent->mde_name, "-client") != NULL)
2038 if (strlen(dirent->mde_name) <= len ||
2039 strncmp(fsname, dirent->mde_name, len) != 0 ||
2040 dirent->mde_name[len] != '-')
2043 CDEBUG(D_MGS, "Changing log %s\n", dirent->mde_name);
2044 /* Erase any old settings of this same parameter */
2045 rc = mgs_modify(env, mgs, fsdb, mti, dirent->mde_name,
2046 devname, comment, CM_SKIP);
2048 CERROR("%s: Can't modify llog %s: rc = %d\n",
2049 mgs->mgs_obd->obd_name, dirent->mde_name, rc);
2052 /* Write the new one */
2053 rc = mgs_write_log_direct(env, mgs, fsdb, dirent->mde_name,
2054 lcr, devname, comment);
2056 CERROR("%s: writing log %s: rc = %d\n",
2057 mgs->mgs_obd->obd_name, dirent->mde_name, rc);
2059 mgs_direntry_free(dirent);
2065 static int mgs_write_log_osp_to_mdt(const struct lu_env *env,
2066 struct mgs_device *mgs,
2068 struct mgs_target_info *mti,
2069 int index, char *logname);
2070 static int mgs_write_log_osc_to_lov(const struct lu_env *env,
2071 struct mgs_device *mgs,
2073 struct mgs_target_info *mti,
2074 char *logname, char *suffix, char *lovname,
2075 enum lustre_sec_part sec_part, int flags);
2076 static int name_create_mdt_and_lov(char **logname, char **lovname,
2077 struct fs_db *fsdb, int i);
2079 static int add_param(char *params, char *key, char *val)
2081 char *start = params + strlen(params);
2082 char *end = params + sizeof(((struct mgs_target_info *)0)->mti_params);
2086 keylen = strlen(key);
2087 if (start + 1 + keylen + strlen(val) >= end) {
2088 CERROR("params are too long: %s %s%s\n",
2089 params, key != NULL ? key : "", val);
2093 sprintf(start, " %s%s", key != NULL ? key : "", val);
2098 * Walk through client config log record and convert the related records
2101 static int mgs_steal_client_llog_handler(const struct lu_env *env,
2102 struct llog_handle *llh,
2103 struct llog_rec_hdr *rec, void *data)
2105 struct mgs_device *mgs;
2106 struct obd_device *obd;
2107 struct mgs_target_info *mti, *tmti;
2109 int cfg_len = rec->lrh_len;
2110 char *cfg_buf = (char*) (rec + 1);
2111 struct lustre_cfg *lcfg;
2113 struct llog_handle *mdt_llh = NULL;
2114 static int got_an_osc_or_mdc = 0;
2115 /* 0: not found any osc/mdc;
2119 static int last_step = -1;
2124 mti = ((struct temp_comp*)data)->comp_mti;
2125 tmti = ((struct temp_comp*)data)->comp_tmti;
2126 fsdb = ((struct temp_comp*)data)->comp_fsdb;
2127 obd = ((struct temp_comp *)data)->comp_obd;
2128 mgs = lu2mgs_dev(obd->obd_lu_dev);
2131 if (rec->lrh_type != OBD_CFG_REC) {
2132 CERROR("unhandled lrh_type: %#x\n", rec->lrh_type);
2136 rc = lustre_cfg_sanity_check(cfg_buf, cfg_len);
2138 CERROR("Insane cfg\n");
2142 lcfg = (struct lustre_cfg *)cfg_buf;
2144 if (lcfg->lcfg_command == LCFG_MARKER) {
2145 struct cfg_marker *marker;
2146 marker = lustre_cfg_buf(lcfg, 1);
2147 if (!strncmp(marker->cm_comment, "add osc", 7) &&
2148 (marker->cm_flags & CM_START) &&
2149 !(marker->cm_flags & CM_SKIP)) {
2150 got_an_osc_or_mdc = 1;
2151 cplen = strlcpy(tmti->mti_svname, marker->cm_tgtname,
2152 sizeof(tmti->mti_svname));
2153 if (cplen >= sizeof(tmti->mti_svname))
2155 rc = record_start_log(env, mgs, &mdt_llh,
2159 rc = record_marker(env, mdt_llh, fsdb, CM_START,
2160 mti->mti_svname, "add osc(copied)");
2161 record_end_log(env, &mdt_llh);
2162 last_step = marker->cm_step;
2165 if (!strncmp(marker->cm_comment, "add osc", 7) &&
2166 (marker->cm_flags & CM_END) &&
2167 !(marker->cm_flags & CM_SKIP)) {
2168 LASSERT(last_step == marker->cm_step);
2170 got_an_osc_or_mdc = 0;
2171 memset(tmti, 0, sizeof(*tmti));
2172 rc = record_start_log(env, mgs, &mdt_llh,
2176 rc = record_marker(env, mdt_llh, fsdb, CM_END,
2177 mti->mti_svname, "add osc(copied)");
2178 record_end_log(env, &mdt_llh);
2181 if (!strncmp(marker->cm_comment, "add mdc", 7) &&
2182 (marker->cm_flags & CM_START) &&
2183 !(marker->cm_flags & CM_SKIP)) {
2184 got_an_osc_or_mdc = 2;
2185 last_step = marker->cm_step;
2186 memcpy(tmti->mti_svname, marker->cm_tgtname,
2187 strlen(marker->cm_tgtname));
2191 if (!strncmp(marker->cm_comment, "add mdc", 7) &&
2192 (marker->cm_flags & CM_END) &&
2193 !(marker->cm_flags & CM_SKIP)) {
2194 LASSERT(last_step == marker->cm_step);
2196 got_an_osc_or_mdc = 0;
2197 memset(tmti, 0, sizeof(*tmti));
2202 if (got_an_osc_or_mdc == 0 || last_step < 0)
2205 if (lcfg->lcfg_command == LCFG_ADD_UUID) {
2206 __u64 nodenid = lcfg->lcfg_nid;
2208 if (strlen(tmti->mti_uuid) == 0) {
2209 /* target uuid not set, this config record is before
2210 * LCFG_SETUP, this nid is one of target node nid.
2212 tmti->mti_nids[tmti->mti_nid_count] = nodenid;
2213 tmti->mti_nid_count++;
2215 char nidstr[LNET_NIDSTR_SIZE];
2217 /* failover node nid */
2218 libcfs_nid2str_r(nodenid, nidstr, sizeof(nidstr));
2219 rc = add_param(tmti->mti_params, PARAM_FAILNODE,
2226 if (lcfg->lcfg_command == LCFG_SETUP) {
2229 target = lustre_cfg_string(lcfg, 1);
2230 memcpy(tmti->mti_uuid, target, strlen(target));
2234 /* ignore client side sptlrpc_conf_log */
2235 if (lcfg->lcfg_command == LCFG_SPTLRPC_CONF)
2238 if (lcfg->lcfg_command == LCFG_ADD_MDC &&
2239 strstr(lustre_cfg_string(lcfg, 0), "-clilmv") != NULL) {
2242 if (sscanf(lustre_cfg_buf(lcfg, 2), "%d", &index) != 1)
2244 if (index == mti->mti_stripe_index) {
2246 "attempt to create MDT%04x->MDT%04x osp device\n",
2250 memcpy(tmti->mti_fsname, mti->mti_fsname,
2251 strlen(mti->mti_fsname));
2252 tmti->mti_stripe_index = index;
2254 rc = mgs_write_log_osp_to_mdt(env, mgs, fsdb, tmti,
2255 mti->mti_stripe_index,
2257 memset(tmti, 0, sizeof(*tmti));
2261 if (lcfg->lcfg_command == LCFG_LOV_ADD_OBD) {
2264 char *logname, *lovname;
2266 rc = name_create_mdt_and_lov(&logname, &lovname, fsdb,
2267 mti->mti_stripe_index);
2270 sprintf(mdt_index, "-MDT%04x", mti->mti_stripe_index);
2272 if (sscanf(lustre_cfg_buf(lcfg, 2), "%d", &index) != 1) {
2273 name_destroy(&logname);
2274 name_destroy(&lovname);
2278 tmti->mti_stripe_index = index;
2279 rc = mgs_write_log_osc_to_lov(env, mgs, fsdb, tmti, logname,
2282 name_destroy(&logname);
2283 name_destroy(&lovname);
2289 /* fsdb->fsdb_mutex is already held in mgs_write_log_target*/
2290 /* stealed from mgs_get_fsdb_from_llog*/
2291 static int mgs_steal_llog_for_mdt_from_client(const struct lu_env *env,
2292 struct mgs_device *mgs,
2294 struct temp_comp* comp)
2296 struct llog_handle *loghandle;
2297 struct mgs_target_info *tmti;
2298 struct llog_ctxt *ctxt;
2303 ctxt = llog_get_context(mgs->mgs_obd, LLOG_CONFIG_ORIG_CTXT);
2304 LASSERT(ctxt != NULL);
2306 OBD_ALLOC_PTR(tmti);
2308 GOTO(out_ctxt, rc = -ENOMEM);
2310 comp->comp_tmti = tmti;
2311 comp->comp_obd = mgs->mgs_obd;
2313 rc = llog_open(env, ctxt, &loghandle, NULL, client_name,
2321 rc = llog_init_handle(env, loghandle, LLOG_F_IS_PLAIN, NULL);
2323 GOTO(out_close, rc);
2325 rc = llog_process_or_fork(env, loghandle, mgs_steal_client_llog_handler,
2326 (void *)comp, NULL, false);
2327 CDEBUG(D_MGS, "steal llog re = %d\n", rc);
2329 llog_close(env, loghandle);
2333 llog_ctxt_put(ctxt);
2337 /* lmv is the second thing for client logs */
2338 /* copied from mgs_write_log_lov. Please refer to that. */
2339 static int mgs_write_log_lmv(const struct lu_env *env,
2340 struct mgs_device *mgs,
2342 struct mgs_target_info *mti,
2343 char *logname, char *lmvname)
2345 struct llog_handle *llh = NULL;
2346 struct lmv_desc *lmvdesc;
2351 CDEBUG(D_MGS, "Writing lmv(%s) log for %s\n", lmvname,logname);
2353 OBD_ALLOC_PTR(lmvdesc);
2354 if (lmvdesc == NULL)
2356 lmvdesc->ld_active_tgt_count = 0;
2357 lmvdesc->ld_tgt_count = 0;
2358 sprintf((char*)lmvdesc->ld_uuid.uuid, "%s_UUID", lmvname);
2359 uuid = (char *)lmvdesc->ld_uuid.uuid;
2361 rc = record_start_log(env, mgs, &llh, logname);
2364 rc = record_marker(env, llh, fsdb, CM_START, lmvname, "lmv setup");
2367 rc = record_attach(env, llh, lmvname, "lmv", uuid);
2370 rc = record_lmv_setup(env, llh, lmvname, lmvdesc);
2373 rc = record_marker(env, llh, fsdb, CM_END, lmvname, "lmv setup");
2377 record_end_log(env, &llh);
2379 OBD_FREE_PTR(lmvdesc);
2383 /* lov is the first thing in the mdt and client logs */
2384 static int mgs_write_log_lov(const struct lu_env *env, struct mgs_device *mgs,
2385 struct fs_db *fsdb, struct mgs_target_info *mti,
2386 char *logname, char *lovname)
2388 struct llog_handle *llh = NULL;
2389 struct lov_desc *lovdesc;
2394 CDEBUG(D_MGS, "Writing lov(%s) log for %s\n", lovname, logname);
2397 #01 L attach 0:lov_mdsA 1:lov 2:71ccb_lov_mdsA_19f961a9e1
2398 #02 L lov_setup 0:lov_mdsA 1:(struct lov_desc)
2399 uuid=lov1_UUID, stripe count=1, size=1048576, offset=0, pattern=0
2402 /* FIXME just make lov_setup accept empty desc (put uuid in buf 2) */
2403 OBD_ALLOC_PTR(lovdesc);
2404 if (lovdesc == NULL)
2406 lovdesc->ld_magic = LOV_DESC_MAGIC;
2407 lovdesc->ld_tgt_count = 0;
2408 /* Defaults. Can be changed later by lcfg config_param */
2409 lovdesc->ld_default_stripe_count = 1;
2410 lovdesc->ld_pattern = LOV_PATTERN_RAID0;
2411 lovdesc->ld_default_stripe_size = LOV_DESC_STRIPE_SIZE_DEFAULT;
2412 lovdesc->ld_default_stripe_offset = -1;
2413 lovdesc->ld_qos_maxage = LOV_DESC_QOS_MAXAGE_DEFAULT;
2414 sprintf((char*)lovdesc->ld_uuid.uuid, "%s_UUID", lovname);
2415 /* can these be the same? */
2416 uuid = (char *)lovdesc->ld_uuid.uuid;
2418 /* This should always be the first entry in a log.
2419 rc = mgs_clear_log(obd, logname); */
2420 rc = record_start_log(env, mgs, &llh, logname);
2423 /* FIXME these should be a single journal transaction */
2424 rc = record_marker(env, llh, fsdb, CM_START, lovname, "lov setup");
2427 rc = record_attach(env, llh, lovname, "lov", uuid);
2430 rc = record_lov_setup(env, llh, lovname, lovdesc);
2433 rc = record_marker(env, llh, fsdb, CM_END, lovname, "lov setup");
2438 record_end_log(env, &llh);
2440 OBD_FREE_PTR(lovdesc);
2444 /* add failnids to open log */
2445 static int mgs_write_log_failnids(const struct lu_env *env,
2446 struct mgs_target_info *mti,
2447 struct llog_handle *llh,
2450 char *failnodeuuid = NULL;
2451 char *ptr = mti->mti_params;
2456 #03 L add_uuid nid=uml1@tcp(0x20000c0a80201) nal=90 0: 1:uml1_UUID
2457 #04 L add_uuid nid=1@elan(0x1000000000001) nal=90 0: 1:uml1_UUID
2458 #05 L setup 0:OSC_uml1_ost1_mdsA 1:ost1_UUID 2:uml1_UUID
2459 #06 L add_uuid nid=uml2@tcp(0x20000c0a80202) nal=90 0: 1:uml2_UUID
2460 #0x L add_uuid nid=2@elan(0x1000000000002) nal=90 0: 1:uml2_UUID
2461 #07 L add_conn 0:OSC_uml1_ost1_mdsA 1:uml2_UUID
2465 * Pull failnid info out of params string, which may contain something
2466 * like "<nid1>,<nid2>:<nid3>,<nid4>". class_parse_nid() does not
2467 * complain about abnormal inputs like ",:<nid1>", "<nid1>:,<nid2>",
2468 * etc. However, convert_hostnames() should have caught those.
2470 while (class_find_param(ptr, PARAM_FAILNODE, &ptr) == 0) {
2471 while (class_parse_nid(ptr, &nid, &ptr) == 0) {
2472 char nidstr[LNET_NIDSTR_SIZE];
2474 if (failnodeuuid == NULL) {
2475 /* We don't know the failover node name,
2476 * so just use the first nid as the uuid */
2477 libcfs_nid2str_r(nid, nidstr, sizeof(nidstr));
2478 rc = name_create(&failnodeuuid, nidstr, "");
2482 CDEBUG(D_MGS, "add nid %s for failover uuid %s, "
2484 libcfs_nid2str_r(nid, nidstr, sizeof(nidstr)),
2485 failnodeuuid, cliname);
2486 rc = record_add_uuid(env, llh, nid, failnodeuuid);
2488 * If *ptr is ':', we have added all NIDs for
2492 rc = record_add_conn(env, llh, cliname,
2494 name_destroy(&failnodeuuid);
2495 failnodeuuid = NULL;
2499 rc = record_add_conn(env, llh, cliname, failnodeuuid);
2500 name_destroy(&failnodeuuid);
2501 failnodeuuid = NULL;
2508 static int mgs_write_log_mdc_to_lmv(const struct lu_env *env,
2509 struct mgs_device *mgs,
2511 struct mgs_target_info *mti,
2512 char *logname, char *lmvname)
2514 struct llog_handle *llh = NULL;
2515 char *mdcname = NULL;
2516 char *nodeuuid = NULL;
2517 char *mdcuuid = NULL;
2518 char *lmvuuid = NULL;
2520 char nidstr[LNET_NIDSTR_SIZE];
2524 if (mgs_log_is_empty(env, mgs, logname)) {
2525 CERROR("log is empty! Logical error\n");
2529 CDEBUG(D_MGS, "adding mdc for %s to log %s:lmv(%s)\n",
2530 mti->mti_svname, logname, lmvname);
2532 libcfs_nid2str_r(mti->mti_nids[0], nidstr, sizeof(nidstr));
2533 rc = name_create(&nodeuuid, nidstr, "");
2536 rc = name_create(&mdcname, mti->mti_svname, "-mdc");
2539 rc = name_create(&mdcuuid, mdcname, "_UUID");
2542 rc = name_create(&lmvuuid, lmvname, "_UUID");
2546 rc = mgs_modify(env, mgs, fsdb, mti, logname, mti->mti_svname,
2547 "add mdc", CM_SKIP);
2551 rc = record_start_log(env, mgs, &llh, logname);
2554 rc = record_marker(env, llh, fsdb, CM_START, mti->mti_svname,
2558 for (i = 0; i < mti->mti_nid_count; i++) {
2559 CDEBUG(D_MGS, "add nid %s for mdt\n",
2560 libcfs_nid2str_r(mti->mti_nids[i],
2561 nidstr, sizeof(nidstr)));
2563 rc = record_add_uuid(env, llh, mti->mti_nids[i], nodeuuid);
2568 rc = record_attach(env, llh, mdcname, LUSTRE_MDC_NAME, lmvuuid);
2571 rc = record_setup(env, llh, mdcname, mti->mti_uuid, nodeuuid,
2575 rc = mgs_write_log_failnids(env, mti, llh, mdcname);
2578 snprintf(index, sizeof(index), "%d", mti->mti_stripe_index);
2579 rc = record_mdc_add(env, llh, lmvname, mdcuuid, mti->mti_uuid,
2583 rc = record_marker(env, llh, fsdb, CM_END, mti->mti_svname,
2588 record_end_log(env, &llh);
2590 name_destroy(&lmvuuid);
2591 name_destroy(&mdcuuid);
2592 name_destroy(&mdcname);
2593 name_destroy(&nodeuuid);
2597 static inline int name_create_lov(char **lovname, char *mdtname,
2598 struct fs_db *fsdb, int index)
2601 if (index == 0 && test_bit(FSDB_OSCNAME18, &fsdb->fsdb_flags))
2602 return name_create(lovname, fsdb->fsdb_name, "-mdtlov");
2604 return name_create(lovname, mdtname, "-mdtlov");
2607 static int name_create_mdt_and_lov(char **logname, char **lovname,
2608 struct fs_db *fsdb, int i)
2612 rc = name_create_mdt(logname, fsdb->fsdb_name, i);
2616 if (i == 0 && test_bit(FSDB_OSCNAME18, &fsdb->fsdb_flags))
2617 rc = name_create(lovname, fsdb->fsdb_name, "-mdtlov");
2619 rc = name_create(lovname, *logname, "-mdtlov");
2621 name_destroy(logname);
2627 static inline int name_create_mdt_osc(char **oscname, char *ostname,
2628 struct fs_db *fsdb, int i)
2632 if (i == 0 && test_bit(FSDB_OSCNAME18, &fsdb->fsdb_flags))
2633 sprintf(suffix, "-osc");
2635 sprintf(suffix, "-osc-MDT%04x", i);
2636 return name_create(oscname, ostname, suffix);
2639 /* add new mdc to already existent MDS */
2640 static int mgs_write_log_osp_to_mdt(const struct lu_env *env,
2641 struct mgs_device *mgs,
2643 struct mgs_target_info *mti,
2644 int mdt_index, char *logname)
2646 struct llog_handle *llh = NULL;
2647 char *nodeuuid = NULL;
2648 char *ospname = NULL;
2649 char *lovuuid = NULL;
2650 char *mdtuuid = NULL;
2651 char *svname = NULL;
2652 char *mdtname = NULL;
2653 char *lovname = NULL;
2655 char nidstr[LNET_NIDSTR_SIZE];
2659 if (mgs_log_is_empty(env, mgs, mti->mti_svname)) {
2660 CERROR("log is empty! Logical error\n");
2664 CDEBUG(D_MGS, "adding osp index %d to %s\n", mti->mti_stripe_index,
2667 rc = name_create_mdt(&mdtname, fsdb->fsdb_name, mti->mti_stripe_index);
2671 libcfs_nid2str_r(mti->mti_nids[0], nidstr, sizeof(nidstr));
2672 rc = name_create(&nodeuuid, nidstr, "");
2674 GOTO(out_destory, rc);
2676 rc = name_create(&svname, mdtname, "-osp");
2678 GOTO(out_destory, rc);
2680 sprintf(index_str, "-MDT%04x", mdt_index);
2681 rc = name_create(&ospname, svname, index_str);
2683 GOTO(out_destory, rc);
2685 rc = name_create_lov(&lovname, logname, fsdb, mdt_index);
2687 GOTO(out_destory, rc);
2689 rc = name_create(&lovuuid, lovname, "_UUID");
2691 GOTO(out_destory, rc);
2693 rc = name_create(&mdtuuid, mdtname, "_UUID");
2695 GOTO(out_destory, rc);
2697 rc = mgs_modify(env, mgs, fsdb, mti, logname, mti->mti_svname,
2698 "add osp", CM_SKIP);
2700 GOTO(out_destory, rc);
2702 rc = record_start_log(env, mgs, &llh, logname);
2704 GOTO(out_destory, rc);
2706 rc = record_marker(env, llh, fsdb, CM_START, mti->mti_svname,
2709 GOTO(out_destory, rc);
2711 for (i = 0; i < mti->mti_nid_count; i++) {
2712 CDEBUG(D_MGS, "add nid %s for mdt\n",
2713 libcfs_nid2str_r(mti->mti_nids[i],
2714 nidstr, sizeof(nidstr)));
2715 rc = record_add_uuid(env, llh, mti->mti_nids[i], nodeuuid);
2720 rc = record_attach(env, llh, ospname, LUSTRE_OSP_NAME, lovuuid);
2724 rc = record_setup(env, llh, ospname, mti->mti_uuid, nodeuuid,
2729 rc = mgs_write_log_failnids(env, mti, llh, ospname);
2733 /* Add mdc(osp) to lod */
2734 snprintf(index_str, sizeof(index_str), "%d", mti->mti_stripe_index);
2735 rc = record_base(env, llh, lovname, 0, LCFG_ADD_MDC, mti->mti_uuid,
2736 index_str, "1", NULL);
2740 rc = record_marker(env, llh, fsdb, CM_END, mti->mti_svname, "add osp");
2745 record_end_log(env, &llh);
2748 name_destroy(&mdtuuid);
2749 name_destroy(&lovuuid);
2750 name_destroy(&lovname);
2751 name_destroy(&ospname);
2752 name_destroy(&svname);
2753 name_destroy(&nodeuuid);
2754 name_destroy(&mdtname);
2758 static int mgs_write_log_mdt0(const struct lu_env *env,
2759 struct mgs_device *mgs,
2761 struct mgs_target_info *mti)
2763 char *log = mti->mti_svname;
2764 struct llog_handle *llh = NULL;
2765 struct obd_uuid *uuid;
2768 char *ptr = mti->mti_params;
2769 int rc = 0, failout = 0;
2772 OBD_ALLOC_PTR(uuid);
2776 if (class_find_param(ptr, PARAM_FAILMODE, &ptr) == 0)
2777 failout = (strncmp(ptr, "failout", 7) == 0);
2779 rc = name_create(&lovname, log, "-mdtlov");
2782 if (mgs_log_is_empty(env, mgs, log)) {
2783 rc = mgs_write_log_lov(env, mgs, fsdb, mti, log, lovname);
2788 sprintf(mdt_index, "%d", mti->mti_stripe_index);
2790 rc = record_start_log(env, mgs, &llh, log);
2794 /* add MDT itself */
2796 /* FIXME this whole fn should be a single journal transaction */
2797 sprintf(uuid->uuid, "%s_UUID", log);
2798 rc = record_marker(env, llh, fsdb, CM_START, log, "add mdt");
2801 rc = record_attach(env, llh, log, LUSTRE_MDT_NAME, uuid->uuid);
2804 rc = record_mount_opt(env, llh, log, lovname, NULL);
2807 rc = record_setup(env, llh, log, uuid->uuid, mdt_index, lovname,
2808 failout ? "n" : "f");
2811 rc = record_marker(env, llh, fsdb, CM_END, log, "add mdt");
2815 record_end_log(env, &llh);
2817 name_destroy(&lovname);
2823 /* envelope method for all layers log */
2824 static int mgs_write_log_mdt(const struct lu_env *env,
2825 struct mgs_device *mgs,
2827 struct mgs_target_info *mti)
2829 struct mgs_thread_info *mgi = mgs_env_info(env);
2830 struct llog_handle *llh = NULL;
2835 CDEBUG(D_MGS, "writing new mdt %s\n", mti->mti_svname);
2837 if (mti->mti_uuid[0] == '\0') {
2838 /* Make up our own uuid */
2839 snprintf(mti->mti_uuid, sizeof(mti->mti_uuid),
2840 "%s_UUID", mti->mti_svname);
2844 rc = mgs_write_log_mdt0(env, mgs, fsdb, mti);
2847 /* Append the mdt info to the client log */
2848 rc = name_create(&cliname, mti->mti_fsname, "-client");
2852 if (mgs_log_is_empty(env, mgs, cliname)) {
2853 /* Start client log */
2854 rc = mgs_write_log_lov(env, mgs, fsdb, mti, cliname,
2858 rc = mgs_write_log_lmv(env, mgs, fsdb, mti, cliname,
2865 #09 L add_uuid nid=uml1@tcp(0x20000c0a80201) 0: 1:uml1_UUID
2866 #10 L attach 0:MDC_uml1_mdsA_MNT_client 1:mdc 2:1d834_MNT_client_03f
2867 #11 L setup 0:MDC_uml1_mdsA_MNT_client 1:mdsA_UUID 2:uml1_UUID
2868 #12 L add_uuid nid=uml2@tcp(0x20000c0a80202) 0: 1:uml2_UUID
2869 #13 L add_conn 0:MDC_uml1_mdsA_MNT_client 1:uml2_UUID
2870 #14 L mount_option 0: 1:client 2:lov1 3:MDC_uml1_mdsA_MNT_client
2873 /* copy client info about lov/lmv */
2874 mgi->mgi_comp.comp_mti = mti;
2875 mgi->mgi_comp.comp_fsdb = fsdb;
2877 rc = mgs_steal_llog_for_mdt_from_client(env, mgs, cliname,
2881 rc = mgs_write_log_mdc_to_lmv(env, mgs, fsdb, mti, cliname,
2887 rc = record_start_log(env, mgs, &llh, cliname);
2891 rc = record_marker(env, llh, fsdb, CM_START, cliname, "mount opts");
2894 rc = record_mount_opt(env, llh, cliname, fsdb->fsdb_clilov,
2898 rc = record_marker(env, llh, fsdb, CM_END, cliname, "mount opts");
2902 /* for_all_existing_mdt except current one */
2903 for (i = 0; i < INDEX_MAP_SIZE * 8; i++) {
2904 if (i != mti->mti_stripe_index &&
2905 test_bit(i, fsdb->fsdb_mdt_index_map)) {
2908 rc = name_create_mdt(&logname, fsdb->fsdb_name, i);
2912 /* NB: If the log for the MDT is empty, it means
2913 * the MDT is only added to the index
2914 * map, and not being process yet, i.e. this
2915 * is an unregistered MDT, see mgs_write_log_target().
2916 * so we should skip it. Otherwise
2918 * 1. MGS get register request for MDT1 and MDT2.
2920 * 2. Then both MDT1 and MDT2 are added into
2921 * fsdb_mdt_index_map. (see mgs_set_index()).
2923 * 3. Then MDT1 get the lock of fsdb_mutex, then
2924 * generate the config log, here, it will regard MDT2
2925 * as an existent MDT, and generate "add osp" for
2926 * lustre-MDT0001-osp-MDT0002. Note: at the moment
2927 * MDT0002 config log is still empty, so it will
2928 * add "add osp" even before "lov setup", which
2929 * will definitly cause trouble.
2931 * 4. MDT1 registeration finished, fsdb_mutex is
2932 * released, then MDT2 get in, then in above
2933 * mgs_steal_llog_for_mdt_from_client(), it will
2934 * add another osp log for lustre-MDT0001-osp-MDT0002,
2935 * which will cause another trouble.*/
2936 if (!mgs_log_is_empty(env, mgs, logname))
2937 rc = mgs_write_log_osp_to_mdt(env, mgs, fsdb,
2940 name_destroy(&logname);
2946 record_end_log(env, &llh);
2948 name_destroy(&cliname);
2952 /* Add the ost info to the client/mdt lov */
2953 static int mgs_write_log_osc_to_lov(const struct lu_env *env,
2954 struct mgs_device *mgs, struct fs_db *fsdb,
2955 struct mgs_target_info *mti,
2956 char *logname, char *suffix, char *lovname,
2957 enum lustre_sec_part sec_part, int flags)
2959 struct llog_handle *llh = NULL;
2960 char *nodeuuid = NULL;
2961 char *oscname = NULL;
2962 char *oscuuid = NULL;
2963 char *lovuuid = NULL;
2964 char *svname = NULL;
2966 char nidstr[LNET_NIDSTR_SIZE];
2970 CDEBUG(D_INFO, "adding osc for %s to log %s\n",
2971 mti->mti_svname, logname);
2973 if (mgs_log_is_empty(env, mgs, logname)) {
2974 CERROR("log is empty! Logical error\n");
2978 libcfs_nid2str_r(mti->mti_nids[0], nidstr, sizeof(nidstr));
2979 rc = name_create(&nodeuuid, nidstr, "");
2982 rc = name_create(&svname, mti->mti_svname, "-osc");
2986 /* for the system upgraded from old 1.8, keep using the old osc naming
2987 * style for mdt, see name_create_mdt_osc(). LU-1257 */
2988 if (test_bit(FSDB_OSCNAME18, &fsdb->fsdb_flags))
2989 rc = name_create(&oscname, svname, "");
2991 rc = name_create(&oscname, svname, suffix);
2995 rc = name_create(&oscuuid, oscname, "_UUID");
2998 rc = name_create(&lovuuid, lovname, "_UUID");
3004 #03 L add_uuid nid=uml1@tcp(0x20000c0a80201) 0: 1:uml1_UUID
3006 #04 L add_uuid nid=1@elan(0x1000000000001) nal=90 0: 1:uml1_UUID
3007 #04 L attach 0:OSC_uml1_ost1_MNT_client 1:osc 2:89070_lov1_a41dff51a
3008 #05 L setup 0:OSC_uml1_ost1_MNT_client 1:ost1_UUID 2:uml1_UUID
3010 #06 L add_uuid nid=uml2@tcp(0x20000c0a80202) 0: 1:uml2_UUID
3011 #07 L add_conn 0:OSC_uml1_ost1_MNT_client 1:uml2_UUID
3012 #08 L lov_modify_tgts add 0:lov1 1:ost1_UUID 2(index):0 3(gen):1
3015 rc = record_start_log(env, mgs, &llh, logname);
3019 /* FIXME these should be a single journal transaction */
3020 rc = record_marker(env, llh, fsdb, CM_START | flags, mti->mti_svname,
3025 /* NB: don't change record order, because upon MDT steal OSC config
3026 * from client, it treats all nids before LCFG_SETUP as target nids
3027 * (multiple interfaces), while nids after as failover node nids.
3028 * See mgs_steal_client_llog_handler() LCFG_ADD_UUID.
3030 for (i = 0; i < mti->mti_nid_count; i++) {
3031 CDEBUG(D_MGS, "add nid %s\n",
3032 libcfs_nid2str_r(mti->mti_nids[i],
3033 nidstr, sizeof(nidstr)));
3034 rc = record_add_uuid(env, llh, mti->mti_nids[i], nodeuuid);
3038 rc = record_attach(env, llh, oscname, LUSTRE_OSC_NAME, lovuuid);
3041 rc = record_setup(env, llh, oscname, mti->mti_uuid, nodeuuid,
3045 rc = mgs_write_log_failnids(env, mti, llh, oscname);
3049 snprintf(index, sizeof(index), "%d", mti->mti_stripe_index);
3051 rc = record_lov_add(env, llh, lovname, mti->mti_uuid, index, "1");
3054 rc = record_marker(env, llh, fsdb, CM_END | flags, mti->mti_svname,
3059 record_end_log(env, &llh);
3061 name_destroy(&lovuuid);
3062 name_destroy(&oscuuid);
3063 name_destroy(&oscname);
3064 name_destroy(&svname);
3065 name_destroy(&nodeuuid);
3069 static int mgs_write_log_ost(const struct lu_env *env,
3070 struct mgs_device *mgs, struct fs_db *fsdb,
3071 struct mgs_target_info *mti)
3073 struct llog_handle *llh = NULL;
3074 char *logname, *lovname;
3075 char *ptr = mti->mti_params;
3076 int rc, flags = 0, failout = 0, i;
3079 CDEBUG(D_MGS, "writing new ost %s\n", mti->mti_svname);
3081 /* The ost startup log */
3083 /* If the ost log already exists, that means that someone reformatted
3084 the ost and it called target_add again. */
3085 if (!mgs_log_is_empty(env, mgs, mti->mti_svname)) {
3086 LCONSOLE_ERROR_MSG(0x141, "The config log for %s already "
3087 "exists, yet the server claims it never "
3088 "registered. It may have been reformatted, "
3089 "or the index changed. writeconf the MDT to "
3090 "regenerate all logs.\n", mti->mti_svname);
3095 attach obdfilter ost1 ost1_UUID
3096 setup /dev/loop2 ldiskfs f|n errors=remount-ro,user_xattr
3098 if (class_find_param(ptr, PARAM_FAILMODE, &ptr) == 0)
3099 failout = (strncmp(ptr, "failout", 7) == 0);
3100 rc = record_start_log(env, mgs, &llh, mti->mti_svname);
3103 /* FIXME these should be a single journal transaction */
3104 rc = record_marker(env, llh, fsdb, CM_START, mti->mti_svname,"add ost");
3107 if (*mti->mti_uuid == '\0')
3108 snprintf(mti->mti_uuid, sizeof(mti->mti_uuid),
3109 "%s_UUID", mti->mti_svname);
3110 rc = record_attach(env, llh, mti->mti_svname,
3111 "obdfilter"/*LUSTRE_OST_NAME*/, mti->mti_uuid);
3114 rc = record_setup(env, llh, mti->mti_svname,
3115 "dev"/*ignored*/, "type"/*ignored*/,
3116 failout ? "n" : "f", NULL/*options*/);
3119 rc = record_marker(env, llh, fsdb, CM_END, mti->mti_svname, "add ost");
3123 record_end_log(env, &llh);
3126 /* We also have to update the other logs where this osc is part of
3129 if (test_bit(FSDB_OLDLOG14, &fsdb->fsdb_flags)) {
3130 /* If we're upgrading, the old mdt log already has our
3131 entry. Let's do a fake one for fun. */
3132 /* Note that we can't add any new failnids, since we don't
3133 know the old osc names. */
3134 flags = CM_SKIP | CM_UPGRADE146;
3136 } else if ((mti->mti_flags & LDD_F_UPDATE) != LDD_F_UPDATE) {
3137 /* If the update flag isn't set, don't update client/mdt
3140 LCONSOLE_WARN("Client log for %s was not updated; writeconf "
3141 "the MDT first to regenerate it.\n",
3145 /* Add ost to all MDT lov defs */
3146 for (i = 0; i < INDEX_MAP_SIZE * 8; i++){
3147 if (test_bit(i, fsdb->fsdb_mdt_index_map)) {
3150 rc = name_create_mdt_and_lov(&logname, &lovname, fsdb,
3155 snprintf(mdt_index, sizeof(mdt_index), "-MDT%04x", i);
3156 rc = mgs_write_log_osc_to_lov(env, mgs, fsdb, mti,
3158 lovname, LUSTRE_SP_MDT,
3160 name_destroy(&logname);
3161 name_destroy(&lovname);
3167 /* Append ost info to the client log */
3168 rc = name_create(&logname, mti->mti_fsname, "-client");
3171 if (mgs_log_is_empty(env, mgs, logname)) {
3172 /* Start client log */
3173 rc = mgs_write_log_lov(env, mgs, fsdb, mti, logname,
3177 rc = mgs_write_log_lmv(env, mgs, fsdb, mti, logname,
3182 rc = mgs_write_log_osc_to_lov(env, mgs, fsdb, mti, logname, "",
3183 fsdb->fsdb_clilov, LUSTRE_SP_CLI, flags);
3185 name_destroy(&logname);
3189 static __inline__ int mgs_param_empty(char *ptr)
3193 if ((tmp = strchr(ptr, '=')) && (*(++tmp) == '\0'))
3198 static int mgs_write_log_failnid_internal(const struct lu_env *env,
3199 struct mgs_device *mgs,
3201 struct mgs_target_info *mti,
3202 char *logname, char *cliname)
3205 struct llog_handle *llh = NULL;
3207 if (mgs_param_empty(mti->mti_params)) {
3208 /* Remove _all_ failnids */
3209 rc = mgs_modify(env, mgs, fsdb, mti, logname,
3210 mti->mti_svname, "add failnid", CM_SKIP);
3211 return rc < 0 ? rc : 0;
3214 /* Otherwise failover nids are additive */
3215 rc = record_start_log(env, mgs, &llh, logname);
3218 /* FIXME this should be a single journal transaction */
3219 rc = record_marker(env, llh, fsdb, CM_START, mti->mti_svname,
3223 rc = mgs_write_log_failnids(env, mti, llh, cliname);
3226 rc = record_marker(env, llh, fsdb, CM_END,
3227 mti->mti_svname, "add failnid");
3229 record_end_log(env, &llh);
3234 /* Add additional failnids to an existing log.
3235 The mdc/osc must have been added to logs first */
3236 /* tcp nids must be in dotted-quad ascii -
3237 we can't resolve hostnames from the kernel. */
3238 static int mgs_write_log_add_failnid(const struct lu_env *env,
3239 struct mgs_device *mgs,
3241 struct mgs_target_info *mti)
3243 char *logname, *cliname;
3247 /* FIXME we currently can't erase the failnids
3248 * given when a target first registers, since they aren't part of
3249 * an "add uuid" stanza
3252 /* Verify that we know about this target */
3253 if (mgs_log_is_empty(env, mgs, mti->mti_svname)) {
3254 LCONSOLE_ERROR_MSG(0x142, "The target %s has not registered "
3255 "yet. It must be started before failnids "
3256 "can be added.\n", mti->mti_svname);
3260 /* Create mdc/osc client name (e.g. lustre-OST0001-osc) */
3261 if (mti->mti_flags & LDD_F_SV_TYPE_MDT) {
3262 rc = name_create(&cliname, mti->mti_svname, "-mdc");
3263 } else if (mti->mti_flags & LDD_F_SV_TYPE_OST) {
3264 rc = name_create(&cliname, mti->mti_svname, "-osc");
3271 /* Add failover nids to the client log */
3272 rc = name_create(&logname, mti->mti_fsname, "-client");
3274 name_destroy(&cliname);
3278 rc = mgs_write_log_failnid_internal(env, mgs, fsdb,mti,logname,cliname);
3279 name_destroy(&logname);
3280 name_destroy(&cliname);
3284 if (mti->mti_flags & LDD_F_SV_TYPE_OST) {
3285 /* Add OST failover nids to the MDT logs as well */
3288 for (i = 0; i < INDEX_MAP_SIZE * 8; i++) {
3289 if (!test_bit(i, fsdb->fsdb_mdt_index_map))
3291 rc = name_create_mdt(&logname, mti->mti_fsname, i);
3294 rc = name_create_mdt_osc(&cliname, mti->mti_svname,
3297 name_destroy(&logname);
3300 rc = mgs_write_log_failnid_internal(env, mgs, fsdb,
3303 name_destroy(&cliname);
3304 name_destroy(&logname);
3313 static int mgs_wlp_lcfg(const struct lu_env *env,
3314 struct mgs_device *mgs, struct fs_db *fsdb,
3315 struct mgs_target_info *mti,
3316 char *logname, struct lustre_cfg_bufs *bufs,
3317 char *tgtname, char *ptr)
3319 char comment[MTI_NAME_MAXLEN];
3321 struct llog_cfg_rec *lcr;
3324 /* Erase any old settings of this same parameter */
3325 strlcpy(comment, ptr, sizeof(comment));
3326 /* But don't try to match the value. */
3327 tmp = strchr(comment, '=');
3330 /* FIXME we should skip settings that are the same as old values */
3331 rc = mgs_modify(env, mgs, fsdb, mti, logname, tgtname, comment,CM_SKIP);
3334 del = mgs_param_empty(ptr);
3336 LCONSOLE_INFO("%s parameter %s.%s in log %s\n", del ? "Disabling" : rc ?
3337 "Setting" : "Modifying", tgtname, comment, logname);
3339 /* mgs_modify() will return 1 if nothing had to be done */
3345 lustre_cfg_bufs_reset(bufs, tgtname);
3346 lustre_cfg_bufs_set_string(bufs, 1, ptr);
3347 if (mti->mti_flags & LDD_F_PARAM2)
3348 lustre_cfg_bufs_set_string(bufs, 2, LCTL_UPCALL);
3350 lcr = lustre_cfg_rec_new((mti->mti_flags & LDD_F_PARAM2) ?
3351 LCFG_SET_PARAM : LCFG_PARAM, bufs);
3355 rc = mgs_write_log_direct(env, mgs, fsdb, logname, lcr, tgtname,
3357 lustre_cfg_rec_free(lcr);
3361 /* write global variable settings into log */
3362 static int mgs_write_log_sys(const struct lu_env *env,
3363 struct mgs_device *mgs, struct fs_db *fsdb,
3364 struct mgs_target_info *mti, char *sys, char *ptr)
3366 struct mgs_thread_info *mgi = mgs_env_info(env);
3367 struct lustre_cfg *lcfg;
3368 struct llog_cfg_rec *lcr;
3370 int rc, cmd, convert = 1;
3372 if (class_match_param(ptr, PARAM_TIMEOUT, &tmp) == 0) {
3373 cmd = LCFG_SET_TIMEOUT;
3374 } else if (class_match_param(ptr, PARAM_LDLM_TIMEOUT, &tmp) == 0) {
3375 cmd = LCFG_SET_LDLM_TIMEOUT;
3376 /* Check for known params here so we can return error to lctl */
3377 } else if ((class_match_param(ptr, PARAM_AT_MIN, &tmp) == 0) ||
3378 (class_match_param(ptr, PARAM_AT_MAX, &tmp) == 0) ||
3379 (class_match_param(ptr, PARAM_AT_EXTRA, &tmp) == 0) ||
3380 (class_match_param(ptr, PARAM_AT_EARLY_MARGIN, &tmp) == 0) ||
3381 (class_match_param(ptr, PARAM_AT_HISTORY, &tmp) == 0)) {
3383 } else if (class_match_param(ptr, PARAM_JOBID_VAR, &tmp) == 0) {
3384 convert = 0; /* Don't convert string value to integer */
3390 if (mgs_param_empty(ptr))
3391 CDEBUG(D_MGS, "global '%s' removed\n", sys);
3393 CDEBUG(D_MGS, "global '%s' val=%s\n", sys, tmp);
3395 lustre_cfg_bufs_reset(&mgi->mgi_bufs, NULL);
3396 lustre_cfg_bufs_set_string(&mgi->mgi_bufs, 1, sys);
3397 if (!convert && *tmp != '\0')
3398 lustre_cfg_bufs_set_string(&mgi->mgi_bufs, 2, tmp);
3399 lcr = lustre_cfg_rec_new(cmd, &mgi->mgi_bufs);
3403 lcfg = &lcr->lcr_cfg;
3405 rc = kstrtouint(tmp, 0, &lcfg->lcfg_num);
3407 GOTO(out_rec_free, rc);
3412 /* truncate the comment to the parameter name */
3416 /* modify all servers and clients */
3417 rc = mgs_write_log_direct_all(env, mgs, fsdb, mti,
3418 *tmp == '\0' ? NULL : lcr,
3419 mti->mti_fsname, sys, 0);
3420 if (rc == 0 && *tmp != '\0') {
3422 case LCFG_SET_TIMEOUT:
3423 if (!obd_timeout_set || lcfg->lcfg_num > obd_timeout)
3424 class_process_config(lcfg);
3426 case LCFG_SET_LDLM_TIMEOUT:
3427 if (!ldlm_timeout_set || lcfg->lcfg_num > ldlm_timeout)
3428 class_process_config(lcfg);
3436 lustre_cfg_rec_free(lcr);
3440 /* write quota settings into log */
3441 static int mgs_write_log_quota(const struct lu_env *env, struct mgs_device *mgs,
3442 struct fs_db *fsdb, struct mgs_target_info *mti,
3443 char *quota, char *ptr)
3445 struct mgs_thread_info *mgi = mgs_env_info(env);
3446 struct llog_cfg_rec *lcr;
3449 int rc, cmd = LCFG_PARAM;
3451 /* support only 'meta' and 'data' pools so far */
3452 if (class_match_param(ptr, QUOTA_METAPOOL_NAME, &tmp) != 0 &&
3453 class_match_param(ptr, QUOTA_DATAPOOL_NAME, &tmp) != 0) {
3454 CERROR("parameter quota.%s isn't supported (only quota.mdt "
3455 "& quota.ost are)\n", ptr);
3460 CDEBUG(D_MGS, "global '%s' removed\n", quota);
3462 CDEBUG(D_MGS, "global '%s'\n", quota);
3464 if (strchr(tmp, 'u') == NULL && strchr(tmp, 'g') == NULL &&
3465 strchr(tmp, 'p') == NULL &&
3466 strcmp(tmp, "none") != 0) {
3467 CERROR("enable option(%s) isn't supported\n", tmp);
3472 lustre_cfg_bufs_reset(&mgi->mgi_bufs, mti->mti_fsname);
3473 lustre_cfg_bufs_set_string(&mgi->mgi_bufs, 1, quota);
3474 lcr = lustre_cfg_rec_new(cmd, &mgi->mgi_bufs);
3478 /* truncate the comment to the parameter name */
3483 /* XXX we duplicated quota enable information in all server
3484 * config logs, it should be moved to a separate config
3485 * log once we cleanup the config log for global param. */
3486 /* modify all servers */
3487 rc = mgs_write_log_direct_all(env, mgs, fsdb, mti,
3488 *tmp == '\0' ? NULL : lcr,
3489 mti->mti_fsname, quota, 1);
3491 lustre_cfg_rec_free(lcr);
3492 return rc < 0 ? rc : 0;
3495 static int mgs_srpc_set_param_disk(const struct lu_env *env,
3496 struct mgs_device *mgs,
3498 struct mgs_target_info *mti,
3501 struct mgs_thread_info *mgi = mgs_env_info(env);
3502 struct llog_cfg_rec *lcr;
3503 struct llog_handle *llh = NULL;
3505 char *comment, *ptr;
3511 ptr = strchr(param, '=');
3512 LASSERT(ptr != NULL);
3515 OBD_ALLOC(comment, len + 1);
3516 if (comment == NULL)
3518 strncpy(comment, param, len);
3519 comment[len] = '\0';
3522 lustre_cfg_bufs_reset(&mgi->mgi_bufs, mti->mti_svname);
3523 lustre_cfg_bufs_set_string(&mgi->mgi_bufs, 1, param);
3524 lcr = lustre_cfg_rec_new(LCFG_SPTLRPC_CONF, &mgi->mgi_bufs);
3526 GOTO(out_comment, rc = -ENOMEM);
3528 /* construct log name */
3529 rc = name_create(&logname, mti->mti_fsname, "-sptlrpc");
3533 if (mgs_log_is_empty(env, mgs, logname)) {
3534 rc = record_start_log(env, mgs, &llh, logname);
3537 record_end_log(env, &llh);
3540 /* obsolete old one */
3541 rc = mgs_modify(env, mgs, fsdb, mti, logname, mti->mti_svname,
3545 /* write the new one */
3546 rc = mgs_write_log_direct(env, mgs, fsdb, logname, lcr,
3547 mti->mti_svname, comment);
3549 CERROR("%s: error writing log %s: rc = %d\n",
3550 mgs->mgs_obd->obd_name, logname, rc);
3552 name_destroy(&logname);
3554 lustre_cfg_rec_free(lcr);
3556 OBD_FREE(comment, len + 1);
3560 static int mgs_srpc_set_param_udesc_mem(struct fs_db *fsdb,
3565 /* disable the adjustable udesc parameter for now, i.e. use default
3566 * setting that client always ship udesc to MDT if possible. to enable
3567 * it simply remove the following line */
3570 ptr = strchr(param, '=');
3575 if (strcmp(param, PARAM_SRPC_UDESC))
3578 if (strcmp(ptr, "yes") == 0) {
3579 set_bit(FSDB_UDESC, &fsdb->fsdb_flags);
3580 CWARN("Enable user descriptor shipping from client to MDT\n");
3581 } else if (strcmp(ptr, "no") == 0) {
3582 clear_bit(FSDB_UDESC, &fsdb->fsdb_flags);
3583 CWARN("Disable user descriptor shipping from client to MDT\n");
3591 CERROR("Invalid param: %s\n", param);
3595 static int mgs_srpc_set_param_mem(struct fs_db *fsdb,
3599 struct sptlrpc_rule rule;
3600 struct sptlrpc_rule_set *rset;
3604 if (strncmp(param, PARAM_SRPC, sizeof(PARAM_SRPC) - 1) != 0) {
3605 CERROR("Invalid sptlrpc parameter: %s\n", param);
3609 if (strncmp(param, PARAM_SRPC_UDESC,
3610 sizeof(PARAM_SRPC_UDESC) - 1) == 0) {
3611 RETURN(mgs_srpc_set_param_udesc_mem(fsdb, param));
3614 if (strncmp(param, PARAM_SRPC_FLVR, sizeof(PARAM_SRPC_FLVR) - 1) != 0) {
3615 CERROR("Invalid sptlrpc flavor parameter: %s\n", param);
3619 param += sizeof(PARAM_SRPC_FLVR) - 1;
3621 rc = sptlrpc_parse_rule(param, &rule);
3625 /* mgs rules implies must be mgc->mgs */
3626 if (test_bit(FSDB_MGS_SELF, &fsdb->fsdb_flags)) {
3627 if ((rule.sr_from != LUSTRE_SP_MGC &&
3628 rule.sr_from != LUSTRE_SP_ANY) ||
3629 (rule.sr_to != LUSTRE_SP_MGS &&
3630 rule.sr_to != LUSTRE_SP_ANY))
3634 /* preapre room for this coming rule. svcname format should be:
3635 * - fsname: general rule
3636 * - fsname-tgtname: target-specific rule
3638 if (strchr(svname, '-')) {
3639 struct mgs_tgt_srpc_conf *tgtconf;
3642 for (tgtconf = fsdb->fsdb_srpc_tgt; tgtconf != NULL;
3643 tgtconf = tgtconf->mtsc_next) {
3644 if (!strcmp(tgtconf->mtsc_tgt, svname)) {
3653 OBD_ALLOC_PTR(tgtconf);
3654 if (tgtconf == NULL)
3657 name_len = strlen(svname);
3659 OBD_ALLOC(tgtconf->mtsc_tgt, name_len + 1);
3660 if (tgtconf->mtsc_tgt == NULL) {
3661 OBD_FREE_PTR(tgtconf);
3664 memcpy(tgtconf->mtsc_tgt, svname, name_len);
3666 tgtconf->mtsc_next = fsdb->fsdb_srpc_tgt;
3667 fsdb->fsdb_srpc_tgt = tgtconf;
3670 rset = &tgtconf->mtsc_rset;
3671 } else if (strcmp(svname, MGSSELF_NAME) == 0) {
3672 /* put _mgs related srpc rule directly in mgs ruleset */
3673 rset = &fsdb->fsdb_mgs->mgs_lut.lut_sptlrpc_rset;
3675 rset = &fsdb->fsdb_srpc_gen;
3678 rc = sptlrpc_rule_set_merge(rset, &rule);
3683 static int mgs_srpc_set_param(const struct lu_env *env,
3684 struct mgs_device *mgs,
3686 struct mgs_target_info *mti,
3696 /* keep a copy of original param, which could be destroied
3698 copy_size = strlen(param) + 1;
3699 OBD_ALLOC(copy, copy_size);
3702 memcpy(copy, param, copy_size);
3704 rc = mgs_srpc_set_param_mem(fsdb, mti->mti_svname, param);
3708 /* previous steps guaranteed the syntax is correct */
3709 rc = mgs_srpc_set_param_disk(env, mgs, fsdb, mti, copy);
3713 if (test_bit(FSDB_MGS_SELF, &fsdb->fsdb_flags)) {
3715 * for mgs rules, make them effective immediately.
3717 LASSERT(fsdb->fsdb_srpc_tgt == NULL);
3718 sptlrpc_target_update_exp_flavor(mgs->mgs_obd,
3719 &fsdb->fsdb_srpc_gen);
3723 OBD_FREE(copy, copy_size);
3727 struct mgs_srpc_read_data {
3728 struct fs_db *msrd_fsdb;
3732 static int mgs_srpc_read_handler(const struct lu_env *env,
3733 struct llog_handle *llh,
3734 struct llog_rec_hdr *rec, void *data)
3736 struct mgs_srpc_read_data *msrd = data;
3737 struct cfg_marker *marker;
3738 struct lustre_cfg *lcfg = REC_DATA(rec);
3739 char *svname, *param;
3743 if (rec->lrh_type != OBD_CFG_REC) {
3744 CERROR("unhandled lrh_type: %#x\n", rec->lrh_type);
3748 cfg_len = REC_DATA_LEN(rec);
3750 rc = lustre_cfg_sanity_check(lcfg, cfg_len);
3752 CERROR("Insane cfg\n");
3756 if (lcfg->lcfg_command == LCFG_MARKER) {
3757 marker = lustre_cfg_buf(lcfg, 1);
3759 if (marker->cm_flags & CM_START &&
3760 marker->cm_flags & CM_SKIP)
3761 msrd->msrd_skip = 1;
3762 if (marker->cm_flags & CM_END)
3763 msrd->msrd_skip = 0;
3768 if (msrd->msrd_skip)
3771 if (lcfg->lcfg_command != LCFG_SPTLRPC_CONF) {
3772 CERROR("invalid command (%x)\n", lcfg->lcfg_command);
3776 svname = lustre_cfg_string(lcfg, 0);
3777 if (svname == NULL) {
3778 CERROR("svname is empty\n");
3782 param = lustre_cfg_string(lcfg, 1);
3783 if (param == NULL) {
3784 CERROR("param is empty\n");
3788 rc = mgs_srpc_set_param_mem(msrd->msrd_fsdb, svname, param);
3790 CERROR("read sptlrpc record error (%d): %s\n", rc, param);
3795 int mgs_get_fsdb_srpc_from_llog(const struct lu_env *env,
3796 struct mgs_device *mgs,
3799 struct llog_handle *llh = NULL;
3800 struct llog_ctxt *ctxt;
3802 struct mgs_srpc_read_data msrd;
3806 /* construct log name */
3807 rc = name_create(&logname, fsdb->fsdb_name, "-sptlrpc");
3811 ctxt = llog_get_context(mgs->mgs_obd, LLOG_CONFIG_ORIG_CTXT);
3812 LASSERT(ctxt != NULL);
3814 if (mgs_log_is_empty(env, mgs, logname))
3817 rc = llog_open(env, ctxt, &llh, NULL, logname,
3825 rc = llog_init_handle(env, llh, LLOG_F_IS_PLAIN, NULL);
3827 GOTO(out_close, rc);
3829 if (llog_get_size(llh) <= 1)
3830 GOTO(out_close, rc = 0);
3832 msrd.msrd_fsdb = fsdb;
3835 rc = llog_process(env, llh, mgs_srpc_read_handler, (void *)&msrd,
3839 llog_close(env, llh);
3841 llog_ctxt_put(ctxt);
3842 name_destroy(&logname);
3845 CERROR("failed to read sptlrpc config database: %d\n", rc);
3849 static int mgs_write_log_param2(const struct lu_env *env,
3850 struct mgs_device *mgs,
3852 struct mgs_target_info *mti, char *ptr)
3854 struct lustre_cfg_bufs bufs;
3858 CDEBUG(D_MGS, "next param '%s'\n", ptr);
3860 /* PARAM_MGSNODE and PARAM_NETWORK are set only when formating
3861 * or during the inital mount. It can never change after that.
3863 if (!class_match_param(ptr, PARAM_MGSNODE, NULL) ||
3864 !class_match_param(ptr, PARAM_NETWORK, NULL)) {
3869 /* Processed in mgs_write_log_ost. Another value that can't
3870 * be changed by lctl set_param -P.
3872 if (!class_match_param(ptr, PARAM_FAILMODE, NULL)) {
3873 LCONSOLE_ERROR_MSG(0x169,
3874 "%s can only be changed with tunefs.lustre and --writeconf\n",
3880 /* FIXME !!! Support for sptlrpc is incomplete. Currently the change
3881 * doesn't transmit to the client. See LU-7183.
3883 if (!class_match_param(ptr, PARAM_SRPC, NULL)) {
3884 rc = mgs_srpc_set_param(env, mgs, fsdb, mti, ptr);
3888 /* Can't use class_match_param since ptr doesn't start with
3889 * PARAM_FAILNODE. So we look for PARAM_FAILNODE contained in ptr.
3891 if (strstr(ptr, PARAM_FAILNODE)) {
3892 /* Add a failover nidlist. We already processed failovers
3893 * params for new targets in mgs_write_log_target.
3897 /* can't use wildcards with failover.node */
3898 if (strchr(ptr, '*')) {
3903 param = strstr(ptr, PARAM_FAILNODE);
3904 if (strlcpy(mti->mti_params, param, sizeof(mti->mti_params)) >=
3905 sizeof(mti->mti_params)) {
3910 CDEBUG(D_MGS, "Adding failnode with param %s\n",
3912 rc = mgs_write_log_add_failnid(env, mgs, fsdb, mti);
3916 rc = mgs_wlp_lcfg(env, mgs, fsdb, mti, PARAMS_FILENAME, &bufs,
3917 mti->mti_svname, ptr);
3922 /* Permanent settings of all parameters by writing into the appropriate
3923 * configuration logs.
3924 * A parameter with null value ("<param>='\0'") means to erase it out of
3927 static int mgs_write_log_param(const struct lu_env *env,
3928 struct mgs_device *mgs, struct fs_db *fsdb,
3929 struct mgs_target_info *mti, char *ptr)
3931 struct mgs_thread_info *mgi = mgs_env_info(env);
3937 /* For various parameter settings, we have to figure out which logs
3938 care about them (e.g. both mdt and client for lov settings) */
3939 CDEBUG(D_MGS, "next param '%s'\n", ptr);
3941 /* The params are stored in MOUNT_DATA_FILE and modified via
3942 tunefs.lustre, or set using lctl conf_param */
3944 /* Processed in lustre_start_mgc */
3945 if (class_match_param(ptr, PARAM_MGSNODE, NULL) == 0)
3948 /* Processed in ost/mdt */
3949 if (class_match_param(ptr, PARAM_NETWORK, NULL) == 0)
3952 /* Processed in mgs_write_log_ost */
3953 if (class_match_param(ptr, PARAM_FAILMODE, NULL) == 0) {
3954 if (mti->mti_flags & LDD_F_PARAM) {
3955 LCONSOLE_ERROR_MSG(0x169,
3956 "%s can only be changed with tunefs.lustre and --writeconf\n",
3963 if (class_match_param(ptr, PARAM_SRPC, NULL) == 0) {
3964 rc = mgs_srpc_set_param(env, mgs, fsdb, mti, ptr);
3968 if (class_match_param(ptr, PARAM_FAILNODE, NULL) == 0) {
3969 /* Add a failover nidlist */
3971 /* We already processed failovers params for new
3972 targets in mgs_write_log_target */
3973 if (mti->mti_flags & LDD_F_PARAM) {
3974 CDEBUG(D_MGS, "Adding failnode\n");
3975 rc = mgs_write_log_add_failnid(env, mgs, fsdb, mti);
3980 if (class_match_param(ptr, PARAM_SYS, &tmp) == 0) {
3981 rc = mgs_write_log_sys(env, mgs, fsdb, mti, ptr, tmp);
3985 if (class_match_param(ptr, PARAM_QUOTA, &tmp) == 0) {
3986 rc = mgs_write_log_quota(env, mgs, fsdb, mti, ptr, tmp);
3990 if (class_match_param(ptr, PARAM_OSC PARAM_ACTIVE, &tmp) == 0 ||
3991 class_match_param(ptr, PARAM_MDC PARAM_ACTIVE, &tmp) == 0) {
3992 /* active=0 means off, anything else means on */
3993 int flag = (*tmp == '0') ? CM_EXCLUDE : 0;
3994 bool deactive_osc = memcmp(ptr, PARAM_OSC PARAM_ACTIVE,
3995 strlen(PARAM_OSC PARAM_ACTIVE)) == 0;
3998 if (!deactive_osc) {
4001 rc = server_name2index(mti->mti_svname, &index, NULL);
4006 LCONSOLE_ERROR_MSG(0x144, "%s: MDC0 can not be"
4007 " (de)activated.\n",
4009 GOTO(end, rc = -EPERM);
4013 LCONSOLE_WARN("Permanently %sactivating %s\n",
4014 flag ? "de" : "re", mti->mti_svname);
4016 rc = name_create(&logname, mti->mti_fsname, "-client");
4019 rc = mgs_modify(env, mgs, fsdb, mti, logname,
4021 deactive_osc ? "add osc" : "add mdc", flag);
4022 name_destroy(&logname);
4027 /* Add to all MDT logs for DNE */
4028 for (i = 0; i < INDEX_MAP_SIZE * 8; i++) {
4029 if (!test_bit(i, fsdb->fsdb_mdt_index_map))
4031 rc = name_create_mdt(&logname, mti->mti_fsname, i);
4034 rc = mgs_modify(env, mgs, fsdb, mti, logname,
4036 deactive_osc ? "add osc" : "add osp",
4038 name_destroy(&logname);
4044 LCONSOLE_ERROR_MSG(0x145,
4045 "Couldn't find %s in log (%d). No permanent changes were made to the config log.\n",
4046 mti->mti_svname, rc);
4047 if (test_bit(FSDB_OLDLOG14, &fsdb->fsdb_flags))
4048 LCONSOLE_ERROR_MSG(0x146,
4049 "This may be because the log is in the old 1.4 style. Consider --writeconf to update the logs.\n");
4052 /* Fall through to osc/mdc proc for deactivating live
4053 OSC/OSP on running MDT / clients. */
4055 /* Below here, let obd's XXX_process_config methods handle it */
4057 /* All lov. in proc */
4058 if (class_match_param(ptr, PARAM_LOV, NULL) == 0) {
4061 CDEBUG(D_MGS, "lov param %s\n", ptr);
4062 if (!(mti->mti_flags & LDD_F_SV_TYPE_MDT)) {
4063 LCONSOLE_ERROR_MSG(0x147, "LOV params must be "
4064 "set on the MDT, not %s. "
4071 if (mgs_log_is_empty(env, mgs, mti->mti_svname))
4072 GOTO(end, rc = -ENODEV);
4074 rc = name_create_mdt_and_lov(&logname, &mdtlovname, fsdb,
4075 mti->mti_stripe_index);
4078 rc = mgs_wlp_lcfg(env, mgs, fsdb, mti, mti->mti_svname,
4079 &mgi->mgi_bufs, mdtlovname, ptr);
4080 name_destroy(&logname);
4081 name_destroy(&mdtlovname);
4086 rc = name_create(&logname, mti->mti_fsname, "-client");
4089 rc = mgs_wlp_lcfg(env, mgs, fsdb, mti, logname, &mgi->mgi_bufs,
4090 fsdb->fsdb_clilov, ptr);
4091 name_destroy(&logname);
4095 /* All osc., mdc., llite. params in proc */
4096 if ((class_match_param(ptr, PARAM_OSC, NULL) == 0) ||
4097 (class_match_param(ptr, PARAM_MDC, NULL) == 0) ||
4098 (class_match_param(ptr, PARAM_LLITE, NULL) == 0)) {
4101 if (test_bit(FSDB_OLDLOG14, &fsdb->fsdb_flags)) {
4102 LCONSOLE_ERROR_MSG(0x148, "Upgraded client logs for %s"
4103 " cannot be modified. Consider"
4104 " updating the configuration with"
4107 GOTO(end, rc = -EINVAL);
4109 if (memcmp(ptr, PARAM_LLITE, strlen(PARAM_LLITE)) == 0) {
4110 rc = name_create(&cname, mti->mti_fsname, "-client");
4111 /* Add the client type to match the obdname in
4112 class_config_llog_handler */
4113 } else if (mti->mti_flags & LDD_F_SV_TYPE_MDT) {
4114 rc = name_create(&cname, mti->mti_svname, "-mdc");
4115 } else if (mti->mti_flags & LDD_F_SV_TYPE_OST) {
4116 rc = name_create(&cname, mti->mti_svname, "-osc");
4118 GOTO(end, rc = -EINVAL);
4123 /* Forbid direct update of llite root squash parameters.
4124 * These parameters are indirectly set via the MDT settings.
4126 if ((class_match_param(ptr, PARAM_LLITE, &tmp) == 0) &&
4127 ((memcmp(tmp, "root_squash=", 12) == 0) ||
4128 (memcmp(tmp, "nosquash_nids=", 14) == 0))) {
4129 LCONSOLE_ERROR("%s: root squash parameters can only "
4130 "be updated through MDT component\n",
4132 name_destroy(&cname);
4133 GOTO(end, rc = -EINVAL);
4136 CDEBUG(D_MGS, "%.3s param %s\n", ptr, ptr + 4);
4139 rc = name_create(&logname, mti->mti_fsname, "-client");
4141 name_destroy(&cname);
4144 rc = mgs_wlp_lcfg(env, mgs, fsdb, mti, logname, &mgi->mgi_bufs,
4147 /* osc params affect the MDT as well */
4148 if (!rc && (mti->mti_flags & LDD_F_SV_TYPE_OST)) {
4151 for (i = 0; i < INDEX_MAP_SIZE * 8; i++){
4152 if (!test_bit(i, fsdb->fsdb_mdt_index_map))
4154 name_destroy(&cname);
4155 rc = name_create_mdt_osc(&cname, mti->mti_svname,
4157 name_destroy(&logname);
4160 rc = name_create_mdt(&logname,
4161 mti->mti_fsname, i);
4164 if (!mgs_log_is_empty(env, mgs, logname)) {
4165 rc = mgs_wlp_lcfg(env, mgs, fsdb,
4175 /* For mdc activate/deactivate, it affects OSP on MDT as well */
4176 if (class_match_param(ptr, PARAM_MDC PARAM_ACTIVE, &tmp) == 0 &&
4179 char *lodname = NULL;
4180 char *param_str = NULL;
4184 /* replace mdc with osp */
4185 memcpy(ptr, PARAM_OSP, strlen(PARAM_OSP));
4186 rc = server_name2index(mti->mti_svname, &index, NULL);
4188 memcpy(ptr, PARAM_MDC, strlen(PARAM_MDC));
4192 for (i = 0; i < INDEX_MAP_SIZE * 8; i++) {
4193 if (!test_bit(i, fsdb->fsdb_mdt_index_map))
4199 name_destroy(&logname);
4200 rc = name_create_mdt(&logname, mti->mti_fsname,
4205 if (mgs_log_is_empty(env, mgs, logname))
4208 snprintf(suffix, sizeof(suffix), "-osp-MDT%04x",
4210 name_destroy(&cname);
4211 rc = name_create(&cname, mti->mti_svname,
4216 rc = mgs_wlp_lcfg(env, mgs, fsdb, mti, logname,
4217 &mgi->mgi_bufs, cname, ptr);
4221 /* Add configuration log for noitfying LOD
4222 * to active/deactive the OSP. */
4223 name_destroy(¶m_str);
4224 rc = name_create(¶m_str, cname,
4225 (*tmp == '0') ? ".active=0" :
4230 name_destroy(&lodname);
4231 rc = name_create(&lodname, logname, "-mdtlov");
4235 rc = mgs_wlp_lcfg(env, mgs, fsdb, mti, logname,
4236 &mgi->mgi_bufs, lodname,
4241 memcpy(ptr, PARAM_MDC, strlen(PARAM_MDC));
4242 name_destroy(&lodname);
4243 name_destroy(¶m_str);
4246 name_destroy(&logname);
4247 name_destroy(&cname);
4251 /* All mdt. params in proc */
4252 if (class_match_param(ptr, PARAM_MDT, &tmp) == 0) {
4256 CDEBUG(D_MGS, "%.3s param %s\n", ptr, ptr + 4);
4257 if (strncmp(mti->mti_svname, mti->mti_fsname,
4258 MTI_NAME_MAXLEN) == 0)
4259 /* device is unspecified completely? */
4260 rc = LDD_F_SV_TYPE_MDT | LDD_F_SV_ALL;
4262 rc = server_name2index(mti->mti_svname, &idx, NULL);
4265 if ((rc & LDD_F_SV_TYPE_MDT) == 0)
4267 if (rc & LDD_F_SV_ALL) {
4268 for (i = 0; i < INDEX_MAP_SIZE * 8; i++) {
4270 fsdb->fsdb_mdt_index_map))
4272 rc = name_create_mdt(&logname,
4273 mti->mti_fsname, i);
4276 rc = mgs_wlp_lcfg(env, mgs, fsdb, mti,
4277 logname, &mgi->mgi_bufs,
4279 name_destroy(&logname);
4284 if ((memcmp(tmp, "root_squash=", 12) == 0) ||
4285 (memcmp(tmp, "nosquash_nids=", 14) == 0)) {
4286 LCONSOLE_ERROR("%s: root squash parameters "
4287 "cannot be applied to a single MDT\n",
4289 GOTO(end, rc = -EINVAL);
4291 rc = mgs_wlp_lcfg(env, mgs, fsdb, mti,
4292 mti->mti_svname, &mgi->mgi_bufs,
4293 mti->mti_svname, ptr);
4298 /* root squash settings are also applied to llite
4299 * config log (see LU-1778) */
4301 ((memcmp(tmp, "root_squash=", 12) == 0) ||
4302 (memcmp(tmp, "nosquash_nids=", 14) == 0))) {
4306 rc = name_create(&cname, mti->mti_fsname, "-client");
4309 rc = name_create(&logname, mti->mti_fsname, "-client");
4311 name_destroy(&cname);
4314 rc = name_create(&ptr2, PARAM_LLITE, tmp);
4316 name_destroy(&cname);
4317 name_destroy(&logname);
4320 rc = mgs_wlp_lcfg(env, mgs, fsdb, mti, logname,
4321 &mgi->mgi_bufs, cname, ptr2);
4322 name_destroy(&ptr2);
4323 name_destroy(&logname);
4324 name_destroy(&cname);
4329 /* All mdd., ost. and osd. params in proc */
4330 if ((class_match_param(ptr, PARAM_MDD, NULL) == 0) ||
4331 (class_match_param(ptr, PARAM_LOD, NULL) == 0) ||
4332 (class_match_param(ptr, PARAM_OST, NULL) == 0) ||
4333 (class_match_param(ptr, PARAM_OSD, NULL) == 0)) {
4334 CDEBUG(D_MGS, "%.3s param %s\n", ptr, ptr + 4);
4335 if (mgs_log_is_empty(env, mgs, mti->mti_svname))
4336 GOTO(end, rc = -ENODEV);
4338 rc = mgs_wlp_lcfg(env, mgs, fsdb, mti, mti->mti_svname,
4339 &mgi->mgi_bufs, mti->mti_svname, ptr);
4343 LCONSOLE_WARN("Ignoring unrecognized param '%s'\n", ptr);
4347 CERROR("err %d on param '%s'\n", rc, ptr);
4352 int mgs_write_log_target(const struct lu_env *env, struct mgs_device *mgs,
4353 struct mgs_target_info *mti, struct fs_db *fsdb)
4360 /* set/check the new target index */
4361 rc = mgs_set_index(env, mgs, mti);
4365 if (rc == EALREADY) {
4366 LCONSOLE_WARN("Found index %d for %s, updating log\n",
4367 mti->mti_stripe_index, mti->mti_svname);
4368 /* We would like to mark old log sections as invalid
4369 and add new log sections in the client and mdt logs.
4370 But if we add new sections, then live clients will
4371 get repeat setup instructions for already running
4372 osc's. So don't update the client/mdt logs. */
4373 mti->mti_flags &= ~LDD_F_UPDATE;
4377 OBD_FAIL_TIMEOUT(OBD_FAIL_MGS_WRITE_TARGET_DELAY, cfs_fail_val > 0 ?
4380 mutex_lock(&fsdb->fsdb_mutex);
4382 if (mti->mti_flags & (LDD_F_VIRGIN | LDD_F_WRITECONF)) {
4383 /* Generate a log from scratch */
4384 if (mti->mti_flags & LDD_F_SV_TYPE_MDT) {
4385 rc = mgs_write_log_mdt(env, mgs, fsdb, mti);
4386 } else if (mti->mti_flags & LDD_F_SV_TYPE_OST) {
4387 rc = mgs_write_log_ost(env, mgs, fsdb, mti);
4389 CERROR("Unknown target type %#x, can't create log for %s\n",
4390 mti->mti_flags, mti->mti_svname);
4393 CERROR("Can't write logs for %s (%d)\n",
4394 mti->mti_svname, rc);
4398 /* Just update the params from tunefs in mgs_write_log_params */
4399 CDEBUG(D_MGS, "Update params for %s\n", mti->mti_svname);
4400 mti->mti_flags |= LDD_F_PARAM;
4403 /* allocate temporary buffer, where class_get_next_param will
4404 make copy of a current parameter */
4405 OBD_ALLOC(buf, strlen(mti->mti_params) + 1);
4407 GOTO(out_up, rc = -ENOMEM);
4408 params = mti->mti_params;
4409 while (params != NULL) {
4410 rc = class_get_next_param(¶ms, buf);
4413 /* there is no next parameter, that is
4418 CDEBUG(D_MGS, "remaining string: '%s', param: '%s'\n",
4420 rc = mgs_write_log_param(env, mgs, fsdb, mti, buf);
4425 OBD_FREE(buf, strlen(mti->mti_params) + 1);
4428 mutex_unlock(&fsdb->fsdb_mutex);
4432 int mgs_erase_log(const struct lu_env *env, struct mgs_device *mgs, char *name)
4434 struct llog_ctxt *ctxt;
4437 ctxt = llog_get_context(mgs->mgs_obd, LLOG_CONFIG_ORIG_CTXT);
4439 CERROR("%s: MGS config context doesn't exist\n",
4440 mgs->mgs_obd->obd_name);
4443 rc = llog_erase(env, ctxt, NULL, name);
4444 /* llog may not exist */
4447 llog_ctxt_put(ctxt);
4451 CERROR("%s: failed to clear log %s: %d\n",
4452 mgs->mgs_obd->obd_name, name, rc);
4457 /* erase all logs for the given fs */
4458 int mgs_erase_logs(const struct lu_env *env, struct mgs_device *mgs,
4461 struct list_head log_list;
4462 struct mgs_direntry *dirent, *n;
4463 char barrier_name[20] = {};
4466 int rc, len = strlen(fsname);
4469 mutex_lock(&mgs->mgs_mutex);
4471 /* Find all the logs in the CONFIGS directory */
4472 rc = class_dentry_readdir(env, mgs, &log_list);
4474 mutex_unlock(&mgs->mgs_mutex);
4478 if (list_empty(&log_list)) {
4479 mutex_unlock(&mgs->mgs_mutex);
4483 snprintf(barrier_name, sizeof(barrier_name) - 1, "%s-%s",
4484 fsname, BARRIER_FILENAME);
4485 /* Delete the barrier fsdb */
4486 mgs_remove_fsdb_by_name(mgs, barrier_name);
4487 /* Delete the fs db */
4488 mgs_remove_fsdb_by_name(mgs, fsname);
4489 mutex_unlock(&mgs->mgs_mutex);
4491 list_for_each_entry_safe(dirent, n, &log_list, mde_list) {
4492 list_del_init(&dirent->mde_list);
4493 suffix = strrchr(dirent->mde_name, '-');
4494 if (suffix != NULL) {
4495 if ((len == suffix - dirent->mde_name) &&
4496 (strncmp(fsname, dirent->mde_name, len) == 0)) {
4497 CDEBUG(D_MGS, "Removing log %s\n",
4499 mgs_erase_log(env, mgs, dirent->mde_name);
4503 mgs_direntry_free(dirent);
4512 /* list all logs for the given fs */
4513 int mgs_list_logs(const struct lu_env *env, struct mgs_device *mgs,
4514 struct obd_ioctl_data *data)
4516 struct list_head log_list;
4517 struct mgs_direntry *dirent, *n;
4518 char *out, *suffix, prefix[] = "config_log: ";
4519 int prefix_len = strlen(prefix);
4520 int len, remains, start = 0, rc;
4524 /* Find all the logs in the CONFIGS directory */
4525 rc = class_dentry_readdir(env, mgs, &log_list);
4529 out = data->ioc_bulk;
4530 remains = data->ioc_inllen1;
4531 /* OBD_FAIL: fetch the config_log records from the specified one */
4532 if (OBD_FAIL_CHECK(OBD_FAIL_CATLIST))
4533 data->ioc_count = cfs_fail_val;
4535 list_for_each_entry_safe(dirent, n, &log_list, mde_list) {
4536 list_del_init(&dirent->mde_list);
4537 suffix = strrchr(dirent->mde_name, '-');
4538 if (suffix != NULL) {
4539 len = prefix_len + dirent->mde_len + 1;
4540 if (remains - len < 0) {
4541 /* No enough space for this record */
4542 mgs_direntry_free(dirent);
4546 if (start < data->ioc_count) {
4547 mgs_direntry_free(dirent);
4550 len = scnprintf(out, remains, "%s%s\n", prefix,
4555 mgs_direntry_free(dirent);
4563 data->ioc_count = start;
4567 struct mgs_lcfg_fork_data {
4568 struct lustre_cfg_bufs mlfd_bufs;
4569 struct mgs_device *mlfd_mgs;
4570 struct llog_handle *mlfd_llh;
4571 const char *mlfd_oldname;
4572 const char *mlfd_newname;
4576 static bool contain_valid_fsname(char *buf, const char *fsname,
4577 int buflen, int namelen)
4579 if (buflen < namelen)
4582 if (memcmp(buf, fsname, namelen) != 0)
4585 if (buf[namelen] != '\0' && buf[namelen] != '-')
4591 static int mgs_lcfg_fork_handler(const struct lu_env *env,
4592 struct llog_handle *o_llh,
4593 struct llog_rec_hdr *o_rec, void *data)
4595 struct mgs_lcfg_fork_data *mlfd = data;
4596 struct lustre_cfg_bufs *n_bufs = &mlfd->mlfd_bufs;
4597 struct lustre_cfg *o_lcfg = (struct lustre_cfg *)(o_rec + 1);
4598 struct llog_cfg_rec *lcr;
4600 char *n_buf = mlfd->mlfd_data;
4602 int o_namelen = strlen(mlfd->mlfd_oldname);
4603 int n_namelen = strlen(mlfd->mlfd_newname);
4604 int diff = n_namelen - o_namelen;
4605 __u32 cmd = o_lcfg->lcfg_command;
4606 __u32 cnt = o_lcfg->lcfg_bufcount;
4612 o_buf = lustre_cfg_buf(o_lcfg, 0);
4613 o_buflen = o_lcfg->lcfg_buflens[0];
4614 if (contain_valid_fsname(o_buf, mlfd->mlfd_oldname, o_buflen,
4616 memcpy(n_buf, mlfd->mlfd_newname, n_namelen);
4617 memcpy(n_buf + n_namelen, o_buf + o_namelen,
4618 o_buflen - o_namelen);
4619 lustre_cfg_bufs_reset(n_bufs, n_buf);
4620 n_buf += cfs_size_round(o_buflen + diff);
4622 lustre_cfg_bufs_reset(n_bufs, o_buflen != 0 ? o_buf : NULL);
4627 struct cfg_marker *o_marker;
4628 struct cfg_marker *n_marker;
4632 CDEBUG(D_MGS, "Unknown cfg marker entry with %d "
4637 /* buf[1] is marker */
4638 o_buf = lustre_cfg_buf(o_lcfg, 1);
4639 o_buflen = o_lcfg->lcfg_buflens[1];
4640 o_marker = (struct cfg_marker *)o_buf;
4641 if (!contain_valid_fsname(o_marker->cm_tgtname,
4643 sizeof(o_marker->cm_tgtname),
4645 lustre_cfg_bufs_set(n_bufs, 1, o_marker,
4650 n_marker = (struct cfg_marker *)n_buf;
4651 *n_marker = *o_marker;
4652 memcpy(n_marker->cm_tgtname, mlfd->mlfd_newname, n_namelen);
4653 tgt_namelen = strlen(o_marker->cm_tgtname);
4654 if (tgt_namelen > o_namelen)
4655 memcpy(n_marker->cm_tgtname + n_namelen,
4656 o_marker->cm_tgtname + o_namelen,
4657 tgt_namelen - o_namelen);
4658 n_marker->cm_tgtname[tgt_namelen + diff] = '\0';
4659 lustre_cfg_bufs_set(n_bufs, 1, n_marker, sizeof(*n_marker));
4663 case LCFG_SET_PARAM: {
4664 for (i = 1; i < cnt; i++)
4665 /* buf[i] is the param value, reuse it directly */
4666 lustre_cfg_bufs_set(n_bufs, i,
4667 lustre_cfg_buf(o_lcfg, i),
4668 o_lcfg->lcfg_buflens[i]);
4674 case LCFG_POOL_DEL: {
4675 if (cnt < 3 || cnt > 4) {
4676 CDEBUG(D_MGS, "Unknown cfg pool (%x) entry with %d "
4677 "buffers\n", cmd, cnt);
4681 /* buf[1] is fsname */
4682 o_buf = lustre_cfg_buf(o_lcfg, 1);
4683 o_buflen = o_lcfg->lcfg_buflens[1];
4684 memcpy(n_buf, mlfd->mlfd_newname, n_namelen);
4685 memcpy(n_buf + n_namelen, o_buf + o_namelen,
4686 o_buflen - o_namelen);
4687 lustre_cfg_bufs_set(n_bufs, 1, n_buf, o_buflen + diff);
4688 n_buf += cfs_size_round(o_buflen + diff);
4690 /* buf[2] is the pool name, reuse it directly */
4691 lustre_cfg_bufs_set(n_bufs, 2, lustre_cfg_buf(o_lcfg, 2),
4692 o_lcfg->lcfg_buflens[2]);
4697 /* buf[3] is ostname */
4698 o_buf = lustre_cfg_buf(o_lcfg, 3);
4699 o_buflen = o_lcfg->lcfg_buflens[3];
4700 memcpy(n_buf, mlfd->mlfd_newname, n_namelen);
4701 memcpy(n_buf + n_namelen, o_buf + o_namelen,
4702 o_buflen - o_namelen);
4703 lustre_cfg_bufs_set(n_bufs, 3, n_buf, o_buflen + diff);
4708 o_buflen = o_lcfg->lcfg_buflens[1];
4709 if (o_buflen == sizeof(struct lov_desc) ||
4710 o_buflen == sizeof(struct lmv_desc)) {
4716 o_buf = lustre_cfg_buf(o_lcfg, 1);
4717 if (o_buflen == sizeof(struct lov_desc)) {
4718 struct lov_desc *o_desc =
4719 (struct lov_desc *)o_buf;
4720 struct lov_desc *n_desc =
4721 (struct lov_desc *)n_buf;
4724 o_uuid = o_desc->ld_uuid.uuid;
4725 n_uuid = n_desc->ld_uuid.uuid;
4726 uuid_len = sizeof(o_desc->ld_uuid.uuid);
4728 struct lmv_desc *o_desc =
4729 (struct lmv_desc *)o_buf;
4730 struct lmv_desc *n_desc =
4731 (struct lmv_desc *)n_buf;
4734 o_uuid = o_desc->ld_uuid.uuid;
4735 n_uuid = n_desc->ld_uuid.uuid;
4736 uuid_len = sizeof(o_desc->ld_uuid.uuid);
4739 if (unlikely(!contain_valid_fsname(o_uuid,
4740 mlfd->mlfd_oldname, uuid_len,
4742 lustre_cfg_bufs_set(n_bufs, 1, o_buf,
4747 memcpy(n_uuid, mlfd->mlfd_newname, n_namelen);
4748 uuid_len = strlen(o_uuid);
4749 if (uuid_len > o_namelen)
4750 memcpy(n_uuid + n_namelen,
4752 uuid_len - o_namelen);
4753 n_uuid[uuid_len + diff] = '\0';
4754 lustre_cfg_bufs_set(n_bufs, 1, n_buf, o_buflen);
4756 } /* else case fall through */
4757 } /* else case fall through */
4761 for (i = 1; i < cnt; i++) {
4762 o_buflen = o_lcfg->lcfg_buflens[i];
4766 o_buf = lustre_cfg_buf(o_lcfg, i);
4767 if (!contain_valid_fsname(o_buf, mlfd->mlfd_oldname,
4768 o_buflen, o_namelen)) {
4769 lustre_cfg_bufs_set(n_bufs, i, o_buf, o_buflen);
4773 memcpy(n_buf, mlfd->mlfd_newname, n_namelen);
4774 if (o_buflen == o_namelen) {
4775 lustre_cfg_bufs_set(n_bufs, i, n_buf,
4777 n_buf += cfs_size_round(n_namelen);
4781 memcpy(n_buf + n_namelen, o_buf + o_namelen,
4782 o_buflen - o_namelen);
4783 lustre_cfg_bufs_set(n_bufs, i, n_buf, o_buflen + diff);
4784 n_buf += cfs_size_round(o_buflen + diff);
4790 lcr = lustre_cfg_rec_new(cmd, n_bufs);
4794 lcr->lcr_cfg = *o_lcfg;
4795 rc = llog_write(env, mlfd->mlfd_llh, &lcr->lcr_hdr, LLOG_NEXT_IDX);
4796 lustre_cfg_rec_free(lcr);
4801 static int mgs_lcfg_fork_one(const struct lu_env *env, struct mgs_device *mgs,
4802 struct mgs_direntry *mde, const char *oldname,
4803 const char *newname)
4805 struct llog_handle *old_llh = NULL;
4806 struct llog_handle *new_llh = NULL;
4807 struct llog_ctxt *ctxt = NULL;
4808 struct mgs_lcfg_fork_data *mlfd = NULL;
4809 char *name_buf = NULL;
4811 int old_namelen = strlen(oldname);
4812 int new_namelen = strlen(newname);
4816 name_buflen = mde->mde_len + new_namelen - old_namelen;
4817 OBD_ALLOC(name_buf, name_buflen);
4821 memcpy(name_buf, newname, new_namelen);
4822 memcpy(name_buf + new_namelen, mde->mde_name + old_namelen,
4823 mde->mde_len - old_namelen);
4825 CDEBUG(D_MGS, "Fork the config-log from %s to %s\n",
4826 mde->mde_name, name_buf);
4828 ctxt = llog_get_context(mgs->mgs_obd, LLOG_CONFIG_ORIG_CTXT);
4831 rc = llog_open_create(env, ctxt, &new_llh, NULL, name_buf);
4835 rc = llog_init_handle(env, new_llh, LLOG_F_IS_PLAIN, NULL);
4839 if (unlikely(mgs_log_is_empty(env, mgs, mde->mde_name)))
4842 rc = llog_open(env, ctxt, &old_llh, NULL, mde->mde_name,
4847 rc = llog_init_handle(env, old_llh, LLOG_F_IS_PLAIN, NULL);
4851 new_llh->lgh_hdr->llh_tgtuuid = old_llh->lgh_hdr->llh_tgtuuid;
4853 OBD_ALLOC(mlfd, LLOG_MIN_CHUNK_SIZE);
4855 GOTO(out, rc = -ENOMEM);
4857 mlfd->mlfd_mgs = mgs;
4858 mlfd->mlfd_llh = new_llh;
4859 mlfd->mlfd_oldname = oldname;
4860 mlfd->mlfd_newname = newname;
4862 rc = llog_process(env, old_llh, mgs_lcfg_fork_handler, mlfd, NULL);
4863 OBD_FREE(mlfd, LLOG_MIN_CHUNK_SIZE);
4869 llog_close(env, old_llh);
4871 llog_close(env, new_llh);
4873 OBD_FREE(name_buf, name_buflen);
4875 llog_ctxt_put(ctxt);
4880 int mgs_lcfg_fork(const struct lu_env *env, struct mgs_device *mgs,
4881 const char *oldname, const char *newname)
4883 struct list_head log_list;
4884 struct mgs_direntry *dirent, *n;
4885 int olen = strlen(oldname);
4886 int nlen = strlen(newname);
4891 if (unlikely(!oldname || oldname[0] == '\0' ||
4892 !newname || newname[0] == '\0'))
4895 if (strcmp(oldname, newname) == 0)
4898 /* lock it to prevent fork/erase/register in parallel. */
4899 mutex_lock(&mgs->mgs_mutex);
4901 rc = class_dentry_readdir(env, mgs, &log_list);
4903 mutex_unlock(&mgs->mgs_mutex);
4907 if (list_empty(&log_list)) {
4908 mutex_unlock(&mgs->mgs_mutex);
4912 list_for_each_entry_safe(dirent, n, &log_list, mde_list) {
4915 ptr = strrchr(dirent->mde_name, '-');
4917 int tlen = ptr - dirent->mde_name;
4920 strncmp(newname, dirent->mde_name, tlen) == 0)
4921 GOTO(out, rc = -EEXIST);
4924 strncmp(oldname, dirent->mde_name, tlen) == 0)
4928 list_del_init(&dirent->mde_list);
4929 mgs_direntry_free(dirent);
4932 if (list_empty(&log_list)) {
4933 mutex_unlock(&mgs->mgs_mutex);
4937 list_for_each_entry(dirent, &log_list, mde_list) {
4938 rc = mgs_lcfg_fork_one(env, mgs, dirent, oldname, newname);
4946 mutex_unlock(&mgs->mgs_mutex);
4948 list_for_each_entry_safe(dirent, n, &log_list, mde_list) {
4949 list_del_init(&dirent->mde_list);
4950 mgs_direntry_free(dirent);
4953 if (rc && count > 0)
4954 mgs_erase_logs(env, mgs, newname);
4959 int mgs_lcfg_erase(const struct lu_env *env, struct mgs_device *mgs,
4965 if (unlikely(!fsname || fsname[0] == '\0'))
4968 rc = mgs_erase_logs(env, mgs, fsname);
4973 static int mgs_xattr_del(const struct lu_env *env, struct dt_object *obj)
4975 struct dt_device *dev;
4976 struct thandle *th = NULL;
4981 dev = container_of(obj->do_lu.lo_dev, struct dt_device, dd_lu_dev);
4982 th = dt_trans_create(env, dev);
4984 RETURN(PTR_ERR(th));
4986 rc = dt_declare_xattr_del(env, obj, XATTR_TARGET_RENAME, th);
4990 rc = dt_trans_start_local(env, dev, th);
4994 dt_write_lock(env, obj, 0);
4995 rc = dt_xattr_del(env, obj, XATTR_TARGET_RENAME, th);
5000 dt_write_unlock(env, obj);
5003 dt_trans_stop(env, dev, th);
5008 int mgs_lcfg_rename(const struct lu_env *env, struct mgs_device *mgs)
5010 struct list_head log_list;
5011 struct mgs_direntry *dirent, *n;
5013 struct lu_buf buf = {
5015 .lb_len = sizeof(fsname)
5021 rc = class_dentry_readdir(env, mgs, &log_list);
5025 if (list_empty(&log_list))
5028 list_for_each_entry_safe(dirent, n, &log_list, mde_list) {
5029 struct dt_object *o = NULL;
5034 list_del_init(&dirent->mde_list);
5035 ptr = strrchr(dirent->mde_name, '-');
5039 len = ptr - dirent->mde_name;
5040 if (unlikely(len >= sizeof(oldname))) {
5041 CDEBUG(D_MGS, "Skip invalid configuration file %s\n",
5046 o = local_file_find(env, mgs->mgs_los, mgs->mgs_configs_dir,
5050 CDEBUG(D_MGS, "Fail to locate file %s: rc = %d\n",
5051 dirent->mde_name, rc);
5055 rc = dt_xattr_get(env, o, &buf, XATTR_TARGET_RENAME);
5061 "Fail to get EA for %s: rc = %d\n",
5062 dirent->mde_name, rc);
5066 if (unlikely(rc == len &&
5067 memcmp(fsname, dirent->mde_name, len) == 0)) {
5068 /* The new fsname is the same as the old one. */
5069 rc = mgs_xattr_del(env, o);
5073 memcpy(oldname, dirent->mde_name, len);
5074 oldname[len] = '\0';
5076 rc = mgs_lcfg_fork_one(env, mgs, dirent, oldname, fsname);
5077 if (rc && rc != -EEXIST) {
5078 CDEBUG(D_MGS, "Fail to fork %s: rc = %d\n",
5079 dirent->mde_name, rc);
5083 rc = mgs_erase_log(env, mgs, dirent->mde_name);
5085 CDEBUG(D_MGS, "Fail to erase old %s: rc = %d\n",
5086 dirent->mde_name, rc);
5087 /* keep it there if failed to remove it. */
5092 if (o && !IS_ERR(o))
5093 lu_object_put(env, &o->do_lu);
5095 mgs_direntry_free(dirent);
5100 list_for_each_entry_safe(dirent, n, &log_list, mde_list) {
5101 list_del_init(&dirent->mde_list);
5102 mgs_direntry_free(dirent);
5108 /* Setup _mgs fsdb and log
5110 int mgs__mgs_fsdb_setup(const struct lu_env *env, struct mgs_device *mgs)
5112 struct fs_db *fsdb = NULL;
5116 rc = mgs_find_or_make_fsdb(env, mgs, MGSSELF_NAME, &fsdb);
5118 mgs_put_fsdb(mgs, fsdb);
5123 /* Setup params fsdb and log
5125 int mgs_params_fsdb_setup(const struct lu_env *env, struct mgs_device *mgs)
5127 struct fs_db *fsdb = NULL;
5128 struct llog_handle *params_llh = NULL;
5132 rc = mgs_find_or_make_fsdb(env, mgs, PARAMS_FILENAME, &fsdb);
5134 mutex_lock(&fsdb->fsdb_mutex);
5135 rc = record_start_log(env, mgs, ¶ms_llh, PARAMS_FILENAME);
5137 rc = record_end_log(env, ¶ms_llh);
5138 mutex_unlock(&fsdb->fsdb_mutex);
5139 mgs_put_fsdb(mgs, fsdb);
5145 /* Cleanup params fsdb and log
5147 int mgs_params_fsdb_cleanup(const struct lu_env *env, struct mgs_device *mgs)
5151 rc = mgs_erase_logs(env, mgs, PARAMS_FILENAME);
5152 return rc == -ENOENT ? 0 : rc;
5156 * Fill in the mgs_target_info based on data devname and param provide.
5158 * @env thread context
5160 * @mti mgs target info. We want to set this based other paramters
5161 * passed to this function. Once setup we write it to the config
5163 * @devname optional OBD device name
5164 * @param string that contains both what tunable to set and the value to
5167 * RETURN 0 for success
5168 * negative error number on failure
5170 static int mgs_set_conf_param(const struct lu_env *env, struct mgs_device *mgs,
5171 struct mgs_target_info *mti, const char *devname,
5174 struct fs_db *fsdb = NULL;
5179 /* lustre, lustre-mdtlov, lustre-client, lustre-MDT0000 */
5183 /* We have two possible cases here:
5185 * 1) the device name embedded in the param:
5186 * lustre-OST0000.osc.max_dirty_mb=32
5188 * 2) the file system name is embedded in
5189 * the param: lustre.sys.at.min=0
5191 len = strcspn(param, ".=");
5192 if (!len || param[len] == '=')
5195 if (len >= sizeof(mti->mti_svname))
5198 snprintf(mti->mti_svname, sizeof(mti->mti_svname),
5199 "%.*s", (int)len, param);
5202 if (strlcpy(mti->mti_svname, devname, sizeof(mti->mti_svname)) >=
5203 sizeof(mti->mti_svname))
5207 if (!strlen(mti->mti_svname)) {
5208 LCONSOLE_ERROR_MSG(0x14d, "No target specified: %s\n", param);
5212 dev_type = mgs_parse_devname(mti->mti_svname, mti->mti_fsname,
5213 &mti->mti_stripe_index);
5215 /* For this case we have an invalid obd device name */
5217 CDEBUG(D_MGS, "%s don't contain an index\n", mti->mti_svname);
5218 strlcpy(mti->mti_fsname, mti->mti_svname, MTI_NAME_MAXLEN);
5221 /* Not an obd device, assume devname is the fsname.
5222 * User might of only provided fsname and not obd device
5225 CDEBUG(D_MGS, "%s is seen as a file system name\n", mti->mti_svname);
5226 strlcpy(mti->mti_fsname, mti->mti_svname, MTI_NAME_MAXLEN);
5231 GOTO(out, rc = dev_type);
5233 /* param related to llite isn't allowed to set by OST or MDT */
5234 if (dev_type & LDD_F_SV_TYPE_OST ||
5235 dev_type & LDD_F_SV_TYPE_MDT) {
5236 /* param related to llite isn't allowed to set by OST
5239 if (!strncmp(param, PARAM_LLITE,
5240 sizeof(PARAM_LLITE) - 1))
5241 GOTO(out, rc = -EINVAL);
5243 /* Strip -osc or -mdc suffix from svname */
5244 if (server_make_name(dev_type, mti->mti_stripe_index,
5245 mti->mti_fsname, mti->mti_svname,
5246 sizeof(mti->mti_svname)))
5247 GOTO(out, rc = -EINVAL);
5252 if (strlcpy(mti->mti_params, param, sizeof(mti->mti_params)) >=
5253 sizeof(mti->mti_params))
5254 GOTO(out, rc = -E2BIG);
5256 CDEBUG(D_MGS, "set_conf_param fs='%s' device='%s' param='%s'\n",
5257 mti->mti_fsname, mti->mti_svname, mti->mti_params);
5259 rc = mgs_find_or_make_fsdb(env, mgs, mti->mti_fsname, &fsdb);
5263 if (!test_bit(FSDB_MGS_SELF, &fsdb->fsdb_flags) &&
5264 test_bit(FSDB_LOG_EMPTY, &fsdb->fsdb_flags)) {
5265 CERROR("No filesystem targets for %s. cfg_device from lctl "
5266 "is '%s'\n", mti->mti_fsname, mti->mti_svname);
5267 mgs_unlink_fsdb(mgs, fsdb);
5268 GOTO(out, rc = -EINVAL);
5272 * Revoke lock so everyone updates. Should be alright if
5273 * someone was already reading while we were updating the logs,
5274 * so we don't really need to hold the lock while we're
5277 mti->mti_flags = dev_type | LDD_F_PARAM;
5278 mutex_lock(&fsdb->fsdb_mutex);
5279 rc = mgs_write_log_param(env, mgs, fsdb, mti, mti->mti_params);
5280 mutex_unlock(&fsdb->fsdb_mutex);
5281 mgs_revoke_lock(mgs, fsdb, MGS_CFG_T_CONFIG);
5285 mgs_put_fsdb(mgs, fsdb);
5290 static int mgs_set_param2(const struct lu_env *env, struct mgs_device *mgs,
5291 struct mgs_target_info *mti, const char *param)
5293 struct fs_db *fsdb = NULL;
5298 if (strlcpy(mti->mti_params, param, sizeof(mti->mti_params)) >=
5299 sizeof(mti->mti_params))
5300 GOTO(out, rc = -E2BIG);
5302 len = strcspn(param, ".=");
5303 if (len && param[len] != '=') {
5304 struct list_head *tmp;
5308 ptr = strchr(param, '.');
5310 len = strlen(param);
5313 if (len >= sizeof(mti->mti_svname))
5314 GOTO(out, rc = -E2BIG);
5316 snprintf(mti->mti_svname, sizeof(mti->mti_svname), "%.*s",
5319 mutex_lock(&mgs->mgs_mutex);
5320 if (unlikely(list_empty(&mgs->mgs_fs_db_list))) {
5321 mutex_unlock(&mgs->mgs_mutex);
5322 GOTO(out, rc = -ENODEV);
5325 list_for_each(tmp, &mgs->mgs_fs_db_list) {
5326 fsdb = list_entry(tmp, struct fs_db, fsdb_list);
5327 if (fsdb->fsdb_has_lproc_entry &&
5328 strcmp(fsdb->fsdb_name, "params") != 0 &&
5329 strstr(param, fsdb->fsdb_name)) {
5330 snprintf(mti->mti_svname,
5331 sizeof(mti->mti_svname), "%s",
5339 snprintf(mti->mti_svname, sizeof(mti->mti_svname),
5342 mutex_unlock(&mgs->mgs_mutex);
5344 snprintf(mti->mti_svname, sizeof(mti->mti_svname), "general");
5347 CDEBUG(D_MGS, "set_param2 fs='%s' device='%s' param='%s'\n",
5348 mti->mti_fsname, mti->mti_svname, mti->mti_params);
5350 /* The return value should be the device type i.e LDD_F_SV_TYPE_XXX.
5351 * A returned error tells us we don't have a target obd device.
5353 dev_type = server_name2index(mti->mti_svname, &mti->mti_stripe_index,
5358 /* the return value should be the device type i.e LDD_F_SV_TYPE_XXX.
5359 * Strip -osc or -mdc suffix from svname
5361 if ((dev_type & LDD_F_SV_TYPE_OST || dev_type & LDD_F_SV_TYPE_MDT) &&
5362 server_make_name(dev_type, mti->mti_stripe_index,
5363 mti->mti_fsname, mti->mti_svname,
5364 sizeof(mti->mti_svname)))
5365 GOTO(out, rc = -EINVAL);
5367 rc = mgs_find_or_make_fsdb(env, mgs, PARAMS_FILENAME, &fsdb);
5371 * Revoke lock so everyone updates. Should be alright if
5372 * someone was already reading while we were updating the logs,
5373 * so we don't really need to hold the lock while we're
5376 mti->mti_flags = dev_type | LDD_F_PARAM2;
5377 mutex_lock(&fsdb->fsdb_mutex);
5378 rc = mgs_write_log_param2(env, mgs, fsdb, mti, mti->mti_params);
5379 mutex_unlock(&fsdb->fsdb_mutex);
5380 mgs_revoke_lock(mgs, fsdb, MGS_CFG_T_PARAMS);
5381 mgs_put_fsdb(mgs, fsdb);
5386 /* Set a permanent (config log) param for a target or fs
5388 * @lcfg buf0 may contain the device (testfs-MDT0000) name
5389 * buf1 contains the single parameter
5391 int mgs_set_param(const struct lu_env *env, struct mgs_device *mgs,
5392 struct lustre_cfg *lcfg)
5394 const char *param = lustre_cfg_string(lcfg, 1);
5395 struct mgs_target_info *mti;
5398 /* Create a fake mti to hold everything */
5403 print_lustre_cfg(lcfg);
5405 if (lcfg->lcfg_command == LCFG_PARAM) {
5406 /* For the case of lctl conf_param devname can be
5407 * lustre, lustre-mdtlov, lustre-client, lustre-MDT0000
5409 const char *devname = lustre_cfg_string(lcfg, 0);
5411 rc = mgs_set_conf_param(env, mgs, mti, devname, param);
5413 /* In the case of lctl set_param -P lcfg[0] will always
5414 * be 'general'. At least for now.
5416 rc = mgs_set_param2(env, mgs, mti, param);
5424 static int mgs_write_log_pool(const struct lu_env *env,
5425 struct mgs_device *mgs, char *logname,
5426 struct fs_db *fsdb, char *tgtname,
5427 enum lcfg_command_type cmd,
5428 char *fsname, char *poolname,
5429 char *ostname, char *comment)
5431 struct llog_handle *llh = NULL;
5434 rc = record_start_log(env, mgs, &llh, logname);
5437 rc = record_marker(env, llh, fsdb, CM_START, tgtname, comment);
5440 rc = record_base(env, llh, tgtname, 0, cmd,
5441 fsname, poolname, ostname, NULL);
5444 rc = record_marker(env, llh, fsdb, CM_END, tgtname, comment);
5446 record_end_log(env, &llh);
5450 int mgs_nodemap_cmd(const struct lu_env *env, struct mgs_device *mgs,
5451 enum lcfg_command_type cmd, const char *nodemap_name,
5462 case LCFG_NODEMAP_ADD:
5463 rc = nodemap_add(nodemap_name);
5465 case LCFG_NODEMAP_DEL:
5466 rc = nodemap_del(nodemap_name);
5468 case LCFG_NODEMAP_ADD_RANGE:
5469 rc = nodemap_parse_range(param, nid);
5472 rc = nodemap_add_range(nodemap_name, nid);
5474 case LCFG_NODEMAP_DEL_RANGE:
5475 rc = nodemap_parse_range(param, nid);
5478 rc = nodemap_del_range(nodemap_name, nid);
5480 case LCFG_NODEMAP_ADMIN:
5481 rc = kstrtobool(param, &bool_switch);
5484 rc = nodemap_set_allow_root(nodemap_name, bool_switch);
5486 case LCFG_NODEMAP_DENY_UNKNOWN:
5487 rc = kstrtobool(param, &bool_switch);
5490 rc = nodemap_set_deny_unknown(nodemap_name, bool_switch);
5492 case LCFG_NODEMAP_AUDIT_MODE:
5493 rc = kstrtobool(param, &bool_switch);
5495 rc = nodemap_set_audit_mode(nodemap_name, bool_switch);
5497 case LCFG_NODEMAP_FORBID_ENCRYPT:
5498 rc = kstrtobool(param, &bool_switch);
5500 rc = nodemap_set_forbid_encryption(nodemap_name,
5503 case LCFG_NODEMAP_MAP_MODE:
5504 if (strcmp("both", param) == 0)
5505 rc = nodemap_set_mapping_mode(nodemap_name,
5507 else if (strcmp("uid_only", param) == 0)
5508 rc = nodemap_set_mapping_mode(nodemap_name,
5509 NODEMAP_MAP_UID_ONLY);
5510 else if (strcmp("gid_only", param) == 0)
5511 rc = nodemap_set_mapping_mode(nodemap_name,
5512 NODEMAP_MAP_GID_ONLY);
5516 case LCFG_NODEMAP_TRUSTED:
5517 rc = kstrtobool(param, &bool_switch);
5520 rc = nodemap_set_trust_client_ids(nodemap_name, bool_switch);
5522 case LCFG_NODEMAP_SQUASH_UID:
5523 rc = kstrtouint(param, 10, &int_id);
5526 rc = nodemap_set_squash_uid(nodemap_name, int_id);
5528 case LCFG_NODEMAP_SQUASH_GID:
5529 rc = kstrtouint(param, 10, &int_id);
5532 rc = nodemap_set_squash_gid(nodemap_name, int_id);
5534 case LCFG_NODEMAP_ADD_UIDMAP:
5535 case LCFG_NODEMAP_ADD_GIDMAP:
5536 rc = nodemap_parse_idmap(param, idmap);
5539 if (cmd == LCFG_NODEMAP_ADD_UIDMAP)
5540 rc = nodemap_add_idmap(nodemap_name, NODEMAP_UID,
5543 rc = nodemap_add_idmap(nodemap_name, NODEMAP_GID,
5546 case LCFG_NODEMAP_DEL_UIDMAP:
5547 case LCFG_NODEMAP_DEL_GIDMAP:
5548 rc = nodemap_parse_idmap(param, idmap);
5551 if (cmd == LCFG_NODEMAP_DEL_UIDMAP)
5552 rc = nodemap_del_idmap(nodemap_name, NODEMAP_UID,
5555 rc = nodemap_del_idmap(nodemap_name, NODEMAP_GID,
5558 case LCFG_NODEMAP_SET_FILESET:
5559 rc = nodemap_set_fileset(nodemap_name, param);
5561 case LCFG_NODEMAP_SET_SEPOL:
5562 rc = nodemap_set_sepol(nodemap_name, param);
5571 int mgs_pool_cmd(const struct lu_env *env, struct mgs_device *mgs,
5572 enum lcfg_command_type cmd, char *fsname,
5573 char *poolname, char *ostname)
5578 char *label = NULL, *canceled_label = NULL;
5580 struct mgs_target_info *mti = NULL;
5581 bool checked = false;
5582 bool locked = false;
5587 rc = mgs_find_or_make_fsdb(env, mgs, fsname, &fsdb);
5589 CERROR("Can't get db for %s\n", fsname);
5592 if (test_bit(FSDB_LOG_EMPTY, &fsdb->fsdb_flags)) {
5593 CERROR("%s is not defined\n", fsname);
5595 GOTO(out_fsdb, rc = -EINVAL);
5598 label_sz = 10 + strlen(fsname) + strlen(poolname);
5600 /* check if ostname match fsname */
5601 if (ostname != NULL) {
5604 ptr = strrchr(ostname, '-');
5605 if ((ptr == NULL) ||
5606 (strncmp(fsname, ostname, ptr-ostname) != 0))
5608 label_sz += strlen(ostname);
5611 OBD_ALLOC(label, label_sz);
5613 GOTO(out_fsdb, rc = -ENOMEM);
5618 "new %s.%s", fsname, poolname);
5622 "add %s.%s.%s", fsname, poolname, ostname);
5625 OBD_ALLOC(canceled_label, label_sz);
5626 if (canceled_label == NULL)
5627 GOTO(out_label, rc = -ENOMEM);
5629 "rem %s.%s.%s", fsname, poolname, ostname);
5630 sprintf(canceled_label,
5631 "add %s.%s.%s", fsname, poolname, ostname);
5634 OBD_ALLOC(canceled_label, label_sz);
5635 if (canceled_label == NULL)
5636 GOTO(out_label, rc = -ENOMEM);
5638 "del %s.%s", fsname, poolname);
5639 sprintf(canceled_label,
5640 "new %s.%s", fsname, poolname);
5648 GOTO(out_cancel, rc = -ENOMEM);
5649 strncpy(mti->mti_svname, "lov pool", sizeof(mti->mti_svname));
5651 mutex_lock(&fsdb->fsdb_mutex);
5653 /* write pool def to all MDT logs */
5654 for (i = 0; i < INDEX_MAP_SIZE * 8; i++) {
5655 if (test_bit(i, fsdb->fsdb_mdt_index_map)) {
5656 rc = name_create_mdt_and_lov(&logname, &lovname,
5661 if (!checked && (canceled_label == NULL)) {
5662 rc = mgs_check_marker(env, mgs, fsdb, mti,
5663 logname, lovname, label);
5665 name_destroy(&logname);
5666 name_destroy(&lovname);
5668 rc = (rc == LLOG_PROC_BREAK ?
5673 if (canceled_label != NULL)
5674 rc = mgs_modify(env, mgs, fsdb, mti, logname,
5675 lovname, canceled_label,
5679 rc = mgs_write_log_pool(env, mgs, logname,
5683 name_destroy(&logname);
5684 name_destroy(&lovname);
5690 rc = name_create(&logname, fsname, "-client");
5694 if (!checked && (canceled_label == NULL)) {
5695 rc = mgs_check_marker(env, mgs, fsdb, mti, logname,
5696 fsdb->fsdb_clilov, label);
5698 name_destroy(&logname);
5699 GOTO(out_mti, rc = (rc == LLOG_PROC_BREAK ?
5703 if (canceled_label != NULL) {
5704 rc = mgs_modify(env, mgs, fsdb, mti, logname,
5705 fsdb->fsdb_clilov, canceled_label, CM_SKIP);
5707 name_destroy(&logname);
5712 rc = mgs_write_log_pool(env, mgs, logname, fsdb, fsdb->fsdb_clilov,
5713 cmd, fsname, poolname, ostname, label);
5714 mutex_unlock(&fsdb->fsdb_mutex);
5716 name_destroy(&logname);
5717 /* request for update */
5718 mgs_revoke_lock(mgs, fsdb, MGS_CFG_T_CONFIG);
5724 mutex_unlock(&fsdb->fsdb_mutex);
5728 if (canceled_label != NULL)
5729 OBD_FREE(canceled_label, label_sz);
5731 OBD_FREE(label, label_sz);
5734 mgs_unlink_fsdb(mgs, fsdb);
5735 mgs_put_fsdb(mgs, fsdb);