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)
2245 memcpy(tmti->mti_fsname, mti->mti_fsname,
2246 strlen(mti->mti_fsname));
2247 tmti->mti_stripe_index = index;
2249 rc = mgs_write_log_osp_to_mdt(env, mgs, fsdb, tmti,
2250 mti->mti_stripe_index,
2252 memset(tmti, 0, sizeof(*tmti));
2256 if (lcfg->lcfg_command == LCFG_LOV_ADD_OBD) {
2259 char *logname, *lovname;
2261 rc = name_create_mdt_and_lov(&logname, &lovname, fsdb,
2262 mti->mti_stripe_index);
2265 sprintf(mdt_index, "-MDT%04x", mti->mti_stripe_index);
2267 if (sscanf(lustre_cfg_buf(lcfg, 2), "%d", &index) != 1) {
2268 name_destroy(&logname);
2269 name_destroy(&lovname);
2273 tmti->mti_stripe_index = index;
2274 rc = mgs_write_log_osc_to_lov(env, mgs, fsdb, tmti, logname,
2277 name_destroy(&logname);
2278 name_destroy(&lovname);
2284 /* fsdb->fsdb_mutex is already held in mgs_write_log_target*/
2285 /* stealed from mgs_get_fsdb_from_llog*/
2286 static int mgs_steal_llog_for_mdt_from_client(const struct lu_env *env,
2287 struct mgs_device *mgs,
2289 struct temp_comp* comp)
2291 struct llog_handle *loghandle;
2292 struct mgs_target_info *tmti;
2293 struct llog_ctxt *ctxt;
2298 ctxt = llog_get_context(mgs->mgs_obd, LLOG_CONFIG_ORIG_CTXT);
2299 LASSERT(ctxt != NULL);
2301 OBD_ALLOC_PTR(tmti);
2303 GOTO(out_ctxt, rc = -ENOMEM);
2305 comp->comp_tmti = tmti;
2306 comp->comp_obd = mgs->mgs_obd;
2308 rc = llog_open(env, ctxt, &loghandle, NULL, client_name,
2316 rc = llog_init_handle(env, loghandle, LLOG_F_IS_PLAIN, NULL);
2318 GOTO(out_close, rc);
2320 rc = llog_process_or_fork(env, loghandle, mgs_steal_client_llog_handler,
2321 (void *)comp, NULL, false);
2322 CDEBUG(D_MGS, "steal llog re = %d\n", rc);
2324 llog_close(env, loghandle);
2328 llog_ctxt_put(ctxt);
2332 /* lmv is the second thing for client logs */
2333 /* copied from mgs_write_log_lov. Please refer to that. */
2334 static int mgs_write_log_lmv(const struct lu_env *env,
2335 struct mgs_device *mgs,
2337 struct mgs_target_info *mti,
2338 char *logname, char *lmvname)
2340 struct llog_handle *llh = NULL;
2341 struct lmv_desc *lmvdesc;
2346 CDEBUG(D_MGS, "Writing lmv(%s) log for %s\n", lmvname,logname);
2348 OBD_ALLOC_PTR(lmvdesc);
2349 if (lmvdesc == NULL)
2351 lmvdesc->ld_active_tgt_count = 0;
2352 lmvdesc->ld_tgt_count = 0;
2353 sprintf((char*)lmvdesc->ld_uuid.uuid, "%s_UUID", lmvname);
2354 uuid = (char *)lmvdesc->ld_uuid.uuid;
2356 rc = record_start_log(env, mgs, &llh, logname);
2359 rc = record_marker(env, llh, fsdb, CM_START, lmvname, "lmv setup");
2362 rc = record_attach(env, llh, lmvname, "lmv", uuid);
2365 rc = record_lmv_setup(env, llh, lmvname, lmvdesc);
2368 rc = record_marker(env, llh, fsdb, CM_END, lmvname, "lmv setup");
2372 record_end_log(env, &llh);
2374 OBD_FREE_PTR(lmvdesc);
2378 /* lov is the first thing in the mdt and client logs */
2379 static int mgs_write_log_lov(const struct lu_env *env, struct mgs_device *mgs,
2380 struct fs_db *fsdb, struct mgs_target_info *mti,
2381 char *logname, char *lovname)
2383 struct llog_handle *llh = NULL;
2384 struct lov_desc *lovdesc;
2389 CDEBUG(D_MGS, "Writing lov(%s) log for %s\n", lovname, logname);
2392 #01 L attach 0:lov_mdsA 1:lov 2:71ccb_lov_mdsA_19f961a9e1
2393 #02 L lov_setup 0:lov_mdsA 1:(struct lov_desc)
2394 uuid=lov1_UUID, stripe count=1, size=1048576, offset=0, pattern=0
2397 /* FIXME just make lov_setup accept empty desc (put uuid in buf 2) */
2398 OBD_ALLOC_PTR(lovdesc);
2399 if (lovdesc == NULL)
2401 lovdesc->ld_magic = LOV_DESC_MAGIC;
2402 lovdesc->ld_tgt_count = 0;
2403 /* Defaults. Can be changed later by lcfg config_param */
2404 lovdesc->ld_default_stripe_count = 1;
2405 lovdesc->ld_pattern = LOV_PATTERN_RAID0;
2406 lovdesc->ld_default_stripe_size = LOV_DESC_STRIPE_SIZE_DEFAULT;
2407 lovdesc->ld_default_stripe_offset = -1;
2408 lovdesc->ld_qos_maxage = LOV_DESC_QOS_MAXAGE_DEFAULT;
2409 sprintf((char*)lovdesc->ld_uuid.uuid, "%s_UUID", lovname);
2410 /* can these be the same? */
2411 uuid = (char *)lovdesc->ld_uuid.uuid;
2413 /* This should always be the first entry in a log.
2414 rc = mgs_clear_log(obd, logname); */
2415 rc = record_start_log(env, mgs, &llh, logname);
2418 /* FIXME these should be a single journal transaction */
2419 rc = record_marker(env, llh, fsdb, CM_START, lovname, "lov setup");
2422 rc = record_attach(env, llh, lovname, "lov", uuid);
2425 rc = record_lov_setup(env, llh, lovname, lovdesc);
2428 rc = record_marker(env, llh, fsdb, CM_END, lovname, "lov setup");
2433 record_end_log(env, &llh);
2435 OBD_FREE_PTR(lovdesc);
2439 /* add failnids to open log */
2440 static int mgs_write_log_failnids(const struct lu_env *env,
2441 struct mgs_target_info *mti,
2442 struct llog_handle *llh,
2445 char *failnodeuuid = NULL;
2446 char *ptr = mti->mti_params;
2451 #03 L add_uuid nid=uml1@tcp(0x20000c0a80201) nal=90 0: 1:uml1_UUID
2452 #04 L add_uuid nid=1@elan(0x1000000000001) nal=90 0: 1:uml1_UUID
2453 #05 L setup 0:OSC_uml1_ost1_mdsA 1:ost1_UUID 2:uml1_UUID
2454 #06 L add_uuid nid=uml2@tcp(0x20000c0a80202) nal=90 0: 1:uml2_UUID
2455 #0x L add_uuid nid=2@elan(0x1000000000002) nal=90 0: 1:uml2_UUID
2456 #07 L add_conn 0:OSC_uml1_ost1_mdsA 1:uml2_UUID
2460 * Pull failnid info out of params string, which may contain something
2461 * like "<nid1>,<nid2>:<nid3>,<nid4>". class_parse_nid() does not
2462 * complain about abnormal inputs like ",:<nid1>", "<nid1>:,<nid2>",
2463 * etc. However, convert_hostnames() should have caught those.
2465 while (class_find_param(ptr, PARAM_FAILNODE, &ptr) == 0) {
2466 while (class_parse_nid(ptr, &nid, &ptr) == 0) {
2467 char nidstr[LNET_NIDSTR_SIZE];
2469 if (failnodeuuid == NULL) {
2470 /* We don't know the failover node name,
2471 * so just use the first nid as the uuid */
2472 libcfs_nid2str_r(nid, nidstr, sizeof(nidstr));
2473 rc = name_create(&failnodeuuid, nidstr, "");
2477 CDEBUG(D_MGS, "add nid %s for failover uuid %s, "
2479 libcfs_nid2str_r(nid, nidstr, sizeof(nidstr)),
2480 failnodeuuid, cliname);
2481 rc = record_add_uuid(env, llh, nid, failnodeuuid);
2483 * If *ptr is ':', we have added all NIDs for
2487 rc = record_add_conn(env, llh, cliname,
2489 name_destroy(&failnodeuuid);
2490 failnodeuuid = NULL;
2494 rc = record_add_conn(env, llh, cliname, failnodeuuid);
2495 name_destroy(&failnodeuuid);
2496 failnodeuuid = NULL;
2503 static int mgs_write_log_mdc_to_lmv(const struct lu_env *env,
2504 struct mgs_device *mgs,
2506 struct mgs_target_info *mti,
2507 char *logname, char *lmvname)
2509 struct llog_handle *llh = NULL;
2510 char *mdcname = NULL;
2511 char *nodeuuid = NULL;
2512 char *mdcuuid = NULL;
2513 char *lmvuuid = NULL;
2515 char nidstr[LNET_NIDSTR_SIZE];
2519 if (mgs_log_is_empty(env, mgs, logname)) {
2520 CERROR("log is empty! Logical error\n");
2524 CDEBUG(D_MGS, "adding mdc for %s to log %s:lmv(%s)\n",
2525 mti->mti_svname, logname, lmvname);
2527 libcfs_nid2str_r(mti->mti_nids[0], nidstr, sizeof(nidstr));
2528 rc = name_create(&nodeuuid, nidstr, "");
2531 rc = name_create(&mdcname, mti->mti_svname, "-mdc");
2534 rc = name_create(&mdcuuid, mdcname, "_UUID");
2537 rc = name_create(&lmvuuid, lmvname, "_UUID");
2541 rc = record_start_log(env, mgs, &llh, logname);
2544 rc = record_marker(env, llh, fsdb, CM_START, mti->mti_svname,
2548 for (i = 0; i < mti->mti_nid_count; i++) {
2549 CDEBUG(D_MGS, "add nid %s for mdt\n",
2550 libcfs_nid2str_r(mti->mti_nids[i],
2551 nidstr, sizeof(nidstr)));
2553 rc = record_add_uuid(env, llh, mti->mti_nids[i], nodeuuid);
2558 rc = record_attach(env, llh, mdcname, LUSTRE_MDC_NAME, lmvuuid);
2561 rc = record_setup(env, llh, mdcname, mti->mti_uuid, nodeuuid,
2565 rc = mgs_write_log_failnids(env, mti, llh, mdcname);
2568 snprintf(index, sizeof(index), "%d", mti->mti_stripe_index);
2569 rc = record_mdc_add(env, llh, lmvname, mdcuuid, mti->mti_uuid,
2573 rc = record_marker(env, llh, fsdb, CM_END, mti->mti_svname,
2578 record_end_log(env, &llh);
2580 name_destroy(&lmvuuid);
2581 name_destroy(&mdcuuid);
2582 name_destroy(&mdcname);
2583 name_destroy(&nodeuuid);
2587 static inline int name_create_lov(char **lovname, char *mdtname,
2588 struct fs_db *fsdb, int index)
2591 if (index == 0 && test_bit(FSDB_OSCNAME18, &fsdb->fsdb_flags))
2592 return name_create(lovname, fsdb->fsdb_name, "-mdtlov");
2594 return name_create(lovname, mdtname, "-mdtlov");
2597 static int name_create_mdt_and_lov(char **logname, char **lovname,
2598 struct fs_db *fsdb, int i)
2602 rc = name_create_mdt(logname, fsdb->fsdb_name, i);
2606 if (i == 0 && test_bit(FSDB_OSCNAME18, &fsdb->fsdb_flags))
2607 rc = name_create(lovname, fsdb->fsdb_name, "-mdtlov");
2609 rc = name_create(lovname, *logname, "-mdtlov");
2611 name_destroy(logname);
2617 static inline int name_create_mdt_osc(char **oscname, char *ostname,
2618 struct fs_db *fsdb, int i)
2622 if (i == 0 && test_bit(FSDB_OSCNAME18, &fsdb->fsdb_flags))
2623 sprintf(suffix, "-osc");
2625 sprintf(suffix, "-osc-MDT%04x", i);
2626 return name_create(oscname, ostname, suffix);
2629 /* add new mdc to already existent MDS */
2630 static int mgs_write_log_osp_to_mdt(const struct lu_env *env,
2631 struct mgs_device *mgs,
2633 struct mgs_target_info *mti,
2634 int mdt_index, char *logname)
2636 struct llog_handle *llh = NULL;
2637 char *nodeuuid = NULL;
2638 char *ospname = NULL;
2639 char *lovuuid = NULL;
2640 char *mdtuuid = NULL;
2641 char *svname = NULL;
2642 char *mdtname = NULL;
2643 char *lovname = NULL;
2645 char nidstr[LNET_NIDSTR_SIZE];
2649 if (mgs_log_is_empty(env, mgs, mti->mti_svname)) {
2650 CERROR("log is empty! Logical error\n");
2654 CDEBUG(D_MGS, "adding osp index %d to %s\n", mti->mti_stripe_index,
2657 rc = name_create_mdt(&mdtname, fsdb->fsdb_name, mti->mti_stripe_index);
2661 libcfs_nid2str_r(mti->mti_nids[0], nidstr, sizeof(nidstr));
2662 rc = name_create(&nodeuuid, nidstr, "");
2664 GOTO(out_destory, rc);
2666 rc = name_create(&svname, mdtname, "-osp");
2668 GOTO(out_destory, rc);
2670 sprintf(index_str, "-MDT%04x", mdt_index);
2671 rc = name_create(&ospname, svname, index_str);
2673 GOTO(out_destory, rc);
2675 rc = name_create_lov(&lovname, logname, fsdb, mdt_index);
2677 GOTO(out_destory, rc);
2679 rc = name_create(&lovuuid, lovname, "_UUID");
2681 GOTO(out_destory, rc);
2683 rc = name_create(&mdtuuid, mdtname, "_UUID");
2685 GOTO(out_destory, rc);
2687 rc = record_start_log(env, mgs, &llh, logname);
2689 GOTO(out_destory, rc);
2691 rc = record_marker(env, llh, fsdb, CM_START, mti->mti_svname,
2694 GOTO(out_destory, rc);
2696 for (i = 0; i < mti->mti_nid_count; i++) {
2697 CDEBUG(D_MGS, "add nid %s for mdt\n",
2698 libcfs_nid2str_r(mti->mti_nids[i],
2699 nidstr, sizeof(nidstr)));
2700 rc = record_add_uuid(env, llh, mti->mti_nids[i], nodeuuid);
2705 rc = record_attach(env, llh, ospname, LUSTRE_OSP_NAME, lovuuid);
2709 rc = record_setup(env, llh, ospname, mti->mti_uuid, nodeuuid,
2714 rc = mgs_write_log_failnids(env, mti, llh, ospname);
2718 /* Add mdc(osp) to lod */
2719 snprintf(index_str, sizeof(index_str), "%d", mti->mti_stripe_index);
2720 rc = record_base(env, llh, lovname, 0, LCFG_ADD_MDC, mti->mti_uuid,
2721 index_str, "1", NULL);
2725 rc = record_marker(env, llh, fsdb, CM_END, mti->mti_svname, "add osp");
2730 record_end_log(env, &llh);
2733 name_destroy(&mdtuuid);
2734 name_destroy(&lovuuid);
2735 name_destroy(&lovname);
2736 name_destroy(&ospname);
2737 name_destroy(&svname);
2738 name_destroy(&nodeuuid);
2739 name_destroy(&mdtname);
2743 static int mgs_write_log_mdt0(const struct lu_env *env,
2744 struct mgs_device *mgs,
2746 struct mgs_target_info *mti)
2748 char *log = mti->mti_svname;
2749 struct llog_handle *llh = NULL;
2750 struct obd_uuid *uuid;
2753 char *ptr = mti->mti_params;
2754 int rc = 0, failout = 0;
2757 OBD_ALLOC_PTR(uuid);
2761 if (class_find_param(ptr, PARAM_FAILMODE, &ptr) == 0)
2762 failout = (strncmp(ptr, "failout", 7) == 0);
2764 rc = name_create(&lovname, log, "-mdtlov");
2767 if (mgs_log_is_empty(env, mgs, log)) {
2768 rc = mgs_write_log_lov(env, mgs, fsdb, mti, log, lovname);
2773 sprintf(mdt_index, "%d", mti->mti_stripe_index);
2775 rc = record_start_log(env, mgs, &llh, log);
2779 /* add MDT itself */
2781 /* FIXME this whole fn should be a single journal transaction */
2782 sprintf(uuid->uuid, "%s_UUID", log);
2783 rc = record_marker(env, llh, fsdb, CM_START, log, "add mdt");
2786 rc = record_attach(env, llh, log, LUSTRE_MDT_NAME, uuid->uuid);
2789 rc = record_mount_opt(env, llh, log, lovname, NULL);
2792 rc = record_setup(env, llh, log, uuid->uuid, mdt_index, lovname,
2793 failout ? "n" : "f");
2796 rc = record_marker(env, llh, fsdb, CM_END, log, "add mdt");
2800 record_end_log(env, &llh);
2802 name_destroy(&lovname);
2808 /* envelope method for all layers log */
2809 static int mgs_write_log_mdt(const struct lu_env *env,
2810 struct mgs_device *mgs,
2812 struct mgs_target_info *mti)
2814 struct mgs_thread_info *mgi = mgs_env_info(env);
2815 struct llog_handle *llh = NULL;
2820 CDEBUG(D_MGS, "writing new mdt %s\n", mti->mti_svname);
2822 if (mti->mti_uuid[0] == '\0') {
2823 /* Make up our own uuid */
2824 snprintf(mti->mti_uuid, sizeof(mti->mti_uuid),
2825 "%s_UUID", mti->mti_svname);
2829 rc = mgs_write_log_mdt0(env, mgs, fsdb, mti);
2832 /* Append the mdt info to the client log */
2833 rc = name_create(&cliname, mti->mti_fsname, "-client");
2837 if (mgs_log_is_empty(env, mgs, cliname)) {
2838 /* Start client log */
2839 rc = mgs_write_log_lov(env, mgs, fsdb, mti, cliname,
2843 rc = mgs_write_log_lmv(env, mgs, fsdb, mti, cliname,
2850 #09 L add_uuid nid=uml1@tcp(0x20000c0a80201) 0: 1:uml1_UUID
2851 #10 L attach 0:MDC_uml1_mdsA_MNT_client 1:mdc 2:1d834_MNT_client_03f
2852 #11 L setup 0:MDC_uml1_mdsA_MNT_client 1:mdsA_UUID 2:uml1_UUID
2853 #12 L add_uuid nid=uml2@tcp(0x20000c0a80202) 0: 1:uml2_UUID
2854 #13 L add_conn 0:MDC_uml1_mdsA_MNT_client 1:uml2_UUID
2855 #14 L mount_option 0: 1:client 2:lov1 3:MDC_uml1_mdsA_MNT_client
2858 /* copy client info about lov/lmv */
2859 mgi->mgi_comp.comp_mti = mti;
2860 mgi->mgi_comp.comp_fsdb = fsdb;
2862 rc = mgs_steal_llog_for_mdt_from_client(env, mgs, cliname,
2866 rc = mgs_write_log_mdc_to_lmv(env, mgs, fsdb, mti, cliname,
2872 rc = record_start_log(env, mgs, &llh, cliname);
2876 rc = record_marker(env, llh, fsdb, CM_START, cliname, "mount opts");
2879 rc = record_mount_opt(env, llh, cliname, fsdb->fsdb_clilov,
2883 rc = record_marker(env, llh, fsdb, CM_END, cliname, "mount opts");
2887 /* for_all_existing_mdt except current one */
2888 for (i = 0; i < INDEX_MAP_SIZE * 8; i++) {
2889 if (i != mti->mti_stripe_index &&
2890 test_bit(i, fsdb->fsdb_mdt_index_map)) {
2893 rc = name_create_mdt(&logname, fsdb->fsdb_name, i);
2897 /* NB: If the log for the MDT is empty, it means
2898 * the MDT is only added to the index
2899 * map, and not being process yet, i.e. this
2900 * is an unregistered MDT, see mgs_write_log_target().
2901 * so we should skip it. Otherwise
2903 * 1. MGS get register request for MDT1 and MDT2.
2905 * 2. Then both MDT1 and MDT2 are added into
2906 * fsdb_mdt_index_map. (see mgs_set_index()).
2908 * 3. Then MDT1 get the lock of fsdb_mutex, then
2909 * generate the config log, here, it will regard MDT2
2910 * as an existent MDT, and generate "add osp" for
2911 * lustre-MDT0001-osp-MDT0002. Note: at the moment
2912 * MDT0002 config log is still empty, so it will
2913 * add "add osp" even before "lov setup", which
2914 * will definitly cause trouble.
2916 * 4. MDT1 registeration finished, fsdb_mutex is
2917 * released, then MDT2 get in, then in above
2918 * mgs_steal_llog_for_mdt_from_client(), it will
2919 * add another osp log for lustre-MDT0001-osp-MDT0002,
2920 * which will cause another trouble.*/
2921 if (!mgs_log_is_empty(env, mgs, logname))
2922 rc = mgs_write_log_osp_to_mdt(env, mgs, fsdb,
2925 name_destroy(&logname);
2931 record_end_log(env, &llh);
2933 name_destroy(&cliname);
2937 /* Add the ost info to the client/mdt lov */
2938 static int mgs_write_log_osc_to_lov(const struct lu_env *env,
2939 struct mgs_device *mgs, struct fs_db *fsdb,
2940 struct mgs_target_info *mti,
2941 char *logname, char *suffix, char *lovname,
2942 enum lustre_sec_part sec_part, int flags)
2944 struct llog_handle *llh = NULL;
2945 char *nodeuuid = NULL;
2946 char *oscname = NULL;
2947 char *oscuuid = NULL;
2948 char *lovuuid = NULL;
2949 char *svname = NULL;
2951 char nidstr[LNET_NIDSTR_SIZE];
2955 CDEBUG(D_INFO, "adding osc for %s to log %s\n",
2956 mti->mti_svname, logname);
2958 if (mgs_log_is_empty(env, mgs, logname)) {
2959 CERROR("log is empty! Logical error\n");
2963 libcfs_nid2str_r(mti->mti_nids[0], nidstr, sizeof(nidstr));
2964 rc = name_create(&nodeuuid, nidstr, "");
2967 rc = name_create(&svname, mti->mti_svname, "-osc");
2971 /* for the system upgraded from old 1.8, keep using the old osc naming
2972 * style for mdt, see name_create_mdt_osc(). LU-1257 */
2973 if (test_bit(FSDB_OSCNAME18, &fsdb->fsdb_flags))
2974 rc = name_create(&oscname, svname, "");
2976 rc = name_create(&oscname, svname, suffix);
2980 rc = name_create(&oscuuid, oscname, "_UUID");
2983 rc = name_create(&lovuuid, lovname, "_UUID");
2989 #03 L add_uuid nid=uml1@tcp(0x20000c0a80201) 0: 1:uml1_UUID
2991 #04 L add_uuid nid=1@elan(0x1000000000001) nal=90 0: 1:uml1_UUID
2992 #04 L attach 0:OSC_uml1_ost1_MNT_client 1:osc 2:89070_lov1_a41dff51a
2993 #05 L setup 0:OSC_uml1_ost1_MNT_client 1:ost1_UUID 2:uml1_UUID
2995 #06 L add_uuid nid=uml2@tcp(0x20000c0a80202) 0: 1:uml2_UUID
2996 #07 L add_conn 0:OSC_uml1_ost1_MNT_client 1:uml2_UUID
2997 #08 L lov_modify_tgts add 0:lov1 1:ost1_UUID 2(index):0 3(gen):1
3000 rc = record_start_log(env, mgs, &llh, logname);
3004 /* FIXME these should be a single journal transaction */
3005 rc = record_marker(env, llh, fsdb, CM_START | flags, mti->mti_svname,
3010 /* NB: don't change record order, because upon MDT steal OSC config
3011 * from client, it treats all nids before LCFG_SETUP as target nids
3012 * (multiple interfaces), while nids after as failover node nids.
3013 * See mgs_steal_client_llog_handler() LCFG_ADD_UUID.
3015 for (i = 0; i < mti->mti_nid_count; i++) {
3016 CDEBUG(D_MGS, "add nid %s\n",
3017 libcfs_nid2str_r(mti->mti_nids[i],
3018 nidstr, sizeof(nidstr)));
3019 rc = record_add_uuid(env, llh, mti->mti_nids[i], nodeuuid);
3023 rc = record_attach(env, llh, oscname, LUSTRE_OSC_NAME, lovuuid);
3026 rc = record_setup(env, llh, oscname, mti->mti_uuid, nodeuuid,
3030 rc = mgs_write_log_failnids(env, mti, llh, oscname);
3034 snprintf(index, sizeof(index), "%d", mti->mti_stripe_index);
3036 rc = record_lov_add(env, llh, lovname, mti->mti_uuid, index, "1");
3039 rc = record_marker(env, llh, fsdb, CM_END | flags, mti->mti_svname,
3044 record_end_log(env, &llh);
3046 name_destroy(&lovuuid);
3047 name_destroy(&oscuuid);
3048 name_destroy(&oscname);
3049 name_destroy(&svname);
3050 name_destroy(&nodeuuid);
3054 static int mgs_write_log_ost(const struct lu_env *env,
3055 struct mgs_device *mgs, struct fs_db *fsdb,
3056 struct mgs_target_info *mti)
3058 struct llog_handle *llh = NULL;
3059 char *logname, *lovname;
3060 char *ptr = mti->mti_params;
3061 int rc, flags = 0, failout = 0, i;
3064 CDEBUG(D_MGS, "writing new ost %s\n", mti->mti_svname);
3066 /* The ost startup log */
3068 /* If the ost log already exists, that means that someone reformatted
3069 the ost and it called target_add again. */
3070 if (!mgs_log_is_empty(env, mgs, mti->mti_svname)) {
3071 LCONSOLE_ERROR_MSG(0x141, "The config log for %s already "
3072 "exists, yet the server claims it never "
3073 "registered. It may have been reformatted, "
3074 "or the index changed. writeconf the MDT to "
3075 "regenerate all logs.\n", mti->mti_svname);
3080 attach obdfilter ost1 ost1_UUID
3081 setup /dev/loop2 ldiskfs f|n errors=remount-ro,user_xattr
3083 if (class_find_param(ptr, PARAM_FAILMODE, &ptr) == 0)
3084 failout = (strncmp(ptr, "failout", 7) == 0);
3085 rc = record_start_log(env, mgs, &llh, mti->mti_svname);
3088 /* FIXME these should be a single journal transaction */
3089 rc = record_marker(env, llh, fsdb, CM_START, mti->mti_svname,"add ost");
3092 if (*mti->mti_uuid == '\0')
3093 snprintf(mti->mti_uuid, sizeof(mti->mti_uuid),
3094 "%s_UUID", mti->mti_svname);
3095 rc = record_attach(env, llh, mti->mti_svname,
3096 "obdfilter"/*LUSTRE_OST_NAME*/, mti->mti_uuid);
3099 rc = record_setup(env, llh, mti->mti_svname,
3100 "dev"/*ignored*/, "type"/*ignored*/,
3101 failout ? "n" : "f", NULL/*options*/);
3104 rc = record_marker(env, llh, fsdb, CM_END, mti->mti_svname, "add ost");
3108 record_end_log(env, &llh);
3111 /* We also have to update the other logs where this osc is part of
3114 if (test_bit(FSDB_OLDLOG14, &fsdb->fsdb_flags)) {
3115 /* If we're upgrading, the old mdt log already has our
3116 entry. Let's do a fake one for fun. */
3117 /* Note that we can't add any new failnids, since we don't
3118 know the old osc names. */
3119 flags = CM_SKIP | CM_UPGRADE146;
3121 } else if ((mti->mti_flags & LDD_F_UPDATE) != LDD_F_UPDATE) {
3122 /* If the update flag isn't set, don't update client/mdt
3125 LCONSOLE_WARN("Client log for %s was not updated; writeconf "
3126 "the MDT first to regenerate it.\n",
3130 /* Add ost to all MDT lov defs */
3131 for (i = 0; i < INDEX_MAP_SIZE * 8; i++){
3132 if (test_bit(i, fsdb->fsdb_mdt_index_map)) {
3135 rc = name_create_mdt_and_lov(&logname, &lovname, fsdb,
3140 snprintf(mdt_index, sizeof(mdt_index), "-MDT%04x", i);
3141 rc = mgs_write_log_osc_to_lov(env, mgs, fsdb, mti,
3143 lovname, LUSTRE_SP_MDT,
3145 name_destroy(&logname);
3146 name_destroy(&lovname);
3152 /* Append ost info to the client log */
3153 rc = name_create(&logname, mti->mti_fsname, "-client");
3156 if (mgs_log_is_empty(env, mgs, logname)) {
3157 /* Start client log */
3158 rc = mgs_write_log_lov(env, mgs, fsdb, mti, logname,
3162 rc = mgs_write_log_lmv(env, mgs, fsdb, mti, logname,
3167 rc = mgs_write_log_osc_to_lov(env, mgs, fsdb, mti, logname, "",
3168 fsdb->fsdb_clilov, LUSTRE_SP_CLI, flags);
3170 name_destroy(&logname);
3174 static __inline__ int mgs_param_empty(char *ptr)
3178 if ((tmp = strchr(ptr, '=')) && (*(++tmp) == '\0'))
3183 static int mgs_write_log_failnid_internal(const struct lu_env *env,
3184 struct mgs_device *mgs,
3186 struct mgs_target_info *mti,
3187 char *logname, char *cliname)
3190 struct llog_handle *llh = NULL;
3192 if (mgs_param_empty(mti->mti_params)) {
3193 /* Remove _all_ failnids */
3194 rc = mgs_modify(env, mgs, fsdb, mti, logname,
3195 mti->mti_svname, "add failnid", CM_SKIP);
3196 return rc < 0 ? rc : 0;
3199 /* Otherwise failover nids are additive */
3200 rc = record_start_log(env, mgs, &llh, logname);
3203 /* FIXME this should be a single journal transaction */
3204 rc = record_marker(env, llh, fsdb, CM_START, mti->mti_svname,
3208 rc = mgs_write_log_failnids(env, mti, llh, cliname);
3211 rc = record_marker(env, llh, fsdb, CM_END,
3212 mti->mti_svname, "add failnid");
3214 record_end_log(env, &llh);
3219 /* Add additional failnids to an existing log.
3220 The mdc/osc must have been added to logs first */
3221 /* tcp nids must be in dotted-quad ascii -
3222 we can't resolve hostnames from the kernel. */
3223 static int mgs_write_log_add_failnid(const struct lu_env *env,
3224 struct mgs_device *mgs,
3226 struct mgs_target_info *mti)
3228 char *logname, *cliname;
3232 /* FIXME we currently can't erase the failnids
3233 * given when a target first registers, since they aren't part of
3234 * an "add uuid" stanza
3237 /* Verify that we know about this target */
3238 if (mgs_log_is_empty(env, mgs, mti->mti_svname)) {
3239 LCONSOLE_ERROR_MSG(0x142, "The target %s has not registered "
3240 "yet. It must be started before failnids "
3241 "can be added.\n", mti->mti_svname);
3245 /* Create mdc/osc client name (e.g. lustre-OST0001-osc) */
3246 if (mti->mti_flags & LDD_F_SV_TYPE_MDT) {
3247 rc = name_create(&cliname, mti->mti_svname, "-mdc");
3248 } else if (mti->mti_flags & LDD_F_SV_TYPE_OST) {
3249 rc = name_create(&cliname, mti->mti_svname, "-osc");
3256 /* Add failover nids to the client log */
3257 rc = name_create(&logname, mti->mti_fsname, "-client");
3259 name_destroy(&cliname);
3263 rc = mgs_write_log_failnid_internal(env, mgs, fsdb,mti,logname,cliname);
3264 name_destroy(&logname);
3265 name_destroy(&cliname);
3269 if (mti->mti_flags & LDD_F_SV_TYPE_OST) {
3270 /* Add OST failover nids to the MDT logs as well */
3273 for (i = 0; i < INDEX_MAP_SIZE * 8; i++) {
3274 if (!test_bit(i, fsdb->fsdb_mdt_index_map))
3276 rc = name_create_mdt(&logname, mti->mti_fsname, i);
3279 rc = name_create_mdt_osc(&cliname, mti->mti_svname,
3282 name_destroy(&logname);
3285 rc = mgs_write_log_failnid_internal(env, mgs, fsdb,
3288 name_destroy(&cliname);
3289 name_destroy(&logname);
3298 static int mgs_wlp_lcfg(const struct lu_env *env,
3299 struct mgs_device *mgs, struct fs_db *fsdb,
3300 struct mgs_target_info *mti,
3301 char *logname, struct lustre_cfg_bufs *bufs,
3302 char *tgtname, char *ptr)
3304 char comment[MTI_NAME_MAXLEN];
3306 struct llog_cfg_rec *lcr;
3309 /* Erase any old settings of this same parameter */
3310 strlcpy(comment, ptr, sizeof(comment));
3311 /* But don't try to match the value. */
3312 tmp = strchr(comment, '=');
3315 /* FIXME we should skip settings that are the same as old values */
3316 rc = mgs_modify(env, mgs, fsdb, mti, logname, tgtname, comment,CM_SKIP);
3319 del = mgs_param_empty(ptr);
3321 LCONSOLE_INFO("%s parameter %s.%s in log %s\n", del ? "Disabling" : rc ?
3322 "Setting" : "Modifying", tgtname, comment, logname);
3324 /* mgs_modify() will return 1 if nothing had to be done */
3330 lustre_cfg_bufs_reset(bufs, tgtname);
3331 lustre_cfg_bufs_set_string(bufs, 1, ptr);
3332 if (mti->mti_flags & LDD_F_PARAM2)
3333 lustre_cfg_bufs_set_string(bufs, 2, LCTL_UPCALL);
3335 lcr = lustre_cfg_rec_new((mti->mti_flags & LDD_F_PARAM2) ?
3336 LCFG_SET_PARAM : LCFG_PARAM, bufs);
3340 rc = mgs_write_log_direct(env, mgs, fsdb, logname, lcr, tgtname,
3342 lustre_cfg_rec_free(lcr);
3346 /* write global variable settings into log */
3347 static int mgs_write_log_sys(const struct lu_env *env,
3348 struct mgs_device *mgs, struct fs_db *fsdb,
3349 struct mgs_target_info *mti, char *sys, char *ptr)
3351 struct mgs_thread_info *mgi = mgs_env_info(env);
3352 struct lustre_cfg *lcfg;
3353 struct llog_cfg_rec *lcr;
3355 int rc, cmd, convert = 1;
3357 if (class_match_param(ptr, PARAM_TIMEOUT, &tmp) == 0) {
3358 cmd = LCFG_SET_TIMEOUT;
3359 } else if (class_match_param(ptr, PARAM_LDLM_TIMEOUT, &tmp) == 0) {
3360 cmd = LCFG_SET_LDLM_TIMEOUT;
3361 /* Check for known params here so we can return error to lctl */
3362 } else if ((class_match_param(ptr, PARAM_AT_MIN, &tmp) == 0) ||
3363 (class_match_param(ptr, PARAM_AT_MAX, &tmp) == 0) ||
3364 (class_match_param(ptr, PARAM_AT_EXTRA, &tmp) == 0) ||
3365 (class_match_param(ptr, PARAM_AT_EARLY_MARGIN, &tmp) == 0) ||
3366 (class_match_param(ptr, PARAM_AT_HISTORY, &tmp) == 0)) {
3368 } else if (class_match_param(ptr, PARAM_JOBID_VAR, &tmp) == 0) {
3369 convert = 0; /* Don't convert string value to integer */
3375 if (mgs_param_empty(ptr))
3376 CDEBUG(D_MGS, "global '%s' removed\n", sys);
3378 CDEBUG(D_MGS, "global '%s' val=%s\n", sys, tmp);
3380 lustre_cfg_bufs_reset(&mgi->mgi_bufs, NULL);
3381 lustre_cfg_bufs_set_string(&mgi->mgi_bufs, 1, sys);
3382 if (!convert && *tmp != '\0')
3383 lustre_cfg_bufs_set_string(&mgi->mgi_bufs, 2, tmp);
3384 lcr = lustre_cfg_rec_new(cmd, &mgi->mgi_bufs);
3388 lcfg = &lcr->lcr_cfg;
3390 rc = kstrtouint(tmp, 0, &lcfg->lcfg_num);
3392 GOTO(out_rec_free, rc);
3397 /* truncate the comment to the parameter name */
3401 /* modify all servers and clients */
3402 rc = mgs_write_log_direct_all(env, mgs, fsdb, mti,
3403 *tmp == '\0' ? NULL : lcr,
3404 mti->mti_fsname, sys, 0);
3405 if (rc == 0 && *tmp != '\0') {
3407 case LCFG_SET_TIMEOUT:
3408 if (!obd_timeout_set || lcfg->lcfg_num > obd_timeout)
3409 class_process_config(lcfg);
3411 case LCFG_SET_LDLM_TIMEOUT:
3412 if (!ldlm_timeout_set || lcfg->lcfg_num > ldlm_timeout)
3413 class_process_config(lcfg);
3421 lustre_cfg_rec_free(lcr);
3425 /* write quota settings into log */
3426 static int mgs_write_log_quota(const struct lu_env *env, struct mgs_device *mgs,
3427 struct fs_db *fsdb, struct mgs_target_info *mti,
3428 char *quota, char *ptr)
3430 struct mgs_thread_info *mgi = mgs_env_info(env);
3431 struct llog_cfg_rec *lcr;
3434 int rc, cmd = LCFG_PARAM;
3436 /* support only 'meta' and 'data' pools so far */
3437 if (class_match_param(ptr, QUOTA_METAPOOL_NAME, &tmp) != 0 &&
3438 class_match_param(ptr, QUOTA_DATAPOOL_NAME, &tmp) != 0) {
3439 CERROR("parameter quota.%s isn't supported (only quota.mdt "
3440 "& quota.ost are)\n", ptr);
3445 CDEBUG(D_MGS, "global '%s' removed\n", quota);
3447 CDEBUG(D_MGS, "global '%s'\n", quota);
3449 if (strchr(tmp, 'u') == NULL && strchr(tmp, 'g') == NULL &&
3450 strchr(tmp, 'p') == NULL &&
3451 strcmp(tmp, "none") != 0) {
3452 CERROR("enable option(%s) isn't supported\n", tmp);
3457 lustre_cfg_bufs_reset(&mgi->mgi_bufs, mti->mti_fsname);
3458 lustre_cfg_bufs_set_string(&mgi->mgi_bufs, 1, quota);
3459 lcr = lustre_cfg_rec_new(cmd, &mgi->mgi_bufs);
3463 /* truncate the comment to the parameter name */
3468 /* XXX we duplicated quota enable information in all server
3469 * config logs, it should be moved to a separate config
3470 * log once we cleanup the config log for global param. */
3471 /* modify all servers */
3472 rc = mgs_write_log_direct_all(env, mgs, fsdb, mti,
3473 *tmp == '\0' ? NULL : lcr,
3474 mti->mti_fsname, quota, 1);
3476 lustre_cfg_rec_free(lcr);
3477 return rc < 0 ? rc : 0;
3480 static int mgs_srpc_set_param_disk(const struct lu_env *env,
3481 struct mgs_device *mgs,
3483 struct mgs_target_info *mti,
3486 struct mgs_thread_info *mgi = mgs_env_info(env);
3487 struct llog_cfg_rec *lcr;
3488 struct llog_handle *llh = NULL;
3490 char *comment, *ptr;
3496 ptr = strchr(param, '=');
3497 LASSERT(ptr != NULL);
3500 OBD_ALLOC(comment, len + 1);
3501 if (comment == NULL)
3503 strncpy(comment, param, len);
3504 comment[len] = '\0';
3507 lustre_cfg_bufs_reset(&mgi->mgi_bufs, mti->mti_svname);
3508 lustre_cfg_bufs_set_string(&mgi->mgi_bufs, 1, param);
3509 lcr = lustre_cfg_rec_new(LCFG_SPTLRPC_CONF, &mgi->mgi_bufs);
3511 GOTO(out_comment, rc = -ENOMEM);
3513 /* construct log name */
3514 rc = name_create(&logname, mti->mti_fsname, "-sptlrpc");
3518 if (mgs_log_is_empty(env, mgs, logname)) {
3519 rc = record_start_log(env, mgs, &llh, logname);
3522 record_end_log(env, &llh);
3525 /* obsolete old one */
3526 rc = mgs_modify(env, mgs, fsdb, mti, logname, mti->mti_svname,
3530 /* write the new one */
3531 rc = mgs_write_log_direct(env, mgs, fsdb, logname, lcr,
3532 mti->mti_svname, comment);
3534 CERROR("%s: error writing log %s: rc = %d\n",
3535 mgs->mgs_obd->obd_name, logname, rc);
3537 name_destroy(&logname);
3539 lustre_cfg_rec_free(lcr);
3541 OBD_FREE(comment, len + 1);
3545 static int mgs_srpc_set_param_udesc_mem(struct fs_db *fsdb,
3550 /* disable the adjustable udesc parameter for now, i.e. use default
3551 * setting that client always ship udesc to MDT if possible. to enable
3552 * it simply remove the following line */
3555 ptr = strchr(param, '=');
3560 if (strcmp(param, PARAM_SRPC_UDESC))
3563 if (strcmp(ptr, "yes") == 0) {
3564 set_bit(FSDB_UDESC, &fsdb->fsdb_flags);
3565 CWARN("Enable user descriptor shipping from client to MDT\n");
3566 } else if (strcmp(ptr, "no") == 0) {
3567 clear_bit(FSDB_UDESC, &fsdb->fsdb_flags);
3568 CWARN("Disable user descriptor shipping from client to MDT\n");
3576 CERROR("Invalid param: %s\n", param);
3580 static int mgs_srpc_set_param_mem(struct fs_db *fsdb,
3584 struct sptlrpc_rule rule;
3585 struct sptlrpc_rule_set *rset;
3589 if (strncmp(param, PARAM_SRPC, sizeof(PARAM_SRPC) - 1) != 0) {
3590 CERROR("Invalid sptlrpc parameter: %s\n", param);
3594 if (strncmp(param, PARAM_SRPC_UDESC,
3595 sizeof(PARAM_SRPC_UDESC) - 1) == 0) {
3596 RETURN(mgs_srpc_set_param_udesc_mem(fsdb, param));
3599 if (strncmp(param, PARAM_SRPC_FLVR, sizeof(PARAM_SRPC_FLVR) - 1) != 0) {
3600 CERROR("Invalid sptlrpc flavor parameter: %s\n", param);
3604 param += sizeof(PARAM_SRPC_FLVR) - 1;
3606 rc = sptlrpc_parse_rule(param, &rule);
3610 /* mgs rules implies must be mgc->mgs */
3611 if (test_bit(FSDB_MGS_SELF, &fsdb->fsdb_flags)) {
3612 if ((rule.sr_from != LUSTRE_SP_MGC &&
3613 rule.sr_from != LUSTRE_SP_ANY) ||
3614 (rule.sr_to != LUSTRE_SP_MGS &&
3615 rule.sr_to != LUSTRE_SP_ANY))
3619 /* preapre room for this coming rule. svcname format should be:
3620 * - fsname: general rule
3621 * - fsname-tgtname: target-specific rule
3623 if (strchr(svname, '-')) {
3624 struct mgs_tgt_srpc_conf *tgtconf;
3627 for (tgtconf = fsdb->fsdb_srpc_tgt; tgtconf != NULL;
3628 tgtconf = tgtconf->mtsc_next) {
3629 if (!strcmp(tgtconf->mtsc_tgt, svname)) {
3638 OBD_ALLOC_PTR(tgtconf);
3639 if (tgtconf == NULL)
3642 name_len = strlen(svname);
3644 OBD_ALLOC(tgtconf->mtsc_tgt, name_len + 1);
3645 if (tgtconf->mtsc_tgt == NULL) {
3646 OBD_FREE_PTR(tgtconf);
3649 memcpy(tgtconf->mtsc_tgt, svname, name_len);
3651 tgtconf->mtsc_next = fsdb->fsdb_srpc_tgt;
3652 fsdb->fsdb_srpc_tgt = tgtconf;
3655 rset = &tgtconf->mtsc_rset;
3656 } else if (strcmp(svname, MGSSELF_NAME) == 0) {
3657 /* put _mgs related srpc rule directly in mgs ruleset */
3658 rset = &fsdb->fsdb_mgs->mgs_lut.lut_sptlrpc_rset;
3660 rset = &fsdb->fsdb_srpc_gen;
3663 rc = sptlrpc_rule_set_merge(rset, &rule);
3668 static int mgs_srpc_set_param(const struct lu_env *env,
3669 struct mgs_device *mgs,
3671 struct mgs_target_info *mti,
3681 /* keep a copy of original param, which could be destroied
3683 copy_size = strlen(param) + 1;
3684 OBD_ALLOC(copy, copy_size);
3687 memcpy(copy, param, copy_size);
3689 rc = mgs_srpc_set_param_mem(fsdb, mti->mti_svname, param);
3693 /* previous steps guaranteed the syntax is correct */
3694 rc = mgs_srpc_set_param_disk(env, mgs, fsdb, mti, copy);
3698 if (test_bit(FSDB_MGS_SELF, &fsdb->fsdb_flags)) {
3700 * for mgs rules, make them effective immediately.
3702 LASSERT(fsdb->fsdb_srpc_tgt == NULL);
3703 sptlrpc_target_update_exp_flavor(mgs->mgs_obd,
3704 &fsdb->fsdb_srpc_gen);
3708 OBD_FREE(copy, copy_size);
3712 struct mgs_srpc_read_data {
3713 struct fs_db *msrd_fsdb;
3717 static int mgs_srpc_read_handler(const struct lu_env *env,
3718 struct llog_handle *llh,
3719 struct llog_rec_hdr *rec, void *data)
3721 struct mgs_srpc_read_data *msrd = data;
3722 struct cfg_marker *marker;
3723 struct lustre_cfg *lcfg = REC_DATA(rec);
3724 char *svname, *param;
3728 if (rec->lrh_type != OBD_CFG_REC) {
3729 CERROR("unhandled lrh_type: %#x\n", rec->lrh_type);
3733 cfg_len = REC_DATA_LEN(rec);
3735 rc = lustre_cfg_sanity_check(lcfg, cfg_len);
3737 CERROR("Insane cfg\n");
3741 if (lcfg->lcfg_command == LCFG_MARKER) {
3742 marker = lustre_cfg_buf(lcfg, 1);
3744 if (marker->cm_flags & CM_START &&
3745 marker->cm_flags & CM_SKIP)
3746 msrd->msrd_skip = 1;
3747 if (marker->cm_flags & CM_END)
3748 msrd->msrd_skip = 0;
3753 if (msrd->msrd_skip)
3756 if (lcfg->lcfg_command != LCFG_SPTLRPC_CONF) {
3757 CERROR("invalid command (%x)\n", lcfg->lcfg_command);
3761 svname = lustre_cfg_string(lcfg, 0);
3762 if (svname == NULL) {
3763 CERROR("svname is empty\n");
3767 param = lustre_cfg_string(lcfg, 1);
3768 if (param == NULL) {
3769 CERROR("param is empty\n");
3773 rc = mgs_srpc_set_param_mem(msrd->msrd_fsdb, svname, param);
3775 CERROR("read sptlrpc record error (%d): %s\n", rc, param);
3780 int mgs_get_fsdb_srpc_from_llog(const struct lu_env *env,
3781 struct mgs_device *mgs,
3784 struct llog_handle *llh = NULL;
3785 struct llog_ctxt *ctxt;
3787 struct mgs_srpc_read_data msrd;
3791 /* construct log name */
3792 rc = name_create(&logname, fsdb->fsdb_name, "-sptlrpc");
3796 ctxt = llog_get_context(mgs->mgs_obd, LLOG_CONFIG_ORIG_CTXT);
3797 LASSERT(ctxt != NULL);
3799 if (mgs_log_is_empty(env, mgs, logname))
3802 rc = llog_open(env, ctxt, &llh, NULL, logname,
3810 rc = llog_init_handle(env, llh, LLOG_F_IS_PLAIN, NULL);
3812 GOTO(out_close, rc);
3814 if (llog_get_size(llh) <= 1)
3815 GOTO(out_close, rc = 0);
3817 msrd.msrd_fsdb = fsdb;
3820 rc = llog_process(env, llh, mgs_srpc_read_handler, (void *)&msrd,
3824 llog_close(env, llh);
3826 llog_ctxt_put(ctxt);
3827 name_destroy(&logname);
3830 CERROR("failed to read sptlrpc config database: %d\n", rc);
3834 static int mgs_write_log_param2(const struct lu_env *env,
3835 struct mgs_device *mgs,
3837 struct mgs_target_info *mti, char *ptr)
3839 struct lustre_cfg_bufs bufs;
3843 CDEBUG(D_MGS, "next param '%s'\n", ptr);
3845 /* PARAM_MGSNODE and PARAM_NETWORK are set only when formating
3846 * or during the inital mount. It can never change after that.
3848 if (!class_match_param(ptr, PARAM_MGSNODE, NULL) ||
3849 !class_match_param(ptr, PARAM_NETWORK, NULL)) {
3854 /* Processed in mgs_write_log_ost. Another value that can't
3855 * be changed by lctl set_param -P.
3857 if (!class_match_param(ptr, PARAM_FAILMODE, NULL)) {
3858 LCONSOLE_ERROR_MSG(0x169,
3859 "%s can only be changed with tunefs.lustre and --writeconf\n",
3865 /* FIXME !!! Support for sptlrpc is incomplete. Currently the change
3866 * doesn't transmit to the client. See LU-7183.
3868 if (!class_match_param(ptr, PARAM_SRPC, NULL)) {
3869 rc = mgs_srpc_set_param(env, mgs, fsdb, mti, ptr);
3873 /* Can't use class_match_param since ptr doesn't start with
3874 * PARAM_FAILNODE. So we look for PARAM_FAILNODE contained in ptr.
3876 if (strstr(ptr, PARAM_FAILNODE)) {
3877 /* Add a failover nidlist. We already processed failovers
3878 * params for new targets in mgs_write_log_target.
3882 /* can't use wildcards with failover.node */
3883 if (strchr(ptr, '*')) {
3888 param = strstr(ptr, PARAM_FAILNODE);
3889 if (strlcpy(mti->mti_params, param, sizeof(mti->mti_params)) >=
3890 sizeof(mti->mti_params)) {
3895 CDEBUG(D_MGS, "Adding failnode with param %s\n",
3897 rc = mgs_write_log_add_failnid(env, mgs, fsdb, mti);
3901 rc = mgs_wlp_lcfg(env, mgs, fsdb, mti, PARAMS_FILENAME, &bufs,
3902 mti->mti_svname, ptr);
3907 /* Permanent settings of all parameters by writing into the appropriate
3908 * configuration logs.
3909 * A parameter with null value ("<param>='\0'") means to erase it out of
3912 static int mgs_write_log_param(const struct lu_env *env,
3913 struct mgs_device *mgs, struct fs_db *fsdb,
3914 struct mgs_target_info *mti, char *ptr)
3916 struct mgs_thread_info *mgi = mgs_env_info(env);
3922 /* For various parameter settings, we have to figure out which logs
3923 care about them (e.g. both mdt and client for lov settings) */
3924 CDEBUG(D_MGS, "next param '%s'\n", ptr);
3926 /* The params are stored in MOUNT_DATA_FILE and modified via
3927 tunefs.lustre, or set using lctl conf_param */
3929 /* Processed in lustre_start_mgc */
3930 if (class_match_param(ptr, PARAM_MGSNODE, NULL) == 0)
3933 /* Processed in ost/mdt */
3934 if (class_match_param(ptr, PARAM_NETWORK, NULL) == 0)
3937 /* Processed in mgs_write_log_ost */
3938 if (class_match_param(ptr, PARAM_FAILMODE, NULL) == 0) {
3939 if (mti->mti_flags & LDD_F_PARAM) {
3940 LCONSOLE_ERROR_MSG(0x169,
3941 "%s can only be changed with tunefs.lustre and --writeconf\n",
3948 if (class_match_param(ptr, PARAM_SRPC, NULL) == 0) {
3949 rc = mgs_srpc_set_param(env, mgs, fsdb, mti, ptr);
3953 if (class_match_param(ptr, PARAM_FAILNODE, NULL) == 0) {
3954 /* Add a failover nidlist */
3956 /* We already processed failovers params for new
3957 targets in mgs_write_log_target */
3958 if (mti->mti_flags & LDD_F_PARAM) {
3959 CDEBUG(D_MGS, "Adding failnode\n");
3960 rc = mgs_write_log_add_failnid(env, mgs, fsdb, mti);
3965 if (class_match_param(ptr, PARAM_SYS, &tmp) == 0) {
3966 rc = mgs_write_log_sys(env, mgs, fsdb, mti, ptr, tmp);
3970 if (class_match_param(ptr, PARAM_QUOTA, &tmp) == 0) {
3971 rc = mgs_write_log_quota(env, mgs, fsdb, mti, ptr, tmp);
3975 if (class_match_param(ptr, PARAM_OSC PARAM_ACTIVE, &tmp) == 0 ||
3976 class_match_param(ptr, PARAM_MDC PARAM_ACTIVE, &tmp) == 0) {
3977 /* active=0 means off, anything else means on */
3978 int flag = (*tmp == '0') ? CM_EXCLUDE : 0;
3979 bool deactive_osc = memcmp(ptr, PARAM_OSC PARAM_ACTIVE,
3980 strlen(PARAM_OSC PARAM_ACTIVE)) == 0;
3983 if (!deactive_osc) {
3986 rc = server_name2index(mti->mti_svname, &index, NULL);
3991 LCONSOLE_ERROR_MSG(0x144, "%s: MDC0 can not be"
3992 " (de)activated.\n",
3994 GOTO(end, rc = -EPERM);
3998 LCONSOLE_WARN("Permanently %sactivating %s\n",
3999 flag ? "de" : "re", mti->mti_svname);
4001 rc = name_create(&logname, mti->mti_fsname, "-client");
4004 rc = mgs_modify(env, mgs, fsdb, mti, logname,
4006 deactive_osc ? "add osc" : "add mdc", flag);
4007 name_destroy(&logname);
4012 /* Add to all MDT logs for DNE */
4013 for (i = 0; i < INDEX_MAP_SIZE * 8; i++) {
4014 if (!test_bit(i, fsdb->fsdb_mdt_index_map))
4016 rc = name_create_mdt(&logname, mti->mti_fsname, i);
4019 rc = mgs_modify(env, mgs, fsdb, mti, logname,
4021 deactive_osc ? "add osc" : "add osp",
4023 name_destroy(&logname);
4029 LCONSOLE_ERROR_MSG(0x145,
4030 "Couldn't find %s in log (%d). No permanent changes were made to the config log.\n",
4031 mti->mti_svname, rc);
4032 if (test_bit(FSDB_OLDLOG14, &fsdb->fsdb_flags))
4033 LCONSOLE_ERROR_MSG(0x146,
4034 "This may be because the log is in the old 1.4 style. Consider --writeconf to update the logs.\n");
4037 /* Fall through to osc/mdc proc for deactivating live
4038 OSC/OSP on running MDT / clients. */
4040 /* Below here, let obd's XXX_process_config methods handle it */
4042 /* All lov. in proc */
4043 if (class_match_param(ptr, PARAM_LOV, NULL) == 0) {
4046 CDEBUG(D_MGS, "lov param %s\n", ptr);
4047 if (!(mti->mti_flags & LDD_F_SV_TYPE_MDT)) {
4048 LCONSOLE_ERROR_MSG(0x147, "LOV params must be "
4049 "set on the MDT, not %s. "
4056 if (mgs_log_is_empty(env, mgs, mti->mti_svname))
4057 GOTO(end, rc = -ENODEV);
4059 rc = name_create_mdt_and_lov(&logname, &mdtlovname, fsdb,
4060 mti->mti_stripe_index);
4063 rc = mgs_wlp_lcfg(env, mgs, fsdb, mti, mti->mti_svname,
4064 &mgi->mgi_bufs, mdtlovname, ptr);
4065 name_destroy(&logname);
4066 name_destroy(&mdtlovname);
4071 rc = name_create(&logname, mti->mti_fsname, "-client");
4074 rc = mgs_wlp_lcfg(env, mgs, fsdb, mti, logname, &mgi->mgi_bufs,
4075 fsdb->fsdb_clilov, ptr);
4076 name_destroy(&logname);
4080 /* All osc., mdc., llite. params in proc */
4081 if ((class_match_param(ptr, PARAM_OSC, NULL) == 0) ||
4082 (class_match_param(ptr, PARAM_MDC, NULL) == 0) ||
4083 (class_match_param(ptr, PARAM_LLITE, NULL) == 0)) {
4086 if (test_bit(FSDB_OLDLOG14, &fsdb->fsdb_flags)) {
4087 LCONSOLE_ERROR_MSG(0x148, "Upgraded client logs for %s"
4088 " cannot be modified. Consider"
4089 " updating the configuration with"
4092 GOTO(end, rc = -EINVAL);
4094 if (memcmp(ptr, PARAM_LLITE, strlen(PARAM_LLITE)) == 0) {
4095 rc = name_create(&cname, mti->mti_fsname, "-client");
4096 /* Add the client type to match the obdname in
4097 class_config_llog_handler */
4098 } else if (mti->mti_flags & LDD_F_SV_TYPE_MDT) {
4099 rc = name_create(&cname, mti->mti_svname, "-mdc");
4100 } else if (mti->mti_flags & LDD_F_SV_TYPE_OST) {
4101 rc = name_create(&cname, mti->mti_svname, "-osc");
4103 GOTO(end, rc = -EINVAL);
4108 /* Forbid direct update of llite root squash parameters.
4109 * These parameters are indirectly set via the MDT settings.
4111 if ((class_match_param(ptr, PARAM_LLITE, &tmp) == 0) &&
4112 ((memcmp(tmp, "root_squash=", 12) == 0) ||
4113 (memcmp(tmp, "nosquash_nids=", 14) == 0))) {
4114 LCONSOLE_ERROR("%s: root squash parameters can only "
4115 "be updated through MDT component\n",
4117 name_destroy(&cname);
4118 GOTO(end, rc = -EINVAL);
4121 CDEBUG(D_MGS, "%.3s param %s\n", ptr, ptr + 4);
4124 rc = name_create(&logname, mti->mti_fsname, "-client");
4126 name_destroy(&cname);
4129 rc = mgs_wlp_lcfg(env, mgs, fsdb, mti, logname, &mgi->mgi_bufs,
4132 /* osc params affect the MDT as well */
4133 if (!rc && (mti->mti_flags & LDD_F_SV_TYPE_OST)) {
4136 for (i = 0; i < INDEX_MAP_SIZE * 8; i++){
4137 if (!test_bit(i, fsdb->fsdb_mdt_index_map))
4139 name_destroy(&cname);
4140 rc = name_create_mdt_osc(&cname, mti->mti_svname,
4142 name_destroy(&logname);
4145 rc = name_create_mdt(&logname,
4146 mti->mti_fsname, i);
4149 if (!mgs_log_is_empty(env, mgs, logname)) {
4150 rc = mgs_wlp_lcfg(env, mgs, fsdb,
4160 /* For mdc activate/deactivate, it affects OSP on MDT as well */
4161 if (class_match_param(ptr, PARAM_MDC PARAM_ACTIVE, &tmp) == 0 &&
4164 char *lodname = NULL;
4165 char *param_str = NULL;
4169 /* replace mdc with osp */
4170 memcpy(ptr, PARAM_OSP, strlen(PARAM_OSP));
4171 rc = server_name2index(mti->mti_svname, &index, NULL);
4173 memcpy(ptr, PARAM_MDC, strlen(PARAM_MDC));
4177 for (i = 0; i < INDEX_MAP_SIZE * 8; i++) {
4178 if (!test_bit(i, fsdb->fsdb_mdt_index_map))
4184 name_destroy(&logname);
4185 rc = name_create_mdt(&logname, mti->mti_fsname,
4190 if (mgs_log_is_empty(env, mgs, logname))
4193 snprintf(suffix, sizeof(suffix), "-osp-MDT%04x",
4195 name_destroy(&cname);
4196 rc = name_create(&cname, mti->mti_svname,
4201 rc = mgs_wlp_lcfg(env, mgs, fsdb, mti, logname,
4202 &mgi->mgi_bufs, cname, ptr);
4206 /* Add configuration log for noitfying LOD
4207 * to active/deactive the OSP. */
4208 name_destroy(¶m_str);
4209 rc = name_create(¶m_str, cname,
4210 (*tmp == '0') ? ".active=0" :
4215 name_destroy(&lodname);
4216 rc = name_create(&lodname, logname, "-mdtlov");
4220 rc = mgs_wlp_lcfg(env, mgs, fsdb, mti, logname,
4221 &mgi->mgi_bufs, lodname,
4226 memcpy(ptr, PARAM_MDC, strlen(PARAM_MDC));
4227 name_destroy(&lodname);
4228 name_destroy(¶m_str);
4231 name_destroy(&logname);
4232 name_destroy(&cname);
4236 /* All mdt. params in proc */
4237 if (class_match_param(ptr, PARAM_MDT, &tmp) == 0) {
4241 CDEBUG(D_MGS, "%.3s param %s\n", ptr, ptr + 4);
4242 if (strncmp(mti->mti_svname, mti->mti_fsname,
4243 MTI_NAME_MAXLEN) == 0)
4244 /* device is unspecified completely? */
4245 rc = LDD_F_SV_TYPE_MDT | LDD_F_SV_ALL;
4247 rc = server_name2index(mti->mti_svname, &idx, NULL);
4250 if ((rc & LDD_F_SV_TYPE_MDT) == 0)
4252 if (rc & LDD_F_SV_ALL) {
4253 for (i = 0; i < INDEX_MAP_SIZE * 8; i++) {
4255 fsdb->fsdb_mdt_index_map))
4257 rc = name_create_mdt(&logname,
4258 mti->mti_fsname, i);
4261 rc = mgs_wlp_lcfg(env, mgs, fsdb, mti,
4262 logname, &mgi->mgi_bufs,
4264 name_destroy(&logname);
4269 if ((memcmp(tmp, "root_squash=", 12) == 0) ||
4270 (memcmp(tmp, "nosquash_nids=", 14) == 0)) {
4271 LCONSOLE_ERROR("%s: root squash parameters "
4272 "cannot be applied to a single MDT\n",
4274 GOTO(end, rc = -EINVAL);
4276 rc = mgs_wlp_lcfg(env, mgs, fsdb, mti,
4277 mti->mti_svname, &mgi->mgi_bufs,
4278 mti->mti_svname, ptr);
4283 /* root squash settings are also applied to llite
4284 * config log (see LU-1778) */
4286 ((memcmp(tmp, "root_squash=", 12) == 0) ||
4287 (memcmp(tmp, "nosquash_nids=", 14) == 0))) {
4291 rc = name_create(&cname, mti->mti_fsname, "-client");
4294 rc = name_create(&logname, mti->mti_fsname, "-client");
4296 name_destroy(&cname);
4299 rc = name_create(&ptr2, PARAM_LLITE, tmp);
4301 name_destroy(&cname);
4302 name_destroy(&logname);
4305 rc = mgs_wlp_lcfg(env, mgs, fsdb, mti, logname,
4306 &mgi->mgi_bufs, cname, ptr2);
4307 name_destroy(&ptr2);
4308 name_destroy(&logname);
4309 name_destroy(&cname);
4314 /* All mdd., ost. and osd. params in proc */
4315 if ((class_match_param(ptr, PARAM_MDD, NULL) == 0) ||
4316 (class_match_param(ptr, PARAM_LOD, NULL) == 0) ||
4317 (class_match_param(ptr, PARAM_OST, NULL) == 0) ||
4318 (class_match_param(ptr, PARAM_OSD, NULL) == 0)) {
4319 CDEBUG(D_MGS, "%.3s param %s\n", ptr, ptr + 4);
4320 if (mgs_log_is_empty(env, mgs, mti->mti_svname))
4321 GOTO(end, rc = -ENODEV);
4323 rc = mgs_wlp_lcfg(env, mgs, fsdb, mti, mti->mti_svname,
4324 &mgi->mgi_bufs, mti->mti_svname, ptr);
4328 LCONSOLE_WARN("Ignoring unrecognized param '%s'\n", ptr);
4332 CERROR("err %d on param '%s'\n", rc, ptr);
4337 int mgs_write_log_target(const struct lu_env *env, struct mgs_device *mgs,
4338 struct mgs_target_info *mti, struct fs_db *fsdb)
4345 /* set/check the new target index */
4346 rc = mgs_set_index(env, mgs, mti);
4350 if (rc == EALREADY) {
4351 LCONSOLE_WARN("Found index %d for %s, updating log\n",
4352 mti->mti_stripe_index, mti->mti_svname);
4353 /* We would like to mark old log sections as invalid
4354 and add new log sections in the client and mdt logs.
4355 But if we add new sections, then live clients will
4356 get repeat setup instructions for already running
4357 osc's. So don't update the client/mdt logs. */
4358 mti->mti_flags &= ~LDD_F_UPDATE;
4362 OBD_FAIL_TIMEOUT(OBD_FAIL_MGS_WRITE_TARGET_DELAY, cfs_fail_val > 0 ?
4365 mutex_lock(&fsdb->fsdb_mutex);
4367 if (mti->mti_flags & (LDD_F_VIRGIN | LDD_F_WRITECONF)) {
4368 /* Generate a log from scratch */
4369 if (mti->mti_flags & LDD_F_SV_TYPE_MDT) {
4370 rc = mgs_write_log_mdt(env, mgs, fsdb, mti);
4371 } else if (mti->mti_flags & LDD_F_SV_TYPE_OST) {
4372 rc = mgs_write_log_ost(env, mgs, fsdb, mti);
4374 CERROR("Unknown target type %#x, can't create log for %s\n",
4375 mti->mti_flags, mti->mti_svname);
4378 CERROR("Can't write logs for %s (%d)\n",
4379 mti->mti_svname, rc);
4383 /* Just update the params from tunefs in mgs_write_log_params */
4384 CDEBUG(D_MGS, "Update params for %s\n", mti->mti_svname);
4385 mti->mti_flags |= LDD_F_PARAM;
4388 /* allocate temporary buffer, where class_get_next_param will
4389 make copy of a current parameter */
4390 OBD_ALLOC(buf, strlen(mti->mti_params) + 1);
4392 GOTO(out_up, rc = -ENOMEM);
4393 params = mti->mti_params;
4394 while (params != NULL) {
4395 rc = class_get_next_param(¶ms, buf);
4398 /* there is no next parameter, that is
4403 CDEBUG(D_MGS, "remaining string: '%s', param: '%s'\n",
4405 rc = mgs_write_log_param(env, mgs, fsdb, mti, buf);
4410 OBD_FREE(buf, strlen(mti->mti_params) + 1);
4413 mutex_unlock(&fsdb->fsdb_mutex);
4417 int mgs_erase_log(const struct lu_env *env, struct mgs_device *mgs, char *name)
4419 struct llog_ctxt *ctxt;
4422 ctxt = llog_get_context(mgs->mgs_obd, LLOG_CONFIG_ORIG_CTXT);
4424 CERROR("%s: MGS config context doesn't exist\n",
4425 mgs->mgs_obd->obd_name);
4428 rc = llog_erase(env, ctxt, NULL, name);
4429 /* llog may not exist */
4432 llog_ctxt_put(ctxt);
4436 CERROR("%s: failed to clear log %s: %d\n",
4437 mgs->mgs_obd->obd_name, name, rc);
4442 /* erase all logs for the given fs */
4443 int mgs_erase_logs(const struct lu_env *env, struct mgs_device *mgs,
4446 struct list_head log_list;
4447 struct mgs_direntry *dirent, *n;
4448 char barrier_name[20] = {};
4451 int rc, len = strlen(fsname);
4454 mutex_lock(&mgs->mgs_mutex);
4456 /* Find all the logs in the CONFIGS directory */
4457 rc = class_dentry_readdir(env, mgs, &log_list);
4459 mutex_unlock(&mgs->mgs_mutex);
4463 if (list_empty(&log_list)) {
4464 mutex_unlock(&mgs->mgs_mutex);
4468 snprintf(barrier_name, sizeof(barrier_name) - 1, "%s-%s",
4469 fsname, BARRIER_FILENAME);
4470 /* Delete the barrier fsdb */
4471 mgs_remove_fsdb_by_name(mgs, barrier_name);
4472 /* Delete the fs db */
4473 mgs_remove_fsdb_by_name(mgs, fsname);
4474 mutex_unlock(&mgs->mgs_mutex);
4476 list_for_each_entry_safe(dirent, n, &log_list, mde_list) {
4477 list_del_init(&dirent->mde_list);
4478 suffix = strrchr(dirent->mde_name, '-');
4479 if (suffix != NULL) {
4480 if ((len == suffix - dirent->mde_name) &&
4481 (strncmp(fsname, dirent->mde_name, len) == 0)) {
4482 CDEBUG(D_MGS, "Removing log %s\n",
4484 mgs_erase_log(env, mgs, dirent->mde_name);
4488 mgs_direntry_free(dirent);
4497 /* list all logs for the given fs */
4498 int mgs_list_logs(const struct lu_env *env, struct mgs_device *mgs,
4499 struct obd_ioctl_data *data)
4501 struct list_head log_list;
4502 struct mgs_direntry *dirent, *n;
4503 char *out, *suffix, prefix[] = "config_log: ";
4504 int prefix_len = strlen(prefix);
4505 int len, remains, start = 0, rc;
4509 /* Find all the logs in the CONFIGS directory */
4510 rc = class_dentry_readdir(env, mgs, &log_list);
4514 out = data->ioc_bulk;
4515 remains = data->ioc_inllen1;
4516 /* OBD_FAIL: fetch the config_log records from the specified one */
4517 if (OBD_FAIL_CHECK(OBD_FAIL_CATLIST))
4518 data->ioc_count = cfs_fail_val;
4520 list_for_each_entry_safe(dirent, n, &log_list, mde_list) {
4521 list_del_init(&dirent->mde_list);
4522 suffix = strrchr(dirent->mde_name, '-');
4523 if (suffix != NULL) {
4524 len = prefix_len + dirent->mde_len + 1;
4525 if (remains - len < 0) {
4526 /* No enough space for this record */
4527 mgs_direntry_free(dirent);
4531 if (start < data->ioc_count) {
4532 mgs_direntry_free(dirent);
4535 len = scnprintf(out, remains, "%s%s\n", prefix,
4540 mgs_direntry_free(dirent);
4548 data->ioc_count = start;
4552 struct mgs_lcfg_fork_data {
4553 struct lustre_cfg_bufs mlfd_bufs;
4554 struct mgs_device *mlfd_mgs;
4555 struct llog_handle *mlfd_llh;
4556 const char *mlfd_oldname;
4557 const char *mlfd_newname;
4561 static bool contain_valid_fsname(char *buf, const char *fsname,
4562 int buflen, int namelen)
4564 if (buflen < namelen)
4567 if (memcmp(buf, fsname, namelen) != 0)
4570 if (buf[namelen] != '\0' && buf[namelen] != '-')
4576 static int mgs_lcfg_fork_handler(const struct lu_env *env,
4577 struct llog_handle *o_llh,
4578 struct llog_rec_hdr *o_rec, void *data)
4580 struct mgs_lcfg_fork_data *mlfd = data;
4581 struct lustre_cfg_bufs *n_bufs = &mlfd->mlfd_bufs;
4582 struct lustre_cfg *o_lcfg = (struct lustre_cfg *)(o_rec + 1);
4583 struct llog_cfg_rec *lcr;
4585 char *n_buf = mlfd->mlfd_data;
4587 int o_namelen = strlen(mlfd->mlfd_oldname);
4588 int n_namelen = strlen(mlfd->mlfd_newname);
4589 int diff = n_namelen - o_namelen;
4590 __u32 cmd = o_lcfg->lcfg_command;
4591 __u32 cnt = o_lcfg->lcfg_bufcount;
4597 o_buf = lustre_cfg_buf(o_lcfg, 0);
4598 o_buflen = o_lcfg->lcfg_buflens[0];
4599 if (contain_valid_fsname(o_buf, mlfd->mlfd_oldname, o_buflen,
4601 memcpy(n_buf, mlfd->mlfd_newname, n_namelen);
4602 memcpy(n_buf + n_namelen, o_buf + o_namelen,
4603 o_buflen - o_namelen);
4604 lustre_cfg_bufs_reset(n_bufs, n_buf);
4605 n_buf += cfs_size_round(o_buflen + diff);
4607 lustre_cfg_bufs_reset(n_bufs, o_buflen != 0 ? o_buf : NULL);
4612 struct cfg_marker *o_marker;
4613 struct cfg_marker *n_marker;
4617 CDEBUG(D_MGS, "Unknown cfg marker entry with %d "
4622 /* buf[1] is marker */
4623 o_buf = lustre_cfg_buf(o_lcfg, 1);
4624 o_buflen = o_lcfg->lcfg_buflens[1];
4625 o_marker = (struct cfg_marker *)o_buf;
4626 if (!contain_valid_fsname(o_marker->cm_tgtname,
4628 sizeof(o_marker->cm_tgtname),
4630 lustre_cfg_bufs_set(n_bufs, 1, o_marker,
4635 n_marker = (struct cfg_marker *)n_buf;
4636 *n_marker = *o_marker;
4637 memcpy(n_marker->cm_tgtname, mlfd->mlfd_newname, n_namelen);
4638 tgt_namelen = strlen(o_marker->cm_tgtname);
4639 if (tgt_namelen > o_namelen)
4640 memcpy(n_marker->cm_tgtname + n_namelen,
4641 o_marker->cm_tgtname + o_namelen,
4642 tgt_namelen - o_namelen);
4643 n_marker->cm_tgtname[tgt_namelen + diff] = '\0';
4644 lustre_cfg_bufs_set(n_bufs, 1, n_marker, sizeof(*n_marker));
4648 case LCFG_SET_PARAM: {
4649 for (i = 1; i < cnt; i++)
4650 /* buf[i] is the param value, reuse it directly */
4651 lustre_cfg_bufs_set(n_bufs, i,
4652 lustre_cfg_buf(o_lcfg, i),
4653 o_lcfg->lcfg_buflens[i]);
4659 case LCFG_POOL_DEL: {
4660 if (cnt < 3 || cnt > 4) {
4661 CDEBUG(D_MGS, "Unknown cfg pool (%x) entry with %d "
4662 "buffers\n", cmd, cnt);
4666 /* buf[1] is fsname */
4667 o_buf = lustre_cfg_buf(o_lcfg, 1);
4668 o_buflen = o_lcfg->lcfg_buflens[1];
4669 memcpy(n_buf, mlfd->mlfd_newname, n_namelen);
4670 memcpy(n_buf + n_namelen, o_buf + o_namelen,
4671 o_buflen - o_namelen);
4672 lustre_cfg_bufs_set(n_bufs, 1, n_buf, o_buflen + diff);
4673 n_buf += cfs_size_round(o_buflen + diff);
4675 /* buf[2] is the pool name, reuse it directly */
4676 lustre_cfg_bufs_set(n_bufs, 2, lustre_cfg_buf(o_lcfg, 2),
4677 o_lcfg->lcfg_buflens[2]);
4682 /* buf[3] is ostname */
4683 o_buf = lustre_cfg_buf(o_lcfg, 3);
4684 o_buflen = o_lcfg->lcfg_buflens[3];
4685 memcpy(n_buf, mlfd->mlfd_newname, n_namelen);
4686 memcpy(n_buf + n_namelen, o_buf + o_namelen,
4687 o_buflen - o_namelen);
4688 lustre_cfg_bufs_set(n_bufs, 3, n_buf, o_buflen + diff);
4693 o_buflen = o_lcfg->lcfg_buflens[1];
4694 if (o_buflen == sizeof(struct lov_desc) ||
4695 o_buflen == sizeof(struct lmv_desc)) {
4701 o_buf = lustre_cfg_buf(o_lcfg, 1);
4702 if (o_buflen == sizeof(struct lov_desc)) {
4703 struct lov_desc *o_desc =
4704 (struct lov_desc *)o_buf;
4705 struct lov_desc *n_desc =
4706 (struct lov_desc *)n_buf;
4709 o_uuid = o_desc->ld_uuid.uuid;
4710 n_uuid = n_desc->ld_uuid.uuid;
4711 uuid_len = sizeof(o_desc->ld_uuid.uuid);
4713 struct lmv_desc *o_desc =
4714 (struct lmv_desc *)o_buf;
4715 struct lmv_desc *n_desc =
4716 (struct lmv_desc *)n_buf;
4719 o_uuid = o_desc->ld_uuid.uuid;
4720 n_uuid = n_desc->ld_uuid.uuid;
4721 uuid_len = sizeof(o_desc->ld_uuid.uuid);
4724 if (unlikely(!contain_valid_fsname(o_uuid,
4725 mlfd->mlfd_oldname, uuid_len,
4727 lustre_cfg_bufs_set(n_bufs, 1, o_buf,
4732 memcpy(n_uuid, mlfd->mlfd_newname, n_namelen);
4733 uuid_len = strlen(o_uuid);
4734 if (uuid_len > o_namelen)
4735 memcpy(n_uuid + n_namelen,
4737 uuid_len - o_namelen);
4738 n_uuid[uuid_len + diff] = '\0';
4739 lustre_cfg_bufs_set(n_bufs, 1, n_buf, o_buflen);
4741 } /* else case fall through */
4742 } /* else case fall through */
4746 for (i = 1; i < cnt; i++) {
4747 o_buflen = o_lcfg->lcfg_buflens[i];
4751 o_buf = lustre_cfg_buf(o_lcfg, i);
4752 if (!contain_valid_fsname(o_buf, mlfd->mlfd_oldname,
4753 o_buflen, o_namelen)) {
4754 lustre_cfg_bufs_set(n_bufs, i, o_buf, o_buflen);
4758 memcpy(n_buf, mlfd->mlfd_newname, n_namelen);
4759 if (o_buflen == o_namelen) {
4760 lustre_cfg_bufs_set(n_bufs, i, n_buf,
4762 n_buf += cfs_size_round(n_namelen);
4766 memcpy(n_buf + n_namelen, o_buf + o_namelen,
4767 o_buflen - o_namelen);
4768 lustre_cfg_bufs_set(n_bufs, i, n_buf, o_buflen + diff);
4769 n_buf += cfs_size_round(o_buflen + diff);
4775 lcr = lustre_cfg_rec_new(cmd, n_bufs);
4779 lcr->lcr_cfg = *o_lcfg;
4780 rc = llog_write(env, mlfd->mlfd_llh, &lcr->lcr_hdr, LLOG_NEXT_IDX);
4781 lustre_cfg_rec_free(lcr);
4786 static int mgs_lcfg_fork_one(const struct lu_env *env, struct mgs_device *mgs,
4787 struct mgs_direntry *mde, const char *oldname,
4788 const char *newname)
4790 struct llog_handle *old_llh = NULL;
4791 struct llog_handle *new_llh = NULL;
4792 struct llog_ctxt *ctxt = NULL;
4793 struct mgs_lcfg_fork_data *mlfd = NULL;
4794 char *name_buf = NULL;
4796 int old_namelen = strlen(oldname);
4797 int new_namelen = strlen(newname);
4801 name_buflen = mde->mde_len + new_namelen - old_namelen;
4802 OBD_ALLOC(name_buf, name_buflen);
4806 memcpy(name_buf, newname, new_namelen);
4807 memcpy(name_buf + new_namelen, mde->mde_name + old_namelen,
4808 mde->mde_len - old_namelen);
4810 CDEBUG(D_MGS, "Fork the config-log from %s to %s\n",
4811 mde->mde_name, name_buf);
4813 ctxt = llog_get_context(mgs->mgs_obd, LLOG_CONFIG_ORIG_CTXT);
4816 rc = llog_open_create(env, ctxt, &new_llh, NULL, name_buf);
4820 rc = llog_init_handle(env, new_llh, LLOG_F_IS_PLAIN, NULL);
4824 if (unlikely(mgs_log_is_empty(env, mgs, mde->mde_name)))
4827 rc = llog_open(env, ctxt, &old_llh, NULL, mde->mde_name,
4832 rc = llog_init_handle(env, old_llh, LLOG_F_IS_PLAIN, NULL);
4836 new_llh->lgh_hdr->llh_tgtuuid = old_llh->lgh_hdr->llh_tgtuuid;
4838 OBD_ALLOC(mlfd, LLOG_MIN_CHUNK_SIZE);
4840 GOTO(out, rc = -ENOMEM);
4842 mlfd->mlfd_mgs = mgs;
4843 mlfd->mlfd_llh = new_llh;
4844 mlfd->mlfd_oldname = oldname;
4845 mlfd->mlfd_newname = newname;
4847 rc = llog_process(env, old_llh, mgs_lcfg_fork_handler, mlfd, NULL);
4848 OBD_FREE(mlfd, LLOG_MIN_CHUNK_SIZE);
4854 llog_close(env, old_llh);
4856 llog_close(env, new_llh);
4858 OBD_FREE(name_buf, name_buflen);
4860 llog_ctxt_put(ctxt);
4865 int mgs_lcfg_fork(const struct lu_env *env, struct mgs_device *mgs,
4866 const char *oldname, const char *newname)
4868 struct list_head log_list;
4869 struct mgs_direntry *dirent, *n;
4870 int olen = strlen(oldname);
4871 int nlen = strlen(newname);
4876 if (unlikely(!oldname || oldname[0] == '\0' ||
4877 !newname || newname[0] == '\0'))
4880 if (strcmp(oldname, newname) == 0)
4883 /* lock it to prevent fork/erase/register in parallel. */
4884 mutex_lock(&mgs->mgs_mutex);
4886 rc = class_dentry_readdir(env, mgs, &log_list);
4888 mutex_unlock(&mgs->mgs_mutex);
4892 if (list_empty(&log_list)) {
4893 mutex_unlock(&mgs->mgs_mutex);
4897 list_for_each_entry_safe(dirent, n, &log_list, mde_list) {
4900 ptr = strrchr(dirent->mde_name, '-');
4902 int tlen = ptr - dirent->mde_name;
4905 strncmp(newname, dirent->mde_name, tlen) == 0)
4906 GOTO(out, rc = -EEXIST);
4909 strncmp(oldname, dirent->mde_name, tlen) == 0)
4913 list_del_init(&dirent->mde_list);
4914 mgs_direntry_free(dirent);
4917 if (list_empty(&log_list)) {
4918 mutex_unlock(&mgs->mgs_mutex);
4922 list_for_each_entry(dirent, &log_list, mde_list) {
4923 rc = mgs_lcfg_fork_one(env, mgs, dirent, oldname, newname);
4931 mutex_unlock(&mgs->mgs_mutex);
4933 list_for_each_entry_safe(dirent, n, &log_list, mde_list) {
4934 list_del_init(&dirent->mde_list);
4935 mgs_direntry_free(dirent);
4938 if (rc && count > 0)
4939 mgs_erase_logs(env, mgs, newname);
4944 int mgs_lcfg_erase(const struct lu_env *env, struct mgs_device *mgs,
4950 if (unlikely(!fsname || fsname[0] == '\0'))
4953 rc = mgs_erase_logs(env, mgs, fsname);
4958 static int mgs_xattr_del(const struct lu_env *env, struct dt_object *obj)
4960 struct dt_device *dev;
4961 struct thandle *th = NULL;
4966 dev = container_of(obj->do_lu.lo_dev, struct dt_device, dd_lu_dev);
4967 th = dt_trans_create(env, dev);
4969 RETURN(PTR_ERR(th));
4971 rc = dt_declare_xattr_del(env, obj, XATTR_TARGET_RENAME, th);
4975 rc = dt_trans_start_local(env, dev, th);
4979 dt_write_lock(env, obj, 0);
4980 rc = dt_xattr_del(env, obj, XATTR_TARGET_RENAME, th);
4985 dt_write_unlock(env, obj);
4988 dt_trans_stop(env, dev, th);
4993 int mgs_lcfg_rename(const struct lu_env *env, struct mgs_device *mgs)
4995 struct list_head log_list;
4996 struct mgs_direntry *dirent, *n;
4998 struct lu_buf buf = {
5000 .lb_len = sizeof(fsname)
5006 rc = class_dentry_readdir(env, mgs, &log_list);
5010 if (list_empty(&log_list))
5013 list_for_each_entry_safe(dirent, n, &log_list, mde_list) {
5014 struct dt_object *o = NULL;
5019 list_del_init(&dirent->mde_list);
5020 ptr = strrchr(dirent->mde_name, '-');
5024 len = ptr - dirent->mde_name;
5025 if (unlikely(len >= sizeof(oldname))) {
5026 CDEBUG(D_MGS, "Skip invalid configuration file %s\n",
5031 o = local_file_find(env, mgs->mgs_los, mgs->mgs_configs_dir,
5035 CDEBUG(D_MGS, "Fail to locate file %s: rc = %d\n",
5036 dirent->mde_name, rc);
5040 rc = dt_xattr_get(env, o, &buf, XATTR_TARGET_RENAME);
5046 "Fail to get EA for %s: rc = %d\n",
5047 dirent->mde_name, rc);
5051 if (unlikely(rc == len &&
5052 memcmp(fsname, dirent->mde_name, len) == 0)) {
5053 /* The new fsname is the same as the old one. */
5054 rc = mgs_xattr_del(env, o);
5058 memcpy(oldname, dirent->mde_name, len);
5059 oldname[len] = '\0';
5061 rc = mgs_lcfg_fork_one(env, mgs, dirent, oldname, fsname);
5062 if (rc && rc != -EEXIST) {
5063 CDEBUG(D_MGS, "Fail to fork %s: rc = %d\n",
5064 dirent->mde_name, rc);
5068 rc = mgs_erase_log(env, mgs, dirent->mde_name);
5070 CDEBUG(D_MGS, "Fail to erase old %s: rc = %d\n",
5071 dirent->mde_name, rc);
5072 /* keep it there if failed to remove it. */
5077 if (o && !IS_ERR(o))
5078 lu_object_put(env, &o->do_lu);
5080 mgs_direntry_free(dirent);
5085 list_for_each_entry_safe(dirent, n, &log_list, mde_list) {
5086 list_del_init(&dirent->mde_list);
5087 mgs_direntry_free(dirent);
5093 /* Setup _mgs fsdb and log
5095 int mgs__mgs_fsdb_setup(const struct lu_env *env, struct mgs_device *mgs)
5097 struct fs_db *fsdb = NULL;
5101 rc = mgs_find_or_make_fsdb(env, mgs, MGSSELF_NAME, &fsdb);
5103 mgs_put_fsdb(mgs, fsdb);
5108 /* Setup params fsdb and log
5110 int mgs_params_fsdb_setup(const struct lu_env *env, struct mgs_device *mgs)
5112 struct fs_db *fsdb = NULL;
5113 struct llog_handle *params_llh = NULL;
5117 rc = mgs_find_or_make_fsdb(env, mgs, PARAMS_FILENAME, &fsdb);
5119 mutex_lock(&fsdb->fsdb_mutex);
5120 rc = record_start_log(env, mgs, ¶ms_llh, PARAMS_FILENAME);
5122 rc = record_end_log(env, ¶ms_llh);
5123 mutex_unlock(&fsdb->fsdb_mutex);
5124 mgs_put_fsdb(mgs, fsdb);
5130 /* Cleanup params fsdb and log
5132 int mgs_params_fsdb_cleanup(const struct lu_env *env, struct mgs_device *mgs)
5136 rc = mgs_erase_logs(env, mgs, PARAMS_FILENAME);
5137 return rc == -ENOENT ? 0 : rc;
5141 * Fill in the mgs_target_info based on data devname and param provide.
5143 * @env thread context
5145 * @mti mgs target info. We want to set this based other paramters
5146 * passed to this function. Once setup we write it to the config
5148 * @devname optional OBD device name
5149 * @param string that contains both what tunable to set and the value to
5152 * RETURN 0 for success
5153 * negative error number on failure
5155 static int mgs_set_conf_param(const struct lu_env *env, struct mgs_device *mgs,
5156 struct mgs_target_info *mti, const char *devname,
5159 struct fs_db *fsdb = NULL;
5164 /* lustre, lustre-mdtlov, lustre-client, lustre-MDT0000 */
5168 /* We have two possible cases here:
5170 * 1) the device name embedded in the param:
5171 * lustre-OST0000.osc.max_dirty_mb=32
5173 * 2) the file system name is embedded in
5174 * the param: lustre.sys.at.min=0
5176 len = strcspn(param, ".=");
5177 if (!len || param[len] == '=')
5180 if (len >= sizeof(mti->mti_svname))
5183 snprintf(mti->mti_svname, sizeof(mti->mti_svname),
5184 "%.*s", (int)len, param);
5187 if (strlcpy(mti->mti_svname, devname, sizeof(mti->mti_svname)) >=
5188 sizeof(mti->mti_svname))
5192 if (!strlen(mti->mti_svname)) {
5193 LCONSOLE_ERROR_MSG(0x14d, "No target specified: %s\n", param);
5197 dev_type = mgs_parse_devname(mti->mti_svname, mti->mti_fsname,
5198 &mti->mti_stripe_index);
5200 /* For this case we have an invalid obd device name */
5202 CDEBUG(D_MGS, "%s don't contain an index\n", mti->mti_svname);
5203 strlcpy(mti->mti_fsname, mti->mti_svname, MTI_NAME_MAXLEN);
5206 /* Not an obd device, assume devname is the fsname.
5207 * User might of only provided fsname and not obd device
5210 CDEBUG(D_MGS, "%s is seen as a file system name\n", mti->mti_svname);
5211 strlcpy(mti->mti_fsname, mti->mti_svname, MTI_NAME_MAXLEN);
5216 GOTO(out, rc = dev_type);
5218 /* param related to llite isn't allowed to set by OST or MDT */
5219 if (dev_type & LDD_F_SV_TYPE_OST ||
5220 dev_type & LDD_F_SV_TYPE_MDT) {
5221 /* param related to llite isn't allowed to set by OST
5224 if (!strncmp(param, PARAM_LLITE,
5225 sizeof(PARAM_LLITE) - 1))
5226 GOTO(out, rc = -EINVAL);
5228 /* Strip -osc or -mdc suffix from svname */
5229 if (server_make_name(dev_type, mti->mti_stripe_index,
5230 mti->mti_fsname, mti->mti_svname,
5231 sizeof(mti->mti_svname)))
5232 GOTO(out, rc = -EINVAL);
5237 if (strlcpy(mti->mti_params, param, sizeof(mti->mti_params)) >=
5238 sizeof(mti->mti_params))
5239 GOTO(out, rc = -E2BIG);
5241 CDEBUG(D_MGS, "set_conf_param fs='%s' device='%s' param='%s'\n",
5242 mti->mti_fsname, mti->mti_svname, mti->mti_params);
5244 rc = mgs_find_or_make_fsdb(env, mgs, mti->mti_fsname, &fsdb);
5248 if (!test_bit(FSDB_MGS_SELF, &fsdb->fsdb_flags) &&
5249 test_bit(FSDB_LOG_EMPTY, &fsdb->fsdb_flags)) {
5250 CERROR("No filesystem targets for %s. cfg_device from lctl "
5251 "is '%s'\n", mti->mti_fsname, mti->mti_svname);
5252 mgs_unlink_fsdb(mgs, fsdb);
5253 GOTO(out, rc = -EINVAL);
5257 * Revoke lock so everyone updates. Should be alright if
5258 * someone was already reading while we were updating the logs,
5259 * so we don't really need to hold the lock while we're
5262 mti->mti_flags = dev_type | LDD_F_PARAM;
5263 mutex_lock(&fsdb->fsdb_mutex);
5264 rc = mgs_write_log_param(env, mgs, fsdb, mti, mti->mti_params);
5265 mutex_unlock(&fsdb->fsdb_mutex);
5266 mgs_revoke_lock(mgs, fsdb, CONFIG_T_CONFIG);
5270 mgs_put_fsdb(mgs, fsdb);
5275 static int mgs_set_param2(const struct lu_env *env, struct mgs_device *mgs,
5276 struct mgs_target_info *mti, const char *param)
5278 struct fs_db *fsdb = NULL;
5283 if (strlcpy(mti->mti_params, param, sizeof(mti->mti_params)) >=
5284 sizeof(mti->mti_params))
5285 GOTO(out, rc = -E2BIG);
5287 len = strcspn(param, ".=");
5288 if (len && param[len] != '=') {
5289 struct list_head *tmp;
5293 ptr = strchr(param, '.');
5295 len = strlen(param);
5298 if (len >= sizeof(mti->mti_svname))
5299 GOTO(out, rc = -E2BIG);
5301 snprintf(mti->mti_svname, sizeof(mti->mti_svname), "%.*s",
5304 mutex_lock(&mgs->mgs_mutex);
5305 if (unlikely(list_empty(&mgs->mgs_fs_db_list))) {
5306 mutex_unlock(&mgs->mgs_mutex);
5307 GOTO(out, rc = -ENODEV);
5310 list_for_each(tmp, &mgs->mgs_fs_db_list) {
5311 fsdb = list_entry(tmp, struct fs_db, fsdb_list);
5312 if (fsdb->fsdb_has_lproc_entry &&
5313 strcmp(fsdb->fsdb_name, "params") != 0 &&
5314 strstr(param, fsdb->fsdb_name)) {
5315 snprintf(mti->mti_svname,
5316 sizeof(mti->mti_svname), "%s",
5324 snprintf(mti->mti_svname, sizeof(mti->mti_svname),
5327 mutex_unlock(&mgs->mgs_mutex);
5329 snprintf(mti->mti_svname, sizeof(mti->mti_svname), "general");
5332 CDEBUG(D_MGS, "set_param2 fs='%s' device='%s' param='%s'\n",
5333 mti->mti_fsname, mti->mti_svname, mti->mti_params);
5335 /* The return value should be the device type i.e LDD_F_SV_TYPE_XXX.
5336 * A returned error tells us we don't have a target obd device.
5338 dev_type = server_name2index(mti->mti_svname, &mti->mti_stripe_index,
5343 /* the return value should be the device type i.e LDD_F_SV_TYPE_XXX.
5344 * Strip -osc or -mdc suffix from svname
5346 if ((dev_type & LDD_F_SV_TYPE_OST || dev_type & LDD_F_SV_TYPE_MDT) &&
5347 server_make_name(dev_type, mti->mti_stripe_index,
5348 mti->mti_fsname, mti->mti_svname,
5349 sizeof(mti->mti_svname)))
5350 GOTO(out, rc = -EINVAL);
5352 rc = mgs_find_or_make_fsdb(env, mgs, PARAMS_FILENAME, &fsdb);
5356 * Revoke lock so everyone updates. Should be alright if
5357 * someone was already reading while we were updating the logs,
5358 * so we don't really need to hold the lock while we're
5361 mti->mti_flags = dev_type | LDD_F_PARAM2;
5362 mutex_lock(&fsdb->fsdb_mutex);
5363 rc = mgs_write_log_param2(env, mgs, fsdb, mti, mti->mti_params);
5364 mutex_unlock(&fsdb->fsdb_mutex);
5365 mgs_revoke_lock(mgs, fsdb, CONFIG_T_PARAMS);
5366 mgs_put_fsdb(mgs, fsdb);
5371 /* Set a permanent (config log) param for a target or fs
5373 * @lcfg buf0 may contain the device (testfs-MDT0000) name
5374 * buf1 contains the single parameter
5376 int mgs_set_param(const struct lu_env *env, struct mgs_device *mgs,
5377 struct lustre_cfg *lcfg)
5379 const char *param = lustre_cfg_string(lcfg, 1);
5380 struct mgs_target_info *mti;
5383 /* Create a fake mti to hold everything */
5388 print_lustre_cfg(lcfg);
5390 if (lcfg->lcfg_command == LCFG_PARAM) {
5391 /* For the case of lctl conf_param devname can be
5392 * lustre, lustre-mdtlov, lustre-client, lustre-MDT0000
5394 const char *devname = lustre_cfg_string(lcfg, 0);
5396 rc = mgs_set_conf_param(env, mgs, mti, devname, param);
5398 /* In the case of lctl set_param -P lcfg[0] will always
5399 * be 'general'. At least for now.
5401 rc = mgs_set_param2(env, mgs, mti, param);
5409 static int mgs_write_log_pool(const struct lu_env *env,
5410 struct mgs_device *mgs, char *logname,
5411 struct fs_db *fsdb, char *tgtname,
5412 enum lcfg_command_type cmd,
5413 char *fsname, char *poolname,
5414 char *ostname, char *comment)
5416 struct llog_handle *llh = NULL;
5419 rc = record_start_log(env, mgs, &llh, logname);
5422 rc = record_marker(env, llh, fsdb, CM_START, tgtname, comment);
5425 rc = record_base(env, llh, tgtname, 0, cmd,
5426 fsname, poolname, ostname, NULL);
5429 rc = record_marker(env, llh, fsdb, CM_END, tgtname, comment);
5431 record_end_log(env, &llh);
5435 int mgs_nodemap_cmd(const struct lu_env *env, struct mgs_device *mgs,
5436 enum lcfg_command_type cmd, const char *nodemap_name,
5447 case LCFG_NODEMAP_ADD:
5448 rc = nodemap_add(nodemap_name);
5450 case LCFG_NODEMAP_DEL:
5451 rc = nodemap_del(nodemap_name);
5453 case LCFG_NODEMAP_ADD_RANGE:
5454 rc = nodemap_parse_range(param, nid);
5457 rc = nodemap_add_range(nodemap_name, nid);
5459 case LCFG_NODEMAP_DEL_RANGE:
5460 rc = nodemap_parse_range(param, nid);
5463 rc = nodemap_del_range(nodemap_name, nid);
5465 case LCFG_NODEMAP_ADMIN:
5466 rc = kstrtobool(param, &bool_switch);
5469 rc = nodemap_set_allow_root(nodemap_name, bool_switch);
5471 case LCFG_NODEMAP_DENY_UNKNOWN:
5472 rc = kstrtobool(param, &bool_switch);
5475 rc = nodemap_set_deny_unknown(nodemap_name, bool_switch);
5477 case LCFG_NODEMAP_AUDIT_MODE:
5478 rc = kstrtobool(param, &bool_switch);
5480 rc = nodemap_set_audit_mode(nodemap_name, bool_switch);
5482 case LCFG_NODEMAP_FORBID_ENCRYPT:
5483 rc = kstrtobool(param, &bool_switch);
5485 rc = nodemap_set_forbid_encryption(nodemap_name,
5488 case LCFG_NODEMAP_MAP_MODE:
5489 if (strcmp("both", param) == 0)
5490 rc = nodemap_set_mapping_mode(nodemap_name,
5492 else if (strcmp("uid_only", param) == 0)
5493 rc = nodemap_set_mapping_mode(nodemap_name,
5494 NODEMAP_MAP_UID_ONLY);
5495 else if (strcmp("gid_only", param) == 0)
5496 rc = nodemap_set_mapping_mode(nodemap_name,
5497 NODEMAP_MAP_GID_ONLY);
5501 case LCFG_NODEMAP_TRUSTED:
5502 rc = kstrtobool(param, &bool_switch);
5505 rc = nodemap_set_trust_client_ids(nodemap_name, bool_switch);
5507 case LCFG_NODEMAP_SQUASH_UID:
5508 rc = kstrtouint(param, 10, &int_id);
5511 rc = nodemap_set_squash_uid(nodemap_name, int_id);
5513 case LCFG_NODEMAP_SQUASH_GID:
5514 rc = kstrtouint(param, 10, &int_id);
5517 rc = nodemap_set_squash_gid(nodemap_name, int_id);
5519 case LCFG_NODEMAP_ADD_UIDMAP:
5520 case LCFG_NODEMAP_ADD_GIDMAP:
5521 rc = nodemap_parse_idmap(param, idmap);
5524 if (cmd == LCFG_NODEMAP_ADD_UIDMAP)
5525 rc = nodemap_add_idmap(nodemap_name, NODEMAP_UID,
5528 rc = nodemap_add_idmap(nodemap_name, NODEMAP_GID,
5531 case LCFG_NODEMAP_DEL_UIDMAP:
5532 case LCFG_NODEMAP_DEL_GIDMAP:
5533 rc = nodemap_parse_idmap(param, idmap);
5536 if (cmd == LCFG_NODEMAP_DEL_UIDMAP)
5537 rc = nodemap_del_idmap(nodemap_name, NODEMAP_UID,
5540 rc = nodemap_del_idmap(nodemap_name, NODEMAP_GID,
5543 case LCFG_NODEMAP_SET_FILESET:
5544 rc = nodemap_set_fileset(nodemap_name, param);
5546 case LCFG_NODEMAP_SET_SEPOL:
5547 rc = nodemap_set_sepol(nodemap_name, param);
5556 int mgs_pool_cmd(const struct lu_env *env, struct mgs_device *mgs,
5557 enum lcfg_command_type cmd, char *fsname,
5558 char *poolname, char *ostname)
5563 char *label = NULL, *canceled_label = NULL;
5565 struct mgs_target_info *mti = NULL;
5566 bool checked = false;
5567 bool locked = false;
5572 rc = mgs_find_or_make_fsdb(env, mgs, fsname, &fsdb);
5574 CERROR("Can't get db for %s\n", fsname);
5577 if (test_bit(FSDB_LOG_EMPTY, &fsdb->fsdb_flags)) {
5578 CERROR("%s is not defined\n", fsname);
5580 GOTO(out_fsdb, rc = -EINVAL);
5583 label_sz = 10 + strlen(fsname) + strlen(poolname);
5585 /* check if ostname match fsname */
5586 if (ostname != NULL) {
5589 ptr = strrchr(ostname, '-');
5590 if ((ptr == NULL) ||
5591 (strncmp(fsname, ostname, ptr-ostname) != 0))
5593 label_sz += strlen(ostname);
5596 OBD_ALLOC(label, label_sz);
5598 GOTO(out_fsdb, rc = -ENOMEM);
5603 "new %s.%s", fsname, poolname);
5607 "add %s.%s.%s", fsname, poolname, ostname);
5610 OBD_ALLOC(canceled_label, label_sz);
5611 if (canceled_label == NULL)
5612 GOTO(out_label, rc = -ENOMEM);
5614 "rem %s.%s.%s", fsname, poolname, ostname);
5615 sprintf(canceled_label,
5616 "add %s.%s.%s", fsname, poolname, ostname);
5619 OBD_ALLOC(canceled_label, label_sz);
5620 if (canceled_label == NULL)
5621 GOTO(out_label, rc = -ENOMEM);
5623 "del %s.%s", fsname, poolname);
5624 sprintf(canceled_label,
5625 "new %s.%s", fsname, poolname);
5633 GOTO(out_cancel, rc = -ENOMEM);
5634 strncpy(mti->mti_svname, "lov pool", sizeof(mti->mti_svname));
5636 mutex_lock(&fsdb->fsdb_mutex);
5638 /* write pool def to all MDT logs */
5639 for (i = 0; i < INDEX_MAP_SIZE * 8; i++) {
5640 if (test_bit(i, fsdb->fsdb_mdt_index_map)) {
5641 rc = name_create_mdt_and_lov(&logname, &lovname,
5646 if (!checked && (canceled_label == NULL)) {
5647 rc = mgs_check_marker(env, mgs, fsdb, mti,
5648 logname, lovname, label);
5650 name_destroy(&logname);
5651 name_destroy(&lovname);
5653 rc = (rc == LLOG_PROC_BREAK ?
5658 if (canceled_label != NULL)
5659 rc = mgs_modify(env, mgs, fsdb, mti, logname,
5660 lovname, canceled_label,
5664 rc = mgs_write_log_pool(env, mgs, logname,
5668 name_destroy(&logname);
5669 name_destroy(&lovname);
5675 rc = name_create(&logname, fsname, "-client");
5679 if (!checked && (canceled_label == NULL)) {
5680 rc = mgs_check_marker(env, mgs, fsdb, mti, logname,
5681 fsdb->fsdb_clilov, label);
5683 name_destroy(&logname);
5684 GOTO(out_mti, rc = (rc == LLOG_PROC_BREAK ?
5688 if (canceled_label != NULL) {
5689 rc = mgs_modify(env, mgs, fsdb, mti, logname,
5690 fsdb->fsdb_clilov, canceled_label, CM_SKIP);
5692 name_destroy(&logname);
5697 rc = mgs_write_log_pool(env, mgs, logname, fsdb, fsdb->fsdb_clilov,
5698 cmd, fsname, poolname, ostname, label);
5699 mutex_unlock(&fsdb->fsdb_mutex);
5701 name_destroy(&logname);
5702 /* request for update */
5703 mgs_revoke_lock(mgs, fsdb, CONFIG_T_CONFIG);
5709 mutex_unlock(&fsdb->fsdb_mutex);
5713 if (canceled_label != NULL)
5714 OBD_FREE(canceled_label, label_sz);
5716 OBD_FREE(label, label_sz);
5719 mgs_unlink_fsdb(mgs, fsdb);
5720 mgs_put_fsdb(mgs, fsdb);