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 /* mount opt is the third thing in client logs */
2344 static int mgs_write_log_mount_opt(const struct lu_env *env,
2345 struct mgs_device *mgs, struct fs_db *fsdb,
2348 struct llog_handle *llh = NULL;
2353 CDEBUG(D_MGS, "Writing mount options log for %s\n", logname);
2355 rc = record_start_log(env, mgs, &llh, logname);
2359 rc = record_marker(env, llh, fsdb, CM_START, logname, "mount opts");
2362 rc = record_mount_opt(env, llh, logname, fsdb->fsdb_clilov,
2366 rc = record_marker(env, llh, fsdb, CM_END, logname, "mount opts");
2370 record_end_log(env, &llh);
2374 /* lmv is the second thing for client logs */
2375 /* copied from mgs_write_log_lov. Please refer to that. */
2376 static int mgs_write_log_lmv(const struct lu_env *env,
2377 struct mgs_device *mgs,
2379 struct mgs_target_info *mti,
2380 char *logname, char *lmvname)
2382 struct llog_handle *llh = NULL;
2383 struct lmv_desc *lmvdesc;
2388 CDEBUG(D_MGS, "Writing lmv(%s) log for %s\n", lmvname,logname);
2390 OBD_ALLOC_PTR(lmvdesc);
2391 if (lmvdesc == NULL)
2393 lmvdesc->ld_active_tgt_count = 0;
2394 lmvdesc->ld_tgt_count = 0;
2395 sprintf((char*)lmvdesc->ld_uuid.uuid, "%s_UUID", lmvname);
2396 uuid = (char *)lmvdesc->ld_uuid.uuid;
2398 rc = record_start_log(env, mgs, &llh, logname);
2401 rc = record_marker(env, llh, fsdb, CM_START, lmvname, "lmv setup");
2404 rc = record_attach(env, llh, lmvname, "lmv", uuid);
2407 rc = record_lmv_setup(env, llh, lmvname, lmvdesc);
2410 rc = record_marker(env, llh, fsdb, CM_END, lmvname, "lmv setup");
2414 record_end_log(env, &llh);
2416 OBD_FREE_PTR(lmvdesc);
2420 /* lov is the first thing in the mdt and client logs */
2421 static int mgs_write_log_lov(const struct lu_env *env, struct mgs_device *mgs,
2422 struct fs_db *fsdb, struct mgs_target_info *mti,
2423 char *logname, char *lovname)
2425 struct llog_handle *llh = NULL;
2426 struct lov_desc *lovdesc;
2431 CDEBUG(D_MGS, "Writing lov(%s) log for %s\n", lovname, logname);
2434 #01 L attach 0:lov_mdsA 1:lov 2:71ccb_lov_mdsA_19f961a9e1
2435 #02 L lov_setup 0:lov_mdsA 1:(struct lov_desc)
2436 uuid=lov1_UUID, stripe count=1, size=1048576, offset=0, pattern=0
2439 /* FIXME just make lov_setup accept empty desc (put uuid in buf 2) */
2440 OBD_ALLOC_PTR(lovdesc);
2441 if (lovdesc == NULL)
2443 lovdesc->ld_magic = LOV_DESC_MAGIC;
2444 lovdesc->ld_tgt_count = 0;
2445 /* Defaults. Can be changed later by lcfg config_param */
2446 lovdesc->ld_default_stripe_count = 1;
2447 lovdesc->ld_pattern = LOV_PATTERN_RAID0;
2448 lovdesc->ld_default_stripe_size = LOV_DESC_STRIPE_SIZE_DEFAULT;
2449 lovdesc->ld_default_stripe_offset = -1;
2450 lovdesc->ld_qos_maxage = LOV_DESC_QOS_MAXAGE_DEFAULT;
2451 sprintf((char*)lovdesc->ld_uuid.uuid, "%s_UUID", lovname);
2452 /* can these be the same? */
2453 uuid = (char *)lovdesc->ld_uuid.uuid;
2455 /* This should always be the first entry in a log.
2456 rc = mgs_clear_log(obd, logname); */
2457 rc = record_start_log(env, mgs, &llh, logname);
2460 /* FIXME these should be a single journal transaction */
2461 rc = record_marker(env, llh, fsdb, CM_START, lovname, "lov setup");
2464 rc = record_attach(env, llh, lovname, "lov", uuid);
2467 rc = record_lov_setup(env, llh, lovname, lovdesc);
2470 rc = record_marker(env, llh, fsdb, CM_END, lovname, "lov setup");
2475 record_end_log(env, &llh);
2477 OBD_FREE_PTR(lovdesc);
2481 /* add failnids to open log */
2482 static int mgs_write_log_failnids(const struct lu_env *env,
2483 struct mgs_target_info *mti,
2484 struct llog_handle *llh,
2487 char *failnodeuuid = NULL;
2488 char *ptr = mti->mti_params;
2493 #03 L add_uuid nid=uml1@tcp(0x20000c0a80201) nal=90 0: 1:uml1_UUID
2494 #04 L add_uuid nid=1@elan(0x1000000000001) nal=90 0: 1:uml1_UUID
2495 #05 L setup 0:OSC_uml1_ost1_mdsA 1:ost1_UUID 2:uml1_UUID
2496 #06 L add_uuid nid=uml2@tcp(0x20000c0a80202) nal=90 0: 1:uml2_UUID
2497 #0x L add_uuid nid=2@elan(0x1000000000002) nal=90 0: 1:uml2_UUID
2498 #07 L add_conn 0:OSC_uml1_ost1_mdsA 1:uml2_UUID
2502 * Pull failnid info out of params string, which may contain something
2503 * like "<nid1>,<nid2>:<nid3>,<nid4>". class_parse_nid() does not
2504 * complain about abnormal inputs like ",:<nid1>", "<nid1>:,<nid2>",
2505 * etc. However, convert_hostnames() should have caught those.
2507 while (class_find_param(ptr, PARAM_FAILNODE, &ptr) == 0) {
2508 while (class_parse_nid(ptr, &nid, &ptr) == 0) {
2509 char nidstr[LNET_NIDSTR_SIZE];
2511 if (failnodeuuid == NULL) {
2512 /* We don't know the failover node name,
2513 * so just use the first nid as the uuid */
2514 libcfs_nid2str_r(nid, nidstr, sizeof(nidstr));
2515 rc = name_create(&failnodeuuid, nidstr, "");
2519 CDEBUG(D_MGS, "add nid %s for failover uuid %s, "
2521 libcfs_nid2str_r(nid, nidstr, sizeof(nidstr)),
2522 failnodeuuid, cliname);
2523 rc = record_add_uuid(env, llh, nid, failnodeuuid);
2525 * If *ptr is ':', we have added all NIDs for
2529 rc = record_add_conn(env, llh, cliname,
2531 name_destroy(&failnodeuuid);
2532 failnodeuuid = NULL;
2536 rc = record_add_conn(env, llh, cliname, failnodeuuid);
2537 name_destroy(&failnodeuuid);
2538 failnodeuuid = NULL;
2545 static int mgs_write_log_mdc_to_lmv(const struct lu_env *env,
2546 struct mgs_device *mgs,
2548 struct mgs_target_info *mti,
2549 char *logname, char *lmvname)
2551 struct llog_handle *llh = NULL;
2552 char *mdcname = NULL;
2553 char *nodeuuid = NULL;
2554 char *mdcuuid = NULL;
2555 char *lmvuuid = NULL;
2557 char nidstr[LNET_NIDSTR_SIZE];
2561 if (mgs_log_is_empty(env, mgs, logname)) {
2562 CERROR("log is empty! Logical error\n");
2566 CDEBUG(D_MGS, "adding mdc for %s to log %s:lmv(%s)\n",
2567 mti->mti_svname, logname, lmvname);
2569 libcfs_nid2str_r(mti->mti_nids[0], nidstr, sizeof(nidstr));
2570 rc = name_create(&nodeuuid, nidstr, "");
2573 rc = name_create(&mdcname, mti->mti_svname, "-mdc");
2576 rc = name_create(&mdcuuid, mdcname, "_UUID");
2579 rc = name_create(&lmvuuid, lmvname, "_UUID");
2583 rc = mgs_modify(env, mgs, fsdb, mti, logname, mti->mti_svname,
2584 "add mdc", CM_SKIP);
2588 rc = record_start_log(env, mgs, &llh, logname);
2591 rc = record_marker(env, llh, fsdb, CM_START, mti->mti_svname,
2595 for (i = 0; i < mti->mti_nid_count; i++) {
2596 CDEBUG(D_MGS, "add nid %s for mdt\n",
2597 libcfs_nid2str_r(mti->mti_nids[i],
2598 nidstr, sizeof(nidstr)));
2600 rc = record_add_uuid(env, llh, mti->mti_nids[i], nodeuuid);
2605 rc = record_attach(env, llh, mdcname, LUSTRE_MDC_NAME, lmvuuid);
2608 rc = record_setup(env, llh, mdcname, mti->mti_uuid, nodeuuid,
2612 rc = mgs_write_log_failnids(env, mti, llh, mdcname);
2615 snprintf(index, sizeof(index), "%d", mti->mti_stripe_index);
2616 rc = record_mdc_add(env, llh, lmvname, mdcuuid, mti->mti_uuid,
2620 rc = record_marker(env, llh, fsdb, CM_END, mti->mti_svname,
2625 record_end_log(env, &llh);
2627 name_destroy(&lmvuuid);
2628 name_destroy(&mdcuuid);
2629 name_destroy(&mdcname);
2630 name_destroy(&nodeuuid);
2634 static inline int name_create_lov(char **lovname, char *mdtname,
2635 struct fs_db *fsdb, int index)
2638 if (index == 0 && test_bit(FSDB_OSCNAME18, &fsdb->fsdb_flags))
2639 return name_create(lovname, fsdb->fsdb_name, "-mdtlov");
2641 return name_create(lovname, mdtname, "-mdtlov");
2644 static int name_create_mdt_and_lov(char **logname, char **lovname,
2645 struct fs_db *fsdb, int i)
2649 rc = name_create_mdt(logname, fsdb->fsdb_name, i);
2653 if (i == 0 && test_bit(FSDB_OSCNAME18, &fsdb->fsdb_flags))
2654 rc = name_create(lovname, fsdb->fsdb_name, "-mdtlov");
2656 rc = name_create(lovname, *logname, "-mdtlov");
2658 name_destroy(logname);
2664 static inline int name_create_mdt_osc(char **oscname, char *ostname,
2665 struct fs_db *fsdb, int i)
2669 if (i == 0 && test_bit(FSDB_OSCNAME18, &fsdb->fsdb_flags))
2670 sprintf(suffix, "-osc");
2672 sprintf(suffix, "-osc-MDT%04x", i);
2673 return name_create(oscname, ostname, suffix);
2676 /* add new mdc to already existent MDS */
2677 static int mgs_write_log_osp_to_mdt(const struct lu_env *env,
2678 struct mgs_device *mgs,
2680 struct mgs_target_info *mti,
2681 int mdt_index, char *logname)
2683 struct llog_handle *llh = NULL;
2684 char *nodeuuid = NULL;
2685 char *ospname = NULL;
2686 char *lovuuid = NULL;
2687 char *mdtuuid = NULL;
2688 char *svname = NULL;
2689 char *mdtname = NULL;
2690 char *lovname = NULL;
2692 char nidstr[LNET_NIDSTR_SIZE];
2696 if (mgs_log_is_empty(env, mgs, mti->mti_svname)) {
2697 CERROR("log is empty! Logical error\n");
2701 CDEBUG(D_MGS, "adding osp index %d to %s\n", mti->mti_stripe_index,
2704 rc = name_create_mdt(&mdtname, fsdb->fsdb_name, mti->mti_stripe_index);
2708 libcfs_nid2str_r(mti->mti_nids[0], nidstr, sizeof(nidstr));
2709 rc = name_create(&nodeuuid, nidstr, "");
2711 GOTO(out_destory, rc);
2713 rc = name_create(&svname, mdtname, "-osp");
2715 GOTO(out_destory, rc);
2717 sprintf(index_str, "-MDT%04x", mdt_index);
2718 rc = name_create(&ospname, svname, index_str);
2720 GOTO(out_destory, rc);
2722 rc = name_create_lov(&lovname, logname, fsdb, mdt_index);
2724 GOTO(out_destory, rc);
2726 rc = name_create(&lovuuid, lovname, "_UUID");
2728 GOTO(out_destory, rc);
2730 rc = name_create(&mdtuuid, mdtname, "_UUID");
2732 GOTO(out_destory, rc);
2734 rc = mgs_modify(env, mgs, fsdb, mti, logname, mti->mti_svname,
2735 "add osp", CM_SKIP);
2737 GOTO(out_destory, rc);
2739 rc = record_start_log(env, mgs, &llh, logname);
2741 GOTO(out_destory, rc);
2743 rc = record_marker(env, llh, fsdb, CM_START, mti->mti_svname,
2746 GOTO(out_destory, rc);
2748 for (i = 0; i < mti->mti_nid_count; i++) {
2749 CDEBUG(D_MGS, "add nid %s for mdt\n",
2750 libcfs_nid2str_r(mti->mti_nids[i],
2751 nidstr, sizeof(nidstr)));
2752 rc = record_add_uuid(env, llh, mti->mti_nids[i], nodeuuid);
2757 rc = record_attach(env, llh, ospname, LUSTRE_OSP_NAME, lovuuid);
2761 rc = record_setup(env, llh, ospname, mti->mti_uuid, nodeuuid,
2766 rc = mgs_write_log_failnids(env, mti, llh, ospname);
2770 /* Add mdc(osp) to lod */
2771 snprintf(index_str, sizeof(index_str), "%d", mti->mti_stripe_index);
2772 rc = record_base(env, llh, lovname, 0, LCFG_ADD_MDC, mti->mti_uuid,
2773 index_str, "1", NULL);
2777 rc = record_marker(env, llh, fsdb, CM_END, mti->mti_svname, "add osp");
2782 record_end_log(env, &llh);
2785 name_destroy(&mdtuuid);
2786 name_destroy(&lovuuid);
2787 name_destroy(&lovname);
2788 name_destroy(&ospname);
2789 name_destroy(&svname);
2790 name_destroy(&nodeuuid);
2791 name_destroy(&mdtname);
2795 static int mgs_write_log_mdt0(const struct lu_env *env,
2796 struct mgs_device *mgs,
2798 struct mgs_target_info *mti)
2800 char *log = mti->mti_svname;
2801 struct llog_handle *llh = NULL;
2802 struct obd_uuid *uuid;
2805 char *ptr = mti->mti_params;
2806 int rc = 0, failout = 0;
2809 OBD_ALLOC_PTR(uuid);
2813 if (class_find_param(ptr, PARAM_FAILMODE, &ptr) == 0)
2814 failout = (strncmp(ptr, "failout", 7) == 0);
2816 rc = name_create(&lovname, log, "-mdtlov");
2819 if (mgs_log_is_empty(env, mgs, log)) {
2820 rc = mgs_write_log_lov(env, mgs, fsdb, mti, log, lovname);
2825 sprintf(mdt_index, "%d", mti->mti_stripe_index);
2827 rc = record_start_log(env, mgs, &llh, log);
2831 /* add MDT itself */
2833 /* FIXME this whole fn should be a single journal transaction */
2834 sprintf(uuid->uuid, "%s_UUID", log);
2835 rc = record_marker(env, llh, fsdb, CM_START, log, "add mdt");
2838 rc = record_attach(env, llh, log, LUSTRE_MDT_NAME, uuid->uuid);
2841 rc = record_mount_opt(env, llh, log, lovname, NULL);
2844 rc = record_setup(env, llh, log, uuid->uuid, mdt_index, lovname,
2845 failout ? "n" : "f");
2848 rc = record_marker(env, llh, fsdb, CM_END, log, "add mdt");
2852 record_end_log(env, &llh);
2854 name_destroy(&lovname);
2860 /* envelope method for all layers log */
2861 static int mgs_write_log_mdt(const struct lu_env *env,
2862 struct mgs_device *mgs,
2864 struct mgs_target_info *mti)
2866 struct mgs_thread_info *mgi = mgs_env_info(env);
2867 struct llog_handle *llh = NULL;
2872 CDEBUG(D_MGS, "writing new mdt %s\n", mti->mti_svname);
2874 if (mti->mti_uuid[0] == '\0') {
2875 /* Make up our own uuid */
2876 snprintf(mti->mti_uuid, sizeof(mti->mti_uuid),
2877 "%s_UUID", mti->mti_svname);
2881 rc = mgs_write_log_mdt0(env, mgs, fsdb, mti);
2884 /* Append the mdt info to the client log */
2885 rc = name_create(&cliname, mti->mti_fsname, "-client");
2889 if (mgs_log_is_empty(env, mgs, cliname)) {
2890 /* Start client log */
2891 rc = mgs_write_log_lov(env, mgs, fsdb, mti, cliname,
2895 rc = mgs_write_log_lmv(env, mgs, fsdb, mti, cliname,
2899 rc = mgs_write_log_mount_opt(env, mgs, fsdb, cliname);
2905 #09 L add_uuid nid=uml1@tcp(0x20000c0a80201) 0: 1:uml1_UUID
2906 #10 L attach 0:MDC_uml1_mdsA_MNT_client 1:mdc 2:1d834_MNT_client_03f
2907 #11 L setup 0:MDC_uml1_mdsA_MNT_client 1:mdsA_UUID 2:uml1_UUID
2908 #12 L add_uuid nid=uml2@tcp(0x20000c0a80202) 0: 1:uml2_UUID
2909 #13 L add_conn 0:MDC_uml1_mdsA_MNT_client 1:uml2_UUID
2912 /* copy client info about lov/lmv */
2913 mgi->mgi_comp.comp_mti = mti;
2914 mgi->mgi_comp.comp_fsdb = fsdb;
2916 rc = mgs_steal_llog_for_mdt_from_client(env, mgs, cliname,
2920 rc = mgs_write_log_mdc_to_lmv(env, mgs, fsdb, mti, cliname,
2925 rc = record_start_log(env, mgs, &llh, cliname);
2929 /* for_all_existing_mdt except current one */
2930 for (i = 0; i < INDEX_MAP_SIZE * 8; i++) {
2931 if (i != mti->mti_stripe_index &&
2932 test_bit(i, fsdb->fsdb_mdt_index_map)) {
2935 rc = name_create_mdt(&logname, fsdb->fsdb_name, i);
2939 /* NB: If the log for the MDT is empty, it means
2940 * the MDT is only added to the index
2941 * map, and not being process yet, i.e. this
2942 * is an unregistered MDT, see mgs_write_log_target().
2943 * so we should skip it. Otherwise
2945 * 1. MGS get register request for MDT1 and MDT2.
2947 * 2. Then both MDT1 and MDT2 are added into
2948 * fsdb_mdt_index_map. (see mgs_set_index()).
2950 * 3. Then MDT1 get the lock of fsdb_mutex, then
2951 * generate the config log, here, it will regard MDT2
2952 * as an existent MDT, and generate "add osp" for
2953 * lustre-MDT0001-osp-MDT0002. Note: at the moment
2954 * MDT0002 config log is still empty, so it will
2955 * add "add osp" even before "lov setup", which
2956 * will definitly cause trouble.
2958 * 4. MDT1 registeration finished, fsdb_mutex is
2959 * released, then MDT2 get in, then in above
2960 * mgs_steal_llog_for_mdt_from_client(), it will
2961 * add another osp log for lustre-MDT0001-osp-MDT0002,
2962 * which will cause another trouble.*/
2963 if (!mgs_log_is_empty(env, mgs, logname))
2964 rc = mgs_write_log_osp_to_mdt(env, mgs, fsdb,
2967 name_destroy(&logname);
2973 record_end_log(env, &llh);
2975 name_destroy(&cliname);
2979 /* Add the ost info to the client/mdt lov */
2980 static int mgs_write_log_osc_to_lov(const struct lu_env *env,
2981 struct mgs_device *mgs, struct fs_db *fsdb,
2982 struct mgs_target_info *mti,
2983 char *logname, char *suffix, char *lovname,
2984 enum lustre_sec_part sec_part, int flags)
2986 struct llog_handle *llh = NULL;
2987 char *nodeuuid = NULL;
2988 char *oscname = NULL;
2989 char *oscuuid = NULL;
2990 char *lovuuid = NULL;
2991 char *svname = NULL;
2993 char nidstr[LNET_NIDSTR_SIZE];
2997 CDEBUG(D_INFO, "adding osc for %s to log %s\n",
2998 mti->mti_svname, logname);
3000 if (mgs_log_is_empty(env, mgs, logname)) {
3001 CERROR("log is empty! Logical error\n");
3005 libcfs_nid2str_r(mti->mti_nids[0], nidstr, sizeof(nidstr));
3006 rc = name_create(&nodeuuid, nidstr, "");
3009 rc = name_create(&svname, mti->mti_svname, "-osc");
3013 /* for the system upgraded from old 1.8, keep using the old osc naming
3014 * style for mdt, see name_create_mdt_osc(). LU-1257 */
3015 if (test_bit(FSDB_OSCNAME18, &fsdb->fsdb_flags))
3016 rc = name_create(&oscname, svname, "");
3018 rc = name_create(&oscname, svname, suffix);
3022 rc = name_create(&oscuuid, oscname, "_UUID");
3025 rc = name_create(&lovuuid, lovname, "_UUID");
3031 #03 L add_uuid nid=uml1@tcp(0x20000c0a80201) 0: 1:uml1_UUID
3033 #04 L add_uuid nid=1@elan(0x1000000000001) nal=90 0: 1:uml1_UUID
3034 #04 L attach 0:OSC_uml1_ost1_MNT_client 1:osc 2:89070_lov1_a41dff51a
3035 #05 L setup 0:OSC_uml1_ost1_MNT_client 1:ost1_UUID 2:uml1_UUID
3037 #06 L add_uuid nid=uml2@tcp(0x20000c0a80202) 0: 1:uml2_UUID
3038 #07 L add_conn 0:OSC_uml1_ost1_MNT_client 1:uml2_UUID
3039 #08 L lov_modify_tgts add 0:lov1 1:ost1_UUID 2(index):0 3(gen):1
3042 rc = record_start_log(env, mgs, &llh, logname);
3046 /* FIXME these should be a single journal transaction */
3047 rc = record_marker(env, llh, fsdb, CM_START | flags, mti->mti_svname,
3052 /* NB: don't change record order, because upon MDT steal OSC config
3053 * from client, it treats all nids before LCFG_SETUP as target nids
3054 * (multiple interfaces), while nids after as failover node nids.
3055 * See mgs_steal_client_llog_handler() LCFG_ADD_UUID.
3057 for (i = 0; i < mti->mti_nid_count; i++) {
3058 CDEBUG(D_MGS, "add nid %s\n",
3059 libcfs_nid2str_r(mti->mti_nids[i],
3060 nidstr, sizeof(nidstr)));
3061 rc = record_add_uuid(env, llh, mti->mti_nids[i], nodeuuid);
3065 rc = record_attach(env, llh, oscname, LUSTRE_OSC_NAME, lovuuid);
3068 rc = record_setup(env, llh, oscname, mti->mti_uuid, nodeuuid,
3072 rc = mgs_write_log_failnids(env, mti, llh, oscname);
3076 snprintf(index, sizeof(index), "%d", mti->mti_stripe_index);
3078 rc = record_lov_add(env, llh, lovname, mti->mti_uuid, index, "1");
3081 rc = record_marker(env, llh, fsdb, CM_END | flags, mti->mti_svname,
3086 record_end_log(env, &llh);
3088 name_destroy(&lovuuid);
3089 name_destroy(&oscuuid);
3090 name_destroy(&oscname);
3091 name_destroy(&svname);
3092 name_destroy(&nodeuuid);
3096 static int mgs_write_log_ost(const struct lu_env *env,
3097 struct mgs_device *mgs, struct fs_db *fsdb,
3098 struct mgs_target_info *mti)
3100 struct llog_handle *llh = NULL;
3101 char *logname, *lovname;
3102 char *ptr = mti->mti_params;
3103 int rc, flags = 0, failout = 0, i;
3106 CDEBUG(D_MGS, "writing new ost %s\n", mti->mti_svname);
3108 /* The ost startup log */
3110 /* If the ost log already exists, that means that someone reformatted
3111 the ost and it called target_add again. */
3112 if (!mgs_log_is_empty(env, mgs, mti->mti_svname)) {
3113 LCONSOLE_ERROR_MSG(0x141, "The config log for %s already "
3114 "exists, yet the server claims it never "
3115 "registered. It may have been reformatted, "
3116 "or the index changed. writeconf the MDT to "
3117 "regenerate all logs.\n", mti->mti_svname);
3122 attach obdfilter ost1 ost1_UUID
3123 setup /dev/loop2 ldiskfs f|n errors=remount-ro,user_xattr
3125 if (class_find_param(ptr, PARAM_FAILMODE, &ptr) == 0)
3126 failout = (strncmp(ptr, "failout", 7) == 0);
3127 rc = record_start_log(env, mgs, &llh, mti->mti_svname);
3130 /* FIXME these should be a single journal transaction */
3131 rc = record_marker(env, llh, fsdb, CM_START, mti->mti_svname,"add ost");
3134 if (*mti->mti_uuid == '\0')
3135 snprintf(mti->mti_uuid, sizeof(mti->mti_uuid),
3136 "%s_UUID", mti->mti_svname);
3137 rc = record_attach(env, llh, mti->mti_svname,
3138 "obdfilter"/*LUSTRE_OST_NAME*/, mti->mti_uuid);
3141 rc = record_setup(env, llh, mti->mti_svname,
3142 "dev"/*ignored*/, "type"/*ignored*/,
3143 failout ? "n" : "f", NULL/*options*/);
3146 rc = record_marker(env, llh, fsdb, CM_END, mti->mti_svname, "add ost");
3150 record_end_log(env, &llh);
3153 /* We also have to update the other logs where this osc is part of
3156 if (test_bit(FSDB_OLDLOG14, &fsdb->fsdb_flags)) {
3157 /* If we're upgrading, the old mdt log already has our
3158 entry. Let's do a fake one for fun. */
3159 /* Note that we can't add any new failnids, since we don't
3160 know the old osc names. */
3161 flags = CM_SKIP | CM_UPGRADE146;
3163 } else if ((mti->mti_flags & LDD_F_UPDATE) != LDD_F_UPDATE) {
3164 /* If the update flag isn't set, don't update client/mdt
3167 LCONSOLE_WARN("Client log for %s was not updated; writeconf "
3168 "the MDT first to regenerate it.\n",
3172 /* Add ost to all MDT lov defs */
3173 for (i = 0; i < INDEX_MAP_SIZE * 8; i++){
3174 if (test_bit(i, fsdb->fsdb_mdt_index_map)) {
3177 rc = name_create_mdt_and_lov(&logname, &lovname, fsdb,
3182 snprintf(mdt_index, sizeof(mdt_index), "-MDT%04x", i);
3183 rc = mgs_write_log_osc_to_lov(env, mgs, fsdb, mti,
3185 lovname, LUSTRE_SP_MDT,
3187 name_destroy(&logname);
3188 name_destroy(&lovname);
3194 /* Append ost info to the client log */
3195 rc = name_create(&logname, mti->mti_fsname, "-client");
3198 if (mgs_log_is_empty(env, mgs, logname)) {
3199 /* Start client log */
3200 rc = mgs_write_log_lov(env, mgs, fsdb, mti, logname,
3204 rc = mgs_write_log_lmv(env, mgs, fsdb, mti, logname,
3208 rc = mgs_write_log_mount_opt(env, mgs, fsdb, logname);
3212 rc = mgs_write_log_osc_to_lov(env, mgs, fsdb, mti, logname, "",
3213 fsdb->fsdb_clilov, LUSTRE_SP_CLI, flags);
3215 name_destroy(&logname);
3219 static __inline__ int mgs_param_empty(char *ptr)
3223 if ((tmp = strchr(ptr, '=')) && (*(++tmp) == '\0'))
3228 static int mgs_write_log_failnid_internal(const struct lu_env *env,
3229 struct mgs_device *mgs,
3231 struct mgs_target_info *mti,
3232 char *logname, char *cliname)
3235 struct llog_handle *llh = NULL;
3237 if (mgs_param_empty(mti->mti_params)) {
3238 /* Remove _all_ failnids */
3239 rc = mgs_modify(env, mgs, fsdb, mti, logname,
3240 mti->mti_svname, "add failnid", CM_SKIP);
3241 return rc < 0 ? rc : 0;
3244 /* Otherwise failover nids are additive */
3245 rc = record_start_log(env, mgs, &llh, logname);
3248 /* FIXME this should be a single journal transaction */
3249 rc = record_marker(env, llh, fsdb, CM_START, mti->mti_svname,
3253 rc = mgs_write_log_failnids(env, mti, llh, cliname);
3256 rc = record_marker(env, llh, fsdb, CM_END,
3257 mti->mti_svname, "add failnid");
3259 record_end_log(env, &llh);
3264 /* Add additional failnids to an existing log.
3265 The mdc/osc must have been added to logs first */
3266 /* tcp nids must be in dotted-quad ascii -
3267 we can't resolve hostnames from the kernel. */
3268 static int mgs_write_log_add_failnid(const struct lu_env *env,
3269 struct mgs_device *mgs,
3271 struct mgs_target_info *mti)
3273 char *logname, *cliname;
3277 /* FIXME we currently can't erase the failnids
3278 * given when a target first registers, since they aren't part of
3279 * an "add uuid" stanza
3282 /* Verify that we know about this target */
3283 if (mgs_log_is_empty(env, mgs, mti->mti_svname)) {
3284 LCONSOLE_ERROR_MSG(0x142, "The target %s has not registered "
3285 "yet. It must be started before failnids "
3286 "can be added.\n", mti->mti_svname);
3290 /* Create mdc/osc client name (e.g. lustre-OST0001-osc) */
3291 if (mti->mti_flags & LDD_F_SV_TYPE_MDT) {
3292 rc = name_create(&cliname, mti->mti_svname, "-mdc");
3293 } else if (mti->mti_flags & LDD_F_SV_TYPE_OST) {
3294 rc = name_create(&cliname, mti->mti_svname, "-osc");
3301 /* Add failover nids to the client log */
3302 rc = name_create(&logname, mti->mti_fsname, "-client");
3304 name_destroy(&cliname);
3308 rc = mgs_write_log_failnid_internal(env, mgs, fsdb,mti,logname,cliname);
3309 name_destroy(&logname);
3310 name_destroy(&cliname);
3314 if (mti->mti_flags & LDD_F_SV_TYPE_OST) {
3315 /* Add OST failover nids to the MDT logs as well */
3318 for (i = 0; i < INDEX_MAP_SIZE * 8; i++) {
3319 if (!test_bit(i, fsdb->fsdb_mdt_index_map))
3321 rc = name_create_mdt(&logname, mti->mti_fsname, i);
3324 rc = name_create_mdt_osc(&cliname, mti->mti_svname,
3327 name_destroy(&logname);
3330 rc = mgs_write_log_failnid_internal(env, mgs, fsdb,
3333 name_destroy(&cliname);
3334 name_destroy(&logname);
3343 static int mgs_wlp_lcfg(const struct lu_env *env,
3344 struct mgs_device *mgs, struct fs_db *fsdb,
3345 struct mgs_target_info *mti,
3346 char *logname, struct lustre_cfg_bufs *bufs,
3347 char *tgtname, char *ptr)
3349 char comment[MTI_NAME_MAXLEN];
3351 struct llog_cfg_rec *lcr;
3354 /* Erase any old settings of this same parameter */
3355 strlcpy(comment, ptr, sizeof(comment));
3356 /* But don't try to match the value. */
3357 tmp = strchr(comment, '=');
3360 /* FIXME we should skip settings that are the same as old values */
3361 rc = mgs_modify(env, mgs, fsdb, mti, logname, tgtname, comment,CM_SKIP);
3364 del = mgs_param_empty(ptr);
3366 LCONSOLE_INFO("%s parameter %s.%s in log %s\n", del ? "Disabling" : rc ?
3367 "Setting" : "Modifying", tgtname, comment, logname);
3369 /* mgs_modify() will return 1 if nothing had to be done */
3375 lustre_cfg_bufs_reset(bufs, tgtname);
3376 lustre_cfg_bufs_set_string(bufs, 1, ptr);
3377 if (mti->mti_flags & LDD_F_PARAM2)
3378 lustre_cfg_bufs_set_string(bufs, 2, LCTL_UPCALL);
3380 lcr = lustre_cfg_rec_new((mti->mti_flags & LDD_F_PARAM2) ?
3381 LCFG_SET_PARAM : LCFG_PARAM, bufs);
3385 rc = mgs_write_log_direct(env, mgs, fsdb, logname, lcr, tgtname,
3387 lustre_cfg_rec_free(lcr);
3391 /* write global variable settings into log */
3392 static int mgs_write_log_sys(const struct lu_env *env,
3393 struct mgs_device *mgs, struct fs_db *fsdb,
3394 struct mgs_target_info *mti, char *sys, char *ptr)
3396 struct mgs_thread_info *mgi = mgs_env_info(env);
3397 struct lustre_cfg *lcfg;
3398 struct llog_cfg_rec *lcr;
3400 int rc, cmd, convert = 1;
3402 if (class_match_param(ptr, PARAM_TIMEOUT, &tmp) == 0) {
3403 cmd = LCFG_SET_TIMEOUT;
3404 } else if (class_match_param(ptr, PARAM_LDLM_TIMEOUT, &tmp) == 0) {
3405 cmd = LCFG_SET_LDLM_TIMEOUT;
3406 /* Check for known params here so we can return error to lctl */
3407 } else if ((class_match_param(ptr, PARAM_AT_MIN, &tmp) == 0) ||
3408 (class_match_param(ptr, PARAM_AT_MAX, &tmp) == 0) ||
3409 (class_match_param(ptr, PARAM_AT_EXTRA, &tmp) == 0) ||
3410 (class_match_param(ptr, PARAM_AT_EARLY_MARGIN, &tmp) == 0) ||
3411 (class_match_param(ptr, PARAM_AT_HISTORY, &tmp) == 0)) {
3413 } else if (class_match_param(ptr, PARAM_JOBID_VAR, &tmp) == 0) {
3414 convert = 0; /* Don't convert string value to integer */
3420 if (mgs_param_empty(ptr))
3421 CDEBUG(D_MGS, "global '%s' removed\n", sys);
3423 CDEBUG(D_MGS, "global '%s' val=%s\n", sys, tmp);
3425 lustre_cfg_bufs_reset(&mgi->mgi_bufs, NULL);
3426 lustre_cfg_bufs_set_string(&mgi->mgi_bufs, 1, sys);
3427 if (!convert && *tmp != '\0')
3428 lustre_cfg_bufs_set_string(&mgi->mgi_bufs, 2, tmp);
3429 lcr = lustre_cfg_rec_new(cmd, &mgi->mgi_bufs);
3433 lcfg = &lcr->lcr_cfg;
3435 rc = kstrtouint(tmp, 0, &lcfg->lcfg_num);
3437 GOTO(out_rec_free, rc);
3442 /* truncate the comment to the parameter name */
3446 /* modify all servers and clients */
3447 rc = mgs_write_log_direct_all(env, mgs, fsdb, mti,
3448 *tmp == '\0' ? NULL : lcr,
3449 mti->mti_fsname, sys, 0);
3450 if (rc == 0 && *tmp != '\0') {
3452 case LCFG_SET_TIMEOUT:
3453 if (!obd_timeout_set || lcfg->lcfg_num > obd_timeout)
3454 class_process_config(lcfg);
3456 case LCFG_SET_LDLM_TIMEOUT:
3457 if (!ldlm_timeout_set || lcfg->lcfg_num > ldlm_timeout)
3458 class_process_config(lcfg);
3466 lustre_cfg_rec_free(lcr);
3470 /* write quota settings into log */
3471 static int mgs_write_log_quota(const struct lu_env *env, struct mgs_device *mgs,
3472 struct fs_db *fsdb, struct mgs_target_info *mti,
3473 char *quota, char *ptr)
3475 struct mgs_thread_info *mgi = mgs_env_info(env);
3476 struct llog_cfg_rec *lcr;
3479 int rc, cmd = LCFG_PARAM;
3481 /* support only 'meta' and 'data' pools so far */
3482 if (class_match_param(ptr, QUOTA_METAPOOL_NAME, &tmp) != 0 &&
3483 class_match_param(ptr, QUOTA_DATAPOOL_NAME, &tmp) != 0) {
3484 CERROR("parameter quota.%s isn't supported (only quota.mdt "
3485 "& quota.ost are)\n", ptr);
3490 CDEBUG(D_MGS, "global '%s' removed\n", quota);
3492 CDEBUG(D_MGS, "global '%s'\n", quota);
3494 if (strchr(tmp, 'u') == NULL && strchr(tmp, 'g') == NULL &&
3495 strchr(tmp, 'p') == NULL &&
3496 strcmp(tmp, "none") != 0) {
3497 CERROR("enable option(%s) isn't supported\n", tmp);
3502 lustre_cfg_bufs_reset(&mgi->mgi_bufs, mti->mti_fsname);
3503 lustre_cfg_bufs_set_string(&mgi->mgi_bufs, 1, quota);
3504 lcr = lustre_cfg_rec_new(cmd, &mgi->mgi_bufs);
3508 /* truncate the comment to the parameter name */
3513 /* XXX we duplicated quota enable information in all server
3514 * config logs, it should be moved to a separate config
3515 * log once we cleanup the config log for global param. */
3516 /* modify all servers */
3517 rc = mgs_write_log_direct_all(env, mgs, fsdb, mti,
3518 *tmp == '\0' ? NULL : lcr,
3519 mti->mti_fsname, quota, 1);
3521 lustre_cfg_rec_free(lcr);
3522 return rc < 0 ? rc : 0;
3525 static int mgs_srpc_set_param_disk(const struct lu_env *env,
3526 struct mgs_device *mgs,
3528 struct mgs_target_info *mti,
3531 struct mgs_thread_info *mgi = mgs_env_info(env);
3532 struct llog_cfg_rec *lcr;
3533 struct llog_handle *llh = NULL;
3535 char *comment, *ptr;
3541 ptr = strchr(param, '=');
3542 LASSERT(ptr != NULL);
3545 OBD_ALLOC(comment, len + 1);
3546 if (comment == NULL)
3548 strncpy(comment, param, len);
3549 comment[len] = '\0';
3552 lustre_cfg_bufs_reset(&mgi->mgi_bufs, mti->mti_svname);
3553 lustre_cfg_bufs_set_string(&mgi->mgi_bufs, 1, param);
3554 lcr = lustre_cfg_rec_new(LCFG_SPTLRPC_CONF, &mgi->mgi_bufs);
3556 GOTO(out_comment, rc = -ENOMEM);
3558 /* construct log name */
3559 rc = name_create(&logname, mti->mti_fsname, "-sptlrpc");
3563 if (mgs_log_is_empty(env, mgs, logname)) {
3564 rc = record_start_log(env, mgs, &llh, logname);
3567 record_end_log(env, &llh);
3570 /* obsolete old one */
3571 rc = mgs_modify(env, mgs, fsdb, mti, logname, mti->mti_svname,
3575 /* write the new one */
3576 rc = mgs_write_log_direct(env, mgs, fsdb, logname, lcr,
3577 mti->mti_svname, comment);
3579 CERROR("%s: error writing log %s: rc = %d\n",
3580 mgs->mgs_obd->obd_name, logname, rc);
3582 name_destroy(&logname);
3584 lustre_cfg_rec_free(lcr);
3586 OBD_FREE(comment, len + 1);
3590 static int mgs_srpc_set_param_udesc_mem(struct fs_db *fsdb,
3595 /* disable the adjustable udesc parameter for now, i.e. use default
3596 * setting that client always ship udesc to MDT if possible. to enable
3597 * it simply remove the following line */
3600 ptr = strchr(param, '=');
3605 if (strcmp(param, PARAM_SRPC_UDESC))
3608 if (strcmp(ptr, "yes") == 0) {
3609 set_bit(FSDB_UDESC, &fsdb->fsdb_flags);
3610 CWARN("Enable user descriptor shipping from client to MDT\n");
3611 } else if (strcmp(ptr, "no") == 0) {
3612 clear_bit(FSDB_UDESC, &fsdb->fsdb_flags);
3613 CWARN("Disable user descriptor shipping from client to MDT\n");
3621 CERROR("Invalid param: %s\n", param);
3625 static int mgs_srpc_set_param_mem(struct fs_db *fsdb,
3629 struct sptlrpc_rule rule;
3630 struct sptlrpc_rule_set *rset;
3634 if (strncmp(param, PARAM_SRPC, sizeof(PARAM_SRPC) - 1) != 0) {
3635 CERROR("Invalid sptlrpc parameter: %s\n", param);
3639 if (strncmp(param, PARAM_SRPC_UDESC,
3640 sizeof(PARAM_SRPC_UDESC) - 1) == 0) {
3641 RETURN(mgs_srpc_set_param_udesc_mem(fsdb, param));
3644 if (strncmp(param, PARAM_SRPC_FLVR, sizeof(PARAM_SRPC_FLVR) - 1) != 0) {
3645 CERROR("Invalid sptlrpc flavor parameter: %s\n", param);
3649 param += sizeof(PARAM_SRPC_FLVR) - 1;
3651 rc = sptlrpc_parse_rule(param, &rule);
3655 /* mgs rules implies must be mgc->mgs */
3656 if (test_bit(FSDB_MGS_SELF, &fsdb->fsdb_flags)) {
3657 if ((rule.sr_from != LUSTRE_SP_MGC &&
3658 rule.sr_from != LUSTRE_SP_ANY) ||
3659 (rule.sr_to != LUSTRE_SP_MGS &&
3660 rule.sr_to != LUSTRE_SP_ANY))
3664 /* preapre room for this coming rule. svcname format should be:
3665 * - fsname: general rule
3666 * - fsname-tgtname: target-specific rule
3668 if (strchr(svname, '-')) {
3669 struct mgs_tgt_srpc_conf *tgtconf;
3672 for (tgtconf = fsdb->fsdb_srpc_tgt; tgtconf != NULL;
3673 tgtconf = tgtconf->mtsc_next) {
3674 if (!strcmp(tgtconf->mtsc_tgt, svname)) {
3683 OBD_ALLOC_PTR(tgtconf);
3684 if (tgtconf == NULL)
3687 name_len = strlen(svname);
3689 OBD_ALLOC(tgtconf->mtsc_tgt, name_len + 1);
3690 if (tgtconf->mtsc_tgt == NULL) {
3691 OBD_FREE_PTR(tgtconf);
3694 memcpy(tgtconf->mtsc_tgt, svname, name_len);
3696 tgtconf->mtsc_next = fsdb->fsdb_srpc_tgt;
3697 fsdb->fsdb_srpc_tgt = tgtconf;
3700 rset = &tgtconf->mtsc_rset;
3701 } else if (strcmp(svname, MGSSELF_NAME) == 0) {
3702 /* put _mgs related srpc rule directly in mgs ruleset */
3703 rset = &fsdb->fsdb_mgs->mgs_lut.lut_sptlrpc_rset;
3705 rset = &fsdb->fsdb_srpc_gen;
3708 rc = sptlrpc_rule_set_merge(rset, &rule);
3713 static int mgs_srpc_set_param(const struct lu_env *env,
3714 struct mgs_device *mgs,
3716 struct mgs_target_info *mti,
3726 /* keep a copy of original param, which could be destroied
3728 copy_size = strlen(param) + 1;
3729 OBD_ALLOC(copy, copy_size);
3732 memcpy(copy, param, copy_size);
3734 rc = mgs_srpc_set_param_mem(fsdb, mti->mti_svname, param);
3738 /* previous steps guaranteed the syntax is correct */
3739 rc = mgs_srpc_set_param_disk(env, mgs, fsdb, mti, copy);
3743 if (test_bit(FSDB_MGS_SELF, &fsdb->fsdb_flags)) {
3745 * for mgs rules, make them effective immediately.
3747 LASSERT(fsdb->fsdb_srpc_tgt == NULL);
3748 sptlrpc_target_update_exp_flavor(mgs->mgs_obd,
3749 &fsdb->fsdb_srpc_gen);
3753 OBD_FREE(copy, copy_size);
3757 struct mgs_srpc_read_data {
3758 struct fs_db *msrd_fsdb;
3762 static int mgs_srpc_read_handler(const struct lu_env *env,
3763 struct llog_handle *llh,
3764 struct llog_rec_hdr *rec, void *data)
3766 struct mgs_srpc_read_data *msrd = data;
3767 struct cfg_marker *marker;
3768 struct lustre_cfg *lcfg = REC_DATA(rec);
3769 char *svname, *param;
3773 if (rec->lrh_type != OBD_CFG_REC) {
3774 CERROR("unhandled lrh_type: %#x\n", rec->lrh_type);
3778 cfg_len = REC_DATA_LEN(rec);
3780 rc = lustre_cfg_sanity_check(lcfg, cfg_len);
3782 CERROR("Insane cfg\n");
3786 if (lcfg->lcfg_command == LCFG_MARKER) {
3787 marker = lustre_cfg_buf(lcfg, 1);
3789 if (marker->cm_flags & CM_START &&
3790 marker->cm_flags & CM_SKIP)
3791 msrd->msrd_skip = 1;
3792 if (marker->cm_flags & CM_END)
3793 msrd->msrd_skip = 0;
3798 if (msrd->msrd_skip)
3801 if (lcfg->lcfg_command != LCFG_SPTLRPC_CONF) {
3802 CERROR("invalid command (%x)\n", lcfg->lcfg_command);
3806 svname = lustre_cfg_string(lcfg, 0);
3807 if (svname == NULL) {
3808 CERROR("svname is empty\n");
3812 param = lustre_cfg_string(lcfg, 1);
3813 if (param == NULL) {
3814 CERROR("param is empty\n");
3818 rc = mgs_srpc_set_param_mem(msrd->msrd_fsdb, svname, param);
3820 CERROR("read sptlrpc record error (%d): %s\n", rc, param);
3825 int mgs_get_fsdb_srpc_from_llog(const struct lu_env *env,
3826 struct mgs_device *mgs,
3829 struct llog_handle *llh = NULL;
3830 struct llog_ctxt *ctxt;
3832 struct mgs_srpc_read_data msrd;
3836 /* construct log name */
3837 rc = name_create(&logname, fsdb->fsdb_name, "-sptlrpc");
3841 ctxt = llog_get_context(mgs->mgs_obd, LLOG_CONFIG_ORIG_CTXT);
3842 LASSERT(ctxt != NULL);
3844 if (mgs_log_is_empty(env, mgs, logname))
3847 rc = llog_open(env, ctxt, &llh, NULL, logname,
3855 rc = llog_init_handle(env, llh, LLOG_F_IS_PLAIN, NULL);
3857 GOTO(out_close, rc);
3859 if (llog_get_size(llh) <= 1)
3860 GOTO(out_close, rc = 0);
3862 msrd.msrd_fsdb = fsdb;
3865 rc = llog_process(env, llh, mgs_srpc_read_handler, (void *)&msrd,
3869 llog_close(env, llh);
3871 llog_ctxt_put(ctxt);
3872 name_destroy(&logname);
3875 CERROR("failed to read sptlrpc config database: %d\n", rc);
3879 static int mgs_write_log_param2(const struct lu_env *env,
3880 struct mgs_device *mgs,
3882 struct mgs_target_info *mti, char *ptr)
3884 struct lustre_cfg_bufs bufs;
3888 CDEBUG(D_MGS, "next param '%s'\n", ptr);
3890 /* PARAM_MGSNODE and PARAM_NETWORK are set only when formating
3891 * or during the inital mount. It can never change after that.
3893 if (!class_match_param(ptr, PARAM_MGSNODE, NULL) ||
3894 !class_match_param(ptr, PARAM_NETWORK, NULL)) {
3899 /* Processed in mgs_write_log_ost. Another value that can't
3900 * be changed by lctl set_param -P.
3902 if (!class_match_param(ptr, PARAM_FAILMODE, NULL)) {
3903 LCONSOLE_ERROR_MSG(0x169,
3904 "%s can only be changed with tunefs.lustre and --writeconf\n",
3910 /* FIXME !!! Support for sptlrpc is incomplete. Currently the change
3911 * doesn't transmit to the client. See LU-7183.
3913 if (!class_match_param(ptr, PARAM_SRPC, NULL)) {
3914 rc = mgs_srpc_set_param(env, mgs, fsdb, mti, ptr);
3918 /* Can't use class_match_param since ptr doesn't start with
3919 * PARAM_FAILNODE. So we look for PARAM_FAILNODE contained in ptr.
3921 if (strstr(ptr, PARAM_FAILNODE)) {
3922 /* Add a failover nidlist. We already processed failovers
3923 * params for new targets in mgs_write_log_target.
3927 /* can't use wildcards with failover.node */
3928 if (strchr(ptr, '*')) {
3933 param = strstr(ptr, PARAM_FAILNODE);
3934 if (strlcpy(mti->mti_params, param, sizeof(mti->mti_params)) >=
3935 sizeof(mti->mti_params)) {
3940 CDEBUG(D_MGS, "Adding failnode with param %s\n",
3942 rc = mgs_write_log_add_failnid(env, mgs, fsdb, mti);
3946 /* root squash parameters must not be set on llite subsystem, this can
3947 * lead to inconsistencies between client and server values
3949 if ((strstr(ptr, PARAM_NOSQUASHNIDS) ||
3950 strstr(ptr, PARAM_ROOTSQUASH)) &&
3951 strncmp(ptr, "llite.", strlen("llite.")) == 0) {
3953 CWARN("%s: cannot add %s param to llite subsystem, use mdt instead: rc=%d\n",
3954 mgs->mgs_obd->obd_name,
3955 strstr(ptr, PARAM_ROOTSQUASH) ?
3956 PARAM_ROOTSQUASH : PARAM_NOSQUASHNIDS,
3961 rc = mgs_wlp_lcfg(env, mgs, fsdb, mti, PARAMS_FILENAME, &bufs,
3962 mti->mti_svname, ptr);
3967 /* Permanent settings of all parameters by writing into the appropriate
3968 * configuration logs.
3969 * A parameter with null value ("<param>='\0'") means to erase it out of
3972 static int mgs_write_log_param(const struct lu_env *env,
3973 struct mgs_device *mgs, struct fs_db *fsdb,
3974 struct mgs_target_info *mti, char *ptr)
3976 struct mgs_thread_info *mgi = mgs_env_info(env);
3982 /* For various parameter settings, we have to figure out which logs
3983 care about them (e.g. both mdt and client for lov settings) */
3984 CDEBUG(D_MGS, "next param '%s'\n", ptr);
3986 /* The params are stored in MOUNT_DATA_FILE and modified via
3987 tunefs.lustre, or set using lctl conf_param */
3989 /* Processed in lustre_start_mgc */
3990 if (class_match_param(ptr, PARAM_MGSNODE, NULL) == 0)
3993 /* Processed in ost/mdt */
3994 if (class_match_param(ptr, PARAM_NETWORK, NULL) == 0)
3997 /* Processed in mgs_write_log_ost */
3998 if (class_match_param(ptr, PARAM_FAILMODE, NULL) == 0) {
3999 if (mti->mti_flags & LDD_F_PARAM) {
4000 LCONSOLE_ERROR_MSG(0x169,
4001 "%s can only be changed with tunefs.lustre and --writeconf\n",
4008 if (class_match_param(ptr, PARAM_SRPC, NULL) == 0) {
4009 rc = mgs_srpc_set_param(env, mgs, fsdb, mti, ptr);
4013 if (class_match_param(ptr, PARAM_FAILNODE, NULL) == 0) {
4014 /* Add a failover nidlist */
4016 /* We already processed failovers params for new
4017 targets in mgs_write_log_target */
4018 if (mti->mti_flags & LDD_F_PARAM) {
4019 CDEBUG(D_MGS, "Adding failnode\n");
4020 rc = mgs_write_log_add_failnid(env, mgs, fsdb, mti);
4025 if (class_match_param(ptr, PARAM_SYS, &tmp) == 0) {
4026 rc = mgs_write_log_sys(env, mgs, fsdb, mti, ptr, tmp);
4030 if (class_match_param(ptr, PARAM_QUOTA, &tmp) == 0) {
4031 rc = mgs_write_log_quota(env, mgs, fsdb, mti, ptr, tmp);
4035 if (class_match_param(ptr, PARAM_OSC PARAM_ACTIVE, &tmp) == 0 ||
4036 class_match_param(ptr, PARAM_MDC PARAM_ACTIVE, &tmp) == 0) {
4037 /* active=0 means off, anything else means on */
4038 int flag = (*tmp == '0') ? CM_EXCLUDE : 0;
4039 bool deactive_osc = memcmp(ptr, PARAM_OSC PARAM_ACTIVE,
4040 strlen(PARAM_OSC PARAM_ACTIVE)) == 0;
4043 if (!deactive_osc) {
4046 rc = server_name2index(mti->mti_svname, &index, NULL);
4051 LCONSOLE_ERROR_MSG(0x144, "%s: MDC0 can not be"
4052 " (de)activated.\n",
4054 GOTO(end, rc = -EPERM);
4058 LCONSOLE_WARN("Permanently %sactivating %s\n",
4059 flag ? "de" : "re", mti->mti_svname);
4061 rc = name_create(&logname, mti->mti_fsname, "-client");
4064 rc = mgs_modify(env, mgs, fsdb, mti, logname,
4066 deactive_osc ? "add osc" : "add mdc", flag);
4067 name_destroy(&logname);
4072 /* Add to all MDT logs for DNE */
4073 for (i = 0; i < INDEX_MAP_SIZE * 8; i++) {
4074 if (!test_bit(i, fsdb->fsdb_mdt_index_map))
4076 rc = name_create_mdt(&logname, mti->mti_fsname, i);
4079 rc = mgs_modify(env, mgs, fsdb, mti, logname,
4081 deactive_osc ? "add osc" : "add osp",
4083 name_destroy(&logname);
4089 LCONSOLE_ERROR_MSG(0x145,
4090 "Couldn't find %s in log (%d). No permanent changes were made to the config log.\n",
4091 mti->mti_svname, rc);
4092 if (test_bit(FSDB_OLDLOG14, &fsdb->fsdb_flags))
4093 LCONSOLE_ERROR_MSG(0x146,
4094 "This may be because the log is in the old 1.4 style. Consider --writeconf to update the logs.\n");
4097 /* Fall through to osc/mdc proc for deactivating live
4098 OSC/OSP on running MDT / clients. */
4100 /* Below here, let obd's XXX_process_config methods handle it */
4102 /* All lov. in proc */
4103 if (class_match_param(ptr, PARAM_LOV, NULL) == 0) {
4106 CDEBUG(D_MGS, "lov param %s\n", ptr);
4107 if (!(mti->mti_flags & LDD_F_SV_TYPE_MDT)) {
4108 LCONSOLE_ERROR_MSG(0x147, "LOV params must be "
4109 "set on the MDT, not %s. "
4116 if (mgs_log_is_empty(env, mgs, mti->mti_svname))
4117 GOTO(end, rc = -ENODEV);
4119 rc = name_create_mdt_and_lov(&logname, &mdtlovname, fsdb,
4120 mti->mti_stripe_index);
4123 rc = mgs_wlp_lcfg(env, mgs, fsdb, mti, mti->mti_svname,
4124 &mgi->mgi_bufs, mdtlovname, ptr);
4125 name_destroy(&logname);
4126 name_destroy(&mdtlovname);
4131 rc = name_create(&logname, mti->mti_fsname, "-client");
4134 rc = mgs_wlp_lcfg(env, mgs, fsdb, mti, logname, &mgi->mgi_bufs,
4135 fsdb->fsdb_clilov, ptr);
4136 name_destroy(&logname);
4140 /* All osc., mdc., llite. params in proc */
4141 if ((class_match_param(ptr, PARAM_OSC, NULL) == 0) ||
4142 (class_match_param(ptr, PARAM_MDC, NULL) == 0) ||
4143 (class_match_param(ptr, PARAM_LLITE, NULL) == 0)) {
4146 if (test_bit(FSDB_OLDLOG14, &fsdb->fsdb_flags)) {
4147 LCONSOLE_ERROR_MSG(0x148, "Upgraded client logs for %s"
4148 " cannot be modified. Consider"
4149 " updating the configuration with"
4152 GOTO(end, rc = -EINVAL);
4154 if (memcmp(ptr, PARAM_LLITE, strlen(PARAM_LLITE)) == 0) {
4155 rc = name_create(&cname, mti->mti_fsname, "-client");
4156 /* Add the client type to match the obdname in
4157 class_config_llog_handler */
4158 } else if (mti->mti_flags & LDD_F_SV_TYPE_MDT) {
4159 rc = name_create(&cname, mti->mti_svname, "-mdc");
4160 } else if (mti->mti_flags & LDD_F_SV_TYPE_OST) {
4161 rc = name_create(&cname, mti->mti_svname, "-osc");
4163 GOTO(end, rc = -EINVAL);
4168 /* Forbid direct update of llite root squash parameters.
4169 * These parameters are indirectly set via the MDT settings.
4171 if ((class_match_param(ptr, PARAM_LLITE, &tmp) == 0) &&
4172 ((memcmp(tmp, "root_squash=", 12) == 0) ||
4173 (memcmp(tmp, "nosquash_nids=", 14) == 0))) {
4174 LCONSOLE_ERROR("%s: root squash parameters can only "
4175 "be updated through MDT component\n",
4177 name_destroy(&cname);
4178 GOTO(end, rc = -EINVAL);
4181 CDEBUG(D_MGS, "%.3s param %s\n", ptr, ptr + 4);
4184 rc = name_create(&logname, mti->mti_fsname, "-client");
4186 name_destroy(&cname);
4189 rc = mgs_wlp_lcfg(env, mgs, fsdb, mti, logname, &mgi->mgi_bufs,
4192 /* osc params affect the MDT as well */
4193 if (!rc && (mti->mti_flags & LDD_F_SV_TYPE_OST)) {
4196 for (i = 0; i < INDEX_MAP_SIZE * 8; i++){
4197 if (!test_bit(i, fsdb->fsdb_mdt_index_map))
4199 name_destroy(&cname);
4200 rc = name_create_mdt_osc(&cname, mti->mti_svname,
4202 name_destroy(&logname);
4205 rc = name_create_mdt(&logname,
4206 mti->mti_fsname, i);
4209 if (!mgs_log_is_empty(env, mgs, logname)) {
4210 rc = mgs_wlp_lcfg(env, mgs, fsdb,
4220 /* For mdc activate/deactivate, it affects OSP on MDT as well */
4221 if (class_match_param(ptr, PARAM_MDC PARAM_ACTIVE, &tmp) == 0 &&
4224 char *lodname = NULL;
4225 char *param_str = NULL;
4229 /* replace mdc with osp */
4230 memcpy(ptr, PARAM_OSP, strlen(PARAM_OSP));
4231 rc = server_name2index(mti->mti_svname, &index, NULL);
4233 memcpy(ptr, PARAM_MDC, strlen(PARAM_MDC));
4237 for (i = 0; i < INDEX_MAP_SIZE * 8; i++) {
4238 if (!test_bit(i, fsdb->fsdb_mdt_index_map))
4244 name_destroy(&logname);
4245 rc = name_create_mdt(&logname, mti->mti_fsname,
4250 if (mgs_log_is_empty(env, mgs, logname))
4253 snprintf(suffix, sizeof(suffix), "-osp-MDT%04x",
4255 name_destroy(&cname);
4256 rc = name_create(&cname, mti->mti_svname,
4261 rc = mgs_wlp_lcfg(env, mgs, fsdb, mti, logname,
4262 &mgi->mgi_bufs, cname, ptr);
4266 /* Add configuration log for noitfying LOD
4267 * to active/deactive the OSP. */
4268 name_destroy(¶m_str);
4269 rc = name_create(¶m_str, cname,
4270 (*tmp == '0') ? ".active=0" :
4275 name_destroy(&lodname);
4276 rc = name_create(&lodname, logname, "-mdtlov");
4280 rc = mgs_wlp_lcfg(env, mgs, fsdb, mti, logname,
4281 &mgi->mgi_bufs, lodname,
4286 memcpy(ptr, PARAM_MDC, strlen(PARAM_MDC));
4287 name_destroy(&lodname);
4288 name_destroy(¶m_str);
4291 name_destroy(&logname);
4292 name_destroy(&cname);
4296 /* All mdt. params in proc */
4297 if (class_match_param(ptr, PARAM_MDT, &tmp) == 0) {
4301 CDEBUG(D_MGS, "%.3s param %s\n", ptr, ptr + 4);
4302 if (strncmp(mti->mti_svname, mti->mti_fsname,
4303 MTI_NAME_MAXLEN) == 0)
4304 /* device is unspecified completely? */
4305 rc = LDD_F_SV_TYPE_MDT | LDD_F_SV_ALL;
4307 rc = server_name2index(mti->mti_svname, &idx, NULL);
4310 if ((rc & LDD_F_SV_TYPE_MDT) == 0)
4312 if (rc & LDD_F_SV_ALL) {
4313 for (i = 0; i < INDEX_MAP_SIZE * 8; i++) {
4315 fsdb->fsdb_mdt_index_map))
4317 rc = name_create_mdt(&logname,
4318 mti->mti_fsname, i);
4321 rc = mgs_wlp_lcfg(env, mgs, fsdb, mti,
4322 logname, &mgi->mgi_bufs,
4324 name_destroy(&logname);
4329 if ((memcmp(tmp, "root_squash=", 12) == 0) ||
4330 (memcmp(tmp, "nosquash_nids=", 14) == 0)) {
4331 LCONSOLE_ERROR("%s: root squash parameters "
4332 "cannot be applied to a single MDT\n",
4334 GOTO(end, rc = -EINVAL);
4336 rc = mgs_wlp_lcfg(env, mgs, fsdb, mti,
4337 mti->mti_svname, &mgi->mgi_bufs,
4338 mti->mti_svname, ptr);
4343 /* root squash settings are also applied to llite
4344 * config log (see LU-1778) */
4346 ((memcmp(tmp, "root_squash=", 12) == 0) ||
4347 (memcmp(tmp, "nosquash_nids=", 14) == 0))) {
4351 rc = name_create(&cname, mti->mti_fsname, "-client");
4354 rc = name_create(&logname, mti->mti_fsname, "-client");
4356 name_destroy(&cname);
4359 rc = name_create(&ptr2, PARAM_LLITE, tmp);
4361 name_destroy(&cname);
4362 name_destroy(&logname);
4365 rc = mgs_wlp_lcfg(env, mgs, fsdb, mti, logname,
4366 &mgi->mgi_bufs, cname, ptr2);
4367 name_destroy(&ptr2);
4368 name_destroy(&logname);
4369 name_destroy(&cname);
4374 /* All mdd., ost. and osd. params in proc */
4375 if ((class_match_param(ptr, PARAM_MDD, NULL) == 0) ||
4376 (class_match_param(ptr, PARAM_LOD, NULL) == 0) ||
4377 (class_match_param(ptr, PARAM_OST, NULL) == 0) ||
4378 (class_match_param(ptr, PARAM_OSD, NULL) == 0)) {
4379 CDEBUG(D_MGS, "%.3s param %s\n", ptr, ptr + 4);
4380 if (mgs_log_is_empty(env, mgs, mti->mti_svname))
4381 GOTO(end, rc = -ENODEV);
4383 rc = mgs_wlp_lcfg(env, mgs, fsdb, mti, mti->mti_svname,
4384 &mgi->mgi_bufs, mti->mti_svname, ptr);
4388 LCONSOLE_WARN("Ignoring unrecognized param '%s'\n", ptr);
4392 CERROR("err %d on param '%s'\n", rc, ptr);
4397 int mgs_write_log_target(const struct lu_env *env, struct mgs_device *mgs,
4398 struct mgs_target_info *mti, struct fs_db *fsdb)
4405 /* set/check the new target index */
4406 rc = mgs_set_index(env, mgs, mti);
4410 if (rc == EALREADY) {
4411 LCONSOLE_WARN("Found index %d for %s, updating log\n",
4412 mti->mti_stripe_index, mti->mti_svname);
4413 /* We would like to mark old log sections as invalid
4414 and add new log sections in the client and mdt logs.
4415 But if we add new sections, then live clients will
4416 get repeat setup instructions for already running
4417 osc's. So don't update the client/mdt logs. */
4418 mti->mti_flags &= ~LDD_F_UPDATE;
4422 OBD_FAIL_TIMEOUT(OBD_FAIL_MGS_WRITE_TARGET_DELAY, cfs_fail_val > 0 ?
4425 mutex_lock(&fsdb->fsdb_mutex);
4427 if (mti->mti_flags & (LDD_F_VIRGIN | LDD_F_WRITECONF)) {
4428 /* Generate a log from scratch */
4429 if (mti->mti_flags & LDD_F_SV_TYPE_MDT) {
4430 rc = mgs_write_log_mdt(env, mgs, fsdb, mti);
4431 } else if (mti->mti_flags & LDD_F_SV_TYPE_OST) {
4432 rc = mgs_write_log_ost(env, mgs, fsdb, mti);
4434 CERROR("Unknown target type %#x, can't create log for %s\n",
4435 mti->mti_flags, mti->mti_svname);
4438 CERROR("Can't write logs for %s (%d)\n",
4439 mti->mti_svname, rc);
4443 /* Just update the params from tunefs in mgs_write_log_params */
4444 CDEBUG(D_MGS, "Update params for %s\n", mti->mti_svname);
4445 mti->mti_flags |= LDD_F_PARAM;
4448 /* allocate temporary buffer, where class_get_next_param will
4449 make copy of a current parameter */
4450 OBD_ALLOC(buf, strlen(mti->mti_params) + 1);
4452 GOTO(out_up, rc = -ENOMEM);
4453 params = mti->mti_params;
4454 while (params != NULL) {
4455 rc = class_get_next_param(¶ms, buf);
4458 /* there is no next parameter, that is
4463 CDEBUG(D_MGS, "remaining string: '%s', param: '%s'\n",
4465 rc = mgs_write_log_param(env, mgs, fsdb, mti, buf);
4470 OBD_FREE(buf, strlen(mti->mti_params) + 1);
4473 mutex_unlock(&fsdb->fsdb_mutex);
4477 int mgs_erase_log(const struct lu_env *env, struct mgs_device *mgs, char *name)
4479 struct llog_ctxt *ctxt;
4482 ctxt = llog_get_context(mgs->mgs_obd, LLOG_CONFIG_ORIG_CTXT);
4484 CERROR("%s: MGS config context doesn't exist\n",
4485 mgs->mgs_obd->obd_name);
4488 rc = llog_erase(env, ctxt, NULL, name);
4489 /* llog may not exist */
4492 llog_ctxt_put(ctxt);
4496 CERROR("%s: failed to clear log %s: %d\n",
4497 mgs->mgs_obd->obd_name, name, rc);
4502 /* erase all logs for the given fs */
4503 int mgs_erase_logs(const struct lu_env *env, struct mgs_device *mgs,
4506 struct list_head log_list;
4507 struct mgs_direntry *dirent, *n;
4508 char barrier_name[20] = {};
4511 int rc, len = strlen(fsname);
4514 mutex_lock(&mgs->mgs_mutex);
4516 /* Find all the logs in the CONFIGS directory */
4517 rc = class_dentry_readdir(env, mgs, &log_list);
4519 mutex_unlock(&mgs->mgs_mutex);
4523 if (list_empty(&log_list)) {
4524 mutex_unlock(&mgs->mgs_mutex);
4528 snprintf(barrier_name, sizeof(barrier_name) - 1, "%s-%s",
4529 fsname, BARRIER_FILENAME);
4530 /* Delete the barrier fsdb */
4531 mgs_remove_fsdb_by_name(mgs, barrier_name);
4532 /* Delete the fs db */
4533 mgs_remove_fsdb_by_name(mgs, fsname);
4534 mutex_unlock(&mgs->mgs_mutex);
4536 list_for_each_entry_safe(dirent, n, &log_list, mde_list) {
4537 list_del_init(&dirent->mde_list);
4538 suffix = strrchr(dirent->mde_name, '-');
4539 if (suffix != NULL) {
4540 if ((len == suffix - dirent->mde_name) &&
4541 (strncmp(fsname, dirent->mde_name, len) == 0)) {
4542 CDEBUG(D_MGS, "Removing log %s\n",
4544 mgs_erase_log(env, mgs, dirent->mde_name);
4548 mgs_direntry_free(dirent);
4557 /* list all logs for the given fs */
4558 int mgs_list_logs(const struct lu_env *env, struct mgs_device *mgs,
4559 struct obd_ioctl_data *data)
4561 struct list_head log_list;
4562 struct mgs_direntry *dirent, *n;
4563 char *out, *suffix, prefix[] = "config_log: ";
4564 int prefix_len = strlen(prefix);
4565 int len, remains, start = 0, rc;
4569 /* Find all the logs in the CONFIGS directory */
4570 rc = class_dentry_readdir(env, mgs, &log_list);
4574 out = data->ioc_bulk;
4575 remains = data->ioc_inllen1;
4576 /* OBD_FAIL: fetch the config_log records from the specified one */
4577 if (OBD_FAIL_CHECK(OBD_FAIL_CATLIST))
4578 data->ioc_count = cfs_fail_val;
4580 list_for_each_entry_safe(dirent, n, &log_list, mde_list) {
4581 list_del_init(&dirent->mde_list);
4582 suffix = strrchr(dirent->mde_name, '-');
4583 if (suffix != NULL) {
4584 len = prefix_len + dirent->mde_len + 1;
4585 if (remains - len < 0) {
4586 /* No enough space for this record */
4587 mgs_direntry_free(dirent);
4591 if (start < data->ioc_count) {
4592 mgs_direntry_free(dirent);
4595 len = scnprintf(out, remains, "%s%s\n", prefix,
4600 mgs_direntry_free(dirent);
4608 data->ioc_count = start;
4612 struct mgs_lcfg_fork_data {
4613 struct lustre_cfg_bufs mlfd_bufs;
4614 struct mgs_device *mlfd_mgs;
4615 struct llog_handle *mlfd_llh;
4616 const char *mlfd_oldname;
4617 const char *mlfd_newname;
4621 static bool contain_valid_fsname(char *buf, const char *fsname,
4622 int buflen, int namelen)
4624 if (buflen < namelen)
4627 if (memcmp(buf, fsname, namelen) != 0)
4630 if (buf[namelen] != '\0' && buf[namelen] != '-')
4636 static int mgs_lcfg_fork_handler(const struct lu_env *env,
4637 struct llog_handle *o_llh,
4638 struct llog_rec_hdr *o_rec, void *data)
4640 struct mgs_lcfg_fork_data *mlfd = data;
4641 struct lustre_cfg_bufs *n_bufs = &mlfd->mlfd_bufs;
4642 struct lustre_cfg *o_lcfg = (struct lustre_cfg *)(o_rec + 1);
4643 struct llog_cfg_rec *lcr;
4645 char *n_buf = mlfd->mlfd_data;
4647 int o_namelen = strlen(mlfd->mlfd_oldname);
4648 int n_namelen = strlen(mlfd->mlfd_newname);
4649 int diff = n_namelen - o_namelen;
4650 __u32 cmd = o_lcfg->lcfg_command;
4651 __u32 cnt = o_lcfg->lcfg_bufcount;
4657 o_buf = lustre_cfg_buf(o_lcfg, 0);
4658 o_buflen = o_lcfg->lcfg_buflens[0];
4659 if (contain_valid_fsname(o_buf, mlfd->mlfd_oldname, o_buflen,
4661 memcpy(n_buf, mlfd->mlfd_newname, n_namelen);
4662 memcpy(n_buf + n_namelen, o_buf + o_namelen,
4663 o_buflen - o_namelen);
4664 lustre_cfg_bufs_reset(n_bufs, n_buf);
4665 n_buf += cfs_size_round(o_buflen + diff);
4667 lustre_cfg_bufs_reset(n_bufs, o_buflen != 0 ? o_buf : NULL);
4672 struct cfg_marker *o_marker;
4673 struct cfg_marker *n_marker;
4677 CDEBUG(D_MGS, "Unknown cfg marker entry with %d "
4682 /* buf[1] is marker */
4683 o_buf = lustre_cfg_buf(o_lcfg, 1);
4684 o_buflen = o_lcfg->lcfg_buflens[1];
4685 o_marker = (struct cfg_marker *)o_buf;
4686 if (!contain_valid_fsname(o_marker->cm_tgtname,
4688 sizeof(o_marker->cm_tgtname),
4690 lustre_cfg_bufs_set(n_bufs, 1, o_marker,
4695 n_marker = (struct cfg_marker *)n_buf;
4696 *n_marker = *o_marker;
4697 memcpy(n_marker->cm_tgtname, mlfd->mlfd_newname, n_namelen);
4698 tgt_namelen = strlen(o_marker->cm_tgtname);
4699 if (tgt_namelen > o_namelen)
4700 memcpy(n_marker->cm_tgtname + n_namelen,
4701 o_marker->cm_tgtname + o_namelen,
4702 tgt_namelen - o_namelen);
4703 n_marker->cm_tgtname[tgt_namelen + diff] = '\0';
4704 lustre_cfg_bufs_set(n_bufs, 1, n_marker, sizeof(*n_marker));
4708 case LCFG_SET_PARAM: {
4709 for (i = 1; i < cnt; i++)
4710 /* buf[i] is the param value, reuse it directly */
4711 lustre_cfg_bufs_set(n_bufs, i,
4712 lustre_cfg_buf(o_lcfg, i),
4713 o_lcfg->lcfg_buflens[i]);
4719 case LCFG_POOL_DEL: {
4720 if (cnt < 3 || cnt > 4) {
4721 CDEBUG(D_MGS, "Unknown cfg pool (%x) entry with %d "
4722 "buffers\n", cmd, cnt);
4726 /* buf[1] is fsname */
4727 o_buf = lustre_cfg_buf(o_lcfg, 1);
4728 o_buflen = o_lcfg->lcfg_buflens[1];
4729 memcpy(n_buf, mlfd->mlfd_newname, n_namelen);
4730 memcpy(n_buf + n_namelen, o_buf + o_namelen,
4731 o_buflen - o_namelen);
4732 lustre_cfg_bufs_set(n_bufs, 1, n_buf, o_buflen + diff);
4733 n_buf += cfs_size_round(o_buflen + diff);
4735 /* buf[2] is the pool name, reuse it directly */
4736 lustre_cfg_bufs_set(n_bufs, 2, lustre_cfg_buf(o_lcfg, 2),
4737 o_lcfg->lcfg_buflens[2]);
4742 /* buf[3] is ostname */
4743 o_buf = lustre_cfg_buf(o_lcfg, 3);
4744 o_buflen = o_lcfg->lcfg_buflens[3];
4745 memcpy(n_buf, mlfd->mlfd_newname, n_namelen);
4746 memcpy(n_buf + n_namelen, o_buf + o_namelen,
4747 o_buflen - o_namelen);
4748 lustre_cfg_bufs_set(n_bufs, 3, n_buf, o_buflen + diff);
4753 o_buflen = o_lcfg->lcfg_buflens[1];
4754 if (o_buflen == sizeof(struct lov_desc) ||
4755 o_buflen == sizeof(struct lmv_desc)) {
4761 o_buf = lustre_cfg_buf(o_lcfg, 1);
4762 if (o_buflen == sizeof(struct lov_desc)) {
4763 struct lov_desc *o_desc =
4764 (struct lov_desc *)o_buf;
4765 struct lov_desc *n_desc =
4766 (struct lov_desc *)n_buf;
4769 o_uuid = o_desc->ld_uuid.uuid;
4770 n_uuid = n_desc->ld_uuid.uuid;
4771 uuid_len = sizeof(o_desc->ld_uuid.uuid);
4773 struct lmv_desc *o_desc =
4774 (struct lmv_desc *)o_buf;
4775 struct lmv_desc *n_desc =
4776 (struct lmv_desc *)n_buf;
4779 o_uuid = o_desc->ld_uuid.uuid;
4780 n_uuid = n_desc->ld_uuid.uuid;
4781 uuid_len = sizeof(o_desc->ld_uuid.uuid);
4784 if (unlikely(!contain_valid_fsname(o_uuid,
4785 mlfd->mlfd_oldname, uuid_len,
4787 lustre_cfg_bufs_set(n_bufs, 1, o_buf,
4792 memcpy(n_uuid, mlfd->mlfd_newname, n_namelen);
4793 uuid_len = strlen(o_uuid);
4794 if (uuid_len > o_namelen)
4795 memcpy(n_uuid + n_namelen,
4797 uuid_len - o_namelen);
4798 n_uuid[uuid_len + diff] = '\0';
4799 lustre_cfg_bufs_set(n_bufs, 1, n_buf, o_buflen);
4801 } /* else case fall through */
4802 } /* else case fall through */
4806 for (i = 1; i < cnt; i++) {
4807 o_buflen = o_lcfg->lcfg_buflens[i];
4811 o_buf = lustre_cfg_buf(o_lcfg, i);
4812 if (!contain_valid_fsname(o_buf, mlfd->mlfd_oldname,
4813 o_buflen, o_namelen)) {
4814 lustre_cfg_bufs_set(n_bufs, i, o_buf, o_buflen);
4818 memcpy(n_buf, mlfd->mlfd_newname, n_namelen);
4819 if (o_buflen == o_namelen) {
4820 lustre_cfg_bufs_set(n_bufs, i, n_buf,
4822 n_buf += cfs_size_round(n_namelen);
4826 memcpy(n_buf + n_namelen, o_buf + o_namelen,
4827 o_buflen - o_namelen);
4828 lustre_cfg_bufs_set(n_bufs, i, n_buf, o_buflen + diff);
4829 n_buf += cfs_size_round(o_buflen + diff);
4835 lcr = lustre_cfg_rec_new(cmd, n_bufs);
4839 lcr->lcr_cfg = *o_lcfg;
4840 rc = llog_write(env, mlfd->mlfd_llh, &lcr->lcr_hdr, LLOG_NEXT_IDX);
4841 lustre_cfg_rec_free(lcr);
4846 static int mgs_lcfg_fork_one(const struct lu_env *env, struct mgs_device *mgs,
4847 struct mgs_direntry *mde, const char *oldname,
4848 const char *newname)
4850 struct llog_handle *old_llh = NULL;
4851 struct llog_handle *new_llh = NULL;
4852 struct llog_ctxt *ctxt = NULL;
4853 struct mgs_lcfg_fork_data *mlfd = NULL;
4854 char *name_buf = NULL;
4856 int old_namelen = strlen(oldname);
4857 int new_namelen = strlen(newname);
4861 name_buflen = mde->mde_len + new_namelen - old_namelen;
4862 OBD_ALLOC(name_buf, name_buflen);
4866 memcpy(name_buf, newname, new_namelen);
4867 memcpy(name_buf + new_namelen, mde->mde_name + old_namelen,
4868 mde->mde_len - old_namelen);
4870 CDEBUG(D_MGS, "Fork the config-log from %s to %s\n",
4871 mde->mde_name, name_buf);
4873 ctxt = llog_get_context(mgs->mgs_obd, LLOG_CONFIG_ORIG_CTXT);
4876 rc = llog_open_create(env, ctxt, &new_llh, NULL, name_buf);
4880 rc = llog_init_handle(env, new_llh, LLOG_F_IS_PLAIN, NULL);
4884 if (unlikely(mgs_log_is_empty(env, mgs, mde->mde_name)))
4887 rc = llog_open(env, ctxt, &old_llh, NULL, mde->mde_name,
4892 rc = llog_init_handle(env, old_llh, LLOG_F_IS_PLAIN, NULL);
4896 new_llh->lgh_hdr->llh_tgtuuid = old_llh->lgh_hdr->llh_tgtuuid;
4898 OBD_ALLOC(mlfd, LLOG_MIN_CHUNK_SIZE);
4900 GOTO(out, rc = -ENOMEM);
4902 mlfd->mlfd_mgs = mgs;
4903 mlfd->mlfd_llh = new_llh;
4904 mlfd->mlfd_oldname = oldname;
4905 mlfd->mlfd_newname = newname;
4907 rc = llog_process(env, old_llh, mgs_lcfg_fork_handler, mlfd, NULL);
4908 OBD_FREE(mlfd, LLOG_MIN_CHUNK_SIZE);
4914 llog_close(env, old_llh);
4916 llog_close(env, new_llh);
4918 OBD_FREE(name_buf, name_buflen);
4920 llog_ctxt_put(ctxt);
4925 int mgs_lcfg_fork(const struct lu_env *env, struct mgs_device *mgs,
4926 const char *oldname, const char *newname)
4928 struct list_head log_list;
4929 struct mgs_direntry *dirent, *n;
4930 int olen = strlen(oldname);
4931 int nlen = strlen(newname);
4936 if (unlikely(!oldname || oldname[0] == '\0' ||
4937 !newname || newname[0] == '\0'))
4940 if (strcmp(oldname, newname) == 0)
4943 /* lock it to prevent fork/erase/register in parallel. */
4944 mutex_lock(&mgs->mgs_mutex);
4946 rc = class_dentry_readdir(env, mgs, &log_list);
4948 mutex_unlock(&mgs->mgs_mutex);
4952 if (list_empty(&log_list)) {
4953 mutex_unlock(&mgs->mgs_mutex);
4957 list_for_each_entry_safe(dirent, n, &log_list, mde_list) {
4960 ptr = strrchr(dirent->mde_name, '-');
4962 int tlen = ptr - dirent->mde_name;
4965 strncmp(newname, dirent->mde_name, tlen) == 0)
4966 GOTO(out, rc = -EEXIST);
4969 strncmp(oldname, dirent->mde_name, tlen) == 0)
4973 list_del_init(&dirent->mde_list);
4974 mgs_direntry_free(dirent);
4977 if (list_empty(&log_list)) {
4978 mutex_unlock(&mgs->mgs_mutex);
4982 list_for_each_entry(dirent, &log_list, mde_list) {
4983 rc = mgs_lcfg_fork_one(env, mgs, dirent, oldname, newname);
4991 mutex_unlock(&mgs->mgs_mutex);
4993 list_for_each_entry_safe(dirent, n, &log_list, mde_list) {
4994 list_del_init(&dirent->mde_list);
4995 mgs_direntry_free(dirent);
4998 if (rc && count > 0)
4999 mgs_erase_logs(env, mgs, newname);
5004 int mgs_lcfg_erase(const struct lu_env *env, struct mgs_device *mgs,
5010 if (unlikely(!fsname || fsname[0] == '\0'))
5013 rc = mgs_erase_logs(env, mgs, fsname);
5018 static int mgs_xattr_del(const struct lu_env *env, struct dt_object *obj)
5020 struct dt_device *dev;
5021 struct thandle *th = NULL;
5026 dev = container_of(obj->do_lu.lo_dev, struct dt_device, dd_lu_dev);
5027 th = dt_trans_create(env, dev);
5029 RETURN(PTR_ERR(th));
5031 rc = dt_declare_xattr_del(env, obj, XATTR_TARGET_RENAME, th);
5035 rc = dt_trans_start_local(env, dev, th);
5039 dt_write_lock(env, obj, 0);
5040 rc = dt_xattr_del(env, obj, XATTR_TARGET_RENAME, th);
5045 dt_write_unlock(env, obj);
5048 dt_trans_stop(env, dev, th);
5053 int mgs_lcfg_rename(const struct lu_env *env, struct mgs_device *mgs)
5055 struct list_head log_list;
5056 struct mgs_direntry *dirent, *n;
5058 struct lu_buf buf = {
5060 .lb_len = sizeof(fsname)
5066 rc = class_dentry_readdir(env, mgs, &log_list);
5070 if (list_empty(&log_list))
5073 list_for_each_entry_safe(dirent, n, &log_list, mde_list) {
5074 struct dt_object *o = NULL;
5079 list_del_init(&dirent->mde_list);
5080 ptr = strrchr(dirent->mde_name, '-');
5084 len = ptr - dirent->mde_name;
5085 if (unlikely(len >= sizeof(oldname))) {
5086 CDEBUG(D_MGS, "Skip invalid configuration file %s\n",
5091 o = local_file_find(env, mgs->mgs_los, mgs->mgs_configs_dir,
5095 CDEBUG(D_MGS, "Fail to locate file %s: rc = %d\n",
5096 dirent->mde_name, rc);
5100 rc = dt_xattr_get(env, o, &buf, XATTR_TARGET_RENAME);
5106 "Fail to get EA for %s: rc = %d\n",
5107 dirent->mde_name, rc);
5111 if (unlikely(rc == len &&
5112 memcmp(fsname, dirent->mde_name, len) == 0)) {
5113 /* The new fsname is the same as the old one. */
5114 rc = mgs_xattr_del(env, o);
5118 memcpy(oldname, dirent->mde_name, len);
5119 oldname[len] = '\0';
5121 rc = mgs_lcfg_fork_one(env, mgs, dirent, oldname, fsname);
5122 if (rc && rc != -EEXIST) {
5123 CDEBUG(D_MGS, "Fail to fork %s: rc = %d\n",
5124 dirent->mde_name, rc);
5128 rc = mgs_erase_log(env, mgs, dirent->mde_name);
5130 CDEBUG(D_MGS, "Fail to erase old %s: rc = %d\n",
5131 dirent->mde_name, rc);
5132 /* keep it there if failed to remove it. */
5137 if (o && !IS_ERR(o))
5138 lu_object_put(env, &o->do_lu);
5140 mgs_direntry_free(dirent);
5145 list_for_each_entry_safe(dirent, n, &log_list, mde_list) {
5146 list_del_init(&dirent->mde_list);
5147 mgs_direntry_free(dirent);
5153 /* Setup _mgs fsdb and log
5155 int mgs__mgs_fsdb_setup(const struct lu_env *env, struct mgs_device *mgs)
5157 struct fs_db *fsdb = NULL;
5161 rc = mgs_find_or_make_fsdb(env, mgs, MGSSELF_NAME, &fsdb);
5163 mgs_put_fsdb(mgs, fsdb);
5168 /* Setup params fsdb and log
5170 int mgs_params_fsdb_setup(const struct lu_env *env, struct mgs_device *mgs)
5172 struct fs_db *fsdb = NULL;
5173 struct llog_handle *params_llh = NULL;
5177 rc = mgs_find_or_make_fsdb(env, mgs, PARAMS_FILENAME, &fsdb);
5179 mutex_lock(&fsdb->fsdb_mutex);
5180 rc = record_start_log(env, mgs, ¶ms_llh, PARAMS_FILENAME);
5182 rc = record_end_log(env, ¶ms_llh);
5183 mutex_unlock(&fsdb->fsdb_mutex);
5184 mgs_put_fsdb(mgs, fsdb);
5190 /* Cleanup params fsdb and log
5192 int mgs_params_fsdb_cleanup(const struct lu_env *env, struct mgs_device *mgs)
5196 rc = mgs_erase_logs(env, mgs, PARAMS_FILENAME);
5197 return rc == -ENOENT ? 0 : rc;
5201 * Fill in the mgs_target_info based on data devname and param provide.
5203 * @env thread context
5205 * @mti mgs target info. We want to set this based other paramters
5206 * passed to this function. Once setup we write it to the config
5208 * @devname optional OBD device name
5209 * @param string that contains both what tunable to set and the value to
5212 * RETURN 0 for success
5213 * negative error number on failure
5215 static int mgs_set_conf_param(const struct lu_env *env, struct mgs_device *mgs,
5216 struct mgs_target_info *mti, const char *devname,
5219 struct fs_db *fsdb = NULL;
5224 /* lustre, lustre-mdtlov, lustre-client, lustre-MDT0000 */
5228 /* We have two possible cases here:
5230 * 1) the device name embedded in the param:
5231 * lustre-OST0000.osc.max_dirty_mb=32
5233 * 2) the file system name is embedded in
5234 * the param: lustre.sys.at.min=0
5236 len = strcspn(param, ".=");
5237 if (!len || param[len] == '=')
5240 if (len >= sizeof(mti->mti_svname))
5243 snprintf(mti->mti_svname, sizeof(mti->mti_svname),
5244 "%.*s", (int)len, param);
5247 if (strlcpy(mti->mti_svname, devname, sizeof(mti->mti_svname)) >=
5248 sizeof(mti->mti_svname))
5252 if (!strlen(mti->mti_svname)) {
5253 LCONSOLE_ERROR_MSG(0x14d, "No target specified: %s\n", param);
5257 dev_type = mgs_parse_devname(mti->mti_svname, mti->mti_fsname,
5258 &mti->mti_stripe_index);
5260 /* For this case we have an invalid obd device name */
5262 CDEBUG(D_MGS, "%s don't contain an index\n", mti->mti_svname);
5263 strlcpy(mti->mti_fsname, mti->mti_svname, MTI_NAME_MAXLEN);
5266 /* Not an obd device, assume devname is the fsname.
5267 * User might of only provided fsname and not obd device
5270 CDEBUG(D_MGS, "%s is seen as a file system name\n", mti->mti_svname);
5271 strlcpy(mti->mti_fsname, mti->mti_svname, MTI_NAME_MAXLEN);
5276 GOTO(out, rc = dev_type);
5278 /* param related to llite isn't allowed to set by OST or MDT */
5279 if (dev_type & LDD_F_SV_TYPE_OST ||
5280 dev_type & LDD_F_SV_TYPE_MDT) {
5281 /* param related to llite isn't allowed to set by OST
5284 if (!strncmp(param, PARAM_LLITE,
5285 sizeof(PARAM_LLITE) - 1))
5286 GOTO(out, rc = -EINVAL);
5288 /* Strip -osc or -mdc suffix from svname */
5289 if (server_make_name(dev_type, mti->mti_stripe_index,
5290 mti->mti_fsname, mti->mti_svname,
5291 sizeof(mti->mti_svname)))
5292 GOTO(out, rc = -EINVAL);
5297 if (strlcpy(mti->mti_params, param, sizeof(mti->mti_params)) >=
5298 sizeof(mti->mti_params))
5299 GOTO(out, rc = -E2BIG);
5301 CDEBUG(D_MGS, "set_conf_param fs='%s' device='%s' param='%s'\n",
5302 mti->mti_fsname, mti->mti_svname, mti->mti_params);
5304 rc = mgs_find_or_make_fsdb(env, mgs, mti->mti_fsname, &fsdb);
5308 if (!test_bit(FSDB_MGS_SELF, &fsdb->fsdb_flags) &&
5309 test_bit(FSDB_LOG_EMPTY, &fsdb->fsdb_flags)) {
5310 CERROR("No filesystem targets for %s. cfg_device from lctl "
5311 "is '%s'\n", mti->mti_fsname, mti->mti_svname);
5312 mgs_unlink_fsdb(mgs, fsdb);
5313 GOTO(out, rc = -EINVAL);
5317 * Revoke lock so everyone updates. Should be alright if
5318 * someone was already reading while we were updating the logs,
5319 * so we don't really need to hold the lock while we're
5322 mti->mti_flags = dev_type | LDD_F_PARAM;
5323 mutex_lock(&fsdb->fsdb_mutex);
5324 rc = mgs_write_log_param(env, mgs, fsdb, mti, mti->mti_params);
5325 mutex_unlock(&fsdb->fsdb_mutex);
5326 mgs_revoke_lock(mgs, fsdb, MGS_CFG_T_CONFIG);
5330 mgs_put_fsdb(mgs, fsdb);
5335 static int mgs_set_param2(const struct lu_env *env, struct mgs_device *mgs,
5336 struct mgs_target_info *mti, const char *param)
5338 struct fs_db *fsdb = NULL;
5343 if (strlcpy(mti->mti_params, param, sizeof(mti->mti_params)) >=
5344 sizeof(mti->mti_params))
5345 GOTO(out, rc = -E2BIG);
5347 len = strcspn(param, ".=");
5348 if (len && param[len] != '=') {
5349 struct list_head *tmp;
5353 ptr = strchr(param, '.');
5355 len = strlen(param);
5358 if (len >= sizeof(mti->mti_svname))
5359 GOTO(out, rc = -E2BIG);
5361 snprintf(mti->mti_svname, sizeof(mti->mti_svname), "%.*s",
5364 mutex_lock(&mgs->mgs_mutex);
5365 if (unlikely(list_empty(&mgs->mgs_fs_db_list))) {
5366 mutex_unlock(&mgs->mgs_mutex);
5367 GOTO(out, rc = -ENODEV);
5370 list_for_each(tmp, &mgs->mgs_fs_db_list) {
5371 fsdb = list_entry(tmp, struct fs_db, fsdb_list);
5372 if (fsdb->fsdb_has_lproc_entry &&
5373 strcmp(fsdb->fsdb_name, "params") != 0 &&
5374 strstr(param, fsdb->fsdb_name)) {
5375 snprintf(mti->mti_svname,
5376 sizeof(mti->mti_svname), "%s",
5384 snprintf(mti->mti_svname, sizeof(mti->mti_svname),
5387 mutex_unlock(&mgs->mgs_mutex);
5389 snprintf(mti->mti_svname, sizeof(mti->mti_svname), "general");
5392 CDEBUG(D_MGS, "set_param2 fs='%s' device='%s' param='%s'\n",
5393 mti->mti_fsname, mti->mti_svname, mti->mti_params);
5395 /* The return value should be the device type i.e LDD_F_SV_TYPE_XXX.
5396 * A returned error tells us we don't have a target obd device.
5398 dev_type = server_name2index(mti->mti_svname, &mti->mti_stripe_index,
5403 /* the return value should be the device type i.e LDD_F_SV_TYPE_XXX.
5404 * Strip -osc or -mdc suffix from svname
5406 if ((dev_type & LDD_F_SV_TYPE_OST || dev_type & LDD_F_SV_TYPE_MDT) &&
5407 server_make_name(dev_type, mti->mti_stripe_index,
5408 mti->mti_fsname, mti->mti_svname,
5409 sizeof(mti->mti_svname)))
5410 GOTO(out, rc = -EINVAL);
5412 rc = mgs_find_or_make_fsdb(env, mgs, PARAMS_FILENAME, &fsdb);
5416 * Revoke lock so everyone updates. Should be alright if
5417 * someone was already reading while we were updating the logs,
5418 * so we don't really need to hold the lock while we're
5421 mti->mti_flags = dev_type | LDD_F_PARAM2;
5422 mutex_lock(&fsdb->fsdb_mutex);
5423 rc = mgs_write_log_param2(env, mgs, fsdb, mti, mti->mti_params);
5424 mutex_unlock(&fsdb->fsdb_mutex);
5425 mgs_revoke_lock(mgs, fsdb, MGS_CFG_T_PARAMS);
5426 mgs_put_fsdb(mgs, fsdb);
5431 /* Set a permanent (config log) param for a target or fs
5433 * @lcfg buf0 may contain the device (testfs-MDT0000) name
5434 * buf1 contains the single parameter
5436 int mgs_set_param(const struct lu_env *env, struct mgs_device *mgs,
5437 struct lustre_cfg *lcfg)
5439 const char *param = lustre_cfg_string(lcfg, 1);
5440 struct mgs_target_info *mti;
5443 /* Create a fake mti to hold everything */
5448 print_lustre_cfg(lcfg);
5450 if (lcfg->lcfg_command == LCFG_PARAM) {
5451 /* For the case of lctl conf_param devname can be
5452 * lustre, lustre-mdtlov, lustre-client, lustre-MDT0000
5454 const char *devname = lustre_cfg_string(lcfg, 0);
5456 rc = mgs_set_conf_param(env, mgs, mti, devname, param);
5458 /* In the case of lctl set_param -P lcfg[0] will always
5459 * be 'general'. At least for now.
5461 rc = mgs_set_param2(env, mgs, mti, param);
5469 static int mgs_write_log_pool(const struct lu_env *env,
5470 struct mgs_device *mgs, char *logname,
5471 struct fs_db *fsdb, char *tgtname,
5472 enum lcfg_command_type cmd,
5473 char *fsname, char *poolname,
5474 char *ostname, char *comment)
5476 struct llog_handle *llh = NULL;
5479 rc = record_start_log(env, mgs, &llh, logname);
5482 rc = record_marker(env, llh, fsdb, CM_START, tgtname, comment);
5485 rc = record_base(env, llh, tgtname, 0, cmd,
5486 fsname, poolname, ostname, NULL);
5489 rc = record_marker(env, llh, fsdb, CM_END, tgtname, comment);
5491 record_end_log(env, &llh);
5495 int mgs_nodemap_cmd(const struct lu_env *env, struct mgs_device *mgs,
5496 enum lcfg_command_type cmd, const char *nodemap_name,
5507 case LCFG_NODEMAP_ADD:
5508 rc = nodemap_add(nodemap_name);
5510 case LCFG_NODEMAP_DEL:
5511 rc = nodemap_del(nodemap_name);
5513 case LCFG_NODEMAP_ADD_RANGE:
5514 rc = nodemap_parse_range(param, nid);
5517 rc = nodemap_add_range(nodemap_name, nid);
5519 case LCFG_NODEMAP_DEL_RANGE:
5520 rc = nodemap_parse_range(param, nid);
5523 rc = nodemap_del_range(nodemap_name, nid);
5525 case LCFG_NODEMAP_ADMIN:
5526 rc = kstrtobool(param, &bool_switch);
5529 rc = nodemap_set_allow_root(nodemap_name, bool_switch);
5531 case LCFG_NODEMAP_DENY_UNKNOWN:
5532 rc = kstrtobool(param, &bool_switch);
5535 rc = nodemap_set_deny_unknown(nodemap_name, bool_switch);
5537 case LCFG_NODEMAP_AUDIT_MODE:
5538 rc = kstrtobool(param, &bool_switch);
5540 rc = nodemap_set_audit_mode(nodemap_name, bool_switch);
5542 case LCFG_NODEMAP_FORBID_ENCRYPT:
5543 rc = kstrtobool(param, &bool_switch);
5545 rc = nodemap_set_forbid_encryption(nodemap_name,
5548 case LCFG_NODEMAP_MAP_MODE:
5553 if ((p = strstr(param, "all")) != NULL) {
5554 if ((p == param || *(p-1) == ',') &&
5555 (*(p+3) == '\0' || *(p+3) == ',')) {
5556 map_mode = NODEMAP_MAP_ALL;
5562 while ((p = strsep(¶m, ",")) != NULL) {
5566 if (strcmp("both", p) == 0)
5567 map_mode |= NODEMAP_MAP_BOTH;
5568 else if (strcmp("uid_only", p) == 0 ||
5569 strcmp("uid", p) == 0)
5570 map_mode |= NODEMAP_MAP_UID;
5571 else if (strcmp("gid_only", p) == 0 ||
5572 strcmp("gid", p) == 0)
5573 map_mode |= NODEMAP_MAP_GID;
5574 else if (strcmp("projid_only", p) == 0 ||
5575 strcmp("projid", p) == 0)
5576 map_mode |= NODEMAP_MAP_PROJID;
5586 rc = nodemap_set_mapping_mode(nodemap_name, map_mode);
5589 case LCFG_NODEMAP_TRUSTED:
5590 rc = kstrtobool(param, &bool_switch);
5593 rc = nodemap_set_trust_client_ids(nodemap_name, bool_switch);
5595 case LCFG_NODEMAP_SQUASH_UID:
5596 rc = kstrtouint(param, 10, &int_id);
5599 rc = nodemap_set_squash_uid(nodemap_name, int_id);
5601 case LCFG_NODEMAP_SQUASH_GID:
5602 rc = kstrtouint(param, 10, &int_id);
5605 rc = nodemap_set_squash_gid(nodemap_name, int_id);
5607 case LCFG_NODEMAP_SQUASH_PROJID:
5608 rc = kstrtouint(param, 10, &int_id);
5611 rc = nodemap_set_squash_projid(nodemap_name, int_id);
5613 case LCFG_NODEMAP_ADD_UIDMAP:
5614 case LCFG_NODEMAP_ADD_GIDMAP:
5615 case LCFG_NODEMAP_ADD_PROJIDMAP:
5616 rc = nodemap_parse_idmap(param, idmap);
5619 if (cmd == LCFG_NODEMAP_ADD_UIDMAP)
5620 rc = nodemap_add_idmap(nodemap_name, NODEMAP_UID,
5622 else if (cmd == LCFG_NODEMAP_ADD_GIDMAP)
5623 rc = nodemap_add_idmap(nodemap_name, NODEMAP_GID,
5625 else if (cmd == LCFG_NODEMAP_ADD_PROJIDMAP)
5626 rc = nodemap_add_idmap(nodemap_name, NODEMAP_PROJID,
5631 case LCFG_NODEMAP_DEL_UIDMAP:
5632 case LCFG_NODEMAP_DEL_GIDMAP:
5633 case LCFG_NODEMAP_DEL_PROJIDMAP:
5634 rc = nodemap_parse_idmap(param, idmap);
5637 if (cmd == LCFG_NODEMAP_DEL_UIDMAP)
5638 rc = nodemap_del_idmap(nodemap_name, NODEMAP_UID,
5640 else if (cmd == LCFG_NODEMAP_DEL_GIDMAP)
5641 rc = nodemap_del_idmap(nodemap_name, NODEMAP_GID,
5643 else if (cmd == LCFG_NODEMAP_DEL_PROJIDMAP)
5644 rc = nodemap_del_idmap(nodemap_name, NODEMAP_PROJID,
5649 case LCFG_NODEMAP_SET_FILESET:
5650 rc = nodemap_set_fileset(nodemap_name, param);
5652 case LCFG_NODEMAP_SET_SEPOL:
5653 rc = nodemap_set_sepol(nodemap_name, param);
5662 int mgs_pool_cmd(const struct lu_env *env, struct mgs_device *mgs,
5663 enum lcfg_command_type cmd, char *fsname,
5664 char *poolname, char *ostname)
5669 char *label = NULL, *canceled_label = NULL;
5671 struct mgs_target_info *mti = NULL;
5672 bool checked = false;
5673 bool locked = false;
5678 rc = mgs_find_or_make_fsdb(env, mgs, fsname, &fsdb);
5680 CERROR("Can't get db for %s\n", fsname);
5683 if (test_bit(FSDB_LOG_EMPTY, &fsdb->fsdb_flags)) {
5684 CERROR("%s is not defined\n", fsname);
5686 GOTO(out_fsdb, rc = -EINVAL);
5689 label_sz = 10 + strlen(fsname) + strlen(poolname);
5691 /* check if ostname match fsname */
5692 if (ostname != NULL) {
5695 ptr = strrchr(ostname, '-');
5696 if ((ptr == NULL) ||
5697 (strncmp(fsname, ostname, ptr-ostname) != 0))
5699 label_sz += strlen(ostname);
5702 OBD_ALLOC(label, label_sz);
5704 GOTO(out_fsdb, rc = -ENOMEM);
5709 "new %s.%s", fsname, poolname);
5713 "add %s.%s.%s", fsname, poolname, ostname);
5716 OBD_ALLOC(canceled_label, label_sz);
5717 if (canceled_label == NULL)
5718 GOTO(out_label, rc = -ENOMEM);
5720 "rem %s.%s.%s", fsname, poolname, ostname);
5721 sprintf(canceled_label,
5722 "add %s.%s.%s", fsname, poolname, ostname);
5725 OBD_ALLOC(canceled_label, label_sz);
5726 if (canceled_label == NULL)
5727 GOTO(out_label, rc = -ENOMEM);
5729 "del %s.%s", fsname, poolname);
5730 sprintf(canceled_label,
5731 "new %s.%s", fsname, poolname);
5739 GOTO(out_cancel, rc = -ENOMEM);
5740 strncpy(mti->mti_svname, "lov pool", sizeof(mti->mti_svname));
5742 mutex_lock(&fsdb->fsdb_mutex);
5744 /* write pool def to all MDT logs */
5745 for (i = 0; i < INDEX_MAP_SIZE * 8; i++) {
5746 if (test_bit(i, fsdb->fsdb_mdt_index_map)) {
5747 rc = name_create_mdt_and_lov(&logname, &lovname,
5752 if (!checked && (canceled_label == NULL)) {
5753 rc = mgs_check_marker(env, mgs, fsdb, mti,
5754 logname, lovname, label);
5756 name_destroy(&logname);
5757 name_destroy(&lovname);
5759 rc = (rc == LLOG_PROC_BREAK ?
5764 if (canceled_label != NULL)
5765 rc = mgs_modify(env, mgs, fsdb, mti, logname,
5766 lovname, canceled_label,
5770 rc = mgs_write_log_pool(env, mgs, logname,
5774 name_destroy(&logname);
5775 name_destroy(&lovname);
5781 rc = name_create(&logname, fsname, "-client");
5785 if (!checked && (canceled_label == NULL)) {
5786 rc = mgs_check_marker(env, mgs, fsdb, mti, logname,
5787 fsdb->fsdb_clilov, label);
5789 name_destroy(&logname);
5790 GOTO(out_mti, rc = (rc == LLOG_PROC_BREAK ?
5794 if (canceled_label != NULL) {
5795 rc = mgs_modify(env, mgs, fsdb, mti, logname,
5796 fsdb->fsdb_clilov, canceled_label, CM_SKIP);
5798 name_destroy(&logname);
5803 rc = mgs_write_log_pool(env, mgs, logname, fsdb, fsdb->fsdb_clilov,
5804 cmd, fsname, poolname, ostname, label);
5805 mutex_unlock(&fsdb->fsdb_mutex);
5807 name_destroy(&logname);
5808 /* request for update */
5809 mgs_revoke_lock(mgs, fsdb, MGS_CFG_T_CONFIG);
5815 mutex_unlock(&fsdb->fsdb_mutex);
5819 if (canceled_label != NULL)
5820 OBD_FREE(canceled_label, label_sz);
5822 OBD_FREE(label, label_sz);
5825 mgs_unlink_fsdb(mgs, fsdb);
5826 mgs_put_fsdb(mgs, fsdb);