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)) {
641 if (flags & LDD_F_WRITECONF)
643 else if (flags & LDD_F_VIRGIN)
646 if (!(flags & LDD_F_SV_ALL))
647 snprintf(name_buf, name_buf_size, "%.8s%c%s%04x", fs,
649 (flags & LDD_F_SV_TYPE_MDT) ? "MDT" : "OST",
651 } else if (flags & LDD_F_SV_TYPE_MGS) {
652 snprintf(name_buf, name_buf_size, "MGS");
654 CERROR("unknown server type %#x\n", flags);
661 0 newly marked as in use
663 +EALREADY for update of an old index */
664 static int mgs_set_index(const struct lu_env *env,
665 struct mgs_device *mgs,
666 struct mgs_target_info *mti)
673 rc = mgs_find_or_make_fsdb(env, mgs, mti->mti_fsname, &fsdb);
675 CERROR("Can't get db for %s\n", mti->mti_fsname);
679 mutex_lock(&fsdb->fsdb_mutex);
680 if (mti->mti_flags & LDD_F_SV_TYPE_OST) {
681 imap = fsdb->fsdb_ost_index_map;
682 } else if (mti->mti_flags & LDD_F_SV_TYPE_MDT) {
683 imap = fsdb->fsdb_mdt_index_map;
685 GOTO(out_up, rc = -EINVAL);
688 if (mti->mti_flags & LDD_F_NEED_INDEX) {
689 rc = next_index(imap, INDEX_MAP_SIZE);
691 GOTO(out_up, rc = -ERANGE);
692 mti->mti_stripe_index = rc;
695 /* the last index(0xffff) is reserved for default value. */
696 if (mti->mti_stripe_index >= INDEX_MAP_SIZE * 8 - 1) {
697 LCONSOLE_ERROR_MSG(0x13f, "Server %s requested index %u, "
698 "but index must be less than %u.\n",
699 mti->mti_svname, mti->mti_stripe_index,
700 INDEX_MAP_SIZE * 8 - 1);
701 GOTO(out_up, rc = -ERANGE);
704 if (test_bit(mti->mti_stripe_index, imap)) {
705 if ((mti->mti_flags & LDD_F_VIRGIN) &&
706 !(mti->mti_flags & LDD_F_WRITECONF)) {
707 LCONSOLE_ERROR_MSG(0x140, "Server %s requested index "
708 "%d, but that index is already in "
709 "use. Use --writeconf to force\n",
711 mti->mti_stripe_index);
712 GOTO(out_up, rc = -EADDRINUSE);
714 CDEBUG(D_MGS, "Server %s updating index %d\n",
715 mti->mti_svname, mti->mti_stripe_index);
716 GOTO(out_up, rc = EALREADY);
719 set_bit(mti->mti_stripe_index, imap);
720 if (mti->mti_flags & LDD_F_SV_TYPE_MDT)
721 fsdb->fsdb_mdt_count++;
724 set_bit(mti->mti_stripe_index, imap);
725 clear_bit(FSDB_LOG_EMPTY, &fsdb->fsdb_flags);
726 if (server_make_name(mti->mti_flags & ~(LDD_F_VIRGIN | LDD_F_WRITECONF),
727 mti->mti_stripe_index, mti->mti_fsname,
728 mti->mti_svname, sizeof(mti->mti_svname))) {
729 CERROR("unknown server type %#x\n", mti->mti_flags);
730 GOTO(out_up, rc = -EINVAL);
733 CDEBUG(D_MGS, "Set index for %s to %d\n", mti->mti_svname,
734 mti->mti_stripe_index);
736 GOTO(out_up, rc = 0);
739 mutex_unlock(&fsdb->fsdb_mutex);
740 mgs_put_fsdb(mgs, fsdb);
744 struct mgs_modify_lookup {
745 struct cfg_marker mml_marker;
749 static int mgs_check_record_match(const struct lu_env *env,
750 struct llog_handle *llh,
751 struct llog_rec_hdr *rec, void *data)
753 struct cfg_marker *mc_marker = data;
754 struct cfg_marker *marker;
755 struct lustre_cfg *lcfg = REC_DATA(rec);
756 int cfg_len = REC_DATA_LEN(rec);
761 if (rec->lrh_type != OBD_CFG_REC) {
762 CDEBUG(D_ERROR, "Unhandled lrh_type: %#x\n", rec->lrh_type);
766 rc = lustre_cfg_sanity_check(lcfg, cfg_len);
768 CDEBUG(D_ERROR, "Insane cfg\n");
772 /* We only care about markers */
773 if (lcfg->lcfg_command != LCFG_MARKER)
776 marker = lustre_cfg_buf(lcfg, 1);
778 if (marker->cm_flags & CM_SKIP)
781 if ((strcmp(mc_marker->cm_comment, marker->cm_comment) == 0) &&
782 (strcmp(mc_marker->cm_tgtname, marker->cm_tgtname) == 0)) {
783 /* Found a non-skipped marker match */
784 CDEBUG(D_MGS, "Matched rec %u marker %d flag %x %s %s\n",
785 rec->lrh_index, marker->cm_step,
786 marker->cm_flags, marker->cm_tgtname,
788 rc = LLOG_PROC_BREAK;
795 * Check an existing config log record with matching comment and device
797 * 0 - checked successfully,
798 * LLOG_PROC_BREAK - record matches
801 static int mgs_check_marker(const struct lu_env *env, struct mgs_device *mgs,
802 struct fs_db *fsdb, struct mgs_target_info *mti,
803 char *logname, char *devname, char *comment)
805 struct llog_handle *loghandle;
806 struct llog_ctxt *ctxt;
807 struct cfg_marker *mc_marker;
812 LASSERT(mutex_is_locked(&fsdb->fsdb_mutex));
813 CDEBUG(D_MGS, "mgs check %s/%s/%s\n", logname, devname, comment);
815 ctxt = llog_get_context(mgs->mgs_obd, LLOG_CONFIG_ORIG_CTXT);
816 LASSERT(ctxt != NULL);
817 rc = llog_open(env, ctxt, &loghandle, NULL, logname, LLOG_OPEN_EXISTS);
824 rc = llog_init_handle(env, loghandle, LLOG_F_IS_PLAIN, NULL);
828 if (llog_get_size(loghandle) <= 1)
829 GOTO(out_close, rc = 0);
831 OBD_ALLOC_PTR(mc_marker);
833 GOTO(out_close, rc = -ENOMEM);
834 if (strlcpy(mc_marker->cm_comment, comment,
835 sizeof(mc_marker->cm_comment)) >=
836 sizeof(mc_marker->cm_comment))
837 GOTO(out_free, rc = -E2BIG);
838 if (strlcpy(mc_marker->cm_tgtname, devname,
839 sizeof(mc_marker->cm_tgtname)) >=
840 sizeof(mc_marker->cm_tgtname))
841 GOTO(out_free, rc = -E2BIG);
843 rc = llog_process(env, loghandle, mgs_check_record_match,
844 (void *)mc_marker, NULL);
847 OBD_FREE_PTR(mc_marker);
850 llog_close(env, loghandle);
852 if (rc && rc != LLOG_PROC_BREAK)
853 CDEBUG(D_ERROR, "%s: mgs check %s/%s failed: rc = %d\n",
854 mgs->mgs_obd->obd_name, mti->mti_svname, comment, rc);
859 static int mgs_modify_handler(const struct lu_env *env,
860 struct llog_handle *llh,
861 struct llog_rec_hdr *rec, void *data)
863 struct mgs_modify_lookup *mml = data;
864 struct cfg_marker *marker;
865 struct lustre_cfg *lcfg = REC_DATA(rec);
866 int cfg_len = REC_DATA_LEN(rec);
870 if (rec->lrh_type != OBD_CFG_REC) {
871 CERROR("unhandled lrh_type: %#x\n", rec->lrh_type);
875 rc = lustre_cfg_sanity_check(lcfg, cfg_len);
877 CERROR("Insane cfg\n");
881 /* We only care about markers */
882 if (lcfg->lcfg_command != LCFG_MARKER)
885 marker = lustre_cfg_buf(lcfg, 1);
886 if ((strcmp(mml->mml_marker.cm_comment, marker->cm_comment) == 0) &&
887 (strcmp(mml->mml_marker.cm_tgtname, marker->cm_tgtname) == 0) &&
888 !(marker->cm_flags & CM_SKIP)) {
889 /* Found a non-skipped marker match */
890 CDEBUG(D_MGS, "Changing rec %u marker %d %x->%x: %s %s\n",
891 rec->lrh_index, marker->cm_step,
892 marker->cm_flags, mml->mml_marker.cm_flags,
893 marker->cm_tgtname, marker->cm_comment);
894 /* Overwrite the old marker llog entry */
895 marker->cm_flags &= ~CM_EXCLUDE; /* in case we're unexcluding */
896 marker->cm_flags |= mml->mml_marker.cm_flags;
897 marker->cm_canceltime = mml->mml_marker.cm_canceltime;
898 rc = llog_write(env, llh, rec, rec->lrh_index);
907 * Modify an existing config log record (for CM_SKIP or CM_EXCLUDE)
909 * 0 - modified successfully,
910 * 1 - no modification was done
913 static int mgs_modify(const struct lu_env *env, struct mgs_device *mgs,
914 struct fs_db *fsdb, struct mgs_target_info *mti,
915 char *logname, char *devname, char *comment, int flags)
917 struct llog_handle *loghandle;
918 struct llog_ctxt *ctxt;
919 struct mgs_modify_lookup *mml;
924 LASSERT(mutex_is_locked(&fsdb->fsdb_mutex));
925 CDEBUG(D_MGS, "modify %s/%s/%s fl=%x\n", logname, devname, comment,
928 ctxt = llog_get_context(mgs->mgs_obd, LLOG_CONFIG_ORIG_CTXT);
929 LASSERT(ctxt != NULL);
930 rc = llog_open(env, ctxt, &loghandle, NULL, logname, LLOG_OPEN_EXISTS);
937 rc = llog_init_handle(env, loghandle, LLOG_F_IS_PLAIN, NULL);
941 if (llog_get_size(loghandle) <= 1)
942 GOTO(out_close, rc = 0);
946 GOTO(out_close, rc = -ENOMEM);
947 if (strlcpy(mml->mml_marker.cm_comment, comment,
948 sizeof(mml->mml_marker.cm_comment)) >=
949 sizeof(mml->mml_marker.cm_comment))
950 GOTO(out_free, rc = -E2BIG);
951 if (strlcpy(mml->mml_marker.cm_tgtname, devname,
952 sizeof(mml->mml_marker.cm_tgtname)) >=
953 sizeof(mml->mml_marker.cm_tgtname))
954 GOTO(out_free, rc = -E2BIG);
955 /* Modify mostly means cancel */
956 mml->mml_marker.cm_flags = flags;
957 mml->mml_marker.cm_canceltime = flags ? ktime_get_real_seconds() : 0;
958 mml->mml_modified = 0;
959 rc = llog_process(env, loghandle, mgs_modify_handler, (void *)mml,
961 if (!rc && !mml->mml_modified)
968 llog_close(env, loghandle);
971 CERROR("%s: modify %s/%s failed: rc = %d\n",
972 mgs->mgs_obd->obd_name, mti->mti_svname, comment, rc);
985 /** This structure is passed to mgs_replace_handler */
986 struct mgs_replace_data {
987 /* Nids are replaced for this target device */
988 struct mgs_target_info target;
989 /* Temporary modified llog */
990 struct llog_handle *temp_llh;
991 enum replace_state state;
997 * Check: a) if block should be skipped
998 * b) is it target block
1003 * \retval 0 should not to be skipped
1004 * \retval 1 should to be skipped
1006 static int check_markers(struct lustre_cfg *lcfg,
1007 struct mgs_replace_data *mrd)
1009 struct cfg_marker *marker;
1011 /* Track markers. Find given device */
1012 if (lcfg->lcfg_command == LCFG_MARKER) {
1013 marker = lustre_cfg_buf(lcfg, 1);
1014 /* Clean llog from records marked as CM_SKIP.
1015 CM_EXCLUDE records are used for "active" command
1016 and can be restored if needed */
1017 if ((marker->cm_flags & (CM_SKIP | CM_START)) ==
1018 (CM_SKIP | CM_START)) {
1019 mrd->state = REPLACE_SKIP;
1023 if ((marker->cm_flags & (CM_SKIP | CM_END)) ==
1024 (CM_SKIP | CM_END)) {
1025 mrd->state = REPLACE_COPY;
1029 if (strcmp(mrd->target.mti_svname, marker->cm_tgtname) == 0) {
1030 LASSERT(!(marker->cm_flags & CM_START) ||
1031 !(marker->cm_flags & CM_END));
1032 if (marker->cm_flags & CM_START) {
1033 if (!strncmp(marker->cm_comment,
1034 "add failnid", 11)) {
1035 mrd->state = REPLACE_SKIP;
1037 mrd->state = REPLACE_UUID;
1038 mrd->failover = NULL;
1040 } else if (marker->cm_flags & CM_END)
1041 mrd->state = REPLACE_COPY;
1043 if (!strncmp(marker->cm_comment,
1052 static int record_base(const struct lu_env *env, struct llog_handle *llh,
1053 char *cfgname, lnet_nid_t nid, int cmd,
1054 char *s1, char *s2, char *s3, char *s4)
1056 struct mgs_thread_info *mgi = mgs_env_info(env);
1057 struct llog_cfg_rec *lcr;
1060 CDEBUG(D_MGS, "lcfg %s %#x %s %s %s %s\n", cfgname,
1061 cmd, s1, s2, s3, s4);
1063 lustre_cfg_bufs_reset(&mgi->mgi_bufs, cfgname);
1065 lustre_cfg_bufs_set_string(&mgi->mgi_bufs, 1, s1);
1067 lustre_cfg_bufs_set_string(&mgi->mgi_bufs, 2, s2);
1069 lustre_cfg_bufs_set_string(&mgi->mgi_bufs, 3, s3);
1071 lustre_cfg_bufs_set_string(&mgi->mgi_bufs, 4, s4);
1073 lcr = lustre_cfg_rec_new(cmd, &mgi->mgi_bufs);
1077 lcr->lcr_cfg.lcfg_nid = nid;
1078 rc = llog_write(env, llh, &lcr->lcr_hdr, LLOG_NEXT_IDX);
1080 lustre_cfg_rec_free(lcr);
1084 "failed to write lcfg %s %#x %s %s %s %s: rc = %d\n",
1085 cfgname, cmd, s1, s2, s3, s4, rc);
1089 static inline int record_add_uuid(const struct lu_env *env,
1090 struct llog_handle *llh,
1091 uint64_t nid, char *uuid)
1093 return record_base(env, llh, NULL, nid, LCFG_ADD_UUID, uuid,
1097 static inline int record_add_conn(const struct lu_env *env,
1098 struct llog_handle *llh,
1099 char *devname, char *uuid)
1101 return record_base(env, llh, devname, 0, LCFG_ADD_CONN, uuid,
1105 static inline int record_attach(const struct lu_env *env,
1106 struct llog_handle *llh, char *devname,
1107 char *type, char *uuid)
1109 return record_base(env, llh, devname, 0, LCFG_ATTACH, type, uuid,
1113 static inline int record_setup(const struct lu_env *env,
1114 struct llog_handle *llh, char *devname,
1115 char *s1, char *s2, char *s3, char *s4)
1117 return record_base(env, llh, devname, 0, LCFG_SETUP, s1, s2, s3, s4);
1121 * \retval <0 record processing error
1122 * \retval n record is processed. No need copy original one.
1123 * \retval 0 record is not processed.
1125 static int process_command(const struct lu_env *env, struct lustre_cfg *lcfg,
1126 struct mgs_replace_data *mrd)
1133 if (mrd->state == REPLACE_UUID &&
1134 lcfg->lcfg_command == LCFG_ADD_UUID) {
1135 /* LCFG_ADD_UUID command found. Let's skip original command
1136 and add passed nids */
1137 ptr = mrd->target.mti_params;
1138 while (class_parse_nid(ptr, &nid, &ptr) == 0) {
1139 if (!mrd->nodeuuid) {
1140 rc = name_create(&mrd->nodeuuid,
1141 libcfs_nid2str(nid), "");
1143 CERROR("Can't create uuid for "
1144 "nid %s, device %s\n",
1145 libcfs_nid2str(nid),
1146 mrd->target.mti_svname);
1150 CDEBUG(D_MGS, "add nid %s with uuid %s, "
1151 "device %s\n", libcfs_nid2str(nid),
1152 mrd->target.mti_params,
1154 rc = record_add_uuid(env,
1158 CWARN("%s: Can't add nid %s for uuid %s :rc=%d\n",
1159 mrd->target.mti_svname,
1160 libcfs_nid2str(nid),
1166 mrd->failover = ptr;
1171 if (nids_added == 0) {
1172 CERROR("No new nids were added, nid %s with uuid %s, "
1173 "device %s\n", libcfs_nid2str(nid),
1174 mrd->nodeuuid ? mrd->nodeuuid : "NULL",
1175 mrd->target.mti_svname);
1176 name_destroy(&mrd->nodeuuid);
1179 mrd->state = REPLACE_SETUP;
1185 if (mrd->state == REPLACE_SETUP && lcfg->lcfg_command == LCFG_SETUP) {
1186 /* LCFG_SETUP command found. UUID should be changed */
1187 rc = record_setup(env,
1189 /* devname the same */
1190 lustre_cfg_string(lcfg, 0),
1191 /* s1 is not changed */
1192 lustre_cfg_string(lcfg, 1),
1194 /* s3 is not changed */
1195 lustre_cfg_string(lcfg, 3),
1196 /* s4 is not changed */
1197 lustre_cfg_string(lcfg, 4));
1199 name_destroy(&mrd->nodeuuid);
1203 if (mrd->failover) {
1204 ptr = mrd->failover;
1205 while (class_parse_nid(ptr, &nid, &ptr) == 0) {
1206 if (mrd->nodeuuid == NULL) {
1207 rc = name_create(&mrd->nodeuuid,
1208 libcfs_nid2str(nid),
1214 CDEBUG(D_MGS, "add nid %s for failover %s\n",
1215 libcfs_nid2str(nid), mrd->nodeuuid);
1216 rc = record_add_uuid(env, mrd->temp_llh, nid,
1219 CWARN("%s: Can't add nid %s for failover %s :rc = %d\n",
1220 mrd->target.mti_svname,
1221 libcfs_nid2str(nid),
1223 name_destroy(&mrd->nodeuuid);
1227 rc = record_add_conn(env,
1229 lustre_cfg_string(lcfg, 0),
1231 name_destroy(&mrd->nodeuuid);
1236 if (mrd->nodeuuid) {
1237 rc = record_add_conn(env, mrd->temp_llh,
1238 lustre_cfg_string(lcfg, 0),
1240 name_destroy(&mrd->nodeuuid);
1245 mrd->state = REPLACE_DONE;
1249 /* All new UUID are added. Skip. */
1250 if (mrd->state == REPLACE_SETUP &&
1251 lcfg->lcfg_command == LCFG_ADD_UUID)
1254 /* Another commands in target device block */
1259 * Handler that called for every record in llog.
1260 * Records are processed in order they placed in llog.
1262 * \param[in] llh log to be processed
1263 * \param[in] rec current record
1264 * \param[in] data mgs_replace_data structure
1268 static int mgs_replace_nids_handler(const struct lu_env *env,
1269 struct llog_handle *llh,
1270 struct llog_rec_hdr *rec,
1273 struct mgs_replace_data *mrd;
1274 struct lustre_cfg *lcfg = REC_DATA(rec);
1275 int cfg_len = REC_DATA_LEN(rec);
1279 mrd = (struct mgs_replace_data *)data;
1281 if (rec->lrh_type != OBD_CFG_REC) {
1282 CERROR("unhandled lrh_type: %#x, cmd %x %s %s\n",
1283 rec->lrh_type, lcfg->lcfg_command,
1284 lustre_cfg_string(lcfg, 0),
1285 lustre_cfg_string(lcfg, 1));
1289 rc = lustre_cfg_sanity_check(lcfg, cfg_len);
1291 /* Do not copy any invalidated records */
1292 GOTO(skip_out, rc = 0);
1295 rc = check_markers(lcfg, mrd);
1296 if (rc || mrd->state == REPLACE_SKIP)
1297 GOTO(skip_out, rc = 0);
1299 /* Write to new log all commands outside target device block */
1300 if (mrd->state == REPLACE_COPY)
1301 GOTO(copy_out, rc = 0);
1303 if (mrd->state == REPLACE_DONE &&
1304 (lcfg->lcfg_command == LCFG_ADD_UUID ||
1305 lcfg->lcfg_command == LCFG_ADD_CONN)) {
1307 CWARN("Previous failover is deleted, but new one is "
1308 "not set. This means you configure system "
1309 "without failover or passed wrong replace_nids "
1310 "command parameters. Device %s, passed nids %s\n",
1311 mrd->target.mti_svname, mrd->target.mti_params);
1312 GOTO(skip_out, rc = 0);
1315 rc = process_command(env, lcfg, mrd);
1322 /* Record is placed in temporary llog as is */
1323 rc = llog_write(env, mrd->temp_llh, rec, LLOG_NEXT_IDX);
1325 CDEBUG(D_MGS, "Copied 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 CDEBUG(D_MGS, "Skipped idx=%d, rc=%d, len=%d, cmd %x %s %s\n",
1332 rec->lrh_index, rc, rec->lrh_len, lcfg->lcfg_command,
1333 lustre_cfg_string(lcfg, 0), lustre_cfg_string(lcfg, 1));
1337 static int mgs_log_is_empty(const struct lu_env *env,
1338 struct mgs_device *mgs, char *name)
1340 struct llog_ctxt *ctxt;
1343 ctxt = llog_get_context(mgs->mgs_obd, LLOG_CONFIG_ORIG_CTXT);
1344 LASSERT(ctxt != NULL);
1346 rc = llog_is_empty(env, ctxt, name);
1347 llog_ctxt_put(ctxt);
1351 static int mgs_replace_log(const struct lu_env *env,
1352 struct obd_device *mgs,
1353 char *logname, char *devname,
1354 llog_cb_t replace_handler, void *data)
1356 struct llog_handle *orig_llh, *backup_llh;
1357 struct llog_ctxt *ctxt;
1358 struct mgs_replace_data *mrd;
1359 struct mgs_device *mgs_dev = lu2mgs_dev(mgs->obd_lu_dev);
1360 static struct obd_uuid cfg_uuid = { .uuid = "config_uuid" };
1362 int rc, rc2, buf_size;
1366 ctxt = llog_get_context(mgs, LLOG_CONFIG_ORIG_CTXT);
1367 LASSERT(ctxt != NULL);
1369 if (mgs_log_is_empty(env, mgs_dev, logname)) {
1370 /* Log is empty. Nothing to replace */
1371 GOTO(out_put, rc = 0);
1374 now = ktime_get_real_seconds();
1376 /* max time64_t in decimal fits into 20 bytes long string */
1377 buf_size = strlen(logname) + 1 + 20 + 1 + strlen(".bak") + 1;
1378 OBD_ALLOC(backup, buf_size);
1380 GOTO(out_put, rc = -ENOMEM);
1382 snprintf(backup, buf_size, "%s.%llu.bak", logname, now);
1384 rc = llog_backup(env, mgs, ctxt, ctxt, logname, backup);
1386 /* Now erase original log file. Connections are not allowed.
1387 Backup is already saved */
1388 rc = llog_erase(env, ctxt, NULL, logname);
1391 } else if (rc != -ENOENT) {
1392 CERROR("%s: can't make backup for %s: rc = %d\n",
1393 mgs->obd_name, logname, rc);
1397 /* open local log */
1398 rc = llog_open_create(env, ctxt, &orig_llh, NULL, logname);
1400 GOTO(out_restore, rc);
1402 rc = llog_init_handle(env, orig_llh, LLOG_F_IS_PLAIN, &cfg_uuid);
1404 GOTO(out_closel, rc);
1406 /* open backup llog */
1407 rc = llog_open(env, ctxt, &backup_llh, NULL, backup,
1410 GOTO(out_closel, rc);
1412 rc = llog_init_handle(env, backup_llh, LLOG_F_IS_PLAIN, NULL);
1414 GOTO(out_close, rc);
1416 if (llog_get_size(backup_llh) <= 1)
1417 GOTO(out_close, rc = 0);
1421 GOTO(out_close, rc = -ENOMEM);
1422 /* devname is only needed information to replace UUID records */
1424 strlcpy(mrd->target.mti_svname, devname,
1425 sizeof(mrd->target.mti_svname));
1426 /* data is parsed in llog callback */
1428 strlcpy(mrd->target.mti_params, data,
1429 sizeof(mrd->target.mti_params));
1430 /* Copy records to this temporary llog */
1431 mrd->temp_llh = orig_llh;
1433 rc = llog_process(env, backup_llh, replace_handler,
1437 rc2 = llog_close(NULL, backup_llh);
1441 rc2 = llog_close(NULL, orig_llh);
1447 CERROR("%s: llog should be restored: rc = %d\n",
1449 rc2 = llog_backup(env, mgs, ctxt, ctxt, backup,
1452 CERROR("%s: can't restore backup %s: rc = %d\n",
1453 mgs->obd_name, logname, rc2);
1457 OBD_FREE(backup, buf_size);
1460 llog_ctxt_put(ctxt);
1463 CERROR("%s: failed to replace log %s: rc = %d\n",
1464 mgs->obd_name, logname, rc);
1469 static int mgs_replace_nids_log(const struct lu_env *env,
1470 struct obd_device *obd,
1471 char *logname, char *devname, char *nids)
1473 CDEBUG(D_MGS, "Replace NIDs for %s in %s\n", devname, logname);
1474 return mgs_replace_log(env, obd, logname, devname,
1475 mgs_replace_nids_handler, nids);
1479 * Parse device name and get file system name and/or device index
1481 * @devname device name (ex. lustre-MDT0000)
1482 * @fsname file system name extracted from @devname and returned
1483 * to the caller (optional)
1484 * @index device index extracted from @devname and returned to
1485 * the caller (optional)
1487 * RETURN 0 success if we are only interested in
1488 * extracting fsname from devname.
1491 * LDD_F_SV_TYPE_* Besides extracting the fsname the
1492 * user also wants the index. Report to
1493 * the user the type of obd device the
1494 * returned index belongs too.
1496 * -EINVAL The obd device name is improper so
1497 * fsname could not be extracted.
1499 * -ENXIO Failed to extract the index out of
1500 * the obd device name. Most likely an
1501 * invalid obd device name
1503 static int mgs_parse_devname(char *devname, char *fsname, u32 *index)
1508 /* Extract fsname */
1510 rc = server_name2fsname(devname, fsname, NULL);
1512 CDEBUG(D_MGS, "Device name %s without fsname\n",
1519 rc = server_name2index(devname, index, NULL);
1521 CDEBUG(D_MGS, "Device name %s with wrong index\n",
1527 /* server_name2index can return LDD_F_SV_TYPE_* so always return rc */
1531 /* This is only called during replace_nids */
1532 static int only_mgs_is_running(struct obd_device *mgs_obd)
1534 /* TDB: Is global variable with devices count exists? */
1535 int num_devices = get_devices_count();
1536 int num_exports = 0;
1537 struct obd_export *exp;
1539 spin_lock(&mgs_obd->obd_dev_lock);
1540 list_for_each_entry(exp, &mgs_obd->obd_exports, exp_obd_chain) {
1541 /* skip self export */
1542 if (exp == mgs_obd->obd_self_export)
1547 if (num_exports > 1)
1548 CERROR("%s: node %s still connected during replace_nids connect_flags:%llx\n",
1550 libcfs_nidstr(&exp->exp_nid_stats->nid),
1551 exp_connect_flags(exp));
1553 spin_unlock(&mgs_obd->obd_dev_lock);
1555 /* osd, MGS and MGC + MGC export (nosvc starts MGC)
1556 * (wc -l /proc/fs/lustre/devices <= 3) && (non self exports == 1)
1558 return (num_devices <= 3) && (num_exports <= 1);
1561 static int name_create_mdt(char **logname, char *fsname, int mdt_idx)
1565 if (mdt_idx > INDEX_MAP_MAX_VALUE)
1568 snprintf(postfix, sizeof(postfix), "-MDT%04x", mdt_idx);
1569 return name_create(logname, fsname, postfix);
1573 * Replace nids for \a device to \a nids values
1575 * \param obd MGS obd device
1576 * \param devname nids need to be replaced for this device
1577 * (ex. lustre-OST0000)
1578 * \param nids nids list (ex. nid1,nid2,nid3)
1582 int mgs_replace_nids(const struct lu_env *env,
1583 struct mgs_device *mgs,
1584 char *devname, char *nids)
1586 /* Assume fsname is part of device name */
1587 char fsname[MTI_NAME_MAXLEN];
1591 struct fs_db *fsdb = NULL;
1594 struct obd_device *mgs_obd = mgs->mgs_obd;
1597 /* We can only change NIDs if no other nodes are connected */
1598 spin_lock(&mgs_obd->obd_dev_lock);
1599 conn_state = mgs_obd->obd_no_conn;
1600 mgs_obd->obd_no_conn = 1;
1601 spin_unlock(&mgs_obd->obd_dev_lock);
1603 /* We can not change nids if not only MGS is started */
1604 if (!only_mgs_is_running(mgs_obd)) {
1605 CERROR("Only MGS is allowed to be started\n");
1606 GOTO(out, rc = -EINPROGRESS);
1609 /* Get fsname and index */
1610 rc = mgs_parse_devname(devname, fsname, &index);
1614 rc = mgs_find_or_make_fsdb(env, mgs, fsname, &fsdb);
1616 CERROR("%s: can't find fsdb: rc = %d\n", fsname, rc);
1620 /* Process client llogs */
1621 rc = name_create(&logname, fsname, "-client");
1624 rc = mgs_replace_nids_log(env, mgs_obd, logname, devname, nids);
1625 name_destroy(&logname);
1627 CERROR("%s: error while replacing NIDs for %s: rc = %d\n",
1628 fsname, devname, rc);
1632 /* Process MDT llogs */
1633 for (i = 0; i < INDEX_MAP_SIZE * 8; i++) {
1634 if (!test_bit(i, fsdb->fsdb_mdt_index_map))
1636 rc = name_create_mdt(&logname, fsname, i);
1639 rc = mgs_replace_nids_log(env, mgs_obd, logname, devname, nids);
1640 name_destroy(&logname);
1646 spin_lock(&mgs_obd->obd_dev_lock);
1647 mgs_obd->obd_no_conn = conn_state;
1648 spin_unlock(&mgs_obd->obd_dev_lock);
1651 mgs_put_fsdb(mgs, fsdb);
1657 * This is called for every record in llog. Some of records are
1658 * skipped, others are copied to new log as is.
1659 * Records to be skipped are
1660 * marker records marked SKIP
1661 * records enclosed between SKIP markers
1663 * \param[in] llh log to be processed
1664 * \param[in] rec current record
1665 * \param[in] data mgs_replace_data structure
1669 static int mgs_clear_config_handler(const struct lu_env *env,
1670 struct llog_handle *llh,
1671 struct llog_rec_hdr *rec, void *data)
1673 struct mgs_replace_data *mrd;
1674 struct lustre_cfg *lcfg = REC_DATA(rec);
1675 int cfg_len = REC_DATA_LEN(rec);
1680 mrd = (struct mgs_replace_data *)data;
1682 if (rec->lrh_type != OBD_CFG_REC) {
1683 CDEBUG(D_MGS, "Config llog Name=%s, Record Index=%u, "
1684 "Unhandled Record Type=%#x\n", llh->lgh_name,
1685 rec->lrh_index, rec->lrh_type);
1689 rc = lustre_cfg_sanity_check(lcfg, cfg_len);
1691 CDEBUG(D_MGS, "Config llog Name=%s, Invalid config file.",
1696 if (lcfg->lcfg_command == LCFG_MARKER) {
1697 struct cfg_marker *marker;
1699 marker = lustre_cfg_buf(lcfg, 1);
1700 if (marker->cm_flags & CM_SKIP) {
1701 if (marker->cm_flags & CM_START)
1702 mrd->state = REPLACE_SKIP;
1703 if (marker->cm_flags & CM_END)
1704 mrd->state = REPLACE_COPY;
1705 /* SKIP section started or finished */
1706 CDEBUG(D_MGS, "Skip idx=%d, rc=%d, len=%d, "
1707 "cmd %x %s %s\n", rec->lrh_index, rc,
1708 rec->lrh_len, lcfg->lcfg_command,
1709 lustre_cfg_string(lcfg, 0),
1710 lustre_cfg_string(lcfg, 1));
1714 if (mrd->state == REPLACE_SKIP) {
1715 /* record enclosed between SKIP markers, skip it */
1716 CDEBUG(D_MGS, "Skip idx=%d, rc=%d, len=%d, "
1717 "cmd %x %s %s\n", rec->lrh_index, rc,
1718 rec->lrh_len, lcfg->lcfg_command,
1719 lustre_cfg_string(lcfg, 0),
1720 lustre_cfg_string(lcfg, 1));
1725 /* Record is placed in temporary llog as is */
1726 rc = llog_write(env, mrd->temp_llh, rec, LLOG_NEXT_IDX);
1728 CDEBUG(D_MGS, "Copied idx=%d, rc=%d, len=%d, cmd %x %s %s\n",
1729 rec->lrh_index, rc, rec->lrh_len, lcfg->lcfg_command,
1730 lustre_cfg_string(lcfg, 0), lustre_cfg_string(lcfg, 1));
1735 * Directory CONFIGS/ may contain files which are not config logs to
1736 * be cleared. Skip any llogs with a non-alphanumeric character after
1737 * the last '-'. For example, fsname-MDT0000.sav, fsname-MDT0000.bak,
1738 * fsname-MDT0000.orig, fsname-MDT0000~, fsname-MDT0000.20150516, etc.
1740 static bool config_to_clear(const char *logname)
1745 str = strrchr(logname, '-');
1750 while (isalnum(str[++i]));
1751 return str[i] == '\0';
1755 * Clear config logs for \a name
1758 * \param mgs MGS device
1759 * \param name name of device or of filesystem
1760 * (ex. lustre-OST0000 or lustre) in later case all logs
1765 int mgs_clear_configs(const struct lu_env *env,
1766 struct mgs_device *mgs, const char *name)
1768 struct list_head dentry_list;
1769 struct mgs_direntry *dirent, *n;
1772 struct obd_device *mgs_obd = mgs->mgs_obd;
1777 /* Prevent clients and servers from connecting to mgs */
1778 spin_lock(&mgs_obd->obd_dev_lock);
1779 conn_state = mgs_obd->obd_no_conn;
1780 mgs_obd->obd_no_conn = 1;
1781 spin_unlock(&mgs_obd->obd_dev_lock);
1784 * config logs cannot be cleaned if anything other than
1787 if (!only_mgs_is_running(mgs_obd)) {
1788 CERROR("Only MGS is allowed to be started\n");
1789 GOTO(out, rc = -EBUSY);
1792 /* Find all the logs in the CONFIGS directory */
1793 rc = class_dentry_readdir(env, mgs, &dentry_list);
1795 CERROR("%s: cannot read config directory '%s': rc = %d\n",
1796 mgs_obd->obd_name, MOUNT_CONFIGS_DIR, rc);
1800 if (list_empty(&dentry_list)) {
1801 CERROR("%s: list empty reading config dir '%s': rc = %d\n",
1802 mgs_obd->obd_name, MOUNT_CONFIGS_DIR, -ENOENT);
1803 GOTO(out, rc = -ENOENT);
1806 OBD_ALLOC(namedash, strlen(name) + 2);
1807 if (namedash == NULL)
1808 GOTO(out, rc = -ENOMEM);
1809 snprintf(namedash, strlen(name) + 2, "%s-", name);
1811 list_for_each_entry(dirent, &dentry_list, mde_list) {
1812 if (strcmp(name, dirent->mde_name) &&
1813 strncmp(namedash, dirent->mde_name, strlen(namedash)))
1815 if (!config_to_clear(dirent->mde_name))
1817 CDEBUG(D_MGS, "%s: Clear config log %s\n",
1818 mgs_obd->obd_name, dirent->mde_name);
1819 rc = mgs_replace_log(env, mgs_obd, dirent->mde_name, NULL,
1820 mgs_clear_config_handler, NULL);
1825 list_for_each_entry_safe(dirent, n, &dentry_list, mde_list) {
1826 list_del_init(&dirent->mde_list);
1827 mgs_direntry_free(dirent);
1829 OBD_FREE(namedash, strlen(name) + 2);
1831 spin_lock(&mgs_obd->obd_dev_lock);
1832 mgs_obd->obd_no_conn = conn_state;
1833 spin_unlock(&mgs_obd->obd_dev_lock);
1838 static int record_lov_setup(const struct lu_env *env, struct llog_handle *llh,
1839 char *devname, struct lov_desc *desc)
1841 struct mgs_thread_info *mgi = mgs_env_info(env);
1842 struct llog_cfg_rec *lcr;
1845 lustre_cfg_bufs_reset(&mgi->mgi_bufs, devname);
1846 lustre_cfg_bufs_set(&mgi->mgi_bufs, 1, desc, sizeof(*desc));
1847 lcr = lustre_cfg_rec_new(LCFG_SETUP, &mgi->mgi_bufs);
1851 rc = llog_write(env, llh, &lcr->lcr_hdr, LLOG_NEXT_IDX);
1852 lustre_cfg_rec_free(lcr);
1856 static int record_lmv_setup(const struct lu_env *env, struct llog_handle *llh,
1857 char *devname, struct lmv_desc *desc)
1859 struct mgs_thread_info *mgi = mgs_env_info(env);
1860 struct llog_cfg_rec *lcr;
1863 lustre_cfg_bufs_reset(&mgi->mgi_bufs, devname);
1864 lustre_cfg_bufs_set(&mgi->mgi_bufs, 1, desc, sizeof(*desc));
1865 lcr = lustre_cfg_rec_new(LCFG_SETUP, &mgi->mgi_bufs);
1869 rc = llog_write(env, llh, &lcr->lcr_hdr, LLOG_NEXT_IDX);
1870 lustre_cfg_rec_free(lcr);
1874 static inline int record_mdc_add(const struct lu_env *env,
1875 struct llog_handle *llh,
1876 char *logname, char *mdcuuid,
1877 char *mdtuuid, char *index,
1880 return record_base(env,llh,logname,0,LCFG_ADD_MDC,
1881 mdtuuid,index,gen,mdcuuid);
1884 static inline int record_lov_add(const struct lu_env *env,
1885 struct llog_handle *llh,
1886 char *lov_name, char *ost_uuid,
1887 char *index, char *gen)
1889 return record_base(env, llh, lov_name, 0, LCFG_LOV_ADD_OBD,
1890 ost_uuid, index, gen, NULL);
1893 static inline int record_mount_opt(const struct lu_env *env,
1894 struct llog_handle *llh,
1895 char *profile, char *lov_name,
1898 return record_base(env, llh, NULL, 0, LCFG_MOUNTOPT,
1899 profile, lov_name, mdc_name, NULL);
1902 static int record_marker(const struct lu_env *env,
1903 struct llog_handle *llh,
1904 struct fs_db *fsdb, __u32 flags,
1905 char *tgtname, char *comment)
1907 struct mgs_thread_info *mgi = mgs_env_info(env);
1908 struct llog_cfg_rec *lcr;
1912 if (flags & CM_START)
1914 mgi->mgi_marker.cm_step = fsdb->fsdb_gen;
1915 mgi->mgi_marker.cm_flags = flags;
1916 mgi->mgi_marker.cm_vers = LUSTRE_VERSION_CODE;
1917 cplen = strlcpy(mgi->mgi_marker.cm_tgtname, tgtname,
1918 sizeof(mgi->mgi_marker.cm_tgtname));
1919 if (cplen >= sizeof(mgi->mgi_marker.cm_tgtname))
1921 cplen = strlcpy(mgi->mgi_marker.cm_comment, comment,
1922 sizeof(mgi->mgi_marker.cm_comment));
1923 if (cplen >= sizeof(mgi->mgi_marker.cm_comment))
1925 mgi->mgi_marker.cm_createtime = ktime_get_real_seconds();
1926 mgi->mgi_marker.cm_canceltime = 0;
1927 lustre_cfg_bufs_reset(&mgi->mgi_bufs, NULL);
1928 lustre_cfg_bufs_set(&mgi->mgi_bufs, 1, &mgi->mgi_marker,
1929 sizeof(mgi->mgi_marker));
1930 lcr = lustre_cfg_rec_new(LCFG_MARKER, &mgi->mgi_bufs);
1934 rc = llog_write(env, llh, &lcr->lcr_hdr, LLOG_NEXT_IDX);
1935 lustre_cfg_rec_free(lcr);
1939 static int record_start_log(const struct lu_env *env, struct mgs_device *mgs,
1940 struct llog_handle **llh, char *name)
1942 static struct obd_uuid cfg_uuid = { .uuid = "config_uuid" };
1943 struct llog_ctxt *ctxt;
1948 GOTO(out, rc = -EBUSY);
1950 ctxt = llog_get_context(mgs->mgs_obd, LLOG_CONFIG_ORIG_CTXT);
1952 GOTO(out, rc = -ENODEV);
1953 LASSERT(ctxt->loc_obd == mgs->mgs_obd);
1955 rc = llog_open_create(env, ctxt, llh, NULL, name);
1958 rc = llog_init_handle(env, *llh, LLOG_F_IS_PLAIN, &cfg_uuid);
1960 llog_close(env, *llh);
1962 llog_ctxt_put(ctxt);
1965 CERROR("%s: can't start log %s: rc = %d\n",
1966 mgs->mgs_obd->obd_name, name, rc);
1972 static int record_end_log(const struct lu_env *env, struct llog_handle **llh)
1976 rc = llog_close(env, *llh);
1982 /******************** config "macros" *********************/
1984 /* write an lcfg directly into a log (with markers) */
1985 static int mgs_write_log_direct(const struct lu_env *env,
1986 struct mgs_device *mgs, struct fs_db *fsdb,
1987 char *logname, struct llog_cfg_rec *lcr,
1988 char *devname, char *comment)
1990 struct llog_handle *llh = NULL;
1995 rc = record_start_log(env, mgs, &llh, logname);
1999 /* FIXME These should be a single journal transaction */
2000 rc = record_marker(env, llh, fsdb, CM_START, devname, comment);
2003 rc = llog_write(env, llh, &lcr->lcr_hdr, LLOG_NEXT_IDX);
2006 rc = record_marker(env, llh, fsdb, CM_END, devname, comment);
2010 record_end_log(env, &llh);
2014 /* write the lcfg in all logs for the given fs */
2015 static int mgs_write_log_direct_all(const struct lu_env *env,
2016 struct mgs_device *mgs,
2018 struct mgs_target_info *mti,
2019 struct llog_cfg_rec *lcr, char *devname,
2020 char *comment, int server_only)
2022 struct list_head log_list;
2023 struct mgs_direntry *dirent, *n;
2024 char *fsname = mti->mti_fsname;
2025 int rc = 0, len = strlen(fsname);
2028 /* Find all the logs in the CONFIGS directory */
2029 rc = class_dentry_readdir(env, mgs, &log_list);
2033 /* Could use fsdb index maps instead of directory listing */
2034 list_for_each_entry_safe(dirent, n, &log_list, mde_list) {
2035 list_del_init(&dirent->mde_list);
2036 /* don't write to sptlrpc rule log */
2037 if (strstr(dirent->mde_name, "-sptlrpc") != NULL)
2040 /* caller wants write server logs only */
2041 if (server_only && strstr(dirent->mde_name, "-client") != NULL)
2044 if (strlen(dirent->mde_name) <= len ||
2045 strncmp(fsname, dirent->mde_name, len) != 0 ||
2046 dirent->mde_name[len] != '-')
2049 CDEBUG(D_MGS, "Changing log %s\n", dirent->mde_name);
2050 /* Erase any old settings of this same parameter */
2051 rc = mgs_modify(env, mgs, fsdb, mti, dirent->mde_name,
2052 devname, comment, CM_SKIP);
2054 CERROR("%s: Can't modify llog %s: rc = %d\n",
2055 mgs->mgs_obd->obd_name, dirent->mde_name, rc);
2058 /* Write the new one */
2059 rc = mgs_write_log_direct(env, mgs, fsdb, dirent->mde_name,
2060 lcr, devname, comment);
2062 CERROR("%s: writing log %s: rc = %d\n",
2063 mgs->mgs_obd->obd_name, dirent->mde_name, rc);
2065 mgs_direntry_free(dirent);
2071 static int mgs_write_log_osp_to_mdt(const struct lu_env *env,
2072 struct mgs_device *mgs,
2074 struct mgs_target_info *mti,
2075 int index, char *logname);
2076 static int mgs_write_log_osc_to_lov(const struct lu_env *env,
2077 struct mgs_device *mgs,
2079 struct mgs_target_info *mti,
2080 char *logname, char *suffix, char *lovname,
2081 enum lustre_sec_part sec_part, int flags);
2082 static int name_create_mdt_and_lov(char **logname, char **lovname,
2083 struct fs_db *fsdb, int i);
2085 static int add_param(char *params, char *key, char *val)
2087 char *start = params + strlen(params);
2088 char *end = params + sizeof(((struct mgs_target_info *)0)->mti_params);
2092 keylen = strlen(key);
2093 if (start + 1 + keylen + strlen(val) >= end) {
2094 CERROR("params are too long: %s %s%s\n",
2095 params, key != NULL ? key : "", val);
2099 sprintf(start, " %s%s", key != NULL ? key : "", val);
2104 * Walk through client config log record and convert the related records
2107 static int mgs_steal_client_llog_handler(const struct lu_env *env,
2108 struct llog_handle *llh,
2109 struct llog_rec_hdr *rec, void *data)
2111 struct mgs_device *mgs;
2112 struct obd_device *obd;
2113 struct mgs_target_info *mti, *tmti;
2115 int cfg_len = rec->lrh_len;
2116 char *cfg_buf = (char*) (rec + 1);
2117 struct lustre_cfg *lcfg;
2119 struct llog_handle *mdt_llh = NULL;
2120 static int got_an_osc_or_mdc = 0;
2121 /* 0: not found any osc/mdc;
2125 static int last_step = -1;
2130 mti = ((struct temp_comp*)data)->comp_mti;
2131 tmti = ((struct temp_comp*)data)->comp_tmti;
2132 fsdb = ((struct temp_comp*)data)->comp_fsdb;
2133 obd = ((struct temp_comp *)data)->comp_obd;
2134 mgs = lu2mgs_dev(obd->obd_lu_dev);
2137 if (rec->lrh_type != OBD_CFG_REC) {
2138 CERROR("unhandled lrh_type: %#x\n", rec->lrh_type);
2142 rc = lustre_cfg_sanity_check(cfg_buf, cfg_len);
2144 CERROR("Insane cfg\n");
2148 lcfg = (struct lustre_cfg *)cfg_buf;
2150 if (lcfg->lcfg_command == LCFG_MARKER) {
2151 struct cfg_marker *marker;
2152 marker = lustre_cfg_buf(lcfg, 1);
2153 if (!strncmp(marker->cm_comment, "add osc", 7) &&
2154 (marker->cm_flags & CM_START) &&
2155 !(marker->cm_flags & CM_SKIP)) {
2156 got_an_osc_or_mdc = 1;
2157 cplen = strlcpy(tmti->mti_svname, marker->cm_tgtname,
2158 sizeof(tmti->mti_svname));
2159 if (cplen >= sizeof(tmti->mti_svname))
2161 rc = record_start_log(env, mgs, &mdt_llh,
2165 rc = record_marker(env, mdt_llh, fsdb, CM_START,
2166 mti->mti_svname, "add osc(copied)");
2167 record_end_log(env, &mdt_llh);
2168 last_step = marker->cm_step;
2171 if (!strncmp(marker->cm_comment, "add osc", 7) &&
2172 (marker->cm_flags & CM_END) &&
2173 !(marker->cm_flags & CM_SKIP)) {
2174 LASSERT(last_step == marker->cm_step);
2176 got_an_osc_or_mdc = 0;
2177 memset(tmti, 0, sizeof(*tmti));
2178 rc = record_start_log(env, mgs, &mdt_llh,
2182 rc = record_marker(env, mdt_llh, fsdb, CM_END,
2183 mti->mti_svname, "add osc(copied)");
2184 record_end_log(env, &mdt_llh);
2187 if (!strncmp(marker->cm_comment, "add mdc", 7) &&
2188 (marker->cm_flags & CM_START) &&
2189 !(marker->cm_flags & CM_SKIP)) {
2190 got_an_osc_or_mdc = 2;
2191 last_step = marker->cm_step;
2192 memcpy(tmti->mti_svname, marker->cm_tgtname,
2193 strlen(marker->cm_tgtname));
2197 if (!strncmp(marker->cm_comment, "add mdc", 7) &&
2198 (marker->cm_flags & CM_END) &&
2199 !(marker->cm_flags & CM_SKIP)) {
2200 LASSERT(last_step == marker->cm_step);
2202 got_an_osc_or_mdc = 0;
2203 memset(tmti, 0, sizeof(*tmti));
2208 if (got_an_osc_or_mdc == 0 || last_step < 0)
2211 if (lcfg->lcfg_command == LCFG_ADD_UUID) {
2212 __u64 nodenid = lcfg->lcfg_nid;
2214 if (strlen(tmti->mti_uuid) == 0) {
2215 /* target uuid not set, this config record is before
2216 * LCFG_SETUP, this nid is one of target node nid.
2218 tmti->mti_nids[tmti->mti_nid_count] = nodenid;
2219 tmti->mti_nid_count++;
2221 char nidstr[LNET_NIDSTR_SIZE];
2223 /* failover node nid */
2224 libcfs_nid2str_r(nodenid, nidstr, sizeof(nidstr));
2225 rc = add_param(tmti->mti_params, PARAM_FAILNODE,
2232 if (lcfg->lcfg_command == LCFG_SETUP) {
2235 target = lustre_cfg_string(lcfg, 1);
2236 memcpy(tmti->mti_uuid, target, strlen(target));
2240 /* ignore client side sptlrpc_conf_log */
2241 if (lcfg->lcfg_command == LCFG_SPTLRPC_CONF)
2244 if (lcfg->lcfg_command == LCFG_ADD_MDC &&
2245 strstr(lustre_cfg_string(lcfg, 0), "-clilmv") != NULL) {
2248 if (sscanf(lustre_cfg_buf(lcfg, 2), "%d", &index) != 1)
2250 if (index == mti->mti_stripe_index) {
2252 "attempt to create MDT%04x->MDT%04x osp device\n",
2256 memcpy(tmti->mti_fsname, mti->mti_fsname,
2257 strlen(mti->mti_fsname));
2258 tmti->mti_stripe_index = index;
2260 rc = mgs_write_log_osp_to_mdt(env, mgs, fsdb, tmti,
2261 mti->mti_stripe_index,
2263 memset(tmti, 0, sizeof(*tmti));
2267 if (lcfg->lcfg_command == LCFG_LOV_ADD_OBD) {
2270 char *logname, *lovname;
2272 rc = name_create_mdt_and_lov(&logname, &lovname, fsdb,
2273 mti->mti_stripe_index);
2276 sprintf(mdt_index, "-MDT%04x", mti->mti_stripe_index);
2278 if (sscanf(lustre_cfg_buf(lcfg, 2), "%d", &index) != 1) {
2279 name_destroy(&logname);
2280 name_destroy(&lovname);
2284 tmti->mti_stripe_index = index;
2285 rc = mgs_write_log_osc_to_lov(env, mgs, fsdb, tmti, logname,
2288 name_destroy(&logname);
2289 name_destroy(&lovname);
2295 /* fsdb->fsdb_mutex is already held in mgs_write_log_target*/
2296 /* stealed from mgs_get_fsdb_from_llog*/
2297 static int mgs_steal_llog_for_mdt_from_client(const struct lu_env *env,
2298 struct mgs_device *mgs,
2300 struct temp_comp* comp)
2302 struct llog_handle *loghandle;
2303 struct mgs_target_info *tmti;
2304 struct llog_ctxt *ctxt;
2309 ctxt = llog_get_context(mgs->mgs_obd, LLOG_CONFIG_ORIG_CTXT);
2310 LASSERT(ctxt != NULL);
2312 OBD_ALLOC_PTR(tmti);
2314 GOTO(out_ctxt, rc = -ENOMEM);
2316 comp->comp_tmti = tmti;
2317 comp->comp_obd = mgs->mgs_obd;
2319 rc = llog_open(env, ctxt, &loghandle, NULL, client_name,
2327 rc = llog_init_handle(env, loghandle, LLOG_F_IS_PLAIN, NULL);
2329 GOTO(out_close, rc);
2331 rc = llog_process_or_fork(env, loghandle, mgs_steal_client_llog_handler,
2332 (void *)comp, NULL, false);
2333 CDEBUG(D_MGS, "steal llog re = %d\n", rc);
2335 llog_close(env, loghandle);
2339 llog_ctxt_put(ctxt);
2343 /* lmv is the second thing for client logs */
2344 /* copied from mgs_write_log_lov. Please refer to that. */
2345 static int mgs_write_log_lmv(const struct lu_env *env,
2346 struct mgs_device *mgs,
2348 struct mgs_target_info *mti,
2349 char *logname, char *lmvname)
2351 struct llog_handle *llh = NULL;
2352 struct lmv_desc *lmvdesc;
2357 CDEBUG(D_MGS, "Writing lmv(%s) log for %s\n", lmvname,logname);
2359 OBD_ALLOC_PTR(lmvdesc);
2360 if (lmvdesc == NULL)
2362 lmvdesc->ld_active_tgt_count = 0;
2363 lmvdesc->ld_tgt_count = 0;
2364 sprintf((char*)lmvdesc->ld_uuid.uuid, "%s_UUID", lmvname);
2365 uuid = (char *)lmvdesc->ld_uuid.uuid;
2367 rc = record_start_log(env, mgs, &llh, logname);
2370 rc = record_marker(env, llh, fsdb, CM_START, lmvname, "lmv setup");
2373 rc = record_attach(env, llh, lmvname, "lmv", uuid);
2376 rc = record_lmv_setup(env, llh, lmvname, lmvdesc);
2379 rc = record_marker(env, llh, fsdb, CM_END, lmvname, "lmv setup");
2383 record_end_log(env, &llh);
2385 OBD_FREE_PTR(lmvdesc);
2389 /* lov is the first thing in the mdt and client logs */
2390 static int mgs_write_log_lov(const struct lu_env *env, struct mgs_device *mgs,
2391 struct fs_db *fsdb, struct mgs_target_info *mti,
2392 char *logname, char *lovname)
2394 struct llog_handle *llh = NULL;
2395 struct lov_desc *lovdesc;
2400 CDEBUG(D_MGS, "Writing lov(%s) log for %s\n", lovname, logname);
2403 #01 L attach 0:lov_mdsA 1:lov 2:71ccb_lov_mdsA_19f961a9e1
2404 #02 L lov_setup 0:lov_mdsA 1:(struct lov_desc)
2405 uuid=lov1_UUID, stripe count=1, size=1048576, offset=0, pattern=0
2408 /* FIXME just make lov_setup accept empty desc (put uuid in buf 2) */
2409 OBD_ALLOC_PTR(lovdesc);
2410 if (lovdesc == NULL)
2412 lovdesc->ld_magic = LOV_DESC_MAGIC;
2413 lovdesc->ld_tgt_count = 0;
2414 /* Defaults. Can be changed later by lcfg config_param */
2415 lovdesc->ld_default_stripe_count = 1;
2416 lovdesc->ld_pattern = LOV_PATTERN_RAID0;
2417 lovdesc->ld_default_stripe_size = LOV_DESC_STRIPE_SIZE_DEFAULT;
2418 lovdesc->ld_default_stripe_offset = -1;
2419 lovdesc->ld_qos_maxage = LOV_DESC_QOS_MAXAGE_DEFAULT;
2420 sprintf((char*)lovdesc->ld_uuid.uuid, "%s_UUID", lovname);
2421 /* can these be the same? */
2422 uuid = (char *)lovdesc->ld_uuid.uuid;
2424 /* This should always be the first entry in a log.
2425 rc = mgs_clear_log(obd, logname); */
2426 rc = record_start_log(env, mgs, &llh, logname);
2429 /* FIXME these should be a single journal transaction */
2430 rc = record_marker(env, llh, fsdb, CM_START, lovname, "lov setup");
2433 rc = record_attach(env, llh, lovname, "lov", uuid);
2436 rc = record_lov_setup(env, llh, lovname, lovdesc);
2439 rc = record_marker(env, llh, fsdb, CM_END, lovname, "lov setup");
2444 record_end_log(env, &llh);
2446 OBD_FREE_PTR(lovdesc);
2450 /* add failnids to open log */
2451 static int mgs_write_log_failnids(const struct lu_env *env,
2452 struct mgs_target_info *mti,
2453 struct llog_handle *llh,
2456 char *failnodeuuid = NULL;
2457 char *ptr = mti->mti_params;
2462 #03 L add_uuid nid=uml1@tcp(0x20000c0a80201) nal=90 0: 1:uml1_UUID
2463 #04 L add_uuid nid=1@elan(0x1000000000001) nal=90 0: 1:uml1_UUID
2464 #05 L setup 0:OSC_uml1_ost1_mdsA 1:ost1_UUID 2:uml1_UUID
2465 #06 L add_uuid nid=uml2@tcp(0x20000c0a80202) nal=90 0: 1:uml2_UUID
2466 #0x L add_uuid nid=2@elan(0x1000000000002) nal=90 0: 1:uml2_UUID
2467 #07 L add_conn 0:OSC_uml1_ost1_mdsA 1:uml2_UUID
2471 * Pull failnid info out of params string, which may contain something
2472 * like "<nid1>,<nid2>:<nid3>,<nid4>". class_parse_nid() does not
2473 * complain about abnormal inputs like ",:<nid1>", "<nid1>:,<nid2>",
2474 * etc. However, convert_hostnames() should have caught those.
2476 while (class_find_param(ptr, PARAM_FAILNODE, &ptr) == 0) {
2477 while (class_parse_nid(ptr, &nid, &ptr) == 0) {
2478 char nidstr[LNET_NIDSTR_SIZE];
2480 if (failnodeuuid == NULL) {
2481 /* We don't know the failover node name,
2482 * so just use the first nid as the uuid */
2483 libcfs_nid2str_r(nid, nidstr, sizeof(nidstr));
2484 rc = name_create(&failnodeuuid, nidstr, "");
2488 CDEBUG(D_MGS, "add nid %s for failover uuid %s, "
2490 libcfs_nid2str_r(nid, nidstr, sizeof(nidstr)),
2491 failnodeuuid, cliname);
2492 rc = record_add_uuid(env, llh, nid, failnodeuuid);
2494 * If *ptr is ':', we have added all NIDs for
2498 rc = record_add_conn(env, llh, cliname,
2500 name_destroy(&failnodeuuid);
2501 failnodeuuid = NULL;
2505 rc = record_add_conn(env, llh, cliname, failnodeuuid);
2506 name_destroy(&failnodeuuid);
2507 failnodeuuid = NULL;
2514 static int mgs_write_log_mdc_to_lmv(const struct lu_env *env,
2515 struct mgs_device *mgs,
2517 struct mgs_target_info *mti,
2518 char *logname, char *lmvname)
2520 struct llog_handle *llh = NULL;
2521 char *mdcname = NULL;
2522 char *nodeuuid = NULL;
2523 char *mdcuuid = NULL;
2524 char *lmvuuid = NULL;
2526 char nidstr[LNET_NIDSTR_SIZE];
2530 if (mgs_log_is_empty(env, mgs, logname)) {
2531 CERROR("log is empty! Logical error\n");
2535 CDEBUG(D_MGS, "adding mdc for %s to log %s:lmv(%s)\n",
2536 mti->mti_svname, logname, lmvname);
2538 libcfs_nid2str_r(mti->mti_nids[0], nidstr, sizeof(nidstr));
2539 rc = name_create(&nodeuuid, nidstr, "");
2542 rc = name_create(&mdcname, mti->mti_svname, "-mdc");
2545 rc = name_create(&mdcuuid, mdcname, "_UUID");
2548 rc = name_create(&lmvuuid, lmvname, "_UUID");
2552 rc = mgs_modify(env, mgs, fsdb, mti, logname, mti->mti_svname,
2553 "add mdc", CM_SKIP);
2557 rc = record_start_log(env, mgs, &llh, logname);
2560 rc = record_marker(env, llh, fsdb, CM_START, mti->mti_svname,
2564 for (i = 0; i < mti->mti_nid_count; i++) {
2565 CDEBUG(D_MGS, "add nid %s for mdt\n",
2566 libcfs_nid2str_r(mti->mti_nids[i],
2567 nidstr, sizeof(nidstr)));
2569 rc = record_add_uuid(env, llh, mti->mti_nids[i], nodeuuid);
2574 rc = record_attach(env, llh, mdcname, LUSTRE_MDC_NAME, lmvuuid);
2577 rc = record_setup(env, llh, mdcname, mti->mti_uuid, nodeuuid,
2581 rc = mgs_write_log_failnids(env, mti, llh, mdcname);
2584 snprintf(index, sizeof(index), "%d", mti->mti_stripe_index);
2585 rc = record_mdc_add(env, llh, lmvname, mdcuuid, mti->mti_uuid,
2589 rc = record_marker(env, llh, fsdb, CM_END, mti->mti_svname,
2594 record_end_log(env, &llh);
2596 name_destroy(&lmvuuid);
2597 name_destroy(&mdcuuid);
2598 name_destroy(&mdcname);
2599 name_destroy(&nodeuuid);
2603 static inline int name_create_lov(char **lovname, char *mdtname,
2604 struct fs_db *fsdb, int index)
2607 if (index == 0 && test_bit(FSDB_OSCNAME18, &fsdb->fsdb_flags))
2608 return name_create(lovname, fsdb->fsdb_name, "-mdtlov");
2610 return name_create(lovname, mdtname, "-mdtlov");
2613 static int name_create_mdt_and_lov(char **logname, char **lovname,
2614 struct fs_db *fsdb, int i)
2618 rc = name_create_mdt(logname, fsdb->fsdb_name, i);
2622 if (i == 0 && test_bit(FSDB_OSCNAME18, &fsdb->fsdb_flags))
2623 rc = name_create(lovname, fsdb->fsdb_name, "-mdtlov");
2625 rc = name_create(lovname, *logname, "-mdtlov");
2627 name_destroy(logname);
2633 static inline int name_create_mdt_osc(char **oscname, char *ostname,
2634 struct fs_db *fsdb, int i)
2638 if (i == 0 && test_bit(FSDB_OSCNAME18, &fsdb->fsdb_flags))
2639 sprintf(suffix, "-osc");
2641 sprintf(suffix, "-osc-MDT%04x", i);
2642 return name_create(oscname, ostname, suffix);
2645 /* add new mdc to already existent MDS */
2646 static int mgs_write_log_osp_to_mdt(const struct lu_env *env,
2647 struct mgs_device *mgs,
2649 struct mgs_target_info *mti,
2650 int mdt_index, char *logname)
2652 struct llog_handle *llh = NULL;
2653 char *nodeuuid = NULL;
2654 char *ospname = NULL;
2655 char *lovuuid = NULL;
2656 char *mdtuuid = NULL;
2657 char *svname = NULL;
2658 char *mdtname = NULL;
2659 char *lovname = NULL;
2661 char nidstr[LNET_NIDSTR_SIZE];
2665 if (mgs_log_is_empty(env, mgs, mti->mti_svname)) {
2666 CERROR("log is empty! Logical error\n");
2670 CDEBUG(D_MGS, "adding osp index %d to %s\n", mti->mti_stripe_index,
2673 rc = name_create_mdt(&mdtname, fsdb->fsdb_name, mti->mti_stripe_index);
2677 libcfs_nid2str_r(mti->mti_nids[0], nidstr, sizeof(nidstr));
2678 rc = name_create(&nodeuuid, nidstr, "");
2680 GOTO(out_destory, rc);
2682 rc = name_create(&svname, mdtname, "-osp");
2684 GOTO(out_destory, rc);
2686 sprintf(index_str, "-MDT%04x", mdt_index);
2687 rc = name_create(&ospname, svname, index_str);
2689 GOTO(out_destory, rc);
2691 rc = name_create_lov(&lovname, logname, fsdb, mdt_index);
2693 GOTO(out_destory, rc);
2695 rc = name_create(&lovuuid, lovname, "_UUID");
2697 GOTO(out_destory, rc);
2699 rc = name_create(&mdtuuid, mdtname, "_UUID");
2701 GOTO(out_destory, rc);
2703 rc = mgs_modify(env, mgs, fsdb, mti, logname, mti->mti_svname,
2704 "add osp", CM_SKIP);
2706 GOTO(out_destory, rc);
2708 rc = record_start_log(env, mgs, &llh, logname);
2710 GOTO(out_destory, rc);
2712 rc = record_marker(env, llh, fsdb, CM_START, mti->mti_svname,
2715 GOTO(out_destory, rc);
2717 for (i = 0; i < mti->mti_nid_count; i++) {
2718 CDEBUG(D_MGS, "add nid %s for mdt\n",
2719 libcfs_nid2str_r(mti->mti_nids[i],
2720 nidstr, sizeof(nidstr)));
2721 rc = record_add_uuid(env, llh, mti->mti_nids[i], nodeuuid);
2726 rc = record_attach(env, llh, ospname, LUSTRE_OSP_NAME, lovuuid);
2730 rc = record_setup(env, llh, ospname, mti->mti_uuid, nodeuuid,
2735 rc = mgs_write_log_failnids(env, mti, llh, ospname);
2739 /* Add mdc(osp) to lod */
2740 snprintf(index_str, sizeof(index_str), "%d", mti->mti_stripe_index);
2741 rc = record_base(env, llh, lovname, 0, LCFG_ADD_MDC, mti->mti_uuid,
2742 index_str, "1", NULL);
2746 rc = record_marker(env, llh, fsdb, CM_END, mti->mti_svname, "add osp");
2751 record_end_log(env, &llh);
2754 name_destroy(&mdtuuid);
2755 name_destroy(&lovuuid);
2756 name_destroy(&lovname);
2757 name_destroy(&ospname);
2758 name_destroy(&svname);
2759 name_destroy(&nodeuuid);
2760 name_destroy(&mdtname);
2764 static int mgs_write_log_mdt0(const struct lu_env *env,
2765 struct mgs_device *mgs,
2767 struct mgs_target_info *mti)
2769 char *log = mti->mti_svname;
2770 struct llog_handle *llh = NULL;
2771 struct obd_uuid *uuid;
2774 char *ptr = mti->mti_params;
2775 int rc = 0, failout = 0;
2778 OBD_ALLOC_PTR(uuid);
2782 if (class_find_param(ptr, PARAM_FAILMODE, &ptr) == 0)
2783 failout = (strncmp(ptr, "failout", 7) == 0);
2785 rc = name_create(&lovname, log, "-mdtlov");
2788 if (mgs_log_is_empty(env, mgs, log)) {
2789 rc = mgs_write_log_lov(env, mgs, fsdb, mti, log, lovname);
2794 sprintf(mdt_index, "%d", mti->mti_stripe_index);
2796 rc = record_start_log(env, mgs, &llh, log);
2800 /* add MDT itself */
2802 /* FIXME this whole fn should be a single journal transaction */
2803 sprintf(uuid->uuid, "%s_UUID", log);
2804 rc = record_marker(env, llh, fsdb, CM_START, log, "add mdt");
2807 rc = record_attach(env, llh, log, LUSTRE_MDT_NAME, uuid->uuid);
2810 rc = record_mount_opt(env, llh, log, lovname, NULL);
2813 rc = record_setup(env, llh, log, uuid->uuid, mdt_index, lovname,
2814 failout ? "n" : "f");
2817 rc = record_marker(env, llh, fsdb, CM_END, log, "add mdt");
2821 record_end_log(env, &llh);
2823 name_destroy(&lovname);
2829 /* envelope method for all layers log */
2830 static int mgs_write_log_mdt(const struct lu_env *env,
2831 struct mgs_device *mgs,
2833 struct mgs_target_info *mti)
2835 struct mgs_thread_info *mgi = mgs_env_info(env);
2836 struct llog_handle *llh = NULL;
2841 CDEBUG(D_MGS, "writing new mdt %s\n", mti->mti_svname);
2843 if (mti->mti_uuid[0] == '\0') {
2844 /* Make up our own uuid */
2845 snprintf(mti->mti_uuid, sizeof(mti->mti_uuid),
2846 "%s_UUID", mti->mti_svname);
2850 rc = mgs_write_log_mdt0(env, mgs, fsdb, mti);
2853 /* Append the mdt info to the client log */
2854 rc = name_create(&cliname, mti->mti_fsname, "-client");
2858 if (mgs_log_is_empty(env, mgs, cliname)) {
2859 /* Start client log */
2860 rc = mgs_write_log_lov(env, mgs, fsdb, mti, cliname,
2864 rc = mgs_write_log_lmv(env, mgs, fsdb, mti, cliname,
2871 #09 L add_uuid nid=uml1@tcp(0x20000c0a80201) 0: 1:uml1_UUID
2872 #10 L attach 0:MDC_uml1_mdsA_MNT_client 1:mdc 2:1d834_MNT_client_03f
2873 #11 L setup 0:MDC_uml1_mdsA_MNT_client 1:mdsA_UUID 2:uml1_UUID
2874 #12 L add_uuid nid=uml2@tcp(0x20000c0a80202) 0: 1:uml2_UUID
2875 #13 L add_conn 0:MDC_uml1_mdsA_MNT_client 1:uml2_UUID
2876 #14 L mount_option 0: 1:client 2:lov1 3:MDC_uml1_mdsA_MNT_client
2879 /* copy client info about lov/lmv */
2880 mgi->mgi_comp.comp_mti = mti;
2881 mgi->mgi_comp.comp_fsdb = fsdb;
2883 rc = mgs_steal_llog_for_mdt_from_client(env, mgs, cliname,
2887 rc = mgs_write_log_mdc_to_lmv(env, mgs, fsdb, mti, cliname,
2893 rc = record_start_log(env, mgs, &llh, cliname);
2897 rc = record_marker(env, llh, fsdb, CM_START, cliname, "mount opts");
2900 rc = record_mount_opt(env, llh, cliname, fsdb->fsdb_clilov,
2904 rc = record_marker(env, llh, fsdb, CM_END, cliname, "mount opts");
2908 /* for_all_existing_mdt except current one */
2909 for (i = 0; i < INDEX_MAP_SIZE * 8; i++) {
2910 if (i != mti->mti_stripe_index &&
2911 test_bit(i, fsdb->fsdb_mdt_index_map)) {
2914 rc = name_create_mdt(&logname, fsdb->fsdb_name, i);
2918 /* NB: If the log for the MDT is empty, it means
2919 * the MDT is only added to the index
2920 * map, and not being process yet, i.e. this
2921 * is an unregistered MDT, see mgs_write_log_target().
2922 * so we should skip it. Otherwise
2924 * 1. MGS get register request for MDT1 and MDT2.
2926 * 2. Then both MDT1 and MDT2 are added into
2927 * fsdb_mdt_index_map. (see mgs_set_index()).
2929 * 3. Then MDT1 get the lock of fsdb_mutex, then
2930 * generate the config log, here, it will regard MDT2
2931 * as an existent MDT, and generate "add osp" for
2932 * lustre-MDT0001-osp-MDT0002. Note: at the moment
2933 * MDT0002 config log is still empty, so it will
2934 * add "add osp" even before "lov setup", which
2935 * will definitly cause trouble.
2937 * 4. MDT1 registeration finished, fsdb_mutex is
2938 * released, then MDT2 get in, then in above
2939 * mgs_steal_llog_for_mdt_from_client(), it will
2940 * add another osp log for lustre-MDT0001-osp-MDT0002,
2941 * which will cause another trouble.*/
2942 if (!mgs_log_is_empty(env, mgs, logname))
2943 rc = mgs_write_log_osp_to_mdt(env, mgs, fsdb,
2946 name_destroy(&logname);
2952 record_end_log(env, &llh);
2954 name_destroy(&cliname);
2958 /* Add the ost info to the client/mdt lov */
2959 static int mgs_write_log_osc_to_lov(const struct lu_env *env,
2960 struct mgs_device *mgs, struct fs_db *fsdb,
2961 struct mgs_target_info *mti,
2962 char *logname, char *suffix, char *lovname,
2963 enum lustre_sec_part sec_part, int flags)
2965 struct llog_handle *llh = NULL;
2966 char *nodeuuid = NULL;
2967 char *oscname = NULL;
2968 char *oscuuid = NULL;
2969 char *lovuuid = NULL;
2970 char *svname = NULL;
2972 char nidstr[LNET_NIDSTR_SIZE];
2976 CDEBUG(D_INFO, "adding osc for %s to log %s\n",
2977 mti->mti_svname, logname);
2979 if (mgs_log_is_empty(env, mgs, logname)) {
2980 CERROR("log is empty! Logical error\n");
2984 libcfs_nid2str_r(mti->mti_nids[0], nidstr, sizeof(nidstr));
2985 rc = name_create(&nodeuuid, nidstr, "");
2988 rc = name_create(&svname, mti->mti_svname, "-osc");
2992 /* for the system upgraded from old 1.8, keep using the old osc naming
2993 * style for mdt, see name_create_mdt_osc(). LU-1257 */
2994 if (test_bit(FSDB_OSCNAME18, &fsdb->fsdb_flags))
2995 rc = name_create(&oscname, svname, "");
2997 rc = name_create(&oscname, svname, suffix);
3001 rc = name_create(&oscuuid, oscname, "_UUID");
3004 rc = name_create(&lovuuid, lovname, "_UUID");
3010 #03 L add_uuid nid=uml1@tcp(0x20000c0a80201) 0: 1:uml1_UUID
3012 #04 L add_uuid nid=1@elan(0x1000000000001) nal=90 0: 1:uml1_UUID
3013 #04 L attach 0:OSC_uml1_ost1_MNT_client 1:osc 2:89070_lov1_a41dff51a
3014 #05 L setup 0:OSC_uml1_ost1_MNT_client 1:ost1_UUID 2:uml1_UUID
3016 #06 L add_uuid nid=uml2@tcp(0x20000c0a80202) 0: 1:uml2_UUID
3017 #07 L add_conn 0:OSC_uml1_ost1_MNT_client 1:uml2_UUID
3018 #08 L lov_modify_tgts add 0:lov1 1:ost1_UUID 2(index):0 3(gen):1
3021 rc = record_start_log(env, mgs, &llh, logname);
3025 /* FIXME these should be a single journal transaction */
3026 rc = record_marker(env, llh, fsdb, CM_START | flags, mti->mti_svname,
3031 /* NB: don't change record order, because upon MDT steal OSC config
3032 * from client, it treats all nids before LCFG_SETUP as target nids
3033 * (multiple interfaces), while nids after as failover node nids.
3034 * See mgs_steal_client_llog_handler() LCFG_ADD_UUID.
3036 for (i = 0; i < mti->mti_nid_count; i++) {
3037 CDEBUG(D_MGS, "add nid %s\n",
3038 libcfs_nid2str_r(mti->mti_nids[i],
3039 nidstr, sizeof(nidstr)));
3040 rc = record_add_uuid(env, llh, mti->mti_nids[i], nodeuuid);
3044 rc = record_attach(env, llh, oscname, LUSTRE_OSC_NAME, lovuuid);
3047 rc = record_setup(env, llh, oscname, mti->mti_uuid, nodeuuid,
3051 rc = mgs_write_log_failnids(env, mti, llh, oscname);
3055 snprintf(index, sizeof(index), "%d", mti->mti_stripe_index);
3057 rc = record_lov_add(env, llh, lovname, mti->mti_uuid, index, "1");
3060 rc = record_marker(env, llh, fsdb, CM_END | flags, mti->mti_svname,
3065 record_end_log(env, &llh);
3067 name_destroy(&lovuuid);
3068 name_destroy(&oscuuid);
3069 name_destroy(&oscname);
3070 name_destroy(&svname);
3071 name_destroy(&nodeuuid);
3075 static int mgs_write_log_ost(const struct lu_env *env,
3076 struct mgs_device *mgs, struct fs_db *fsdb,
3077 struct mgs_target_info *mti)
3079 struct llog_handle *llh = NULL;
3080 char *logname, *lovname;
3081 char *ptr = mti->mti_params;
3082 int rc, flags = 0, failout = 0, i;
3085 CDEBUG(D_MGS, "writing new ost %s\n", mti->mti_svname);
3087 /* The ost startup log */
3089 /* If the ost log already exists, that means that someone reformatted
3090 the ost and it called target_add again. */
3091 if (!mgs_log_is_empty(env, mgs, mti->mti_svname)) {
3092 LCONSOLE_ERROR_MSG(0x141, "The config log for %s already "
3093 "exists, yet the server claims it never "
3094 "registered. It may have been reformatted, "
3095 "or the index changed. writeconf the MDT to "
3096 "regenerate all logs.\n", mti->mti_svname);
3101 attach obdfilter ost1 ost1_UUID
3102 setup /dev/loop2 ldiskfs f|n errors=remount-ro,user_xattr
3104 if (class_find_param(ptr, PARAM_FAILMODE, &ptr) == 0)
3105 failout = (strncmp(ptr, "failout", 7) == 0);
3106 rc = record_start_log(env, mgs, &llh, mti->mti_svname);
3109 /* FIXME these should be a single journal transaction */
3110 rc = record_marker(env, llh, fsdb, CM_START, mti->mti_svname,"add ost");
3113 if (*mti->mti_uuid == '\0')
3114 snprintf(mti->mti_uuid, sizeof(mti->mti_uuid),
3115 "%s_UUID", mti->mti_svname);
3116 rc = record_attach(env, llh, mti->mti_svname,
3117 "obdfilter"/*LUSTRE_OST_NAME*/, mti->mti_uuid);
3120 rc = record_setup(env, llh, mti->mti_svname,
3121 "dev"/*ignored*/, "type"/*ignored*/,
3122 failout ? "n" : "f", NULL/*options*/);
3125 rc = record_marker(env, llh, fsdb, CM_END, mti->mti_svname, "add ost");
3129 record_end_log(env, &llh);
3132 /* We also have to update the other logs where this osc is part of
3135 if (test_bit(FSDB_OLDLOG14, &fsdb->fsdb_flags)) {
3136 /* If we're upgrading, the old mdt log already has our
3137 entry. Let's do a fake one for fun. */
3138 /* Note that we can't add any new failnids, since we don't
3139 know the old osc names. */
3140 flags = CM_SKIP | CM_UPGRADE146;
3142 } else if ((mti->mti_flags & LDD_F_UPDATE) != LDD_F_UPDATE) {
3143 /* If the update flag isn't set, don't update client/mdt
3146 LCONSOLE_WARN("Client log for %s was not updated; writeconf "
3147 "the MDT first to regenerate it.\n",
3151 /* Add ost to all MDT lov defs */
3152 for (i = 0; i < INDEX_MAP_SIZE * 8; i++){
3153 if (test_bit(i, fsdb->fsdb_mdt_index_map)) {
3156 rc = name_create_mdt_and_lov(&logname, &lovname, fsdb,
3161 snprintf(mdt_index, sizeof(mdt_index), "-MDT%04x", i);
3162 rc = mgs_write_log_osc_to_lov(env, mgs, fsdb, mti,
3164 lovname, LUSTRE_SP_MDT,
3166 name_destroy(&logname);
3167 name_destroy(&lovname);
3173 /* Append ost info to the client log */
3174 rc = name_create(&logname, mti->mti_fsname, "-client");
3177 if (mgs_log_is_empty(env, mgs, logname)) {
3178 /* Start client log */
3179 rc = mgs_write_log_lov(env, mgs, fsdb, mti, logname,
3183 rc = mgs_write_log_lmv(env, mgs, fsdb, mti, logname,
3188 rc = mgs_write_log_osc_to_lov(env, mgs, fsdb, mti, logname, "",
3189 fsdb->fsdb_clilov, LUSTRE_SP_CLI, flags);
3191 name_destroy(&logname);
3195 static __inline__ int mgs_param_empty(char *ptr)
3199 if ((tmp = strchr(ptr, '=')) && (*(++tmp) == '\0'))
3204 static int mgs_write_log_failnid_internal(const struct lu_env *env,
3205 struct mgs_device *mgs,
3207 struct mgs_target_info *mti,
3208 char *logname, char *cliname)
3211 struct llog_handle *llh = NULL;
3213 if (mgs_param_empty(mti->mti_params)) {
3214 /* Remove _all_ failnids */
3215 rc = mgs_modify(env, mgs, fsdb, mti, logname,
3216 mti->mti_svname, "add failnid", CM_SKIP);
3217 return rc < 0 ? rc : 0;
3220 /* Otherwise failover nids are additive */
3221 rc = record_start_log(env, mgs, &llh, logname);
3224 /* FIXME this should be a single journal transaction */
3225 rc = record_marker(env, llh, fsdb, CM_START, mti->mti_svname,
3229 rc = mgs_write_log_failnids(env, mti, llh, cliname);
3232 rc = record_marker(env, llh, fsdb, CM_END,
3233 mti->mti_svname, "add failnid");
3235 record_end_log(env, &llh);
3240 /* Add additional failnids to an existing log.
3241 The mdc/osc must have been added to logs first */
3242 /* tcp nids must be in dotted-quad ascii -
3243 we can't resolve hostnames from the kernel. */
3244 static int mgs_write_log_add_failnid(const struct lu_env *env,
3245 struct mgs_device *mgs,
3247 struct mgs_target_info *mti)
3249 char *logname, *cliname;
3253 /* FIXME we currently can't erase the failnids
3254 * given when a target first registers, since they aren't part of
3255 * an "add uuid" stanza
3258 /* Verify that we know about this target */
3259 if (mgs_log_is_empty(env, mgs, mti->mti_svname)) {
3260 LCONSOLE_ERROR_MSG(0x142, "The target %s has not registered "
3261 "yet. It must be started before failnids "
3262 "can be added.\n", mti->mti_svname);
3266 /* Create mdc/osc client name (e.g. lustre-OST0001-osc) */
3267 if (mti->mti_flags & LDD_F_SV_TYPE_MDT) {
3268 rc = name_create(&cliname, mti->mti_svname, "-mdc");
3269 } else if (mti->mti_flags & LDD_F_SV_TYPE_OST) {
3270 rc = name_create(&cliname, mti->mti_svname, "-osc");
3277 /* Add failover nids to the client log */
3278 rc = name_create(&logname, mti->mti_fsname, "-client");
3280 name_destroy(&cliname);
3284 rc = mgs_write_log_failnid_internal(env, mgs, fsdb,mti,logname,cliname);
3285 name_destroy(&logname);
3286 name_destroy(&cliname);
3290 if (mti->mti_flags & LDD_F_SV_TYPE_OST) {
3291 /* Add OST failover nids to the MDT logs as well */
3294 for (i = 0; i < INDEX_MAP_SIZE * 8; i++) {
3295 if (!test_bit(i, fsdb->fsdb_mdt_index_map))
3297 rc = name_create_mdt(&logname, mti->mti_fsname, i);
3300 rc = name_create_mdt_osc(&cliname, mti->mti_svname,
3303 name_destroy(&logname);
3306 rc = mgs_write_log_failnid_internal(env, mgs, fsdb,
3309 name_destroy(&cliname);
3310 name_destroy(&logname);
3319 static int mgs_wlp_lcfg(const struct lu_env *env,
3320 struct mgs_device *mgs, struct fs_db *fsdb,
3321 struct mgs_target_info *mti,
3322 char *logname, struct lustre_cfg_bufs *bufs,
3323 char *tgtname, char *ptr)
3325 char comment[MTI_NAME_MAXLEN];
3327 struct llog_cfg_rec *lcr;
3330 /* Erase any old settings of this same parameter */
3331 strlcpy(comment, ptr, sizeof(comment));
3332 /* But don't try to match the value. */
3333 tmp = strchr(comment, '=');
3336 /* FIXME we should skip settings that are the same as old values */
3337 rc = mgs_modify(env, mgs, fsdb, mti, logname, tgtname, comment,CM_SKIP);
3340 del = mgs_param_empty(ptr);
3342 LCONSOLE_INFO("%s parameter %s.%s in log %s\n", del ? "Disabling" : rc ?
3343 "Setting" : "Modifying", tgtname, comment, logname);
3345 /* mgs_modify() will return 1 if nothing had to be done */
3351 lustre_cfg_bufs_reset(bufs, tgtname);
3352 lustre_cfg_bufs_set_string(bufs, 1, ptr);
3353 if (mti->mti_flags & LDD_F_PARAM2)
3354 lustre_cfg_bufs_set_string(bufs, 2, LCTL_UPCALL);
3356 lcr = lustre_cfg_rec_new((mti->mti_flags & LDD_F_PARAM2) ?
3357 LCFG_SET_PARAM : LCFG_PARAM, bufs);
3361 rc = mgs_write_log_direct(env, mgs, fsdb, logname, lcr, tgtname,
3363 lustre_cfg_rec_free(lcr);
3367 /* write global variable settings into log */
3368 static int mgs_write_log_sys(const struct lu_env *env,
3369 struct mgs_device *mgs, struct fs_db *fsdb,
3370 struct mgs_target_info *mti, char *sys, char *ptr)
3372 struct mgs_thread_info *mgi = mgs_env_info(env);
3373 struct lustre_cfg *lcfg;
3374 struct llog_cfg_rec *lcr;
3376 int rc, cmd, convert = 1;
3378 if (class_match_param(ptr, PARAM_TIMEOUT, &tmp) == 0) {
3379 cmd = LCFG_SET_TIMEOUT;
3380 } else if (class_match_param(ptr, PARAM_LDLM_TIMEOUT, &tmp) == 0) {
3381 cmd = LCFG_SET_LDLM_TIMEOUT;
3382 /* Check for known params here so we can return error to lctl */
3383 } else if ((class_match_param(ptr, PARAM_AT_MIN, &tmp) == 0) ||
3384 (class_match_param(ptr, PARAM_AT_MAX, &tmp) == 0) ||
3385 (class_match_param(ptr, PARAM_AT_EXTRA, &tmp) == 0) ||
3386 (class_match_param(ptr, PARAM_AT_EARLY_MARGIN, &tmp) == 0) ||
3387 (class_match_param(ptr, PARAM_AT_HISTORY, &tmp) == 0)) {
3389 } else if (class_match_param(ptr, PARAM_JOBID_VAR, &tmp) == 0) {
3390 convert = 0; /* Don't convert string value to integer */
3396 if (mgs_param_empty(ptr))
3397 CDEBUG(D_MGS, "global '%s' removed\n", sys);
3399 CDEBUG(D_MGS, "global '%s' val=%s\n", sys, tmp);
3401 lustre_cfg_bufs_reset(&mgi->mgi_bufs, NULL);
3402 lustre_cfg_bufs_set_string(&mgi->mgi_bufs, 1, sys);
3403 if (!convert && *tmp != '\0')
3404 lustre_cfg_bufs_set_string(&mgi->mgi_bufs, 2, tmp);
3405 lcr = lustre_cfg_rec_new(cmd, &mgi->mgi_bufs);
3409 lcfg = &lcr->lcr_cfg;
3411 rc = kstrtouint(tmp, 0, &lcfg->lcfg_num);
3413 GOTO(out_rec_free, rc);
3418 /* truncate the comment to the parameter name */
3422 /* modify all servers and clients */
3423 rc = mgs_write_log_direct_all(env, mgs, fsdb, mti,
3424 *tmp == '\0' ? NULL : lcr,
3425 mti->mti_fsname, sys, 0);
3426 if (rc == 0 && *tmp != '\0') {
3428 case LCFG_SET_TIMEOUT:
3429 if (!obd_timeout_set || lcfg->lcfg_num > obd_timeout)
3430 class_process_config(lcfg);
3432 case LCFG_SET_LDLM_TIMEOUT:
3433 if (!ldlm_timeout_set || lcfg->lcfg_num > ldlm_timeout)
3434 class_process_config(lcfg);
3442 lustre_cfg_rec_free(lcr);
3446 /* write quota settings into log */
3447 static int mgs_write_log_quota(const struct lu_env *env, struct mgs_device *mgs,
3448 struct fs_db *fsdb, struct mgs_target_info *mti,
3449 char *quota, char *ptr)
3451 struct mgs_thread_info *mgi = mgs_env_info(env);
3452 struct llog_cfg_rec *lcr;
3455 int rc, cmd = LCFG_PARAM;
3457 /* support only 'meta' and 'data' pools so far */
3458 if (class_match_param(ptr, QUOTA_METAPOOL_NAME, &tmp) != 0 &&
3459 class_match_param(ptr, QUOTA_DATAPOOL_NAME, &tmp) != 0) {
3460 CERROR("parameter quota.%s isn't supported (only quota.mdt "
3461 "& quota.ost are)\n", ptr);
3466 CDEBUG(D_MGS, "global '%s' removed\n", quota);
3468 CDEBUG(D_MGS, "global '%s'\n", quota);
3470 if (strchr(tmp, 'u') == NULL && strchr(tmp, 'g') == NULL &&
3471 strchr(tmp, 'p') == NULL &&
3472 strcmp(tmp, "none") != 0) {
3473 CERROR("enable option(%s) isn't supported\n", tmp);
3478 lustre_cfg_bufs_reset(&mgi->mgi_bufs, mti->mti_fsname);
3479 lustre_cfg_bufs_set_string(&mgi->mgi_bufs, 1, quota);
3480 lcr = lustre_cfg_rec_new(cmd, &mgi->mgi_bufs);
3484 /* truncate the comment to the parameter name */
3489 /* XXX we duplicated quota enable information in all server
3490 * config logs, it should be moved to a separate config
3491 * log once we cleanup the config log for global param. */
3492 /* modify all servers */
3493 rc = mgs_write_log_direct_all(env, mgs, fsdb, mti,
3494 *tmp == '\0' ? NULL : lcr,
3495 mti->mti_fsname, quota, 1);
3497 lustre_cfg_rec_free(lcr);
3498 return rc < 0 ? rc : 0;
3501 static int mgs_srpc_set_param_disk(const struct lu_env *env,
3502 struct mgs_device *mgs,
3504 struct mgs_target_info *mti,
3507 struct mgs_thread_info *mgi = mgs_env_info(env);
3508 struct llog_cfg_rec *lcr;
3509 struct llog_handle *llh = NULL;
3511 char *comment, *ptr;
3517 ptr = strchr(param, '=');
3518 LASSERT(ptr != NULL);
3521 OBD_ALLOC(comment, len + 1);
3522 if (comment == NULL)
3524 strncpy(comment, param, len);
3525 comment[len] = '\0';
3528 lustre_cfg_bufs_reset(&mgi->mgi_bufs, mti->mti_svname);
3529 lustre_cfg_bufs_set_string(&mgi->mgi_bufs, 1, param);
3530 lcr = lustre_cfg_rec_new(LCFG_SPTLRPC_CONF, &mgi->mgi_bufs);
3532 GOTO(out_comment, rc = -ENOMEM);
3534 /* construct log name */
3535 rc = name_create(&logname, mti->mti_fsname, "-sptlrpc");
3539 if (mgs_log_is_empty(env, mgs, logname)) {
3540 rc = record_start_log(env, mgs, &llh, logname);
3543 record_end_log(env, &llh);
3546 /* obsolete old one */
3547 rc = mgs_modify(env, mgs, fsdb, mti, logname, mti->mti_svname,
3551 /* write the new one */
3552 rc = mgs_write_log_direct(env, mgs, fsdb, logname, lcr,
3553 mti->mti_svname, comment);
3555 CERROR("%s: error writing log %s: rc = %d\n",
3556 mgs->mgs_obd->obd_name, logname, rc);
3558 name_destroy(&logname);
3560 lustre_cfg_rec_free(lcr);
3562 OBD_FREE(comment, len + 1);
3566 static int mgs_srpc_set_param_udesc_mem(struct fs_db *fsdb,
3571 /* disable the adjustable udesc parameter for now, i.e. use default
3572 * setting that client always ship udesc to MDT if possible. to enable
3573 * it simply remove the following line */
3576 ptr = strchr(param, '=');
3581 if (strcmp(param, PARAM_SRPC_UDESC))
3584 if (strcmp(ptr, "yes") == 0) {
3585 set_bit(FSDB_UDESC, &fsdb->fsdb_flags);
3586 CWARN("Enable user descriptor shipping from client to MDT\n");
3587 } else if (strcmp(ptr, "no") == 0) {
3588 clear_bit(FSDB_UDESC, &fsdb->fsdb_flags);
3589 CWARN("Disable user descriptor shipping from client to MDT\n");
3597 CERROR("Invalid param: %s\n", param);
3601 static int mgs_srpc_set_param_mem(struct fs_db *fsdb,
3605 struct sptlrpc_rule rule;
3606 struct sptlrpc_rule_set *rset;
3610 if (strncmp(param, PARAM_SRPC, sizeof(PARAM_SRPC) - 1) != 0) {
3611 CERROR("Invalid sptlrpc parameter: %s\n", param);
3615 if (strncmp(param, PARAM_SRPC_UDESC,
3616 sizeof(PARAM_SRPC_UDESC) - 1) == 0) {
3617 RETURN(mgs_srpc_set_param_udesc_mem(fsdb, param));
3620 if (strncmp(param, PARAM_SRPC_FLVR, sizeof(PARAM_SRPC_FLVR) - 1) != 0) {
3621 CERROR("Invalid sptlrpc flavor parameter: %s\n", param);
3625 param += sizeof(PARAM_SRPC_FLVR) - 1;
3627 rc = sptlrpc_parse_rule(param, &rule);
3631 /* mgs rules implies must be mgc->mgs */
3632 if (test_bit(FSDB_MGS_SELF, &fsdb->fsdb_flags)) {
3633 if ((rule.sr_from != LUSTRE_SP_MGC &&
3634 rule.sr_from != LUSTRE_SP_ANY) ||
3635 (rule.sr_to != LUSTRE_SP_MGS &&
3636 rule.sr_to != LUSTRE_SP_ANY))
3640 /* preapre room for this coming rule. svcname format should be:
3641 * - fsname: general rule
3642 * - fsname-tgtname: target-specific rule
3644 if (strchr(svname, '-')) {
3645 struct mgs_tgt_srpc_conf *tgtconf;
3648 for (tgtconf = fsdb->fsdb_srpc_tgt; tgtconf != NULL;
3649 tgtconf = tgtconf->mtsc_next) {
3650 if (!strcmp(tgtconf->mtsc_tgt, svname)) {
3659 OBD_ALLOC_PTR(tgtconf);
3660 if (tgtconf == NULL)
3663 name_len = strlen(svname);
3665 OBD_ALLOC(tgtconf->mtsc_tgt, name_len + 1);
3666 if (tgtconf->mtsc_tgt == NULL) {
3667 OBD_FREE_PTR(tgtconf);
3670 memcpy(tgtconf->mtsc_tgt, svname, name_len);
3672 tgtconf->mtsc_next = fsdb->fsdb_srpc_tgt;
3673 fsdb->fsdb_srpc_tgt = tgtconf;
3676 rset = &tgtconf->mtsc_rset;
3677 } else if (strcmp(svname, MGSSELF_NAME) == 0) {
3678 /* put _mgs related srpc rule directly in mgs ruleset */
3679 rset = &fsdb->fsdb_mgs->mgs_lut.lut_sptlrpc_rset;
3681 rset = &fsdb->fsdb_srpc_gen;
3684 rc = sptlrpc_rule_set_merge(rset, &rule);
3689 static int mgs_srpc_set_param(const struct lu_env *env,
3690 struct mgs_device *mgs,
3692 struct mgs_target_info *mti,
3702 /* keep a copy of original param, which could be destroied
3704 copy_size = strlen(param) + 1;
3705 OBD_ALLOC(copy, copy_size);
3708 memcpy(copy, param, copy_size);
3710 rc = mgs_srpc_set_param_mem(fsdb, mti->mti_svname, param);
3714 /* previous steps guaranteed the syntax is correct */
3715 rc = mgs_srpc_set_param_disk(env, mgs, fsdb, mti, copy);
3719 if (test_bit(FSDB_MGS_SELF, &fsdb->fsdb_flags)) {
3721 * for mgs rules, make them effective immediately.
3723 LASSERT(fsdb->fsdb_srpc_tgt == NULL);
3724 sptlrpc_target_update_exp_flavor(mgs->mgs_obd,
3725 &fsdb->fsdb_srpc_gen);
3729 OBD_FREE(copy, copy_size);
3733 struct mgs_srpc_read_data {
3734 struct fs_db *msrd_fsdb;
3738 static int mgs_srpc_read_handler(const struct lu_env *env,
3739 struct llog_handle *llh,
3740 struct llog_rec_hdr *rec, void *data)
3742 struct mgs_srpc_read_data *msrd = data;
3743 struct cfg_marker *marker;
3744 struct lustre_cfg *lcfg = REC_DATA(rec);
3745 char *svname, *param;
3749 if (rec->lrh_type != OBD_CFG_REC) {
3750 CERROR("unhandled lrh_type: %#x\n", rec->lrh_type);
3754 cfg_len = REC_DATA_LEN(rec);
3756 rc = lustre_cfg_sanity_check(lcfg, cfg_len);
3758 CERROR("Insane cfg\n");
3762 if (lcfg->lcfg_command == LCFG_MARKER) {
3763 marker = lustre_cfg_buf(lcfg, 1);
3765 if (marker->cm_flags & CM_START &&
3766 marker->cm_flags & CM_SKIP)
3767 msrd->msrd_skip = 1;
3768 if (marker->cm_flags & CM_END)
3769 msrd->msrd_skip = 0;
3774 if (msrd->msrd_skip)
3777 if (lcfg->lcfg_command != LCFG_SPTLRPC_CONF) {
3778 CERROR("invalid command (%x)\n", lcfg->lcfg_command);
3782 svname = lustre_cfg_string(lcfg, 0);
3783 if (svname == NULL) {
3784 CERROR("svname is empty\n");
3788 param = lustre_cfg_string(lcfg, 1);
3789 if (param == NULL) {
3790 CERROR("param is empty\n");
3794 rc = mgs_srpc_set_param_mem(msrd->msrd_fsdb, svname, param);
3796 CERROR("read sptlrpc record error (%d): %s\n", rc, param);
3801 int mgs_get_fsdb_srpc_from_llog(const struct lu_env *env,
3802 struct mgs_device *mgs,
3805 struct llog_handle *llh = NULL;
3806 struct llog_ctxt *ctxt;
3808 struct mgs_srpc_read_data msrd;
3812 /* construct log name */
3813 rc = name_create(&logname, fsdb->fsdb_name, "-sptlrpc");
3817 ctxt = llog_get_context(mgs->mgs_obd, LLOG_CONFIG_ORIG_CTXT);
3818 LASSERT(ctxt != NULL);
3820 if (mgs_log_is_empty(env, mgs, logname))
3823 rc = llog_open(env, ctxt, &llh, NULL, logname,
3831 rc = llog_init_handle(env, llh, LLOG_F_IS_PLAIN, NULL);
3833 GOTO(out_close, rc);
3835 if (llog_get_size(llh) <= 1)
3836 GOTO(out_close, rc = 0);
3838 msrd.msrd_fsdb = fsdb;
3841 rc = llog_process(env, llh, mgs_srpc_read_handler, (void *)&msrd,
3845 llog_close(env, llh);
3847 llog_ctxt_put(ctxt);
3848 name_destroy(&logname);
3851 CERROR("failed to read sptlrpc config database: %d\n", rc);
3855 static int mgs_write_log_param2(const struct lu_env *env,
3856 struct mgs_device *mgs,
3858 struct mgs_target_info *mti, char *ptr)
3860 struct lustre_cfg_bufs bufs;
3864 CDEBUG(D_MGS, "next param '%s'\n", ptr);
3866 /* PARAM_MGSNODE and PARAM_NETWORK are set only when formating
3867 * or during the inital mount. It can never change after that.
3869 if (!class_match_param(ptr, PARAM_MGSNODE, NULL) ||
3870 !class_match_param(ptr, PARAM_NETWORK, NULL)) {
3875 /* Processed in mgs_write_log_ost. Another value that can't
3876 * be changed by lctl set_param -P.
3878 if (!class_match_param(ptr, PARAM_FAILMODE, NULL)) {
3879 LCONSOLE_ERROR_MSG(0x169,
3880 "%s can only be changed with tunefs.lustre and --writeconf\n",
3886 /* FIXME !!! Support for sptlrpc is incomplete. Currently the change
3887 * doesn't transmit to the client. See LU-7183.
3889 if (!class_match_param(ptr, PARAM_SRPC, NULL)) {
3890 rc = mgs_srpc_set_param(env, mgs, fsdb, mti, ptr);
3894 /* Can't use class_match_param since ptr doesn't start with
3895 * PARAM_FAILNODE. So we look for PARAM_FAILNODE contained in ptr.
3897 if (strstr(ptr, PARAM_FAILNODE)) {
3898 /* Add a failover nidlist. We already processed failovers
3899 * params for new targets in mgs_write_log_target.
3903 /* can't use wildcards with failover.node */
3904 if (strchr(ptr, '*')) {
3909 param = strstr(ptr, PARAM_FAILNODE);
3910 if (strlcpy(mti->mti_params, param, sizeof(mti->mti_params)) >=
3911 sizeof(mti->mti_params)) {
3916 CDEBUG(D_MGS, "Adding failnode with param %s\n",
3918 rc = mgs_write_log_add_failnid(env, mgs, fsdb, mti);
3922 /* root squash parameters must not be set on llite subsystem, this can
3923 * lead to inconsistencies between client and server values
3925 if ((strstr(ptr, PARAM_NOSQUASHNIDS) ||
3926 strstr(ptr, PARAM_ROOTSQUASH)) &&
3927 strncmp(ptr, "llite.", strlen("llite.")) == 0) {
3929 CWARN("%s: cannot add %s param to llite subsystem, use mdt instead: rc=%d\n",
3930 mgs->mgs_obd->obd_name,
3931 strstr(ptr, PARAM_ROOTSQUASH) ?
3932 PARAM_ROOTSQUASH : PARAM_NOSQUASHNIDS,
3937 rc = mgs_wlp_lcfg(env, mgs, fsdb, mti, PARAMS_FILENAME, &bufs,
3938 mti->mti_svname, ptr);
3943 /* Permanent settings of all parameters by writing into the appropriate
3944 * configuration logs.
3945 * A parameter with null value ("<param>='\0'") means to erase it out of
3948 static int mgs_write_log_param(const struct lu_env *env,
3949 struct mgs_device *mgs, struct fs_db *fsdb,
3950 struct mgs_target_info *mti, char *ptr)
3952 struct mgs_thread_info *mgi = mgs_env_info(env);
3958 /* For various parameter settings, we have to figure out which logs
3959 care about them (e.g. both mdt and client for lov settings) */
3960 CDEBUG(D_MGS, "next param '%s'\n", ptr);
3962 /* The params are stored in MOUNT_DATA_FILE and modified via
3963 tunefs.lustre, or set using lctl conf_param */
3965 /* Processed in lustre_start_mgc */
3966 if (class_match_param(ptr, PARAM_MGSNODE, NULL) == 0)
3969 /* Processed in ost/mdt */
3970 if (class_match_param(ptr, PARAM_NETWORK, NULL) == 0)
3973 /* Processed in mgs_write_log_ost */
3974 if (class_match_param(ptr, PARAM_FAILMODE, NULL) == 0) {
3975 if (mti->mti_flags & LDD_F_PARAM) {
3976 LCONSOLE_ERROR_MSG(0x169,
3977 "%s can only be changed with tunefs.lustre and --writeconf\n",
3984 if (class_match_param(ptr, PARAM_SRPC, NULL) == 0) {
3985 rc = mgs_srpc_set_param(env, mgs, fsdb, mti, ptr);
3989 if (class_match_param(ptr, PARAM_FAILNODE, NULL) == 0) {
3990 /* Add a failover nidlist */
3992 /* We already processed failovers params for new
3993 targets in mgs_write_log_target */
3994 if (mti->mti_flags & LDD_F_PARAM) {
3995 CDEBUG(D_MGS, "Adding failnode\n");
3996 rc = mgs_write_log_add_failnid(env, mgs, fsdb, mti);
4001 if (class_match_param(ptr, PARAM_SYS, &tmp) == 0) {
4002 rc = mgs_write_log_sys(env, mgs, fsdb, mti, ptr, tmp);
4006 if (class_match_param(ptr, PARAM_QUOTA, &tmp) == 0) {
4007 rc = mgs_write_log_quota(env, mgs, fsdb, mti, ptr, tmp);
4011 if (class_match_param(ptr, PARAM_OSC PARAM_ACTIVE, &tmp) == 0 ||
4012 class_match_param(ptr, PARAM_MDC PARAM_ACTIVE, &tmp) == 0) {
4013 /* active=0 means off, anything else means on */
4014 int flag = (*tmp == '0') ? CM_EXCLUDE : 0;
4015 bool deactive_osc = memcmp(ptr, PARAM_OSC PARAM_ACTIVE,
4016 strlen(PARAM_OSC PARAM_ACTIVE)) == 0;
4019 if (!deactive_osc) {
4022 rc = server_name2index(mti->mti_svname, &index, NULL);
4027 LCONSOLE_ERROR_MSG(0x144, "%s: MDC0 can not be"
4028 " (de)activated.\n",
4030 GOTO(end, rc = -EPERM);
4034 LCONSOLE_WARN("Permanently %sactivating %s\n",
4035 flag ? "de" : "re", mti->mti_svname);
4037 rc = name_create(&logname, mti->mti_fsname, "-client");
4040 rc = mgs_modify(env, mgs, fsdb, mti, logname,
4042 deactive_osc ? "add osc" : "add mdc", flag);
4043 name_destroy(&logname);
4048 /* Add to all MDT logs for DNE */
4049 for (i = 0; i < INDEX_MAP_SIZE * 8; i++) {
4050 if (!test_bit(i, fsdb->fsdb_mdt_index_map))
4052 rc = name_create_mdt(&logname, mti->mti_fsname, i);
4055 rc = mgs_modify(env, mgs, fsdb, mti, logname,
4057 deactive_osc ? "add osc" : "add osp",
4059 name_destroy(&logname);
4065 LCONSOLE_ERROR_MSG(0x145,
4066 "Couldn't find %s in log (%d). No permanent changes were made to the config log.\n",
4067 mti->mti_svname, rc);
4068 if (test_bit(FSDB_OLDLOG14, &fsdb->fsdb_flags))
4069 LCONSOLE_ERROR_MSG(0x146,
4070 "This may be because the log is in the old 1.4 style. Consider --writeconf to update the logs.\n");
4073 /* Fall through to osc/mdc proc for deactivating live
4074 OSC/OSP on running MDT / clients. */
4076 /* Below here, let obd's XXX_process_config methods handle it */
4078 /* All lov. in proc */
4079 if (class_match_param(ptr, PARAM_LOV, NULL) == 0) {
4082 CDEBUG(D_MGS, "lov param %s\n", ptr);
4083 if (!(mti->mti_flags & LDD_F_SV_TYPE_MDT)) {
4084 LCONSOLE_ERROR_MSG(0x147, "LOV params must be "
4085 "set on the MDT, not %s. "
4092 if (mgs_log_is_empty(env, mgs, mti->mti_svname))
4093 GOTO(end, rc = -ENODEV);
4095 rc = name_create_mdt_and_lov(&logname, &mdtlovname, fsdb,
4096 mti->mti_stripe_index);
4099 rc = mgs_wlp_lcfg(env, mgs, fsdb, mti, mti->mti_svname,
4100 &mgi->mgi_bufs, mdtlovname, ptr);
4101 name_destroy(&logname);
4102 name_destroy(&mdtlovname);
4107 rc = name_create(&logname, mti->mti_fsname, "-client");
4110 rc = mgs_wlp_lcfg(env, mgs, fsdb, mti, logname, &mgi->mgi_bufs,
4111 fsdb->fsdb_clilov, ptr);
4112 name_destroy(&logname);
4116 /* All osc., mdc., llite. params in proc */
4117 if ((class_match_param(ptr, PARAM_OSC, NULL) == 0) ||
4118 (class_match_param(ptr, PARAM_MDC, NULL) == 0) ||
4119 (class_match_param(ptr, PARAM_LLITE, NULL) == 0)) {
4122 if (test_bit(FSDB_OLDLOG14, &fsdb->fsdb_flags)) {
4123 LCONSOLE_ERROR_MSG(0x148, "Upgraded client logs for %s"
4124 " cannot be modified. Consider"
4125 " updating the configuration with"
4128 GOTO(end, rc = -EINVAL);
4130 if (memcmp(ptr, PARAM_LLITE, strlen(PARAM_LLITE)) == 0) {
4131 rc = name_create(&cname, mti->mti_fsname, "-client");
4132 /* Add the client type to match the obdname in
4133 class_config_llog_handler */
4134 } else if (mti->mti_flags & LDD_F_SV_TYPE_MDT) {
4135 rc = name_create(&cname, mti->mti_svname, "-mdc");
4136 } else if (mti->mti_flags & LDD_F_SV_TYPE_OST) {
4137 rc = name_create(&cname, mti->mti_svname, "-osc");
4139 GOTO(end, rc = -EINVAL);
4144 /* Forbid direct update of llite root squash parameters.
4145 * These parameters are indirectly set via the MDT settings.
4147 if ((class_match_param(ptr, PARAM_LLITE, &tmp) == 0) &&
4148 ((memcmp(tmp, "root_squash=", 12) == 0) ||
4149 (memcmp(tmp, "nosquash_nids=", 14) == 0))) {
4150 LCONSOLE_ERROR("%s: root squash parameters can only "
4151 "be updated through MDT component\n",
4153 name_destroy(&cname);
4154 GOTO(end, rc = -EINVAL);
4157 CDEBUG(D_MGS, "%.3s param %s\n", ptr, ptr + 4);
4160 rc = name_create(&logname, mti->mti_fsname, "-client");
4162 name_destroy(&cname);
4165 rc = mgs_wlp_lcfg(env, mgs, fsdb, mti, logname, &mgi->mgi_bufs,
4168 /* osc params affect the MDT as well */
4169 if (!rc && (mti->mti_flags & LDD_F_SV_TYPE_OST)) {
4172 for (i = 0; i < INDEX_MAP_SIZE * 8; i++){
4173 if (!test_bit(i, fsdb->fsdb_mdt_index_map))
4175 name_destroy(&cname);
4176 rc = name_create_mdt_osc(&cname, mti->mti_svname,
4178 name_destroy(&logname);
4181 rc = name_create_mdt(&logname,
4182 mti->mti_fsname, i);
4185 if (!mgs_log_is_empty(env, mgs, logname)) {
4186 rc = mgs_wlp_lcfg(env, mgs, fsdb,
4196 /* For mdc activate/deactivate, it affects OSP on MDT as well */
4197 if (class_match_param(ptr, PARAM_MDC PARAM_ACTIVE, &tmp) == 0 &&
4200 char *lodname = NULL;
4201 char *param_str = NULL;
4205 /* replace mdc with osp */
4206 memcpy(ptr, PARAM_OSP, strlen(PARAM_OSP));
4207 rc = server_name2index(mti->mti_svname, &index, NULL);
4209 memcpy(ptr, PARAM_MDC, strlen(PARAM_MDC));
4213 for (i = 0; i < INDEX_MAP_SIZE * 8; i++) {
4214 if (!test_bit(i, fsdb->fsdb_mdt_index_map))
4220 name_destroy(&logname);
4221 rc = name_create_mdt(&logname, mti->mti_fsname,
4226 if (mgs_log_is_empty(env, mgs, logname))
4229 snprintf(suffix, sizeof(suffix), "-osp-MDT%04x",
4231 name_destroy(&cname);
4232 rc = name_create(&cname, mti->mti_svname,
4237 rc = mgs_wlp_lcfg(env, mgs, fsdb, mti, logname,
4238 &mgi->mgi_bufs, cname, ptr);
4242 /* Add configuration log for noitfying LOD
4243 * to active/deactive the OSP. */
4244 name_destroy(¶m_str);
4245 rc = name_create(¶m_str, cname,
4246 (*tmp == '0') ? ".active=0" :
4251 name_destroy(&lodname);
4252 rc = name_create(&lodname, logname, "-mdtlov");
4256 rc = mgs_wlp_lcfg(env, mgs, fsdb, mti, logname,
4257 &mgi->mgi_bufs, lodname,
4262 memcpy(ptr, PARAM_MDC, strlen(PARAM_MDC));
4263 name_destroy(&lodname);
4264 name_destroy(¶m_str);
4267 name_destroy(&logname);
4268 name_destroy(&cname);
4272 /* All mdt. params in proc */
4273 if (class_match_param(ptr, PARAM_MDT, &tmp) == 0) {
4277 CDEBUG(D_MGS, "%.3s param %s\n", ptr, ptr + 4);
4278 if (strncmp(mti->mti_svname, mti->mti_fsname,
4279 MTI_NAME_MAXLEN) == 0)
4280 /* device is unspecified completely? */
4281 rc = LDD_F_SV_TYPE_MDT | LDD_F_SV_ALL;
4283 rc = server_name2index(mti->mti_svname, &idx, NULL);
4286 if ((rc & LDD_F_SV_TYPE_MDT) == 0)
4288 if (rc & LDD_F_SV_ALL) {
4289 for (i = 0; i < INDEX_MAP_SIZE * 8; i++) {
4291 fsdb->fsdb_mdt_index_map))
4293 rc = name_create_mdt(&logname,
4294 mti->mti_fsname, i);
4297 rc = mgs_wlp_lcfg(env, mgs, fsdb, mti,
4298 logname, &mgi->mgi_bufs,
4300 name_destroy(&logname);
4305 if ((memcmp(tmp, "root_squash=", 12) == 0) ||
4306 (memcmp(tmp, "nosquash_nids=", 14) == 0)) {
4307 LCONSOLE_ERROR("%s: root squash parameters "
4308 "cannot be applied to a single MDT\n",
4310 GOTO(end, rc = -EINVAL);
4312 rc = mgs_wlp_lcfg(env, mgs, fsdb, mti,
4313 mti->mti_svname, &mgi->mgi_bufs,
4314 mti->mti_svname, ptr);
4319 /* root squash settings are also applied to llite
4320 * config log (see LU-1778) */
4322 ((memcmp(tmp, "root_squash=", 12) == 0) ||
4323 (memcmp(tmp, "nosquash_nids=", 14) == 0))) {
4327 rc = name_create(&cname, mti->mti_fsname, "-client");
4330 rc = name_create(&logname, mti->mti_fsname, "-client");
4332 name_destroy(&cname);
4335 rc = name_create(&ptr2, PARAM_LLITE, tmp);
4337 name_destroy(&cname);
4338 name_destroy(&logname);
4341 rc = mgs_wlp_lcfg(env, mgs, fsdb, mti, logname,
4342 &mgi->mgi_bufs, cname, ptr2);
4343 name_destroy(&ptr2);
4344 name_destroy(&logname);
4345 name_destroy(&cname);
4350 /* All mdd., ost. and osd. params in proc */
4351 if ((class_match_param(ptr, PARAM_MDD, NULL) == 0) ||
4352 (class_match_param(ptr, PARAM_LOD, NULL) == 0) ||
4353 (class_match_param(ptr, PARAM_OST, NULL) == 0) ||
4354 (class_match_param(ptr, PARAM_OSD, NULL) == 0)) {
4355 CDEBUG(D_MGS, "%.3s param %s\n", ptr, ptr + 4);
4356 if (mgs_log_is_empty(env, mgs, mti->mti_svname))
4357 GOTO(end, rc = -ENODEV);
4359 rc = mgs_wlp_lcfg(env, mgs, fsdb, mti, mti->mti_svname,
4360 &mgi->mgi_bufs, mti->mti_svname, ptr);
4364 LCONSOLE_WARN("Ignoring unrecognized param '%s'\n", ptr);
4368 CERROR("err %d on param '%s'\n", rc, ptr);
4373 int mgs_write_log_target(const struct lu_env *env, struct mgs_device *mgs,
4374 struct mgs_target_info *mti, struct fs_db *fsdb)
4381 /* set/check the new target index */
4382 rc = mgs_set_index(env, mgs, mti);
4386 if (rc == EALREADY) {
4387 LCONSOLE_WARN("Found index %d for %s, updating log\n",
4388 mti->mti_stripe_index, mti->mti_svname);
4389 /* We would like to mark old log sections as invalid
4390 and add new log sections in the client and mdt logs.
4391 But if we add new sections, then live clients will
4392 get repeat setup instructions for already running
4393 osc's. So don't update the client/mdt logs. */
4394 mti->mti_flags &= ~LDD_F_UPDATE;
4398 OBD_FAIL_TIMEOUT(OBD_FAIL_MGS_WRITE_TARGET_DELAY, cfs_fail_val > 0 ?
4401 mutex_lock(&fsdb->fsdb_mutex);
4403 if (mti->mti_flags & (LDD_F_VIRGIN | LDD_F_WRITECONF)) {
4404 /* Generate a log from scratch */
4405 if (mti->mti_flags & LDD_F_SV_TYPE_MDT) {
4406 rc = mgs_write_log_mdt(env, mgs, fsdb, mti);
4407 } else if (mti->mti_flags & LDD_F_SV_TYPE_OST) {
4408 rc = mgs_write_log_ost(env, mgs, fsdb, mti);
4410 CERROR("Unknown target type %#x, can't create log for %s\n",
4411 mti->mti_flags, mti->mti_svname);
4414 CERROR("Can't write logs for %s (%d)\n",
4415 mti->mti_svname, rc);
4419 /* Just update the params from tunefs in mgs_write_log_params */
4420 CDEBUG(D_MGS, "Update params for %s\n", mti->mti_svname);
4421 mti->mti_flags |= LDD_F_PARAM;
4424 /* allocate temporary buffer, where class_get_next_param will
4425 make copy of a current parameter */
4426 OBD_ALLOC(buf, strlen(mti->mti_params) + 1);
4428 GOTO(out_up, rc = -ENOMEM);
4429 params = mti->mti_params;
4430 while (params != NULL) {
4431 rc = class_get_next_param(¶ms, buf);
4434 /* there is no next parameter, that is
4439 CDEBUG(D_MGS, "remaining string: '%s', param: '%s'\n",
4441 rc = mgs_write_log_param(env, mgs, fsdb, mti, buf);
4446 OBD_FREE(buf, strlen(mti->mti_params) + 1);
4449 mutex_unlock(&fsdb->fsdb_mutex);
4453 int mgs_erase_log(const struct lu_env *env, struct mgs_device *mgs, char *name)
4455 struct llog_ctxt *ctxt;
4458 ctxt = llog_get_context(mgs->mgs_obd, LLOG_CONFIG_ORIG_CTXT);
4460 CERROR("%s: MGS config context doesn't exist\n",
4461 mgs->mgs_obd->obd_name);
4464 rc = llog_erase(env, ctxt, NULL, name);
4465 /* llog may not exist */
4468 llog_ctxt_put(ctxt);
4472 CERROR("%s: failed to clear log %s: %d\n",
4473 mgs->mgs_obd->obd_name, name, rc);
4478 /* erase all logs for the given fs */
4479 int mgs_erase_logs(const struct lu_env *env, struct mgs_device *mgs,
4482 struct list_head log_list;
4483 struct mgs_direntry *dirent, *n;
4484 char barrier_name[20] = {};
4487 int rc, len = strlen(fsname);
4490 mutex_lock(&mgs->mgs_mutex);
4492 /* Find all the logs in the CONFIGS directory */
4493 rc = class_dentry_readdir(env, mgs, &log_list);
4495 mutex_unlock(&mgs->mgs_mutex);
4499 if (list_empty(&log_list)) {
4500 mutex_unlock(&mgs->mgs_mutex);
4504 snprintf(barrier_name, sizeof(barrier_name) - 1, "%s-%s",
4505 fsname, BARRIER_FILENAME);
4506 /* Delete the barrier fsdb */
4507 mgs_remove_fsdb_by_name(mgs, barrier_name);
4508 /* Delete the fs db */
4509 mgs_remove_fsdb_by_name(mgs, fsname);
4510 mutex_unlock(&mgs->mgs_mutex);
4512 list_for_each_entry_safe(dirent, n, &log_list, mde_list) {
4513 list_del_init(&dirent->mde_list);
4514 suffix = strrchr(dirent->mde_name, '-');
4515 if (suffix != NULL) {
4516 if ((len == suffix - dirent->mde_name) &&
4517 (strncmp(fsname, dirent->mde_name, len) == 0)) {
4518 CDEBUG(D_MGS, "Removing log %s\n",
4520 mgs_erase_log(env, mgs, dirent->mde_name);
4524 mgs_direntry_free(dirent);
4533 /* list all logs for the given fs */
4534 int mgs_list_logs(const struct lu_env *env, struct mgs_device *mgs,
4535 struct obd_ioctl_data *data)
4537 struct list_head log_list;
4538 struct mgs_direntry *dirent, *n;
4539 char *out, *suffix, prefix[] = "config_log: ";
4540 int prefix_len = strlen(prefix);
4541 int len, remains, start = 0, rc;
4545 /* Find all the logs in the CONFIGS directory */
4546 rc = class_dentry_readdir(env, mgs, &log_list);
4550 out = data->ioc_bulk;
4551 remains = data->ioc_inllen1;
4552 /* OBD_FAIL: fetch the config_log records from the specified one */
4553 if (OBD_FAIL_CHECK(OBD_FAIL_CATLIST))
4554 data->ioc_count = cfs_fail_val;
4556 list_for_each_entry_safe(dirent, n, &log_list, mde_list) {
4557 list_del_init(&dirent->mde_list);
4558 suffix = strrchr(dirent->mde_name, '-');
4559 if (suffix != NULL) {
4560 len = prefix_len + dirent->mde_len + 1;
4561 if (remains - len < 0) {
4562 /* No enough space for this record */
4563 mgs_direntry_free(dirent);
4567 if (start < data->ioc_count) {
4568 mgs_direntry_free(dirent);
4571 len = scnprintf(out, remains, "%s%s\n", prefix,
4576 mgs_direntry_free(dirent);
4584 data->ioc_count = start;
4588 struct mgs_lcfg_fork_data {
4589 struct lustre_cfg_bufs mlfd_bufs;
4590 struct mgs_device *mlfd_mgs;
4591 struct llog_handle *mlfd_llh;
4592 const char *mlfd_oldname;
4593 const char *mlfd_newname;
4597 static bool contain_valid_fsname(char *buf, const char *fsname,
4598 int buflen, int namelen)
4600 if (buflen < namelen)
4603 if (memcmp(buf, fsname, namelen) != 0)
4606 if (buf[namelen] != '\0' && buf[namelen] != '-')
4612 static int mgs_lcfg_fork_handler(const struct lu_env *env,
4613 struct llog_handle *o_llh,
4614 struct llog_rec_hdr *o_rec, void *data)
4616 struct mgs_lcfg_fork_data *mlfd = data;
4617 struct lustre_cfg_bufs *n_bufs = &mlfd->mlfd_bufs;
4618 struct lustre_cfg *o_lcfg = (struct lustre_cfg *)(o_rec + 1);
4619 struct llog_cfg_rec *lcr;
4621 char *n_buf = mlfd->mlfd_data;
4623 int o_namelen = strlen(mlfd->mlfd_oldname);
4624 int n_namelen = strlen(mlfd->mlfd_newname);
4625 int diff = n_namelen - o_namelen;
4626 __u32 cmd = o_lcfg->lcfg_command;
4627 __u32 cnt = o_lcfg->lcfg_bufcount;
4633 o_buf = lustre_cfg_buf(o_lcfg, 0);
4634 o_buflen = o_lcfg->lcfg_buflens[0];
4635 if (contain_valid_fsname(o_buf, mlfd->mlfd_oldname, o_buflen,
4637 memcpy(n_buf, mlfd->mlfd_newname, n_namelen);
4638 memcpy(n_buf + n_namelen, o_buf + o_namelen,
4639 o_buflen - o_namelen);
4640 lustre_cfg_bufs_reset(n_bufs, n_buf);
4641 n_buf += cfs_size_round(o_buflen + diff);
4643 lustre_cfg_bufs_reset(n_bufs, o_buflen != 0 ? o_buf : NULL);
4648 struct cfg_marker *o_marker;
4649 struct cfg_marker *n_marker;
4653 CDEBUG(D_MGS, "Unknown cfg marker entry with %d "
4658 /* buf[1] is marker */
4659 o_buf = lustre_cfg_buf(o_lcfg, 1);
4660 o_buflen = o_lcfg->lcfg_buflens[1];
4661 o_marker = (struct cfg_marker *)o_buf;
4662 if (!contain_valid_fsname(o_marker->cm_tgtname,
4664 sizeof(o_marker->cm_tgtname),
4666 lustre_cfg_bufs_set(n_bufs, 1, o_marker,
4671 n_marker = (struct cfg_marker *)n_buf;
4672 *n_marker = *o_marker;
4673 memcpy(n_marker->cm_tgtname, mlfd->mlfd_newname, n_namelen);
4674 tgt_namelen = strlen(o_marker->cm_tgtname);
4675 if (tgt_namelen > o_namelen)
4676 memcpy(n_marker->cm_tgtname + n_namelen,
4677 o_marker->cm_tgtname + o_namelen,
4678 tgt_namelen - o_namelen);
4679 n_marker->cm_tgtname[tgt_namelen + diff] = '\0';
4680 lustre_cfg_bufs_set(n_bufs, 1, n_marker, sizeof(*n_marker));
4684 case LCFG_SET_PARAM: {
4685 for (i = 1; i < cnt; i++)
4686 /* buf[i] is the param value, reuse it directly */
4687 lustre_cfg_bufs_set(n_bufs, i,
4688 lustre_cfg_buf(o_lcfg, i),
4689 o_lcfg->lcfg_buflens[i]);
4695 case LCFG_POOL_DEL: {
4696 if (cnt < 3 || cnt > 4) {
4697 CDEBUG(D_MGS, "Unknown cfg pool (%x) entry with %d "
4698 "buffers\n", cmd, cnt);
4702 /* buf[1] is fsname */
4703 o_buf = lustre_cfg_buf(o_lcfg, 1);
4704 o_buflen = o_lcfg->lcfg_buflens[1];
4705 memcpy(n_buf, mlfd->mlfd_newname, n_namelen);
4706 memcpy(n_buf + n_namelen, o_buf + o_namelen,
4707 o_buflen - o_namelen);
4708 lustre_cfg_bufs_set(n_bufs, 1, n_buf, o_buflen + diff);
4709 n_buf += cfs_size_round(o_buflen + diff);
4711 /* buf[2] is the pool name, reuse it directly */
4712 lustre_cfg_bufs_set(n_bufs, 2, lustre_cfg_buf(o_lcfg, 2),
4713 o_lcfg->lcfg_buflens[2]);
4718 /* buf[3] is ostname */
4719 o_buf = lustre_cfg_buf(o_lcfg, 3);
4720 o_buflen = o_lcfg->lcfg_buflens[3];
4721 memcpy(n_buf, mlfd->mlfd_newname, n_namelen);
4722 memcpy(n_buf + n_namelen, o_buf + o_namelen,
4723 o_buflen - o_namelen);
4724 lustre_cfg_bufs_set(n_bufs, 3, n_buf, o_buflen + diff);
4729 o_buflen = o_lcfg->lcfg_buflens[1];
4730 if (o_buflen == sizeof(struct lov_desc) ||
4731 o_buflen == sizeof(struct lmv_desc)) {
4737 o_buf = lustre_cfg_buf(o_lcfg, 1);
4738 if (o_buflen == sizeof(struct lov_desc)) {
4739 struct lov_desc *o_desc =
4740 (struct lov_desc *)o_buf;
4741 struct lov_desc *n_desc =
4742 (struct lov_desc *)n_buf;
4745 o_uuid = o_desc->ld_uuid.uuid;
4746 n_uuid = n_desc->ld_uuid.uuid;
4747 uuid_len = sizeof(o_desc->ld_uuid.uuid);
4749 struct lmv_desc *o_desc =
4750 (struct lmv_desc *)o_buf;
4751 struct lmv_desc *n_desc =
4752 (struct lmv_desc *)n_buf;
4755 o_uuid = o_desc->ld_uuid.uuid;
4756 n_uuid = n_desc->ld_uuid.uuid;
4757 uuid_len = sizeof(o_desc->ld_uuid.uuid);
4760 if (unlikely(!contain_valid_fsname(o_uuid,
4761 mlfd->mlfd_oldname, uuid_len,
4763 lustre_cfg_bufs_set(n_bufs, 1, o_buf,
4768 memcpy(n_uuid, mlfd->mlfd_newname, n_namelen);
4769 uuid_len = strlen(o_uuid);
4770 if (uuid_len > o_namelen)
4771 memcpy(n_uuid + n_namelen,
4773 uuid_len - o_namelen);
4774 n_uuid[uuid_len + diff] = '\0';
4775 lustre_cfg_bufs_set(n_bufs, 1, n_buf, o_buflen);
4777 } /* else case fall through */
4778 } /* else case fall through */
4782 for (i = 1; i < cnt; i++) {
4783 o_buflen = o_lcfg->lcfg_buflens[i];
4787 o_buf = lustre_cfg_buf(o_lcfg, i);
4788 if (!contain_valid_fsname(o_buf, mlfd->mlfd_oldname,
4789 o_buflen, o_namelen)) {
4790 lustre_cfg_bufs_set(n_bufs, i, o_buf, o_buflen);
4794 memcpy(n_buf, mlfd->mlfd_newname, n_namelen);
4795 if (o_buflen == o_namelen) {
4796 lustre_cfg_bufs_set(n_bufs, i, n_buf,
4798 n_buf += cfs_size_round(n_namelen);
4802 memcpy(n_buf + n_namelen, o_buf + o_namelen,
4803 o_buflen - o_namelen);
4804 lustre_cfg_bufs_set(n_bufs, i, n_buf, o_buflen + diff);
4805 n_buf += cfs_size_round(o_buflen + diff);
4811 lcr = lustre_cfg_rec_new(cmd, n_bufs);
4815 lcr->lcr_cfg = *o_lcfg;
4816 rc = llog_write(env, mlfd->mlfd_llh, &lcr->lcr_hdr, LLOG_NEXT_IDX);
4817 lustre_cfg_rec_free(lcr);
4822 static int mgs_lcfg_fork_one(const struct lu_env *env, struct mgs_device *mgs,
4823 struct mgs_direntry *mde, const char *oldname,
4824 const char *newname)
4826 struct llog_handle *old_llh = NULL;
4827 struct llog_handle *new_llh = NULL;
4828 struct llog_ctxt *ctxt = NULL;
4829 struct mgs_lcfg_fork_data *mlfd = NULL;
4830 char *name_buf = NULL;
4832 int old_namelen = strlen(oldname);
4833 int new_namelen = strlen(newname);
4837 name_buflen = mde->mde_len + new_namelen - old_namelen;
4838 OBD_ALLOC(name_buf, name_buflen);
4842 memcpy(name_buf, newname, new_namelen);
4843 memcpy(name_buf + new_namelen, mde->mde_name + old_namelen,
4844 mde->mde_len - old_namelen);
4846 CDEBUG(D_MGS, "Fork the config-log from %s to %s\n",
4847 mde->mde_name, name_buf);
4849 ctxt = llog_get_context(mgs->mgs_obd, LLOG_CONFIG_ORIG_CTXT);
4852 rc = llog_open_create(env, ctxt, &new_llh, NULL, name_buf);
4856 rc = llog_init_handle(env, new_llh, LLOG_F_IS_PLAIN, NULL);
4860 if (unlikely(mgs_log_is_empty(env, mgs, mde->mde_name)))
4863 rc = llog_open(env, ctxt, &old_llh, NULL, mde->mde_name,
4868 rc = llog_init_handle(env, old_llh, LLOG_F_IS_PLAIN, NULL);
4872 new_llh->lgh_hdr->llh_tgtuuid = old_llh->lgh_hdr->llh_tgtuuid;
4874 OBD_ALLOC(mlfd, LLOG_MIN_CHUNK_SIZE);
4876 GOTO(out, rc = -ENOMEM);
4878 mlfd->mlfd_mgs = mgs;
4879 mlfd->mlfd_llh = new_llh;
4880 mlfd->mlfd_oldname = oldname;
4881 mlfd->mlfd_newname = newname;
4883 rc = llog_process(env, old_llh, mgs_lcfg_fork_handler, mlfd, NULL);
4884 OBD_FREE(mlfd, LLOG_MIN_CHUNK_SIZE);
4890 llog_close(env, old_llh);
4892 llog_close(env, new_llh);
4894 OBD_FREE(name_buf, name_buflen);
4896 llog_ctxt_put(ctxt);
4901 int mgs_lcfg_fork(const struct lu_env *env, struct mgs_device *mgs,
4902 const char *oldname, const char *newname)
4904 struct list_head log_list;
4905 struct mgs_direntry *dirent, *n;
4906 int olen = strlen(oldname);
4907 int nlen = strlen(newname);
4912 if (unlikely(!oldname || oldname[0] == '\0' ||
4913 !newname || newname[0] == '\0'))
4916 if (strcmp(oldname, newname) == 0)
4919 /* lock it to prevent fork/erase/register in parallel. */
4920 mutex_lock(&mgs->mgs_mutex);
4922 rc = class_dentry_readdir(env, mgs, &log_list);
4924 mutex_unlock(&mgs->mgs_mutex);
4928 if (list_empty(&log_list)) {
4929 mutex_unlock(&mgs->mgs_mutex);
4933 list_for_each_entry_safe(dirent, n, &log_list, mde_list) {
4936 ptr = strrchr(dirent->mde_name, '-');
4938 int tlen = ptr - dirent->mde_name;
4941 strncmp(newname, dirent->mde_name, tlen) == 0)
4942 GOTO(out, rc = -EEXIST);
4945 strncmp(oldname, dirent->mde_name, tlen) == 0)
4949 list_del_init(&dirent->mde_list);
4950 mgs_direntry_free(dirent);
4953 if (list_empty(&log_list)) {
4954 mutex_unlock(&mgs->mgs_mutex);
4958 list_for_each_entry(dirent, &log_list, mde_list) {
4959 rc = mgs_lcfg_fork_one(env, mgs, dirent, oldname, newname);
4967 mutex_unlock(&mgs->mgs_mutex);
4969 list_for_each_entry_safe(dirent, n, &log_list, mde_list) {
4970 list_del_init(&dirent->mde_list);
4971 mgs_direntry_free(dirent);
4974 if (rc && count > 0)
4975 mgs_erase_logs(env, mgs, newname);
4980 int mgs_lcfg_erase(const struct lu_env *env, struct mgs_device *mgs,
4986 if (unlikely(!fsname || fsname[0] == '\0'))
4989 rc = mgs_erase_logs(env, mgs, fsname);
4994 static int mgs_xattr_del(const struct lu_env *env, struct dt_object *obj)
4996 struct dt_device *dev;
4997 struct thandle *th = NULL;
5002 dev = container_of(obj->do_lu.lo_dev, struct dt_device, dd_lu_dev);
5003 th = dt_trans_create(env, dev);
5005 RETURN(PTR_ERR(th));
5007 rc = dt_declare_xattr_del(env, obj, XATTR_TARGET_RENAME, th);
5011 rc = dt_trans_start_local(env, dev, th);
5015 dt_write_lock(env, obj, 0);
5016 rc = dt_xattr_del(env, obj, XATTR_TARGET_RENAME, th);
5021 dt_write_unlock(env, obj);
5024 dt_trans_stop(env, dev, th);
5029 int mgs_lcfg_rename(const struct lu_env *env, struct mgs_device *mgs)
5031 struct list_head log_list;
5032 struct mgs_direntry *dirent, *n;
5034 struct lu_buf buf = {
5036 .lb_len = sizeof(fsname)
5042 rc = class_dentry_readdir(env, mgs, &log_list);
5046 if (list_empty(&log_list))
5049 list_for_each_entry_safe(dirent, n, &log_list, mde_list) {
5050 struct dt_object *o = NULL;
5055 list_del_init(&dirent->mde_list);
5056 ptr = strrchr(dirent->mde_name, '-');
5060 len = ptr - dirent->mde_name;
5061 if (unlikely(len >= sizeof(oldname))) {
5062 CDEBUG(D_MGS, "Skip invalid configuration file %s\n",
5067 o = local_file_find(env, mgs->mgs_los, mgs->mgs_configs_dir,
5071 CDEBUG(D_MGS, "Fail to locate file %s: rc = %d\n",
5072 dirent->mde_name, rc);
5076 rc = dt_xattr_get(env, o, &buf, XATTR_TARGET_RENAME);
5082 "Fail to get EA for %s: rc = %d\n",
5083 dirent->mde_name, rc);
5087 if (unlikely(rc == len &&
5088 memcmp(fsname, dirent->mde_name, len) == 0)) {
5089 /* The new fsname is the same as the old one. */
5090 rc = mgs_xattr_del(env, o);
5094 memcpy(oldname, dirent->mde_name, len);
5095 oldname[len] = '\0';
5097 rc = mgs_lcfg_fork_one(env, mgs, dirent, oldname, fsname);
5098 if (rc && rc != -EEXIST) {
5099 CDEBUG(D_MGS, "Fail to fork %s: rc = %d\n",
5100 dirent->mde_name, rc);
5104 rc = mgs_erase_log(env, mgs, dirent->mde_name);
5106 CDEBUG(D_MGS, "Fail to erase old %s: rc = %d\n",
5107 dirent->mde_name, rc);
5108 /* keep it there if failed to remove it. */
5113 if (o && !IS_ERR(o))
5114 lu_object_put(env, &o->do_lu);
5116 mgs_direntry_free(dirent);
5121 list_for_each_entry_safe(dirent, n, &log_list, mde_list) {
5122 list_del_init(&dirent->mde_list);
5123 mgs_direntry_free(dirent);
5129 /* Setup _mgs fsdb and log
5131 int mgs__mgs_fsdb_setup(const struct lu_env *env, struct mgs_device *mgs)
5133 struct fs_db *fsdb = NULL;
5137 rc = mgs_find_or_make_fsdb(env, mgs, MGSSELF_NAME, &fsdb);
5139 mgs_put_fsdb(mgs, fsdb);
5144 /* Setup params fsdb and log
5146 int mgs_params_fsdb_setup(const struct lu_env *env, struct mgs_device *mgs)
5148 struct fs_db *fsdb = NULL;
5149 struct llog_handle *params_llh = NULL;
5153 rc = mgs_find_or_make_fsdb(env, mgs, PARAMS_FILENAME, &fsdb);
5155 mutex_lock(&fsdb->fsdb_mutex);
5156 rc = record_start_log(env, mgs, ¶ms_llh, PARAMS_FILENAME);
5158 rc = record_end_log(env, ¶ms_llh);
5159 mutex_unlock(&fsdb->fsdb_mutex);
5160 mgs_put_fsdb(mgs, fsdb);
5166 /* Cleanup params fsdb and log
5168 int mgs_params_fsdb_cleanup(const struct lu_env *env, struct mgs_device *mgs)
5172 rc = mgs_erase_logs(env, mgs, PARAMS_FILENAME);
5173 return rc == -ENOENT ? 0 : rc;
5177 * Fill in the mgs_target_info based on data devname and param provide.
5179 * @env thread context
5181 * @mti mgs target info. We want to set this based other paramters
5182 * passed to this function. Once setup we write it to the config
5184 * @devname optional OBD device name
5185 * @param string that contains both what tunable to set and the value to
5188 * RETURN 0 for success
5189 * negative error number on failure
5191 static int mgs_set_conf_param(const struct lu_env *env, struct mgs_device *mgs,
5192 struct mgs_target_info *mti, const char *devname,
5195 struct fs_db *fsdb = NULL;
5200 /* lustre, lustre-mdtlov, lustre-client, lustre-MDT0000 */
5204 /* We have two possible cases here:
5206 * 1) the device name embedded in the param:
5207 * lustre-OST0000.osc.max_dirty_mb=32
5209 * 2) the file system name is embedded in
5210 * the param: lustre.sys.at.min=0
5212 len = strcspn(param, ".=");
5213 if (!len || param[len] == '=')
5216 if (len >= sizeof(mti->mti_svname))
5219 snprintf(mti->mti_svname, sizeof(mti->mti_svname),
5220 "%.*s", (int)len, param);
5223 if (strlcpy(mti->mti_svname, devname, sizeof(mti->mti_svname)) >=
5224 sizeof(mti->mti_svname))
5228 if (!strlen(mti->mti_svname)) {
5229 LCONSOLE_ERROR_MSG(0x14d, "No target specified: %s\n", param);
5233 dev_type = mgs_parse_devname(mti->mti_svname, mti->mti_fsname,
5234 &mti->mti_stripe_index);
5236 /* For this case we have an invalid obd device name */
5238 CDEBUG(D_MGS, "%s don't contain an index\n", mti->mti_svname);
5239 strlcpy(mti->mti_fsname, mti->mti_svname, MTI_NAME_MAXLEN);
5242 /* Not an obd device, assume devname is the fsname.
5243 * User might of only provided fsname and not obd device
5246 CDEBUG(D_MGS, "%s is seen as a file system name\n", mti->mti_svname);
5247 strlcpy(mti->mti_fsname, mti->mti_svname, MTI_NAME_MAXLEN);
5252 GOTO(out, rc = dev_type);
5254 /* param related to llite isn't allowed to set by OST or MDT */
5255 if (dev_type & LDD_F_SV_TYPE_OST ||
5256 dev_type & LDD_F_SV_TYPE_MDT) {
5257 /* param related to llite isn't allowed to set by OST
5260 if (!strncmp(param, PARAM_LLITE,
5261 sizeof(PARAM_LLITE) - 1))
5262 GOTO(out, rc = -EINVAL);
5264 /* Strip -osc or -mdc suffix from svname */
5265 if (server_make_name(dev_type, mti->mti_stripe_index,
5266 mti->mti_fsname, mti->mti_svname,
5267 sizeof(mti->mti_svname)))
5268 GOTO(out, rc = -EINVAL);
5273 if (strlcpy(mti->mti_params, param, sizeof(mti->mti_params)) >=
5274 sizeof(mti->mti_params))
5275 GOTO(out, rc = -E2BIG);
5277 CDEBUG(D_MGS, "set_conf_param fs='%s' device='%s' param='%s'\n",
5278 mti->mti_fsname, mti->mti_svname, mti->mti_params);
5280 rc = mgs_find_or_make_fsdb(env, mgs, mti->mti_fsname, &fsdb);
5284 if (!test_bit(FSDB_MGS_SELF, &fsdb->fsdb_flags) &&
5285 test_bit(FSDB_LOG_EMPTY, &fsdb->fsdb_flags)) {
5286 CERROR("No filesystem targets for %s. cfg_device from lctl "
5287 "is '%s'\n", mti->mti_fsname, mti->mti_svname);
5288 mgs_unlink_fsdb(mgs, fsdb);
5289 GOTO(out, rc = -EINVAL);
5293 * Revoke lock so everyone updates. Should be alright if
5294 * someone was already reading while we were updating the logs,
5295 * so we don't really need to hold the lock while we're
5298 mti->mti_flags = dev_type | LDD_F_PARAM;
5299 mutex_lock(&fsdb->fsdb_mutex);
5300 rc = mgs_write_log_param(env, mgs, fsdb, mti, mti->mti_params);
5301 mutex_unlock(&fsdb->fsdb_mutex);
5302 mgs_revoke_lock(mgs, fsdb, MGS_CFG_T_CONFIG);
5306 mgs_put_fsdb(mgs, fsdb);
5311 static int mgs_set_param2(const struct lu_env *env, struct mgs_device *mgs,
5312 struct mgs_target_info *mti, const char *param)
5314 struct fs_db *fsdb = NULL;
5319 if (strlcpy(mti->mti_params, param, sizeof(mti->mti_params)) >=
5320 sizeof(mti->mti_params))
5321 GOTO(out, rc = -E2BIG);
5323 len = strcspn(param, ".=");
5324 if (len && param[len] != '=') {
5325 struct list_head *tmp;
5329 ptr = strchr(param, '.');
5331 len = strlen(param);
5334 if (len >= sizeof(mti->mti_svname))
5335 GOTO(out, rc = -E2BIG);
5337 snprintf(mti->mti_svname, sizeof(mti->mti_svname), "%.*s",
5340 mutex_lock(&mgs->mgs_mutex);
5341 if (unlikely(list_empty(&mgs->mgs_fs_db_list))) {
5342 mutex_unlock(&mgs->mgs_mutex);
5343 GOTO(out, rc = -ENODEV);
5346 list_for_each(tmp, &mgs->mgs_fs_db_list) {
5347 fsdb = list_entry(tmp, struct fs_db, fsdb_list);
5348 if (fsdb->fsdb_has_lproc_entry &&
5349 strcmp(fsdb->fsdb_name, "params") != 0 &&
5350 strstr(param, fsdb->fsdb_name)) {
5351 snprintf(mti->mti_svname,
5352 sizeof(mti->mti_svname), "%s",
5360 snprintf(mti->mti_svname, sizeof(mti->mti_svname),
5363 mutex_unlock(&mgs->mgs_mutex);
5365 snprintf(mti->mti_svname, sizeof(mti->mti_svname), "general");
5368 CDEBUG(D_MGS, "set_param2 fs='%s' device='%s' param='%s'\n",
5369 mti->mti_fsname, mti->mti_svname, mti->mti_params);
5371 /* The return value should be the device type i.e LDD_F_SV_TYPE_XXX.
5372 * A returned error tells us we don't have a target obd device.
5374 dev_type = server_name2index(mti->mti_svname, &mti->mti_stripe_index,
5379 /* the return value should be the device type i.e LDD_F_SV_TYPE_XXX.
5380 * Strip -osc or -mdc suffix from svname
5382 if ((dev_type & LDD_F_SV_TYPE_OST || dev_type & LDD_F_SV_TYPE_MDT) &&
5383 server_make_name(dev_type, mti->mti_stripe_index,
5384 mti->mti_fsname, mti->mti_svname,
5385 sizeof(mti->mti_svname)))
5386 GOTO(out, rc = -EINVAL);
5388 rc = mgs_find_or_make_fsdb(env, mgs, PARAMS_FILENAME, &fsdb);
5392 * Revoke lock so everyone updates. Should be alright if
5393 * someone was already reading while we were updating the logs,
5394 * so we don't really need to hold the lock while we're
5397 mti->mti_flags = dev_type | LDD_F_PARAM2;
5398 mutex_lock(&fsdb->fsdb_mutex);
5399 rc = mgs_write_log_param2(env, mgs, fsdb, mti, mti->mti_params);
5400 mutex_unlock(&fsdb->fsdb_mutex);
5401 mgs_revoke_lock(mgs, fsdb, MGS_CFG_T_PARAMS);
5402 mgs_put_fsdb(mgs, fsdb);
5407 /* Set a permanent (config log) param for a target or fs
5409 * @lcfg buf0 may contain the device (testfs-MDT0000) name
5410 * buf1 contains the single parameter
5412 int mgs_set_param(const struct lu_env *env, struct mgs_device *mgs,
5413 struct lustre_cfg *lcfg)
5415 const char *param = lustre_cfg_string(lcfg, 1);
5416 struct mgs_target_info *mti;
5419 /* Create a fake mti to hold everything */
5424 print_lustre_cfg(lcfg);
5426 if (lcfg->lcfg_command == LCFG_PARAM) {
5427 /* For the case of lctl conf_param devname can be
5428 * lustre, lustre-mdtlov, lustre-client, lustre-MDT0000
5430 const char *devname = lustre_cfg_string(lcfg, 0);
5432 rc = mgs_set_conf_param(env, mgs, mti, devname, param);
5434 /* In the case of lctl set_param -P lcfg[0] will always
5435 * be 'general'. At least for now.
5437 rc = mgs_set_param2(env, mgs, mti, param);
5445 static int mgs_write_log_pool(const struct lu_env *env,
5446 struct mgs_device *mgs, char *logname,
5447 struct fs_db *fsdb, char *tgtname,
5448 enum lcfg_command_type cmd,
5449 char *fsname, char *poolname,
5450 char *ostname, char *comment)
5452 struct llog_handle *llh = NULL;
5455 rc = record_start_log(env, mgs, &llh, logname);
5458 rc = record_marker(env, llh, fsdb, CM_START, tgtname, comment);
5461 rc = record_base(env, llh, tgtname, 0, cmd,
5462 fsname, poolname, ostname, NULL);
5465 rc = record_marker(env, llh, fsdb, CM_END, tgtname, comment);
5467 record_end_log(env, &llh);
5471 int mgs_nodemap_cmd(const struct lu_env *env, struct mgs_device *mgs,
5472 enum lcfg_command_type cmd, const char *nodemap_name,
5483 case LCFG_NODEMAP_ADD:
5484 rc = nodemap_add(nodemap_name);
5486 case LCFG_NODEMAP_DEL:
5487 rc = nodemap_del(nodemap_name);
5489 case LCFG_NODEMAP_ADD_RANGE:
5490 rc = nodemap_parse_range(param, nid);
5493 rc = nodemap_add_range(nodemap_name, nid);
5495 case LCFG_NODEMAP_DEL_RANGE:
5496 rc = nodemap_parse_range(param, nid);
5499 rc = nodemap_del_range(nodemap_name, nid);
5501 case LCFG_NODEMAP_ADMIN:
5502 rc = kstrtobool(param, &bool_switch);
5505 rc = nodemap_set_allow_root(nodemap_name, bool_switch);
5507 case LCFG_NODEMAP_DENY_UNKNOWN:
5508 rc = kstrtobool(param, &bool_switch);
5511 rc = nodemap_set_deny_unknown(nodemap_name, bool_switch);
5513 case LCFG_NODEMAP_AUDIT_MODE:
5514 rc = kstrtobool(param, &bool_switch);
5516 rc = nodemap_set_audit_mode(nodemap_name, bool_switch);
5518 case LCFG_NODEMAP_FORBID_ENCRYPT:
5519 rc = kstrtobool(param, &bool_switch);
5521 rc = nodemap_set_forbid_encryption(nodemap_name,
5524 case LCFG_NODEMAP_READONLY_MOUNT:
5525 rc = kstrtobool(param, &bool_switch);
5527 rc = nodemap_set_readonly_mount(nodemap_name,
5530 case LCFG_NODEMAP_MAP_MODE:
5535 if ((p = strstr(param, "all")) != NULL) {
5536 if ((p == param || *(p-1) == ',') &&
5537 (*(p+3) == '\0' || *(p+3) == ',')) {
5538 map_mode = NODEMAP_MAP_ALL;
5544 while ((p = strsep(¶m, ",")) != NULL) {
5548 if (strcmp("both", p) == 0)
5549 map_mode |= NODEMAP_MAP_BOTH;
5550 else if (strcmp("uid_only", p) == 0 ||
5551 strcmp("uid", p) == 0)
5552 map_mode |= NODEMAP_MAP_UID;
5553 else if (strcmp("gid_only", p) == 0 ||
5554 strcmp("gid", p) == 0)
5555 map_mode |= NODEMAP_MAP_GID;
5556 else if (strcmp("projid_only", p) == 0 ||
5557 strcmp("projid", p) == 0)
5558 map_mode |= NODEMAP_MAP_PROJID;
5568 rc = nodemap_set_mapping_mode(nodemap_name, map_mode);
5571 case LCFG_NODEMAP_TRUSTED:
5572 rc = kstrtobool(param, &bool_switch);
5575 rc = nodemap_set_trust_client_ids(nodemap_name, bool_switch);
5577 case LCFG_NODEMAP_SQUASH_UID:
5578 rc = kstrtouint(param, 10, &int_id);
5581 rc = nodemap_set_squash_uid(nodemap_name, int_id);
5583 case LCFG_NODEMAP_SQUASH_GID:
5584 rc = kstrtouint(param, 10, &int_id);
5587 rc = nodemap_set_squash_gid(nodemap_name, int_id);
5589 case LCFG_NODEMAP_SQUASH_PROJID:
5590 rc = kstrtouint(param, 10, &int_id);
5593 rc = nodemap_set_squash_projid(nodemap_name, int_id);
5595 case LCFG_NODEMAP_ADD_UIDMAP:
5596 case LCFG_NODEMAP_ADD_GIDMAP:
5597 case LCFG_NODEMAP_ADD_PROJIDMAP:
5598 rc = nodemap_parse_idmap(param, idmap);
5601 if (cmd == LCFG_NODEMAP_ADD_UIDMAP)
5602 rc = nodemap_add_idmap(nodemap_name, NODEMAP_UID,
5604 else if (cmd == LCFG_NODEMAP_ADD_GIDMAP)
5605 rc = nodemap_add_idmap(nodemap_name, NODEMAP_GID,
5607 else if (cmd == LCFG_NODEMAP_ADD_PROJIDMAP)
5608 rc = nodemap_add_idmap(nodemap_name, NODEMAP_PROJID,
5613 case LCFG_NODEMAP_DEL_UIDMAP:
5614 case LCFG_NODEMAP_DEL_GIDMAP:
5615 case LCFG_NODEMAP_DEL_PROJIDMAP:
5616 rc = nodemap_parse_idmap(param, idmap);
5619 if (cmd == LCFG_NODEMAP_DEL_UIDMAP)
5620 rc = nodemap_del_idmap(nodemap_name, NODEMAP_UID,
5622 else if (cmd == LCFG_NODEMAP_DEL_GIDMAP)
5623 rc = nodemap_del_idmap(nodemap_name, NODEMAP_GID,
5625 else if (cmd == LCFG_NODEMAP_DEL_PROJIDMAP)
5626 rc = nodemap_del_idmap(nodemap_name, NODEMAP_PROJID,
5631 case LCFG_NODEMAP_SET_FILESET:
5632 rc = nodemap_set_fileset(nodemap_name, param);
5634 case LCFG_NODEMAP_SET_SEPOL:
5635 rc = nodemap_set_sepol(nodemap_name, param);
5644 int mgs_pool_cmd(const struct lu_env *env, struct mgs_device *mgs,
5645 enum lcfg_command_type cmd, char *fsname,
5646 char *poolname, char *ostname)
5651 char *label = NULL, *canceled_label = NULL;
5653 struct mgs_target_info *mti = NULL;
5654 bool checked = false;
5655 bool locked = false;
5660 rc = mgs_find_or_make_fsdb(env, mgs, fsname, &fsdb);
5662 CERROR("Can't get db for %s\n", fsname);
5665 if (test_bit(FSDB_LOG_EMPTY, &fsdb->fsdb_flags)) {
5666 CERROR("%s is not defined\n", fsname);
5668 GOTO(out_fsdb, rc = -EINVAL);
5671 label_sz = 10 + strlen(fsname) + strlen(poolname);
5673 /* check if ostname match fsname */
5674 if (ostname != NULL) {
5677 ptr = strrchr(ostname, '-');
5678 if ((ptr == NULL) ||
5679 (strncmp(fsname, ostname, ptr-ostname) != 0))
5681 label_sz += strlen(ostname);
5684 OBD_ALLOC(label, label_sz);
5686 GOTO(out_fsdb, rc = -ENOMEM);
5691 "new %s.%s", fsname, poolname);
5695 "add %s.%s.%s", fsname, poolname, ostname);
5698 OBD_ALLOC(canceled_label, label_sz);
5699 if (canceled_label == NULL)
5700 GOTO(out_label, rc = -ENOMEM);
5702 "rem %s.%s.%s", fsname, poolname, ostname);
5703 sprintf(canceled_label,
5704 "add %s.%s.%s", fsname, poolname, ostname);
5707 OBD_ALLOC(canceled_label, label_sz);
5708 if (canceled_label == NULL)
5709 GOTO(out_label, rc = -ENOMEM);
5711 "del %s.%s", fsname, poolname);
5712 sprintf(canceled_label,
5713 "new %s.%s", fsname, poolname);
5721 GOTO(out_cancel, rc = -ENOMEM);
5722 strncpy(mti->mti_svname, "lov pool", sizeof(mti->mti_svname));
5724 mutex_lock(&fsdb->fsdb_mutex);
5726 /* write pool def to all MDT logs */
5727 for (i = 0; i < INDEX_MAP_SIZE * 8; i++) {
5728 if (test_bit(i, fsdb->fsdb_mdt_index_map)) {
5729 rc = name_create_mdt_and_lov(&logname, &lovname,
5734 if (!checked && (canceled_label == NULL)) {
5735 rc = mgs_check_marker(env, mgs, fsdb, mti,
5736 logname, lovname, label);
5738 name_destroy(&logname);
5739 name_destroy(&lovname);
5741 rc = (rc == LLOG_PROC_BREAK ?
5746 if (canceled_label != NULL)
5747 rc = mgs_modify(env, mgs, fsdb, mti, logname,
5748 lovname, canceled_label,
5752 rc = mgs_write_log_pool(env, mgs, logname,
5756 name_destroy(&logname);
5757 name_destroy(&lovname);
5763 rc = name_create(&logname, fsname, "-client");
5767 if (!checked && (canceled_label == NULL)) {
5768 rc = mgs_check_marker(env, mgs, fsdb, mti, logname,
5769 fsdb->fsdb_clilov, label);
5771 name_destroy(&logname);
5772 GOTO(out_mti, rc = (rc == LLOG_PROC_BREAK ?
5776 if (canceled_label != NULL) {
5777 rc = mgs_modify(env, mgs, fsdb, mti, logname,
5778 fsdb->fsdb_clilov, canceled_label, CM_SKIP);
5780 name_destroy(&logname);
5785 rc = mgs_write_log_pool(env, mgs, logname, fsdb, fsdb->fsdb_clilov,
5786 cmd, fsname, poolname, ostname, label);
5787 mutex_unlock(&fsdb->fsdb_mutex);
5789 name_destroy(&logname);
5790 /* request for update */
5791 mgs_revoke_lock(mgs, fsdb, MGS_CFG_T_CONFIG);
5797 mutex_unlock(&fsdb->fsdb_mutex);
5801 if (canceled_label != NULL)
5802 OBD_FREE(canceled_label, label_sz);
5804 OBD_FREE(label, label_sz);
5807 mgs_unlink_fsdb(mgs, fsdb);
5808 mgs_put_fsdb(mgs, fsdb);