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;
269 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
585 int mgs_check_index(const struct lu_env *env,
586 struct mgs_device *mgs,
587 struct mgs_target_info *mti)
594 LASSERT(!(mti->mti_flags & LDD_F_NEED_INDEX));
596 rc = mgs_find_or_make_fsdb(env, mgs, mti->mti_fsname, &fsdb);
598 CERROR("Can't get db for %s\n", mti->mti_fsname);
602 if (test_bit(FSDB_LOG_EMPTY, &fsdb->fsdb_flags))
605 if (mti->mti_flags & LDD_F_SV_TYPE_OST)
606 imap = fsdb->fsdb_ost_index_map;
607 else if (mti->mti_flags & LDD_F_SV_TYPE_MDT)
608 imap = fsdb->fsdb_mdt_index_map;
610 GOTO(out, rc = -EINVAL);
612 if (test_bit(mti->mti_stripe_index, imap))
618 mgs_put_fsdb(mgs, fsdb);
622 static __inline__ int next_index(void *index_map, int map_len)
626 for (i = 0; i < map_len * 8; i++)
627 if (!test_bit(i, index_map))
629 CERROR("max index %d exceeded.\n", i);
633 /* Make the mdt/ost server obd name based on the filesystem name */
634 static bool server_make_name(u32 flags, u16 index, const char *fs,
635 char *name_buf, size_t name_buf_size)
637 bool invalid_flag = false;
639 if (flags & (LDD_F_SV_TYPE_MDT | LDD_F_SV_TYPE_OST)) {
642 if (flags & LDD_F_WRITECONF)
644 else if (flags & LDD_F_VIRGIN)
647 if (!(flags & LDD_F_SV_ALL))
648 snprintf(name_buf, name_buf_size, "%.8s%c%s%04x", fs,
650 (flags & LDD_F_SV_TYPE_MDT) ? "MDT" : "OST",
652 } else if (flags & LDD_F_SV_TYPE_MGS) {
653 snprintf(name_buf, name_buf_size, "MGS");
655 CERROR("unknown server type %#x\n", flags);
662 * 0 newly marked as in use
664 * +EALREADY for update of an old index
666 static int mgs_set_index(const struct lu_env *env,
667 struct mgs_device *mgs,
668 struct mgs_target_info *mti)
676 rc = mgs_find_or_make_fsdb(env, mgs, mti->mti_fsname, &fsdb);
678 CERROR("Can't get db for %s\n", mti->mti_fsname);
682 mutex_lock(&fsdb->fsdb_mutex);
683 if (mti->mti_flags & LDD_F_SV_TYPE_OST)
684 imap = fsdb->fsdb_ost_index_map;
685 else if (mti->mti_flags & LDD_F_SV_TYPE_MDT)
686 imap = fsdb->fsdb_mdt_index_map;
688 GOTO(out_up, rc = -EINVAL);
690 if (mti->mti_flags & LDD_F_NEED_INDEX) {
691 rc = next_index(imap, INDEX_MAP_SIZE);
693 GOTO(out_up, rc = -ERANGE);
694 mti->mti_stripe_index = rc;
697 /* the last index(0xffff) is reserved for default value. */
698 if (mti->mti_stripe_index >= INDEX_MAP_SIZE * 8 - 1) {
699 LCONSOLE_ERROR_MSG(0x13f, "Server %s requested index %u, "
700 "but index must be less than %u.\n",
701 mti->mti_svname, mti->mti_stripe_index,
702 INDEX_MAP_SIZE * 8 - 1);
703 GOTO(out_up, rc = -ERANGE);
706 if (test_bit(mti->mti_stripe_index, imap)) {
707 if ((mti->mti_flags & LDD_F_VIRGIN) &&
708 !(mti->mti_flags & LDD_F_WRITECONF)) {
711 "Server %s requested index %d, but that index is already in use. Use --writeconf to force\n",
713 mti->mti_stripe_index);
714 GOTO(out_up, rc = -EADDRINUSE);
716 CDEBUG(D_MGS, "Server %s updating index %d\n",
717 mti->mti_svname, mti->mti_stripe_index);
718 GOTO(out_up, rc = EALREADY);
721 set_bit(mti->mti_stripe_index, imap);
722 if (mti->mti_flags & LDD_F_SV_TYPE_MDT)
723 fsdb->fsdb_mdt_count++;
726 set_bit(mti->mti_stripe_index, imap);
727 clear_bit(FSDB_LOG_EMPTY, &fsdb->fsdb_flags);
728 if (server_make_name(mti->mti_flags & ~(LDD_F_VIRGIN | LDD_F_WRITECONF),
729 mti->mti_stripe_index, mti->mti_fsname,
730 mti->mti_svname, sizeof(mti->mti_svname))) {
731 CERROR("unknown server type %#x\n", mti->mti_flags);
732 GOTO(out_up, rc = -EINVAL);
735 CDEBUG(D_MGS, "Set index for %s to %d\n", mti->mti_svname,
736 mti->mti_stripe_index);
738 GOTO(out_up, rc = 0);
741 mutex_unlock(&fsdb->fsdb_mutex);
742 mgs_put_fsdb(mgs, fsdb);
746 struct mgs_modify_lookup {
747 struct cfg_marker mml_marker;
751 static int mgs_check_record_match(const struct lu_env *env,
752 struct llog_handle *llh,
753 struct llog_rec_hdr *rec, void *data)
755 struct cfg_marker *mc_marker = data;
756 struct cfg_marker *marker;
757 struct lustre_cfg *lcfg = REC_DATA(rec);
758 int cfg_len = REC_DATA_LEN(rec);
762 if (rec->lrh_type != OBD_CFG_REC) {
763 CDEBUG(D_ERROR, "Unhandled lrh_type: %#x\n", rec->lrh_type);
767 rc = lustre_cfg_sanity_check(lcfg, cfg_len);
769 CDEBUG(D_ERROR, "Insane cfg\n");
773 /* We only care about markers */
774 if (lcfg->lcfg_command != LCFG_MARKER)
777 marker = lustre_cfg_buf(lcfg, 1);
779 if (marker->cm_flags & CM_SKIP)
782 if ((strcmp(mc_marker->cm_comment, marker->cm_comment) == 0) &&
783 (strcmp(mc_marker->cm_tgtname, marker->cm_tgtname) == 0)) {
784 /* Found a non-skipped marker match */
785 CDEBUG(D_MGS, "Matched rec %u marker %d flag %x %s %s\n",
786 rec->lrh_index, marker->cm_step,
787 marker->cm_flags, marker->cm_tgtname,
789 rc = LLOG_PROC_BREAK;
796 * Check an existing config log record with matching comment and device
798 * 0 - checked successfully,
799 * LLOG_PROC_BREAK - record matches
802 static int mgs_check_marker(const struct lu_env *env, struct mgs_device *mgs,
803 struct fs_db *fsdb, struct mgs_target_info *mti,
804 char *logname, char *devname, char *comment)
806 struct llog_handle *loghandle;
807 struct llog_ctxt *ctxt;
808 struct cfg_marker *mc_marker;
813 LASSERT(mutex_is_locked(&fsdb->fsdb_mutex));
814 CDEBUG(D_MGS, "mgs check %s/%s/%s\n", logname, devname, comment);
816 ctxt = llog_get_context(mgs->mgs_obd, LLOG_CONFIG_ORIG_CTXT);
817 LASSERT(ctxt != NULL);
818 rc = llog_open(env, ctxt, &loghandle, NULL, logname, LLOG_OPEN_EXISTS);
825 rc = llog_init_handle(env, loghandle, LLOG_F_IS_PLAIN, NULL);
829 if (llog_get_size(loghandle) <= 1)
830 GOTO(out_close, rc = 0);
832 OBD_ALLOC_PTR(mc_marker);
834 GOTO(out_close, rc = -ENOMEM);
835 if (strlcpy(mc_marker->cm_comment, comment,
836 sizeof(mc_marker->cm_comment)) >=
837 sizeof(mc_marker->cm_comment))
838 GOTO(out_free, rc = -E2BIG);
839 if (strlcpy(mc_marker->cm_tgtname, devname,
840 sizeof(mc_marker->cm_tgtname)) >=
841 sizeof(mc_marker->cm_tgtname))
842 GOTO(out_free, rc = -E2BIG);
844 rc = llog_process(env, loghandle, mgs_check_record_match,
845 (void *)mc_marker, NULL);
848 OBD_FREE_PTR(mc_marker);
851 llog_close(env, loghandle);
853 if (rc && rc != LLOG_PROC_BREAK)
854 CDEBUG(D_ERROR, "%s: mgs check %s/%s failed: rc = %d\n",
855 mgs->mgs_obd->obd_name, mti->mti_svname, comment, rc);
860 static int mgs_modify_handler(const struct lu_env *env,
861 struct llog_handle *llh,
862 struct llog_rec_hdr *rec, void *data)
864 struct mgs_modify_lookup *mml = data;
865 struct cfg_marker *marker;
866 struct lustre_cfg *lcfg = REC_DATA(rec);
867 int cfg_len = REC_DATA_LEN(rec);
871 if (rec->lrh_type != OBD_CFG_REC) {
872 CERROR("unhandled lrh_type: %#x\n", rec->lrh_type);
876 rc = lustre_cfg_sanity_check(lcfg, cfg_len);
878 CERROR("Insane cfg\n");
882 /* We only care about markers */
883 if (lcfg->lcfg_command != LCFG_MARKER)
886 marker = lustre_cfg_buf(lcfg, 1);
887 if ((strcmp(mml->mml_marker.cm_comment, marker->cm_comment) == 0) &&
888 (strcmp(mml->mml_marker.cm_tgtname, marker->cm_tgtname) == 0) &&
889 !(marker->cm_flags & CM_SKIP)) {
890 /* Found a non-skipped marker match */
891 CDEBUG(D_MGS, "Changing rec %u marker %d %x->%x: %s %s\n",
892 rec->lrh_index, marker->cm_step,
893 marker->cm_flags, mml->mml_marker.cm_flags,
894 marker->cm_tgtname, marker->cm_comment);
895 /* Overwrite the old marker llog entry */
896 marker->cm_flags &= ~CM_EXCLUDE; /* in case we're unexcluding */
897 marker->cm_flags |= mml->mml_marker.cm_flags;
898 marker->cm_canceltime = mml->mml_marker.cm_canceltime;
899 rc = llog_write(env, llh, rec, rec->lrh_index);
908 * Modify an existing config log record (for CM_SKIP or CM_EXCLUDE)
910 * 0 - modified successfully,
911 * 1 - no modification was done
914 static int mgs_modify(const struct lu_env *env, struct mgs_device *mgs,
915 struct fs_db *fsdb, struct mgs_target_info *mti,
916 char *logname, char *devname, char *comment, int flags)
918 struct llog_handle *loghandle;
919 struct llog_ctxt *ctxt;
920 struct mgs_modify_lookup *mml;
925 LASSERT(mutex_is_locked(&fsdb->fsdb_mutex));
926 CDEBUG(D_MGS, "modify %s/%s/%s fl=%x\n", logname, devname, comment,
929 ctxt = llog_get_context(mgs->mgs_obd, LLOG_CONFIG_ORIG_CTXT);
930 LASSERT(ctxt != NULL);
931 rc = llog_open(env, ctxt, &loghandle, NULL, logname, LLOG_OPEN_EXISTS);
938 rc = llog_init_handle(env, loghandle, LLOG_F_IS_PLAIN, NULL);
942 if (llog_get_size(loghandle) <= 1)
943 GOTO(out_close, rc = 0);
947 GOTO(out_close, rc = -ENOMEM);
948 if (strlcpy(mml->mml_marker.cm_comment, comment,
949 sizeof(mml->mml_marker.cm_comment)) >=
950 sizeof(mml->mml_marker.cm_comment))
951 GOTO(out_free, rc = -E2BIG);
952 if (strlcpy(mml->mml_marker.cm_tgtname, devname,
953 sizeof(mml->mml_marker.cm_tgtname)) >=
954 sizeof(mml->mml_marker.cm_tgtname))
955 GOTO(out_free, rc = -E2BIG);
956 /* Modify mostly means cancel */
957 mml->mml_marker.cm_flags = flags;
958 mml->mml_marker.cm_canceltime = flags ? ktime_get_real_seconds() : 0;
959 mml->mml_modified = 0;
960 rc = llog_process(env, loghandle, mgs_modify_handler, (void *)mml,
962 if (!rc && !mml->mml_modified)
969 llog_close(env, loghandle);
972 CERROR("%s: modify %s/%s failed: rc = %d\n",
973 mgs->mgs_obd->obd_name, mti->mti_svname, comment, rc);
986 /** This structure is passed to mgs_replace_handler */
987 struct mgs_replace_data {
988 /* Nids are replaced for this target device */
989 struct mgs_target_info target;
990 /* Temporary modified llog */
991 struct llog_handle *temp_llh;
992 enum replace_state state;
998 * Check: a) if block should be skipped
999 * b) is it target block
1004 * \retval 0 should not to be skipped
1005 * \retval 1 should to be skipped
1007 static int check_markers(struct lustre_cfg *lcfg,
1008 struct mgs_replace_data *mrd)
1010 struct cfg_marker *marker;
1012 /* Track markers. Find given device */
1013 if (lcfg->lcfg_command == LCFG_MARKER) {
1014 marker = lustre_cfg_buf(lcfg, 1);
1015 /* Clean llog from records marked as CM_SKIP.
1016 CM_EXCLUDE records are used for "active" command
1017 and can be restored if needed */
1018 if ((marker->cm_flags & (CM_SKIP | CM_START)) ==
1019 (CM_SKIP | CM_START)) {
1020 mrd->state = REPLACE_SKIP;
1024 if ((marker->cm_flags & (CM_SKIP | CM_END)) ==
1025 (CM_SKIP | CM_END)) {
1026 mrd->state = REPLACE_COPY;
1030 if (strcmp(mrd->target.mti_svname, marker->cm_tgtname) == 0) {
1031 LASSERT(!(marker->cm_flags & CM_START) ||
1032 !(marker->cm_flags & CM_END));
1033 if (marker->cm_flags & CM_START) {
1034 if (!strncmp(marker->cm_comment,
1035 "add failnid", 11)) {
1036 mrd->state = REPLACE_SKIP;
1038 mrd->state = REPLACE_UUID;
1039 mrd->failover = NULL;
1041 } else if (marker->cm_flags & CM_END)
1042 mrd->state = REPLACE_COPY;
1044 if (!strncmp(marker->cm_comment,
1053 static int record_base(const struct lu_env *env, struct llog_handle *llh,
1054 char *cfgname, lnet_nid_t nid, int cmd,
1055 char *s1, char *s2, char *s3, char *s4)
1057 struct mgs_thread_info *mgi = mgs_env_info(env);
1058 struct llog_cfg_rec *lcr;
1061 CDEBUG(D_MGS, "lcfg %s %#x %s %s %s %s\n", cfgname,
1062 cmd, s1, s2, s3, s4);
1064 lustre_cfg_bufs_reset(&mgi->mgi_bufs, cfgname);
1066 lustre_cfg_bufs_set_string(&mgi->mgi_bufs, 1, s1);
1068 lustre_cfg_bufs_set_string(&mgi->mgi_bufs, 2, s2);
1070 lustre_cfg_bufs_set_string(&mgi->mgi_bufs, 3, s3);
1072 lustre_cfg_bufs_set_string(&mgi->mgi_bufs, 4, s4);
1074 lcr = lustre_cfg_rec_new(cmd, &mgi->mgi_bufs);
1078 lcr->lcr_cfg.lcfg_nid = nid;
1079 rc = llog_write(env, llh, &lcr->lcr_hdr, LLOG_NEXT_IDX);
1081 lustre_cfg_rec_free(lcr);
1085 "failed to write lcfg %s %#x %s %s %s %s: rc = %d\n",
1086 cfgname, cmd, s1, s2, s3, s4, rc);
1090 static inline int record_add_uuid(const struct lu_env *env,
1091 struct llog_handle *llh,
1092 struct lnet_nid *nid, char *uuid)
1094 if (nid_is_nid4(nid))
1095 return record_base(env, llh, NULL, lnet_nid_to_nid4(nid),
1096 LCFG_ADD_UUID, uuid,
1101 static inline int record_add_conn(const struct lu_env *env,
1102 struct llog_handle *llh,
1103 char *devname, char *uuid)
1105 return record_base(env, llh, devname, 0, LCFG_ADD_CONN, uuid,
1109 static inline int record_attach(const struct lu_env *env,
1110 struct llog_handle *llh, char *devname,
1111 char *type, char *uuid)
1113 return record_base(env, llh, devname, 0, LCFG_ATTACH, type, uuid,
1117 static inline int record_setup(const struct lu_env *env,
1118 struct llog_handle *llh, char *devname,
1119 char *s1, char *s2, char *s3, char *s4)
1121 return record_base(env, llh, devname, 0, LCFG_SETUP, s1, s2, s3, s4);
1125 * \retval <0 record processing error
1126 * \retval n record is processed. No need copy original one.
1127 * \retval 0 record is not processed.
1129 static int process_command(const struct lu_env *env, struct lustre_cfg *lcfg,
1130 struct mgs_replace_data *mrd)
1137 if (mrd->state == REPLACE_UUID &&
1138 lcfg->lcfg_command == LCFG_ADD_UUID) {
1139 /* LCFG_ADD_UUID command found. Let's skip original command
1140 and add passed nids */
1141 ptr = mrd->target.mti_params;
1142 while (class_parse_nid4(ptr, &nid, &ptr) == 0) {
1143 struct lnet_nid lnid;
1145 if (!mrd->nodeuuid) {
1146 rc = name_create(&mrd->nodeuuid,
1147 libcfs_nid2str(nid), "");
1149 CERROR("Can't create uuid for "
1150 "nid %s, device %s\n",
1151 libcfs_nid2str(nid),
1152 mrd->target.mti_svname);
1156 CDEBUG(D_MGS, "add nid %s with uuid %s, "
1157 "device %s\n", libcfs_nid2str(nid),
1158 mrd->target.mti_params,
1160 lnet_nid4_to_nid(nid, &lnid);
1161 rc = record_add_uuid(env,
1162 mrd->temp_llh, &lnid,
1165 CWARN("%s: Can't add nid %s for uuid %s :rc=%d\n",
1166 mrd->target.mti_svname,
1167 libcfs_nid2str(nid),
1173 mrd->failover = ptr;
1178 if (nids_added == 0) {
1179 CERROR("No new nids were added, nid %s with uuid %s, "
1180 "device %s\n", libcfs_nid2str(nid),
1181 mrd->nodeuuid ? mrd->nodeuuid : "NULL",
1182 mrd->target.mti_svname);
1183 name_destroy(&mrd->nodeuuid);
1186 mrd->state = REPLACE_SETUP;
1192 if (mrd->state == REPLACE_SETUP && lcfg->lcfg_command == LCFG_SETUP) {
1193 /* LCFG_SETUP command found. UUID should be changed */
1194 rc = record_setup(env,
1196 /* devname the same */
1197 lustre_cfg_string(lcfg, 0),
1198 /* s1 is not changed */
1199 lustre_cfg_string(lcfg, 1),
1201 /* s3 is not changed */
1202 lustre_cfg_string(lcfg, 3),
1203 /* s4 is not changed */
1204 lustre_cfg_string(lcfg, 4));
1206 name_destroy(&mrd->nodeuuid);
1210 if (mrd->failover) {
1211 ptr = mrd->failover;
1212 while (class_parse_nid4(ptr, &nid, &ptr) == 0) {
1213 struct lnet_nid lnid;
1215 if (mrd->nodeuuid == NULL) {
1216 rc = name_create(&mrd->nodeuuid,
1217 libcfs_nid2str(nid),
1223 CDEBUG(D_MGS, "add nid %s for failover %s\n",
1224 libcfs_nid2str(nid), mrd->nodeuuid);
1225 lnet_nid4_to_nid(nid, &lnid);
1226 rc = record_add_uuid(env, mrd->temp_llh, &lnid,
1229 CWARN("%s: Can't add nid %s for failover %s :rc = %d\n",
1230 mrd->target.mti_svname,
1231 libcfs_nid2str(nid),
1233 name_destroy(&mrd->nodeuuid);
1237 rc = record_add_conn(env,
1239 lustre_cfg_string(lcfg, 0),
1241 name_destroy(&mrd->nodeuuid);
1246 if (mrd->nodeuuid) {
1247 rc = record_add_conn(env, mrd->temp_llh,
1248 lustre_cfg_string(lcfg, 0),
1250 name_destroy(&mrd->nodeuuid);
1255 mrd->state = REPLACE_DONE;
1259 /* All new UUID are added. Skip. */
1260 if (mrd->state == REPLACE_SETUP &&
1261 lcfg->lcfg_command == LCFG_ADD_UUID)
1264 /* Another commands in target device block */
1269 * Handler that called for every record in llog.
1270 * Records are processed in order they placed in llog.
1272 * \param[in] llh log to be processed
1273 * \param[in] rec current record
1274 * \param[in] data mgs_replace_data structure
1278 static int mgs_replace_nids_handler(const struct lu_env *env,
1279 struct llog_handle *llh,
1280 struct llog_rec_hdr *rec,
1283 struct mgs_replace_data *mrd;
1284 struct lustre_cfg *lcfg = REC_DATA(rec);
1285 int cfg_len = REC_DATA_LEN(rec);
1289 mrd = (struct mgs_replace_data *)data;
1291 if (rec->lrh_type != OBD_CFG_REC) {
1292 CERROR("unhandled lrh_type: %#x, cmd %x %s %s\n",
1293 rec->lrh_type, lcfg->lcfg_command,
1294 lustre_cfg_string(lcfg, 0),
1295 lustre_cfg_string(lcfg, 1));
1299 rc = lustre_cfg_sanity_check(lcfg, cfg_len);
1301 /* Do not copy any invalidated records */
1302 GOTO(skip_out, rc = 0);
1305 rc = check_markers(lcfg, mrd);
1306 if (rc || mrd->state == REPLACE_SKIP)
1307 GOTO(skip_out, rc = 0);
1309 /* Write to new log all commands outside target device block */
1310 if (mrd->state == REPLACE_COPY)
1311 GOTO(copy_out, rc = 0);
1313 if (mrd->state == REPLACE_DONE &&
1314 (lcfg->lcfg_command == LCFG_ADD_UUID ||
1315 lcfg->lcfg_command == LCFG_ADD_CONN)) {
1317 CWARN("Previous failover is deleted, but new one is "
1318 "not set. This means you configure system "
1319 "without failover or passed wrong replace_nids "
1320 "command parameters. Device %s, passed nids %s\n",
1321 mrd->target.mti_svname, mrd->target.mti_params);
1322 GOTO(skip_out, rc = 0);
1325 rc = process_command(env, lcfg, mrd);
1332 /* Record is placed in temporary llog as is */
1333 rc = llog_write(env, mrd->temp_llh, rec, LLOG_NEXT_IDX);
1335 CDEBUG(D_MGS, "Copied idx=%d, rc=%d, len=%d, cmd %x %s %s\n",
1336 rec->lrh_index, rc, rec->lrh_len, lcfg->lcfg_command,
1337 lustre_cfg_string(lcfg, 0), lustre_cfg_string(lcfg, 1));
1341 CDEBUG(D_MGS, "Skipped idx=%d, rc=%d, len=%d, cmd %x %s %s\n",
1342 rec->lrh_index, rc, rec->lrh_len, lcfg->lcfg_command,
1343 lustre_cfg_string(lcfg, 0), lustre_cfg_string(lcfg, 1));
1347 static int mgs_log_is_empty(const struct lu_env *env,
1348 struct mgs_device *mgs, char *name)
1350 struct llog_ctxt *ctxt;
1353 ctxt = llog_get_context(mgs->mgs_obd, LLOG_CONFIG_ORIG_CTXT);
1354 LASSERT(ctxt != NULL);
1356 rc = llog_is_empty(env, ctxt, name);
1357 llog_ctxt_put(ctxt);
1361 static int mgs_replace_log(const struct lu_env *env,
1362 struct obd_device *mgs,
1363 char *logname, char *devname,
1364 llog_cb_t replace_handler, void *data)
1366 struct llog_handle *orig_llh, *backup_llh;
1367 struct llog_ctxt *ctxt;
1368 struct mgs_replace_data *mrd;
1369 struct mgs_device *mgs_dev = lu2mgs_dev(mgs->obd_lu_dev);
1370 static struct obd_uuid cfg_uuid = { .uuid = "config_uuid" };
1372 int rc, rc2, buf_size;
1376 ctxt = llog_get_context(mgs, LLOG_CONFIG_ORIG_CTXT);
1377 LASSERT(ctxt != NULL);
1379 if (mgs_log_is_empty(env, mgs_dev, logname)) {
1380 /* Log is empty. Nothing to replace */
1381 GOTO(out_put, rc = 0);
1384 now = ktime_get_real_seconds();
1386 /* max time64_t in decimal fits into 20 bytes long string */
1387 buf_size = strlen(logname) + 1 + 20 + 1 + strlen(".bak") + 1;
1388 OBD_ALLOC(backup, buf_size);
1390 GOTO(out_put, rc = -ENOMEM);
1392 snprintf(backup, buf_size, "%s.%llu.bak", logname, now);
1394 rc = llog_backup(env, mgs, ctxt, ctxt, logname, backup);
1396 /* Now erase original log file. Connections are not allowed.
1397 Backup is already saved */
1398 rc = llog_erase(env, ctxt, NULL, logname);
1401 } else if (rc != -ENOENT) {
1402 CERROR("%s: can't make backup for %s: rc = %d\n",
1403 mgs->obd_name, logname, rc);
1407 /* open local log */
1408 rc = llog_open_create(env, ctxt, &orig_llh, NULL, logname);
1410 GOTO(out_restore, rc);
1412 rc = llog_init_handle(env, orig_llh, LLOG_F_IS_PLAIN, &cfg_uuid);
1414 GOTO(out_closel, rc);
1416 /* open backup llog */
1417 rc = llog_open(env, ctxt, &backup_llh, NULL, backup,
1420 GOTO(out_closel, rc);
1422 rc = llog_init_handle(env, backup_llh, LLOG_F_IS_PLAIN, NULL);
1424 GOTO(out_close, rc);
1426 if (llog_get_size(backup_llh) <= 1)
1427 GOTO(out_close, rc = 0);
1431 GOTO(out_close, rc = -ENOMEM);
1432 /* devname is only needed information to replace UUID records */
1434 strlcpy(mrd->target.mti_svname, devname,
1435 sizeof(mrd->target.mti_svname));
1436 /* data is parsed in llog callback */
1438 strlcpy(mrd->target.mti_params, data,
1439 sizeof(mrd->target.mti_params));
1440 /* Copy records to this temporary llog */
1441 mrd->temp_llh = orig_llh;
1443 rc = llog_process(env, backup_llh, replace_handler,
1447 rc2 = llog_close(NULL, backup_llh);
1451 rc2 = llog_close(NULL, orig_llh);
1457 CERROR("%s: llog should be restored: rc = %d\n",
1459 rc2 = llog_backup(env, mgs, ctxt, ctxt, backup,
1462 CERROR("%s: can't restore backup %s: rc = %d\n",
1463 mgs->obd_name, logname, rc2);
1467 OBD_FREE(backup, buf_size);
1470 llog_ctxt_put(ctxt);
1473 CERROR("%s: failed to replace log %s: rc = %d\n",
1474 mgs->obd_name, logname, rc);
1479 static int mgs_replace_nids_log(const struct lu_env *env,
1480 struct obd_device *obd,
1481 char *logname, char *devname, char *nids)
1483 CDEBUG(D_MGS, "Replace NIDs for %s in %s\n", devname, logname);
1484 return mgs_replace_log(env, obd, logname, devname,
1485 mgs_replace_nids_handler, nids);
1489 * Parse device name and get file system name and/or device index
1491 * @devname device name (ex. lustre-MDT0000)
1492 * @fsname file system name extracted from @devname and returned
1493 * to the caller (optional)
1494 * @index device index extracted from @devname and returned to
1495 * the caller (optional)
1497 * RETURN 0 success if we are only interested in
1498 * extracting fsname from devname.
1501 * LDD_F_SV_TYPE_* Besides extracting the fsname the
1502 * user also wants the index. Report to
1503 * the user the type of obd device the
1504 * returned index belongs too.
1506 * -EINVAL The obd device name is improper so
1507 * fsname could not be extracted.
1509 * -ENXIO Failed to extract the index out of
1510 * the obd device name. Most likely an
1511 * invalid obd device name
1513 static int mgs_parse_devname(char *devname, char *fsname, u32 *index)
1518 /* Extract fsname */
1520 rc = server_name2fsname(devname, fsname, NULL);
1522 CDEBUG(D_MGS, "Device name %s without fsname\n",
1529 rc = server_name2index(devname, index, NULL);
1531 CDEBUG(D_MGS, "Device name %s with wrong index\n",
1537 /* server_name2index can return LDD_F_SV_TYPE_* so always return rc */
1541 /* This is only called during replace_nids */
1542 static int only_mgs_is_running(struct obd_device *mgs_obd)
1544 /* TDB: Is global variable with devices count exists? */
1545 int num_devices = get_devices_count();
1546 int num_exports = 0;
1547 struct obd_export *exp;
1549 spin_lock(&mgs_obd->obd_dev_lock);
1550 list_for_each_entry(exp, &mgs_obd->obd_exports, exp_obd_chain) {
1551 /* skip self export */
1552 if (exp == mgs_obd->obd_self_export)
1557 if (num_exports > 1)
1558 CERROR("%s: node %s still connected during replace_nids connect_flags:%llx\n",
1560 libcfs_nidstr(&exp->exp_nid_stats->nid),
1561 exp_connect_flags(exp));
1563 spin_unlock(&mgs_obd->obd_dev_lock);
1565 /* osd, MGS and MGC + MGC export (nosvc starts MGC)
1566 * (wc -l /proc/fs/lustre/devices <= 3) && (non self exports == 1)
1568 return (num_devices <= 3) && (num_exports <= 1);
1571 static int name_create_mdt(char **logname, char *fsname, int mdt_idx)
1575 if (mdt_idx > INDEX_MAP_MAX_VALUE)
1578 snprintf(postfix, sizeof(postfix), "-MDT%04x", mdt_idx);
1579 return name_create(logname, fsname, postfix);
1583 * Replace nids for \a device to \a nids values
1585 * \param obd MGS obd device
1586 * \param devname nids need to be replaced for this device
1587 * (ex. lustre-OST0000)
1588 * \param nids nids list (ex. nid1,nid2,nid3)
1592 int mgs_replace_nids(const struct lu_env *env,
1593 struct mgs_device *mgs,
1594 char *devname, char *nids)
1596 /* Assume fsname is part of device name */
1597 char fsname[MTI_NAME_MAXLEN];
1601 struct fs_db *fsdb = NULL;
1604 struct obd_device *mgs_obd = mgs->mgs_obd;
1607 /* We can only change NIDs if no other nodes are connected */
1608 spin_lock(&mgs_obd->obd_dev_lock);
1609 conn_state = mgs_obd->obd_no_conn;
1610 mgs_obd->obd_no_conn = 1;
1611 spin_unlock(&mgs_obd->obd_dev_lock);
1613 /* We can not change nids if not only MGS is started */
1614 if (!only_mgs_is_running(mgs_obd)) {
1615 CERROR("Only MGS is allowed to be started\n");
1616 GOTO(out, rc = -EINPROGRESS);
1619 /* Get fsname and index */
1620 rc = mgs_parse_devname(devname, fsname, &index);
1624 rc = mgs_find_or_make_fsdb(env, mgs, fsname, &fsdb);
1626 CERROR("%s: can't find fsdb: rc = %d\n", fsname, rc);
1630 /* Process client llogs */
1631 rc = name_create(&logname, fsname, "-client");
1634 rc = mgs_replace_nids_log(env, mgs_obd, logname, devname, nids);
1635 name_destroy(&logname);
1637 CERROR("%s: error while replacing NIDs for %s: rc = %d\n",
1638 fsname, devname, rc);
1642 /* Process MDT llogs */
1643 for (i = 0; i < INDEX_MAP_SIZE * 8; i++) {
1644 if (!test_bit(i, fsdb->fsdb_mdt_index_map))
1646 rc = name_create_mdt(&logname, fsname, i);
1649 rc = mgs_replace_nids_log(env, mgs_obd, logname, devname, nids);
1650 name_destroy(&logname);
1656 spin_lock(&mgs_obd->obd_dev_lock);
1657 mgs_obd->obd_no_conn = conn_state;
1658 spin_unlock(&mgs_obd->obd_dev_lock);
1661 mgs_put_fsdb(mgs, fsdb);
1667 * This is called for every record in llog. Some of records are
1668 * skipped, others are copied to new log as is.
1669 * Records to be skipped are
1670 * marker records marked SKIP
1671 * records enclosed between SKIP markers
1673 * \param[in] llh log to be processed
1674 * \param[in] rec current record
1675 * \param[in] data mgs_replace_data structure
1679 static int mgs_clear_config_handler(const struct lu_env *env,
1680 struct llog_handle *llh,
1681 struct llog_rec_hdr *rec, void *data)
1683 struct mgs_replace_data *mrd;
1684 struct lustre_cfg *lcfg = REC_DATA(rec);
1685 int cfg_len = REC_DATA_LEN(rec);
1690 mrd = (struct mgs_replace_data *)data;
1692 if (rec->lrh_type != OBD_CFG_REC) {
1693 CDEBUG(D_MGS, "Config llog Name=%s, Record Index=%u, "
1694 "Unhandled Record Type=%#x\n", llh->lgh_name,
1695 rec->lrh_index, rec->lrh_type);
1699 rc = lustre_cfg_sanity_check(lcfg, cfg_len);
1701 CDEBUG(D_MGS, "Config llog Name=%s, Invalid config file.",
1706 if (lcfg->lcfg_command == LCFG_MARKER) {
1707 struct cfg_marker *marker;
1709 marker = lustre_cfg_buf(lcfg, 1);
1710 if (marker->cm_flags & CM_SKIP) {
1711 if (marker->cm_flags & CM_START)
1712 mrd->state = REPLACE_SKIP;
1713 if (marker->cm_flags & CM_END)
1714 mrd->state = REPLACE_COPY;
1715 /* SKIP section started or finished */
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));
1724 if (mrd->state == REPLACE_SKIP) {
1725 /* record enclosed between SKIP markers, skip it */
1726 CDEBUG(D_MGS, "Skip idx=%d, rc=%d, len=%d, "
1727 "cmd %x %s %s\n", rec->lrh_index, rc,
1728 rec->lrh_len, lcfg->lcfg_command,
1729 lustre_cfg_string(lcfg, 0),
1730 lustre_cfg_string(lcfg, 1));
1735 /* Record is placed in temporary llog as is */
1736 rc = llog_write(env, mrd->temp_llh, rec, LLOG_NEXT_IDX);
1738 CDEBUG(D_MGS, "Copied idx=%d, rc=%d, len=%d, cmd %x %s %s\n",
1739 rec->lrh_index, rc, rec->lrh_len, lcfg->lcfg_command,
1740 lustre_cfg_string(lcfg, 0), lustre_cfg_string(lcfg, 1));
1745 * Directory CONFIGS/ may contain files which are not config logs to
1746 * be cleared. Skip any llogs with a non-alphanumeric character after
1747 * the last '-'. For example, fsname-MDT0000.sav, fsname-MDT0000.bak,
1748 * fsname-MDT0000.orig, fsname-MDT0000~, fsname-MDT0000.20150516, etc.
1750 static bool config_to_clear(const char *logname)
1755 str = strrchr(logname, '-');
1760 while (isalnum(str[++i]));
1761 return str[i] == '\0';
1765 * Clear config logs for \a name
1768 * \param mgs MGS device
1769 * \param name name of device or of filesystem
1770 * (ex. lustre-OST0000 or lustre) in later case all logs
1775 int mgs_clear_configs(const struct lu_env *env,
1776 struct mgs_device *mgs, const char *name)
1778 struct list_head dentry_list;
1779 struct mgs_direntry *dirent, *n;
1782 struct obd_device *mgs_obd = mgs->mgs_obd;
1787 /* Prevent clients and servers from connecting to mgs */
1788 spin_lock(&mgs_obd->obd_dev_lock);
1789 conn_state = mgs_obd->obd_no_conn;
1790 mgs_obd->obd_no_conn = 1;
1791 spin_unlock(&mgs_obd->obd_dev_lock);
1794 * config logs cannot be cleaned if anything other than
1797 if (!only_mgs_is_running(mgs_obd)) {
1798 CERROR("Only MGS is allowed to be started\n");
1799 GOTO(out, rc = -EBUSY);
1802 /* Find all the logs in the CONFIGS directory */
1803 rc = class_dentry_readdir(env, mgs, &dentry_list);
1805 CERROR("%s: cannot read config directory '%s': rc = %d\n",
1806 mgs_obd->obd_name, MOUNT_CONFIGS_DIR, rc);
1810 if (list_empty(&dentry_list)) {
1811 CERROR("%s: list empty reading config dir '%s': rc = %d\n",
1812 mgs_obd->obd_name, MOUNT_CONFIGS_DIR, -ENOENT);
1813 GOTO(out, rc = -ENOENT);
1816 OBD_ALLOC(namedash, strlen(name) + 2);
1817 if (namedash == NULL)
1818 GOTO(out, rc = -ENOMEM);
1819 snprintf(namedash, strlen(name) + 2, "%s-", name);
1821 list_for_each_entry(dirent, &dentry_list, mde_list) {
1822 if (strcmp(name, dirent->mde_name) &&
1823 strncmp(namedash, dirent->mde_name, strlen(namedash)))
1825 if (!config_to_clear(dirent->mde_name))
1827 CDEBUG(D_MGS, "%s: Clear config log %s\n",
1828 mgs_obd->obd_name, dirent->mde_name);
1829 rc = mgs_replace_log(env, mgs_obd, dirent->mde_name, NULL,
1830 mgs_clear_config_handler, NULL);
1835 list_for_each_entry_safe(dirent, n, &dentry_list, mde_list) {
1836 list_del_init(&dirent->mde_list);
1837 mgs_direntry_free(dirent);
1839 OBD_FREE(namedash, strlen(name) + 2);
1841 spin_lock(&mgs_obd->obd_dev_lock);
1842 mgs_obd->obd_no_conn = conn_state;
1843 spin_unlock(&mgs_obd->obd_dev_lock);
1848 static int record_lov_setup(const struct lu_env *env, struct llog_handle *llh,
1849 char *devname, struct lov_desc *desc)
1851 struct mgs_thread_info *mgi = mgs_env_info(env);
1852 struct llog_cfg_rec *lcr;
1855 lustre_cfg_bufs_reset(&mgi->mgi_bufs, devname);
1856 lustre_cfg_bufs_set(&mgi->mgi_bufs, 1, desc, sizeof(*desc));
1857 lcr = lustre_cfg_rec_new(LCFG_SETUP, &mgi->mgi_bufs);
1861 rc = llog_write(env, llh, &lcr->lcr_hdr, LLOG_NEXT_IDX);
1862 lustre_cfg_rec_free(lcr);
1866 static int record_lmv_setup(const struct lu_env *env, struct llog_handle *llh,
1867 char *devname, struct lmv_desc *desc)
1869 struct mgs_thread_info *mgi = mgs_env_info(env);
1870 struct llog_cfg_rec *lcr;
1873 lustre_cfg_bufs_reset(&mgi->mgi_bufs, devname);
1874 lustre_cfg_bufs_set(&mgi->mgi_bufs, 1, desc, sizeof(*desc));
1875 lcr = lustre_cfg_rec_new(LCFG_SETUP, &mgi->mgi_bufs);
1879 rc = llog_write(env, llh, &lcr->lcr_hdr, LLOG_NEXT_IDX);
1880 lustre_cfg_rec_free(lcr);
1884 static inline int record_mdc_add(const struct lu_env *env,
1885 struct llog_handle *llh,
1886 char *logname, char *mdcuuid,
1887 char *mdtuuid, char *index,
1890 return record_base(env,llh,logname,0,LCFG_ADD_MDC,
1891 mdtuuid, index, gen, mdcuuid);
1894 static inline int record_lov_add(const struct lu_env *env,
1895 struct llog_handle *llh,
1896 char *lov_name, char *ost_uuid,
1897 char *index, char *gen)
1899 return record_base(env, llh, lov_name, 0, LCFG_LOV_ADD_OBD,
1900 ost_uuid, index, gen, NULL);
1903 static inline int record_mount_opt(const struct lu_env *env,
1904 struct llog_handle *llh,
1905 char *profile, char *lov_name,
1908 return record_base(env, llh, NULL, 0, LCFG_MOUNTOPT,
1909 profile, lov_name, mdc_name, NULL);
1912 static int record_marker(const struct lu_env *env,
1913 struct llog_handle *llh,
1914 struct fs_db *fsdb, __u32 flags,
1915 char *tgtname, char *comment)
1917 struct mgs_thread_info *mgi = mgs_env_info(env);
1918 struct llog_cfg_rec *lcr;
1922 if (flags & CM_START)
1924 mgi->mgi_marker.cm_step = fsdb->fsdb_gen;
1925 mgi->mgi_marker.cm_flags = flags;
1926 mgi->mgi_marker.cm_vers = LUSTRE_VERSION_CODE;
1927 cplen = strlcpy(mgi->mgi_marker.cm_tgtname, tgtname,
1928 sizeof(mgi->mgi_marker.cm_tgtname));
1929 if (cplen >= sizeof(mgi->mgi_marker.cm_tgtname))
1931 cplen = strlcpy(mgi->mgi_marker.cm_comment, comment,
1932 sizeof(mgi->mgi_marker.cm_comment));
1933 if (cplen >= sizeof(mgi->mgi_marker.cm_comment))
1935 mgi->mgi_marker.cm_createtime = ktime_get_real_seconds();
1936 mgi->mgi_marker.cm_canceltime = 0;
1937 lustre_cfg_bufs_reset(&mgi->mgi_bufs, NULL);
1938 lustre_cfg_bufs_set(&mgi->mgi_bufs, 1, &mgi->mgi_marker,
1939 sizeof(mgi->mgi_marker));
1940 lcr = lustre_cfg_rec_new(LCFG_MARKER, &mgi->mgi_bufs);
1944 rc = llog_write(env, llh, &lcr->lcr_hdr, LLOG_NEXT_IDX);
1945 lustre_cfg_rec_free(lcr);
1949 static int record_start_log(const struct lu_env *env, struct mgs_device *mgs,
1950 struct llog_handle **llh, char *name)
1952 static struct obd_uuid cfg_uuid = { .uuid = "config_uuid" };
1953 struct llog_ctxt *ctxt;
1958 GOTO(out, rc = -EBUSY);
1960 ctxt = llog_get_context(mgs->mgs_obd, LLOG_CONFIG_ORIG_CTXT);
1962 GOTO(out, rc = -ENODEV);
1963 LASSERT(ctxt->loc_obd == mgs->mgs_obd);
1965 rc = llog_open_create(env, ctxt, llh, NULL, name);
1968 rc = llog_init_handle(env, *llh, LLOG_F_IS_PLAIN, &cfg_uuid);
1970 llog_close(env, *llh);
1972 llog_ctxt_put(ctxt);
1975 CERROR("%s: can't start log %s: rc = %d\n",
1976 mgs->mgs_obd->obd_name, name, rc);
1982 static int record_end_log(const struct lu_env *env, struct llog_handle **llh)
1986 rc = llog_close(env, *llh);
1992 /******************** config "macros" *********************/
1994 /* write an lcfg directly into a log (with markers) */
1995 static int mgs_write_log_direct(const struct lu_env *env,
1996 struct mgs_device *mgs, struct fs_db *fsdb,
1997 char *logname, struct llog_cfg_rec *lcr,
1998 char *devname, char *comment)
2000 struct llog_handle *llh = NULL;
2005 rc = record_start_log(env, mgs, &llh, logname);
2009 /* FIXME These should be a single journal transaction */
2010 rc = record_marker(env, llh, fsdb, CM_START, devname, comment);
2013 rc = llog_write(env, llh, &lcr->lcr_hdr, LLOG_NEXT_IDX);
2016 rc = record_marker(env, llh, fsdb, CM_END, devname, comment);
2020 record_end_log(env, &llh);
2024 /* write the lcfg in all logs for the given fs */
2025 static int mgs_write_log_direct_all(const struct lu_env *env,
2026 struct mgs_device *mgs,
2028 struct mgs_target_info *mti,
2029 struct llog_cfg_rec *lcr, char *devname,
2030 char *comment, int server_only)
2032 struct list_head log_list;
2033 struct mgs_direntry *dirent, *n;
2034 char *fsname = mti->mti_fsname;
2035 int rc = 0, len = strlen(fsname);
2038 /* Find all the logs in the CONFIGS directory */
2039 rc = class_dentry_readdir(env, mgs, &log_list);
2043 /* Could use fsdb index maps instead of directory listing */
2044 list_for_each_entry_safe(dirent, n, &log_list, mde_list) {
2045 list_del_init(&dirent->mde_list);
2046 /* don't write to sptlrpc rule log */
2047 if (strstr(dirent->mde_name, "-sptlrpc") != NULL)
2050 /* caller wants write server logs only */
2051 if (server_only && strstr(dirent->mde_name, "-client") != NULL)
2054 if (strlen(dirent->mde_name) <= len ||
2055 strncmp(fsname, dirent->mde_name, len) != 0 ||
2056 dirent->mde_name[len] != '-')
2059 CDEBUG(D_MGS, "Changing log %s\n", dirent->mde_name);
2060 /* Erase any old settings of this same parameter */
2061 rc = mgs_modify(env, mgs, fsdb, mti, dirent->mde_name,
2062 devname, comment, CM_SKIP);
2064 CERROR("%s: Can't modify llog %s: rc = %d\n",
2065 mgs->mgs_obd->obd_name, dirent->mde_name, rc);
2068 /* Write the new one */
2069 rc = mgs_write_log_direct(env, mgs, fsdb, dirent->mde_name,
2070 lcr, devname, comment);
2072 CERROR("%s: writing log %s: rc = %d\n",
2073 mgs->mgs_obd->obd_name, dirent->mde_name, rc);
2075 mgs_direntry_free(dirent);
2081 static int mgs_write_log_osp_to_mdt(const struct lu_env *env,
2082 struct mgs_device *mgs,
2084 struct mgs_target_info *mti,
2085 int index, char *logname);
2086 static int mgs_write_log_osc_to_lov(const struct lu_env *env,
2087 struct mgs_device *mgs,
2089 struct mgs_target_info *mti,
2090 char *logname, char *suffix, char *lovname,
2091 enum lustre_sec_part sec_part, int flags);
2092 static int name_create_mdt_and_lov(char **logname, char **lovname,
2093 struct fs_db *fsdb, int i);
2095 static int add_param(char *params, char *key, char *val)
2097 char *start = params + strlen(params);
2098 char *end = params + sizeof(((struct mgs_target_info *)0)->mti_params);
2102 keylen = strlen(key);
2103 if (start + 1 + keylen + strlen(val) >= end) {
2104 CERROR("params are too long: %s %s%s\n",
2105 params, key != NULL ? key : "", val);
2109 sprintf(start, " %s%s", key != NULL ? key : "", val);
2114 * Walk through client config log record and convert the related records
2117 static int mgs_steal_client_llog_handler(const struct lu_env *env,
2118 struct llog_handle *llh,
2119 struct llog_rec_hdr *rec, void *data)
2121 struct mgs_device *mgs;
2122 struct obd_device *obd;
2123 struct mgs_target_info *mti, *tmti;
2125 int cfg_len = rec->lrh_len;
2126 char *cfg_buf = (char *)(rec + 1);
2127 struct lustre_cfg *lcfg;
2129 struct llog_handle *mdt_llh = NULL;
2130 static int got_an_osc_or_mdc = 0;
2131 /* 0: not found any osc/mdc;
2135 static int last_step = -1;
2140 mti = ((struct temp_comp *)data)->comp_mti;
2141 tmti = ((struct temp_comp *)data)->comp_tmti;
2142 fsdb = ((struct temp_comp *)data)->comp_fsdb;
2143 obd = ((struct temp_comp *)data)->comp_obd;
2144 mgs = lu2mgs_dev(obd->obd_lu_dev);
2147 if (rec->lrh_type != OBD_CFG_REC) {
2148 CERROR("unhandled lrh_type: %#x\n", rec->lrh_type);
2152 rc = lustre_cfg_sanity_check(cfg_buf, cfg_len);
2154 CERROR("Insane cfg\n");
2158 lcfg = (struct lustre_cfg *)cfg_buf;
2160 if (lcfg->lcfg_command == LCFG_MARKER) {
2161 struct cfg_marker *marker;
2162 marker = lustre_cfg_buf(lcfg, 1);
2163 if (!strncmp(marker->cm_comment, "add osc", 7) &&
2164 (marker->cm_flags & CM_START) &&
2165 !(marker->cm_flags & CM_SKIP)) {
2166 got_an_osc_or_mdc = 1;
2167 cplen = strlcpy(tmti->mti_svname, marker->cm_tgtname,
2168 sizeof(tmti->mti_svname));
2169 if (cplen >= sizeof(tmti->mti_svname))
2171 rc = record_start_log(env, mgs, &mdt_llh,
2175 rc = record_marker(env, mdt_llh, fsdb, CM_START,
2176 mti->mti_svname, "add osc(copied)");
2177 record_end_log(env, &mdt_llh);
2178 last_step = marker->cm_step;
2181 if (!strncmp(marker->cm_comment, "add osc", 7) &&
2182 (marker->cm_flags & CM_END) &&
2183 !(marker->cm_flags & CM_SKIP)) {
2184 LASSERT(last_step == marker->cm_step);
2186 got_an_osc_or_mdc = 0;
2187 memset(tmti, 0, sizeof(*tmti));
2188 rc = record_start_log(env, mgs, &mdt_llh,
2192 rc = record_marker(env, mdt_llh, fsdb, CM_END,
2193 mti->mti_svname, "add osc(copied)");
2194 record_end_log(env, &mdt_llh);
2197 if (!strncmp(marker->cm_comment, "add mdc", 7) &&
2198 (marker->cm_flags & CM_START) &&
2199 !(marker->cm_flags & CM_SKIP)) {
2200 got_an_osc_or_mdc = 2;
2201 last_step = marker->cm_step;
2202 memcpy(tmti->mti_svname, marker->cm_tgtname,
2203 strlen(marker->cm_tgtname));
2207 if (!strncmp(marker->cm_comment, "add mdc", 7) &&
2208 (marker->cm_flags & CM_END) &&
2209 !(marker->cm_flags & CM_SKIP)) {
2210 LASSERT(last_step == marker->cm_step);
2212 got_an_osc_or_mdc = 0;
2213 memset(tmti, 0, sizeof(*tmti));
2218 if (got_an_osc_or_mdc == 0 || last_step < 0)
2221 if (lcfg->lcfg_command == LCFG_ADD_UUID) {
2222 __u64 nodenid = lcfg->lcfg_nid;
2224 if (strlen(tmti->mti_uuid) == 0) {
2225 /* target uuid not set, this config record is before
2226 * LCFG_SETUP, this nid is one of target node nid.
2228 tmti->mti_nids[tmti->mti_nid_count] = nodenid;
2229 tmti->mti_nid_count++;
2231 char nidstr[LNET_NIDSTR_SIZE];
2233 /* failover node nid */
2234 libcfs_nid2str_r(nodenid, nidstr, sizeof(nidstr));
2235 rc = add_param(tmti->mti_params, PARAM_FAILNODE,
2242 if (lcfg->lcfg_command == LCFG_SETUP) {
2245 target = lustre_cfg_string(lcfg, 1);
2246 memcpy(tmti->mti_uuid, target, strlen(target));
2250 /* ignore client side sptlrpc_conf_log */
2251 if (lcfg->lcfg_command == LCFG_SPTLRPC_CONF)
2254 if (lcfg->lcfg_command == LCFG_ADD_MDC &&
2255 strstr(lustre_cfg_string(lcfg, 0), "-clilmv") != NULL) {
2258 if (sscanf(lustre_cfg_buf(lcfg, 2), "%d", &index) != 1)
2260 if (index == mti->mti_stripe_index) {
2262 "attempt to create MDT%04x->MDT%04x osp device\n",
2266 memcpy(tmti->mti_fsname, mti->mti_fsname,
2267 strlen(mti->mti_fsname));
2268 tmti->mti_stripe_index = index;
2270 rc = mgs_write_log_osp_to_mdt(env, mgs, fsdb, tmti,
2271 mti->mti_stripe_index,
2273 memset(tmti, 0, sizeof(*tmti));
2277 if (lcfg->lcfg_command == LCFG_LOV_ADD_OBD) {
2280 char *logname, *lovname;
2282 rc = name_create_mdt_and_lov(&logname, &lovname, fsdb,
2283 mti->mti_stripe_index);
2286 sprintf(mdt_index, "-MDT%04x", mti->mti_stripe_index);
2288 if (sscanf(lustre_cfg_buf(lcfg, 2), "%d", &index) != 1) {
2289 name_destroy(&logname);
2290 name_destroy(&lovname);
2294 tmti->mti_stripe_index = index;
2295 rc = mgs_write_log_osc_to_lov(env, mgs, fsdb, tmti, logname,
2298 name_destroy(&logname);
2299 name_destroy(&lovname);
2305 /* fsdb->fsdb_mutex is already held in mgs_write_log_target*/
2306 /* stealed from mgs_get_fsdb_from_llog*/
2307 static int mgs_steal_llog_for_mdt_from_client(const struct lu_env *env,
2308 struct mgs_device *mgs,
2310 struct temp_comp *comp)
2312 struct llog_handle *loghandle;
2313 struct mgs_target_info *tmti;
2314 struct llog_ctxt *ctxt;
2319 ctxt = llog_get_context(mgs->mgs_obd, LLOG_CONFIG_ORIG_CTXT);
2320 LASSERT(ctxt != NULL);
2322 OBD_ALLOC_PTR(tmti);
2324 GOTO(out_ctxt, rc = -ENOMEM);
2326 comp->comp_tmti = tmti;
2327 comp->comp_obd = mgs->mgs_obd;
2329 rc = llog_open(env, ctxt, &loghandle, NULL, client_name,
2337 rc = llog_init_handle(env, loghandle, LLOG_F_IS_PLAIN, NULL);
2339 GOTO(out_close, rc);
2341 rc = llog_process_or_fork(env, loghandle, mgs_steal_client_llog_handler,
2342 (void *)comp, NULL, false);
2343 CDEBUG(D_MGS, "steal llog re = %d\n", rc);
2345 llog_close(env, loghandle);
2349 llog_ctxt_put(ctxt);
2353 /* mount opt is the third thing in client logs */
2354 static int mgs_write_log_mount_opt(const struct lu_env *env,
2355 struct mgs_device *mgs, struct fs_db *fsdb,
2358 struct llog_handle *llh = NULL;
2363 CDEBUG(D_MGS, "Writing mount options log for %s\n", logname);
2365 rc = record_start_log(env, mgs, &llh, logname);
2369 rc = record_marker(env, llh, fsdb, CM_START, logname, "mount opts");
2372 rc = record_mount_opt(env, llh, logname, fsdb->fsdb_clilov,
2376 rc = record_marker(env, llh, fsdb, CM_END, logname, "mount opts");
2380 record_end_log(env, &llh);
2384 /* lmv is the second thing for client logs */
2385 /* copied from mgs_write_log_lov. Please refer to that. */
2386 static int mgs_write_log_lmv(const struct lu_env *env,
2387 struct mgs_device *mgs,
2389 struct mgs_target_info *mti,
2390 char *logname, char *lmvname)
2392 struct llog_handle *llh = NULL;
2393 struct lmv_desc *lmvdesc;
2398 CDEBUG(D_MGS, "Writing lmv(%s) log for %s\n", lmvname, logname);
2400 OBD_ALLOC_PTR(lmvdesc);
2401 if (lmvdesc == NULL)
2403 lmvdesc->ld_active_tgt_count = 0;
2404 lmvdesc->ld_tgt_count = 0;
2405 sprintf((char *)lmvdesc->ld_uuid.uuid, "%s_UUID", lmvname);
2406 uuid = (char *)lmvdesc->ld_uuid.uuid;
2408 rc = record_start_log(env, mgs, &llh, logname);
2411 rc = record_marker(env, llh, fsdb, CM_START, lmvname, "lmv setup");
2414 rc = record_attach(env, llh, lmvname, "lmv", uuid);
2417 rc = record_lmv_setup(env, llh, lmvname, lmvdesc);
2420 rc = record_marker(env, llh, fsdb, CM_END, lmvname, "lmv setup");
2424 record_end_log(env, &llh);
2426 OBD_FREE_PTR(lmvdesc);
2430 /* lov is the first thing in the mdt and client logs */
2431 static int mgs_write_log_lov(const struct lu_env *env, struct mgs_device *mgs,
2432 struct fs_db *fsdb, struct mgs_target_info *mti,
2433 char *logname, char *lovname)
2435 struct llog_handle *llh = NULL;
2436 struct lov_desc *lovdesc;
2441 CDEBUG(D_MGS, "Writing lov(%s) log for %s\n", lovname, logname);
2444 * #01 L attach 0:lov_mdsA 1:lov 2:71ccb_lov_mdsA_19f961a9e1
2445 * #02 L lov_setup 0:lov_mdsA 1:(struct lov_desc)
2446 * uuid=lov1_UUID, stripe count=1, size=1048576, offset=0, pattern=0
2449 /* FIXME just make lov_setup accept empty desc (put uuid in buf 2) */
2450 OBD_ALLOC_PTR(lovdesc);
2451 if (lovdesc == NULL)
2453 lovdesc->ld_magic = LOV_DESC_MAGIC;
2454 lovdesc->ld_tgt_count = 0;
2455 /* Defaults. Can be changed later by lcfg config_param */
2456 lovdesc->ld_default_stripe_count = 1;
2457 lovdesc->ld_pattern = LOV_PATTERN_RAID0;
2458 lovdesc->ld_default_stripe_size = LOV_DESC_STRIPE_SIZE_DEFAULT;
2459 lovdesc->ld_default_stripe_offset = -1;
2460 lovdesc->ld_qos_maxage = LOV_DESC_QOS_MAXAGE_DEFAULT;
2461 sprintf((char *)lovdesc->ld_uuid.uuid, "%s_UUID", lovname);
2462 /* can these be the same? */
2463 uuid = (char *)lovdesc->ld_uuid.uuid;
2465 /* This should always be the first entry in a log.
2466 * rc = mgs_clear_log(obd, logname);
2468 rc = record_start_log(env, mgs, &llh, logname);
2471 /* FIXME these should be a single journal transaction */
2472 rc = record_marker(env, llh, fsdb, CM_START, lovname, "lov setup");
2475 rc = record_attach(env, llh, lovname, "lov", uuid);
2478 rc = record_lov_setup(env, llh, lovname, lovdesc);
2481 rc = record_marker(env, llh, fsdb, CM_END, lovname, "lov setup");
2486 record_end_log(env, &llh);
2488 OBD_FREE_PTR(lovdesc);
2492 /* add failnids to open log */
2493 static int mgs_write_log_failnids(const struct lu_env *env,
2494 struct mgs_target_info *mti,
2495 struct llog_handle *llh,
2498 char *failnodeuuid = NULL;
2499 char *ptr = mti->mti_params;
2504 * #03 L add_uuid nid=uml1@tcp(0x20000c0a80201) nal=90 0: 1:uml1_UUID
2505 * #04 L add_uuid nid=1@elan(0x1000000000001) nal=90 0: 1:uml1_UUID
2506 * #05 L setup 0:OSC_uml1_ost1_mdsA 1:ost1_UUID 2:uml1_UUID
2507 * #06 L add_uuid nid=uml2@tcp(0x20000c0a80202) nal=90 0: 1:uml2_UUID
2508 * #0x L add_uuid nid=2@elan(0x1000000000002) nal=90 0: 1:uml2_UUID
2509 * #07 L add_conn 0:OSC_uml1_ost1_mdsA 1:uml2_UUID
2513 * Pull failnid info out of params string, which may contain something
2514 * like "<nid1>,<nid2>:<nid3>,<nid4>". class_parse_nid4() does not
2515 * complain about abnormal inputs like ",:<nid1>", "<nid1>:,<nid2>",
2516 * etc. However, convert_hostnames() should have caught those.
2518 while (class_find_param(ptr, PARAM_FAILNODE, &ptr) == 0) {
2519 while (class_parse_nid4(ptr, &nid, &ptr) == 0) {
2520 char nidstr[LNET_NIDSTR_SIZE];
2521 struct lnet_nid lnid;
2523 if (failnodeuuid == NULL) {
2524 /* We don't know the failover node name,
2525 * so just use the first nid as the uuid */
2526 libcfs_nid2str_r(nid, nidstr, sizeof(nidstr));
2527 rc = name_create(&failnodeuuid, nidstr, "");
2532 "add nid %s for failover uuid %s, client %s\n",
2533 libcfs_nid2str_r(nid, nidstr, sizeof(nidstr)),
2534 failnodeuuid, cliname);
2535 lnet_nid4_to_nid(nid, &lnid);
2536 rc = record_add_uuid(env, llh, &lnid, failnodeuuid);
2538 * If *ptr is ':', we have added all NIDs for
2542 rc = record_add_conn(env, llh, cliname,
2544 name_destroy(&failnodeuuid);
2545 failnodeuuid = NULL;
2549 rc = record_add_conn(env, llh, cliname, failnodeuuid);
2550 name_destroy(&failnodeuuid);
2551 failnodeuuid = NULL;
2558 static int mgs_write_log_mdc_to_lmv(const struct lu_env *env,
2559 struct mgs_device *mgs,
2561 struct mgs_target_info *mti,
2562 char *logname, char *lmvname)
2564 struct llog_handle *llh = NULL;
2565 char *mdcname = NULL;
2566 char *nodeuuid = NULL;
2567 char *mdcuuid = NULL;
2568 char *lmvuuid = NULL;
2570 char nidstr[LNET_NIDSTR_SIZE];
2574 if (mgs_log_is_empty(env, mgs, logname)) {
2575 CERROR("log is empty! Logical error\n");
2579 CDEBUG(D_MGS, "adding mdc for %s to log %s:lmv(%s)\n",
2580 mti->mti_svname, logname, lmvname);
2582 libcfs_nid2str_r(mti->mti_nids[0], nidstr, sizeof(nidstr));
2583 rc = name_create(&nodeuuid, nidstr, "");
2586 rc = name_create(&mdcname, mti->mti_svname, "-mdc");
2589 rc = name_create(&mdcuuid, mdcname, "_UUID");
2592 rc = name_create(&lmvuuid, lmvname, "_UUID");
2596 rc = mgs_modify(env, mgs, fsdb, mti, logname, mti->mti_svname,
2597 "add mdc", CM_SKIP);
2601 rc = record_start_log(env, mgs, &llh, logname);
2604 rc = record_marker(env, llh, fsdb, CM_START, mti->mti_svname,
2608 for (i = 0; i < mti->mti_nid_count; i++) {
2609 struct lnet_nid nid;
2611 lnet_nid4_to_nid(mti->mti_nids[i], &nid);
2612 CDEBUG(D_MGS, "add nid %s for mdt\n",
2613 libcfs_nidstr_r(&nid, nidstr, sizeof(nidstr)));
2615 rc = record_add_uuid(env, llh, &nid, nodeuuid);
2620 rc = record_attach(env, llh, mdcname, LUSTRE_MDC_NAME, lmvuuid);
2623 rc = record_setup(env, llh, mdcname, mti->mti_uuid, nodeuuid,
2627 rc = mgs_write_log_failnids(env, mti, llh, mdcname);
2630 snprintf(index, sizeof(index), "%d", mti->mti_stripe_index);
2631 rc = record_mdc_add(env, llh, lmvname, mdcuuid, mti->mti_uuid,
2635 rc = record_marker(env, llh, fsdb, CM_END, mti->mti_svname,
2640 record_end_log(env, &llh);
2642 name_destroy(&lmvuuid);
2643 name_destroy(&mdcuuid);
2644 name_destroy(&mdcname);
2645 name_destroy(&nodeuuid);
2649 static inline int name_create_lov(char **lovname, char *mdtname,
2650 struct fs_db *fsdb, int index)
2653 if (index == 0 && test_bit(FSDB_OSCNAME18, &fsdb->fsdb_flags))
2654 return name_create(lovname, fsdb->fsdb_name, "-mdtlov");
2656 return name_create(lovname, mdtname, "-mdtlov");
2659 static int name_create_mdt_and_lov(char **logname, char **lovname,
2660 struct fs_db *fsdb, int i)
2664 rc = name_create_mdt(logname, fsdb->fsdb_name, i);
2668 if (i == 0 && test_bit(FSDB_OSCNAME18, &fsdb->fsdb_flags))
2669 rc = name_create(lovname, fsdb->fsdb_name, "-mdtlov");
2671 rc = name_create(lovname, *logname, "-mdtlov");
2673 name_destroy(logname);
2679 static inline int name_create_mdt_osc(char **oscname, char *ostname,
2680 struct fs_db *fsdb, int i)
2684 if (i == 0 && test_bit(FSDB_OSCNAME18, &fsdb->fsdb_flags))
2685 sprintf(suffix, "-osc");
2687 sprintf(suffix, "-osc-MDT%04x", i);
2688 return name_create(oscname, ostname, suffix);
2691 /* add new mdc to already existent MDS */
2692 static int mgs_write_log_osp_to_mdt(const struct lu_env *env,
2693 struct mgs_device *mgs,
2695 struct mgs_target_info *mti,
2696 int mdt_index, char *logname)
2698 struct llog_handle *llh = NULL;
2699 char *nodeuuid = NULL;
2700 char *ospname = NULL;
2701 char *lovuuid = NULL;
2702 char *mdtuuid = NULL;
2703 char *svname = NULL;
2704 char *mdtname = NULL;
2705 char *lovname = NULL;
2707 char nidstr[LNET_NIDSTR_SIZE];
2711 if (mgs_log_is_empty(env, mgs, mti->mti_svname)) {
2712 CERROR("log is empty! Logical error\n");
2716 CDEBUG(D_MGS, "adding osp index %d to %s\n", mti->mti_stripe_index,
2719 rc = name_create_mdt(&mdtname, fsdb->fsdb_name, mti->mti_stripe_index);
2723 libcfs_nid2str_r(mti->mti_nids[0], nidstr, sizeof(nidstr));
2724 rc = name_create(&nodeuuid, nidstr, "");
2726 GOTO(out_destory, rc);
2728 rc = name_create(&svname, mdtname, "-osp");
2730 GOTO(out_destory, rc);
2732 sprintf(index_str, "-MDT%04x", mdt_index);
2733 rc = name_create(&ospname, svname, index_str);
2735 GOTO(out_destory, rc);
2737 rc = name_create_lov(&lovname, logname, fsdb, mdt_index);
2739 GOTO(out_destory, rc);
2741 rc = name_create(&lovuuid, lovname, "_UUID");
2743 GOTO(out_destory, rc);
2745 rc = name_create(&mdtuuid, mdtname, "_UUID");
2747 GOTO(out_destory, rc);
2749 rc = mgs_modify(env, mgs, fsdb, mti, logname, mti->mti_svname,
2750 "add osp", CM_SKIP);
2752 GOTO(out_destory, rc);
2754 rc = record_start_log(env, mgs, &llh, logname);
2756 GOTO(out_destory, rc);
2758 rc = record_marker(env, llh, fsdb, CM_START, mti->mti_svname,
2761 GOTO(out_destory, rc);
2763 for (i = 0; i < mti->mti_nid_count; i++) {
2764 struct lnet_nid nid;
2766 lnet_nid4_to_nid(mti->mti_nids[i], &nid);
2767 CDEBUG(D_MGS, "add nid %s for mdt\n",
2768 libcfs_nidstr_r(&nid, nidstr, sizeof(nidstr)));
2769 rc = record_add_uuid(env, llh, &nid, nodeuuid);
2774 rc = record_attach(env, llh, ospname, LUSTRE_OSP_NAME, lovuuid);
2778 rc = record_setup(env, llh, ospname, mti->mti_uuid, nodeuuid,
2783 rc = mgs_write_log_failnids(env, mti, llh, ospname);
2787 /* Add mdc(osp) to lod */
2788 snprintf(index_str, sizeof(index_str), "%d", mti->mti_stripe_index);
2789 rc = record_base(env, llh, lovname, 0, LCFG_ADD_MDC, mti->mti_uuid,
2790 index_str, "1", NULL);
2794 rc = record_marker(env, llh, fsdb, CM_END, mti->mti_svname, "add osp");
2799 record_end_log(env, &llh);
2802 name_destroy(&mdtuuid);
2803 name_destroy(&lovuuid);
2804 name_destroy(&lovname);
2805 name_destroy(&ospname);
2806 name_destroy(&svname);
2807 name_destroy(&nodeuuid);
2808 name_destroy(&mdtname);
2812 static int mgs_write_log_mdt0(const struct lu_env *env,
2813 struct mgs_device *mgs,
2815 struct mgs_target_info *mti)
2817 char *log = mti->mti_svname;
2818 struct llog_handle *llh = NULL;
2819 struct obd_uuid *uuid;
2822 char *ptr = mti->mti_params;
2823 int rc = 0, failout = 0;
2826 OBD_ALLOC_PTR(uuid);
2830 if (class_find_param(ptr, PARAM_FAILMODE, &ptr) == 0)
2831 failout = (strncmp(ptr, "failout", 7) == 0);
2833 rc = name_create(&lovname, log, "-mdtlov");
2836 if (mgs_log_is_empty(env, mgs, log)) {
2837 rc = mgs_write_log_lov(env, mgs, fsdb, mti, log, lovname);
2842 sprintf(mdt_index, "%d", mti->mti_stripe_index);
2844 rc = record_start_log(env, mgs, &llh, log);
2848 /* add MDT itself */
2850 /* FIXME this whole fn should be a single journal transaction */
2851 sprintf(uuid->uuid, "%s_UUID", log);
2852 rc = record_marker(env, llh, fsdb, CM_START, log, "add mdt");
2855 rc = record_attach(env, llh, log, LUSTRE_MDT_NAME, uuid->uuid);
2858 rc = record_mount_opt(env, llh, log, lovname, NULL);
2861 rc = record_setup(env, llh, log, uuid->uuid, mdt_index, lovname,
2862 failout ? "n" : "f");
2865 rc = record_marker(env, llh, fsdb, CM_END, log, "add mdt");
2869 record_end_log(env, &llh);
2871 name_destroy(&lovname);
2877 /* envelope method for all layers log */
2878 static int mgs_write_log_mdt(const struct lu_env *env,
2879 struct mgs_device *mgs,
2881 struct mgs_target_info *mti)
2883 struct mgs_thread_info *mgi = mgs_env_info(env);
2884 struct llog_handle *llh = NULL;
2889 CDEBUG(D_MGS, "writing new mdt %s\n", mti->mti_svname);
2891 if (mti->mti_uuid[0] == '\0') {
2892 /* Make up our own uuid */
2893 snprintf(mti->mti_uuid, sizeof(mti->mti_uuid),
2894 "%s_UUID", mti->mti_svname);
2898 rc = mgs_write_log_mdt0(env, mgs, fsdb, mti);
2901 /* Append the mdt info to the client log */
2902 rc = name_create(&cliname, mti->mti_fsname, "-client");
2906 if (mgs_log_is_empty(env, mgs, cliname)) {
2907 /* Start client log */
2908 rc = mgs_write_log_lov(env, mgs, fsdb, mti, cliname,
2912 rc = mgs_write_log_lmv(env, mgs, fsdb, mti, cliname,
2916 rc = mgs_write_log_mount_opt(env, mgs, fsdb, cliname);
2922 * #09 L add_uuid nid=uml1@tcp(0x20000c0a80201) 0: 1:uml1_UUID
2923 * #10 L attach 0:MDC_uml1_mdsA_MNT_client 1:mdc 2:1d834_MNT_client_03f
2924 * #11 L setup 0:MDC_uml1_mdsA_MNT_client 1:mdsA_UUID 2:uml1_UUID
2925 * #12 L add_uuid nid=uml2@tcp(0x20000c0a80202) 0: 1:uml2_UUID
2926 * #13 L add_conn 0:MDC_uml1_mdsA_MNT_client 1:uml2_UUID
2929 /* copy client info about lov/lmv */
2930 mgi->mgi_comp.comp_mti = mti;
2931 mgi->mgi_comp.comp_fsdb = fsdb;
2933 rc = mgs_steal_llog_for_mdt_from_client(env, mgs, cliname,
2937 rc = mgs_write_log_mdc_to_lmv(env, mgs, fsdb, mti, cliname,
2942 rc = record_start_log(env, mgs, &llh, cliname);
2946 /* for_all_existing_mdt except current one */
2947 for (i = 0; i < INDEX_MAP_SIZE * 8; i++) {
2948 if (i != mti->mti_stripe_index &&
2949 test_bit(i, fsdb->fsdb_mdt_index_map)) {
2952 rc = name_create_mdt(&logname, fsdb->fsdb_name, i);
2956 /* NB: If the log for the MDT is empty, it means
2957 * the MDT is only added to the index
2958 * map, and not being process yet, i.e. this
2959 * is an unregistered MDT, see mgs_write_log_target().
2960 * so we should skip it. Otherwise
2962 * 1. MGS get register request for MDT1 and MDT2.
2964 * 2. Then both MDT1 and MDT2 are added into
2965 * fsdb_mdt_index_map. (see mgs_set_index()).
2967 * 3. Then MDT1 get the lock of fsdb_mutex, then
2968 * generate the config log, here, it will regard MDT2
2969 * as an existent MDT, and generate "add osp" for
2970 * lustre-MDT0001-osp-MDT0002. Note: at the moment
2971 * MDT0002 config log is still empty, so it will
2972 * add "add osp" even before "lov setup", which
2973 * will definitly cause trouble.
2975 * 4. MDT1 registeration finished, fsdb_mutex is
2976 * released, then MDT2 get in, then in above
2977 * mgs_steal_llog_for_mdt_from_client(), it will
2978 * add another osp log for lustre-MDT0001-osp-MDT0002,
2979 * which will cause another trouble.*/
2980 if (!mgs_log_is_empty(env, mgs, logname))
2981 rc = mgs_write_log_osp_to_mdt(env, mgs, fsdb,
2984 name_destroy(&logname);
2990 record_end_log(env, &llh);
2992 name_destroy(&cliname);
2996 /* Add the ost info to the client/mdt lov */
2997 static int mgs_write_log_osc_to_lov(const struct lu_env *env,
2998 struct mgs_device *mgs, struct fs_db *fsdb,
2999 struct mgs_target_info *mti,
3000 char *logname, char *suffix, char *lovname,
3001 enum lustre_sec_part sec_part, int flags)
3003 struct llog_handle *llh = NULL;
3004 char *nodeuuid = NULL;
3005 char *oscname = NULL;
3006 char *oscuuid = NULL;
3007 char *lovuuid = NULL;
3008 char *svname = NULL;
3010 char nidstr[LNET_NIDSTR_SIZE];
3014 CDEBUG(D_INFO, "adding osc for %s to log %s\n",
3015 mti->mti_svname, logname);
3017 if (mgs_log_is_empty(env, mgs, logname)) {
3018 CERROR("log is empty! Logical error\n");
3022 libcfs_nid2str_r(mti->mti_nids[0], nidstr, sizeof(nidstr));
3023 rc = name_create(&nodeuuid, nidstr, "");
3026 rc = name_create(&svname, mti->mti_svname, "-osc");
3030 /* for the system upgraded from old 1.8, keep using the old osc naming
3031 * style for mdt, see name_create_mdt_osc(). LU-1257 */
3032 if (test_bit(FSDB_OSCNAME18, &fsdb->fsdb_flags))
3033 rc = name_create(&oscname, svname, "");
3035 rc = name_create(&oscname, svname, suffix);
3039 rc = name_create(&oscuuid, oscname, "_UUID");
3042 rc = name_create(&lovuuid, lovname, "_UUID");
3047 * #03 L add_uuid nid=uml1@tcp(0x20000c0a80201) 0: 1:uml1_UUID
3049 * #04 L add_uuid nid=1@elan(0x1000000000001) nal=90 0: 1:uml1_UUID
3050 * #04 L attach 0:OSC_uml1_ost1_MNT_client 1:osc 2:89070_lov1_a41dff51a
3051 * #05 L setup 0:OSC_uml1_ost1_MNT_client 1:ost1_UUID 2:uml1_UUID
3053 * #06 L add_uuid nid=uml2@tcp(0x20000c0a80202) 0: 1:uml2_UUID
3054 * #07 L add_conn 0:OSC_uml1_ost1_MNT_client 1:uml2_UUID
3055 * #08 L lov_modify_tgts add 0:lov1 1:ost1_UUID 2(index):0 3(gen):1
3058 rc = record_start_log(env, mgs, &llh, logname);
3062 /* FIXME these should be a single journal transaction */
3063 rc = record_marker(env, llh, fsdb, CM_START | flags, mti->mti_svname,
3068 /* NB: don't change record order, because upon MDT steal OSC config
3069 * from client, it treats all nids before LCFG_SETUP as target nids
3070 * (multiple interfaces), while nids after as failover node nids.
3071 * See mgs_steal_client_llog_handler() LCFG_ADD_UUID.
3073 for (i = 0; i < mti->mti_nid_count; i++) {
3074 struct lnet_nid nid;
3076 lnet_nid4_to_nid(mti->mti_nids[i], &nid);
3077 CDEBUG(D_MGS, "add nid %s\n",
3078 libcfs_nidstr_r(&nid, nidstr, sizeof(nidstr)));
3079 rc = record_add_uuid(env, llh, &nid, nodeuuid);
3083 rc = record_attach(env, llh, oscname, LUSTRE_OSC_NAME, lovuuid);
3086 rc = record_setup(env, llh, oscname, mti->mti_uuid, nodeuuid,
3090 rc = mgs_write_log_failnids(env, mti, llh, oscname);
3094 snprintf(index, sizeof(index), "%d", mti->mti_stripe_index);
3096 rc = record_lov_add(env, llh, lovname, mti->mti_uuid, index, "1");
3099 rc = record_marker(env, llh, fsdb, CM_END | flags, mti->mti_svname,
3104 record_end_log(env, &llh);
3106 name_destroy(&lovuuid);
3107 name_destroy(&oscuuid);
3108 name_destroy(&oscname);
3109 name_destroy(&svname);
3110 name_destroy(&nodeuuid);
3114 static int mgs_write_log_ost(const struct lu_env *env,
3115 struct mgs_device *mgs, struct fs_db *fsdb,
3116 struct mgs_target_info *mti)
3118 struct llog_handle *llh = NULL;
3119 char *logname, *lovname;
3120 char *ptr = mti->mti_params;
3121 int rc, flags = 0, failout = 0, i;
3124 CDEBUG(D_MGS, "writing new ost %s\n", mti->mti_svname);
3126 /* The ost startup log */
3128 /* If the ost log already exists, that means that someone reformatted
3129 * the ost and it called target_add again.
3131 if (!mgs_log_is_empty(env, mgs, mti->mti_svname)) {
3132 LCONSOLE_ERROR_MSG(0x141,
3133 "The config log for %s already exists, yet the server claims it never registered. It may have been reformatted, or the index changed. writeconf the MDT to regenerate all logs.\n",
3139 * attach obdfilter ost1 ost1_UUID
3140 * setup /dev/loop2 ldiskfs f|n errors=remount-ro,user_xattr
3142 if (class_find_param(ptr, PARAM_FAILMODE, &ptr) == 0)
3143 failout = (strncmp(ptr, "failout", 7) == 0);
3144 rc = record_start_log(env, mgs, &llh, mti->mti_svname);
3147 /* FIXME these should be a single journal transaction */
3148 rc = record_marker(env, llh, fsdb, CM_START, mti->mti_svname,"add ost");
3151 if (*mti->mti_uuid == '\0')
3152 snprintf(mti->mti_uuid, sizeof(mti->mti_uuid),
3153 "%s_UUID", mti->mti_svname);
3154 rc = record_attach(env, llh, mti->mti_svname,
3155 "obdfilter"/*LUSTRE_OST_NAME*/, mti->mti_uuid);
3158 rc = record_setup(env, llh, mti->mti_svname,
3159 "dev"/*ignored*/, "type"/*ignored*/,
3160 failout ? "n" : "f", NULL/*options*/);
3163 rc = record_marker(env, llh, fsdb, CM_END, mti->mti_svname, "add ost");
3167 record_end_log(env, &llh);
3170 /* We also have to update the other logs where this osc is part of
3174 if (test_bit(FSDB_OLDLOG14, &fsdb->fsdb_flags)) {
3175 /* If we're upgrading, the old mdt log already has our
3176 * entry. Let's do a fake one for fun.
3178 /* Note that we can't add any new failnids, since we don't
3179 * know the old osc names.
3181 flags = CM_SKIP | CM_UPGRADE146;
3182 } else if ((mti->mti_flags & LDD_F_UPDATE) != LDD_F_UPDATE) {
3183 /* If the update flag isn't set, don't update client/mdt
3187 LCONSOLE_WARN("Client log for %s was not updated; writeconf the MDT first to regenerate it.\n",
3191 /* Add ost to all MDT lov defs */
3192 for (i = 0; i < INDEX_MAP_SIZE * 8; i++) {
3193 if (test_bit(i, fsdb->fsdb_mdt_index_map)) {
3196 rc = name_create_mdt_and_lov(&logname, &lovname, fsdb,
3201 snprintf(mdt_index, sizeof(mdt_index), "-MDT%04x", i);
3202 rc = mgs_write_log_osc_to_lov(env, mgs, fsdb, mti,
3204 lovname, LUSTRE_SP_MDT,
3206 name_destroy(&logname);
3207 name_destroy(&lovname);
3213 /* Append ost info to the client log */
3214 rc = name_create(&logname, mti->mti_fsname, "-client");
3217 if (mgs_log_is_empty(env, mgs, logname)) {
3218 /* Start client log */
3219 rc = mgs_write_log_lov(env, mgs, fsdb, mti, logname,
3223 rc = mgs_write_log_lmv(env, mgs, fsdb, mti, logname,
3227 rc = mgs_write_log_mount_opt(env, mgs, fsdb, logname);
3231 rc = mgs_write_log_osc_to_lov(env, mgs, fsdb, mti, logname, "",
3232 fsdb->fsdb_clilov, LUSTRE_SP_CLI, flags);
3234 name_destroy(&logname);
3238 static __inline__ int mgs_param_empty(char *ptr)
3240 char *tmp = strchr(ptr, '=');
3242 if (tmp && tmp[1] == '\0')
3247 static int mgs_write_log_failnid_internal(const struct lu_env *env,
3248 struct mgs_device *mgs,
3250 struct mgs_target_info *mti,
3251 char *logname, char *cliname)
3254 struct llog_handle *llh = NULL;
3256 if (mgs_param_empty(mti->mti_params)) {
3257 /* Remove _all_ failnids */
3258 rc = mgs_modify(env, mgs, fsdb, mti, logname,
3259 mti->mti_svname, "add failnid", CM_SKIP);
3260 return rc < 0 ? rc : 0;
3263 /* Otherwise failover nids are additive */
3264 rc = record_start_log(env, mgs, &llh, logname);
3267 /* FIXME this should be a single journal transaction */
3268 rc = record_marker(env, llh, fsdb, CM_START, mti->mti_svname,
3272 rc = mgs_write_log_failnids(env, mti, llh, cliname);
3275 rc = record_marker(env, llh, fsdb, CM_END,
3276 mti->mti_svname, "add failnid");
3278 record_end_log(env, &llh);
3282 /* Add additional failnids to an existing log.
3283 The mdc/osc must have been added to logs first */
3284 /* tcp nids must be in dotted-quad ascii -
3285 we can't resolve hostnames from the kernel. */
3286 static int mgs_write_log_add_failnid(const struct lu_env *env,
3287 struct mgs_device *mgs,
3289 struct mgs_target_info *mti)
3291 char *logname, *cliname;
3295 /* FIXME we currently can't erase the failnids
3296 * given when a target first registers, since they aren't part of
3297 * an "add uuid" stanza
3300 /* Verify that we know about this target */
3301 if (mgs_log_is_empty(env, mgs, mti->mti_svname)) {
3302 LCONSOLE_ERROR_MSG(0x142,
3303 "The target %s has not registered yet. It must be started before failnids can be added.\n",
3308 /* Create mdc/osc client name (e.g. lustre-OST0001-osc) */
3309 if (mti->mti_flags & LDD_F_SV_TYPE_MDT)
3310 rc = name_create(&cliname, mti->mti_svname, "-mdc");
3311 else if (mti->mti_flags & LDD_F_SV_TYPE_OST)
3312 rc = name_create(&cliname, mti->mti_svname, "-osc");
3319 /* Add failover nids to the client log */
3320 rc = name_create(&logname, mti->mti_fsname, "-client");
3322 name_destroy(&cliname);
3326 rc = mgs_write_log_failnid_internal(env, mgs, fsdb,mti,logname,cliname);
3327 name_destroy(&logname);
3328 name_destroy(&cliname);
3332 if (mti->mti_flags & LDD_F_SV_TYPE_OST) {
3333 /* Add OST failover nids to the MDT logs as well */
3336 for (i = 0; i < INDEX_MAP_SIZE * 8; i++) {
3337 if (!test_bit(i, fsdb->fsdb_mdt_index_map))
3339 rc = name_create_mdt(&logname, mti->mti_fsname, i);
3342 rc = name_create_mdt_osc(&cliname, mti->mti_svname,
3345 name_destroy(&logname);
3348 rc = mgs_write_log_failnid_internal(env, mgs, fsdb,
3351 name_destroy(&cliname);
3352 name_destroy(&logname);
3361 static int mgs_wlp_lcfg(const struct lu_env *env,
3362 struct mgs_device *mgs, struct fs_db *fsdb,
3363 struct mgs_target_info *mti,
3364 char *logname, struct lustre_cfg_bufs *bufs,
3365 char *tgtname, char *ptr)
3367 char comment[MTI_NAME_MAXLEN];
3369 struct llog_cfg_rec *lcr;
3372 /* Erase any old settings of this same parameter */
3373 strlcpy(comment, ptr, sizeof(comment));
3374 /* But don't try to match the value. */
3375 tmp = strchr(comment, '=');
3378 /* FIXME we should skip settings that are the same as old values */
3379 rc = mgs_modify(env, mgs, fsdb, mti, logname, tgtname, comment,CM_SKIP);
3382 del = mgs_param_empty(ptr);
3384 LCONSOLE_INFO("%s parameter %s.%s in log %s\n", del ? "Disabling" : rc ?
3385 "Setting" : "Modifying", tgtname, comment, logname);
3387 /* mgs_modify() will return 1 if nothing had to be done */
3393 lustre_cfg_bufs_reset(bufs, tgtname);
3394 lustre_cfg_bufs_set_string(bufs, 1, ptr);
3395 if (mti->mti_flags & LDD_F_PARAM2)
3396 lustre_cfg_bufs_set_string(bufs, 2, LCTL_UPCALL);
3398 lcr = lustre_cfg_rec_new((mti->mti_flags & LDD_F_PARAM2) ?
3399 LCFG_SET_PARAM : LCFG_PARAM, bufs);
3403 rc = mgs_write_log_direct(env, mgs, fsdb, logname, lcr, tgtname,
3405 lustre_cfg_rec_free(lcr);
3409 /* write global variable settings into log */
3410 static int mgs_write_log_sys(const struct lu_env *env,
3411 struct mgs_device *mgs, struct fs_db *fsdb,
3412 struct mgs_target_info *mti, char *sys, char *ptr)
3414 struct mgs_thread_info *mgi = mgs_env_info(env);
3415 struct lustre_cfg *lcfg;
3416 struct llog_cfg_rec *lcr;
3418 int rc, cmd, convert = 1;
3420 if (class_match_param(ptr, PARAM_TIMEOUT, &tmp) == 0) {
3421 cmd = LCFG_SET_TIMEOUT;
3422 } else if (class_match_param(ptr, PARAM_LDLM_TIMEOUT, &tmp) == 0) {
3423 cmd = LCFG_SET_LDLM_TIMEOUT;
3424 /* Check for known params here so we can return error to lctl */
3425 } else if ((class_match_param(ptr, PARAM_AT_MIN, &tmp) == 0) ||
3426 (class_match_param(ptr, PARAM_AT_MAX, &tmp) == 0) ||
3427 (class_match_param(ptr, PARAM_AT_EXTRA, &tmp) == 0) ||
3428 (class_match_param(ptr, PARAM_AT_EARLY_MARGIN, &tmp) == 0) ||
3429 (class_match_param(ptr, PARAM_AT_HISTORY, &tmp) == 0)) {
3431 } else if (class_match_param(ptr, PARAM_JOBID_VAR, &tmp) == 0) {
3432 convert = 0; /* Don't convert string value to integer */
3438 if (mgs_param_empty(ptr))
3439 CDEBUG(D_MGS, "global '%s' removed\n", sys);
3441 CDEBUG(D_MGS, "global '%s' val=%s\n", sys, tmp);
3443 lustre_cfg_bufs_reset(&mgi->mgi_bufs, NULL);
3444 lustre_cfg_bufs_set_string(&mgi->mgi_bufs, 1, sys);
3445 if (!convert && *tmp != '\0')
3446 lustre_cfg_bufs_set_string(&mgi->mgi_bufs, 2, tmp);
3447 lcr = lustre_cfg_rec_new(cmd, &mgi->mgi_bufs);
3451 lcfg = &lcr->lcr_cfg;
3453 rc = kstrtouint(tmp, 0, &lcfg->lcfg_num);
3455 GOTO(out_rec_free, rc);
3460 /* truncate the comment to the parameter name */
3464 /* modify all servers and clients */
3465 rc = mgs_write_log_direct_all(env, mgs, fsdb, mti,
3466 *tmp == '\0' ? NULL : lcr,
3467 mti->mti_fsname, sys, 0);
3468 if (rc == 0 && *tmp != '\0') {
3470 case LCFG_SET_TIMEOUT:
3471 if (!obd_timeout_set || lcfg->lcfg_num > obd_timeout)
3472 class_process_config(lcfg);
3474 case LCFG_SET_LDLM_TIMEOUT:
3475 if (!ldlm_timeout_set || lcfg->lcfg_num > ldlm_timeout)
3476 class_process_config(lcfg);
3484 lustre_cfg_rec_free(lcr);
3488 /* write quota settings into log */
3489 static int mgs_write_log_quota(const struct lu_env *env, struct mgs_device *mgs,
3490 struct fs_db *fsdb, struct mgs_target_info *mti,
3491 char *quota, char *ptr)
3493 struct mgs_thread_info *mgi = mgs_env_info(env);
3494 struct llog_cfg_rec *lcr;
3497 int rc, cmd = LCFG_PARAM;
3499 /* support only 'meta' and 'data' pools so far */
3500 if (class_match_param(ptr, QUOTA_METAPOOL_NAME, &tmp) != 0 &&
3501 class_match_param(ptr, QUOTA_DATAPOOL_NAME, &tmp) != 0) {
3502 CERROR("parameter quota.%s isn't supported (only quota.mdt "
3503 "& quota.ost are)\n", ptr);
3508 CDEBUG(D_MGS, "global '%s' removed\n", quota);
3510 CDEBUG(D_MGS, "global '%s'\n", quota);
3512 if (strchr(tmp, 'u') == NULL && strchr(tmp, 'g') == NULL &&
3513 strchr(tmp, 'p') == NULL &&
3514 strcmp(tmp, "none") != 0) {
3515 CERROR("enable option(%s) isn't supported\n", tmp);
3520 lustre_cfg_bufs_reset(&mgi->mgi_bufs, mti->mti_fsname);
3521 lustre_cfg_bufs_set_string(&mgi->mgi_bufs, 1, quota);
3522 lcr = lustre_cfg_rec_new(cmd, &mgi->mgi_bufs);
3526 /* truncate the comment to the parameter name */
3531 /* XXX we duplicated quota enable information in all server
3532 * config logs, it should be moved to a separate config
3533 * log once we cleanup the config log for global param. */
3534 /* modify all servers */
3535 rc = mgs_write_log_direct_all(env, mgs, fsdb, mti,
3536 *tmp == '\0' ? NULL : lcr,
3537 mti->mti_fsname, quota, 1);
3539 lustre_cfg_rec_free(lcr);
3540 return rc < 0 ? rc : 0;
3543 static int mgs_srpc_set_param_disk(const struct lu_env *env,
3544 struct mgs_device *mgs,
3546 struct mgs_target_info *mti,
3549 struct mgs_thread_info *mgi = mgs_env_info(env);
3550 struct llog_cfg_rec *lcr;
3551 struct llog_handle *llh = NULL;
3553 char *comment, *ptr;
3559 ptr = strchr(param, '=');
3560 LASSERT(ptr != NULL);
3563 OBD_ALLOC(comment, len + 1);
3564 if (comment == NULL)
3566 strncpy(comment, param, len);
3567 comment[len] = '\0';
3570 lustre_cfg_bufs_reset(&mgi->mgi_bufs, mti->mti_svname);
3571 lustre_cfg_bufs_set_string(&mgi->mgi_bufs, 1, param);
3572 lcr = lustre_cfg_rec_new(LCFG_SPTLRPC_CONF, &mgi->mgi_bufs);
3574 GOTO(out_comment, rc = -ENOMEM);
3576 /* construct log name */
3577 rc = name_create(&logname, mti->mti_fsname, "-sptlrpc");
3581 if (mgs_log_is_empty(env, mgs, logname)) {
3582 rc = record_start_log(env, mgs, &llh, logname);
3585 record_end_log(env, &llh);
3588 /* obsolete old one */
3589 rc = mgs_modify(env, mgs, fsdb, mti, logname, mti->mti_svname,
3593 /* write the new one */
3594 rc = mgs_write_log_direct(env, mgs, fsdb, logname, lcr,
3595 mti->mti_svname, comment);
3597 CERROR("%s: error writing log %s: rc = %d\n",
3598 mgs->mgs_obd->obd_name, logname, rc);
3600 name_destroy(&logname);
3602 lustre_cfg_rec_free(lcr);
3604 OBD_FREE(comment, len + 1);
3608 static int mgs_srpc_set_param_udesc_mem(struct fs_db *fsdb,
3613 /* disable the adjustable udesc parameter for now, i.e. use default
3614 * setting that client always ship udesc to MDT if possible. to enable
3615 * it simply remove the following line
3619 ptr = strchr(param, '=');
3624 if (strcmp(param, PARAM_SRPC_UDESC))
3627 if (strcmp(ptr, "yes") == 0) {
3628 set_bit(FSDB_UDESC, &fsdb->fsdb_flags);
3629 CWARN("Enable user descriptor shipping from client to MDT\n");
3630 } else if (strcmp(ptr, "no") == 0) {
3631 clear_bit(FSDB_UDESC, &fsdb->fsdb_flags);
3632 CWARN("Disable user descriptor shipping from client to MDT\n");
3640 CERROR("Invalid param: %s\n", param);
3644 static int mgs_srpc_set_param_mem(struct fs_db *fsdb,
3648 struct sptlrpc_rule rule;
3649 struct sptlrpc_rule_set *rset;
3653 if (strncmp(param, PARAM_SRPC, sizeof(PARAM_SRPC) - 1) != 0) {
3654 CERROR("Invalid sptlrpc parameter: %s\n", param);
3658 if (strncmp(param, PARAM_SRPC_UDESC,
3659 sizeof(PARAM_SRPC_UDESC) - 1) == 0) {
3660 RETURN(mgs_srpc_set_param_udesc_mem(fsdb, param));
3663 if (strncmp(param, PARAM_SRPC_FLVR, sizeof(PARAM_SRPC_FLVR) - 1) != 0) {
3664 CERROR("Invalid sptlrpc flavor parameter: %s\n", param);
3668 param += sizeof(PARAM_SRPC_FLVR) - 1;
3670 rc = sptlrpc_parse_rule(param, &rule);
3674 /* mgs rules implies must be mgc->mgs */
3675 if (test_bit(FSDB_MGS_SELF, &fsdb->fsdb_flags)) {
3676 if ((rule.sr_from != LUSTRE_SP_MGC &&
3677 rule.sr_from != LUSTRE_SP_ANY) ||
3678 (rule.sr_to != LUSTRE_SP_MGS &&
3679 rule.sr_to != LUSTRE_SP_ANY))
3683 /* prepare room for this coming rule. svcname format should be:
3684 * - fsname: general rule
3685 * - fsname-tgtname: target-specific rule
3687 if (strchr(svname, '-')) {
3688 struct mgs_tgt_srpc_conf *tgtconf;
3691 for (tgtconf = fsdb->fsdb_srpc_tgt; tgtconf != NULL;
3692 tgtconf = tgtconf->mtsc_next) {
3693 if (!strcmp(tgtconf->mtsc_tgt, svname)) {
3702 OBD_ALLOC_PTR(tgtconf);
3703 if (tgtconf == NULL)
3706 name_len = strlen(svname);
3708 OBD_ALLOC(tgtconf->mtsc_tgt, name_len + 1);
3709 if (tgtconf->mtsc_tgt == NULL) {
3710 OBD_FREE_PTR(tgtconf);
3713 memcpy(tgtconf->mtsc_tgt, svname, name_len);
3715 tgtconf->mtsc_next = fsdb->fsdb_srpc_tgt;
3716 fsdb->fsdb_srpc_tgt = tgtconf;
3719 rset = &tgtconf->mtsc_rset;
3720 } else if (strcmp(svname, MGSSELF_NAME) == 0) {
3721 /* put _mgs related srpc rule directly in mgs ruleset */
3722 rset = &fsdb->fsdb_mgs->mgs_lut.lut_sptlrpc_rset;
3724 rset = &fsdb->fsdb_srpc_gen;
3727 rc = sptlrpc_rule_set_merge(rset, &rule);
3732 static int mgs_srpc_set_param(const struct lu_env *env,
3733 struct mgs_device *mgs,
3735 struct mgs_target_info *mti,
3745 /* keep a copy of original param, which could be destroyed
3748 copy_size = strlen(param) + 1;
3749 OBD_ALLOC(copy, copy_size);
3752 memcpy(copy, param, copy_size);
3754 rc = mgs_srpc_set_param_mem(fsdb, mti->mti_svname, param);
3758 /* previous steps guaranteed the syntax is correct */
3759 rc = mgs_srpc_set_param_disk(env, mgs, fsdb, mti, copy);
3763 if (test_bit(FSDB_MGS_SELF, &fsdb->fsdb_flags)) {
3765 * for mgs rules, make them effective immediately.
3767 LASSERT(fsdb->fsdb_srpc_tgt == NULL);
3768 sptlrpc_target_update_exp_flavor(mgs->mgs_obd,
3769 &fsdb->fsdb_srpc_gen);
3773 OBD_FREE(copy, copy_size);
3777 struct mgs_srpc_read_data {
3778 struct fs_db *msrd_fsdb;
3782 static int mgs_srpc_read_handler(const struct lu_env *env,
3783 struct llog_handle *llh,
3784 struct llog_rec_hdr *rec, void *data)
3786 struct mgs_srpc_read_data *msrd = data;
3787 struct cfg_marker *marker;
3788 struct lustre_cfg *lcfg = REC_DATA(rec);
3789 char *svname, *param;
3793 if (rec->lrh_type != OBD_CFG_REC) {
3794 CERROR("unhandled lrh_type: %#x\n", rec->lrh_type);
3798 cfg_len = REC_DATA_LEN(rec);
3800 rc = lustre_cfg_sanity_check(lcfg, cfg_len);
3802 CERROR("Insane cfg\n");
3806 if (lcfg->lcfg_command == LCFG_MARKER) {
3807 marker = lustre_cfg_buf(lcfg, 1);
3809 if (marker->cm_flags & CM_START &&
3810 marker->cm_flags & CM_SKIP)
3811 msrd->msrd_skip = 1;
3812 if (marker->cm_flags & CM_END)
3813 msrd->msrd_skip = 0;
3818 if (msrd->msrd_skip)
3821 if (lcfg->lcfg_command != LCFG_SPTLRPC_CONF) {
3822 CERROR("invalid command (%x)\n", lcfg->lcfg_command);
3826 svname = lustre_cfg_string(lcfg, 0);
3827 if (svname == NULL) {
3828 CERROR("svname is empty\n");
3832 param = lustre_cfg_string(lcfg, 1);
3833 if (param == NULL) {
3834 CERROR("param is empty\n");
3838 rc = mgs_srpc_set_param_mem(msrd->msrd_fsdb, svname, param);
3840 CERROR("read sptlrpc record error (%d): %s\n", rc, param);
3845 int mgs_get_fsdb_srpc_from_llog(const struct lu_env *env,
3846 struct mgs_device *mgs,
3849 struct llog_handle *llh = NULL;
3850 struct llog_ctxt *ctxt;
3852 struct mgs_srpc_read_data msrd;
3856 /* construct log name */
3857 rc = name_create(&logname, fsdb->fsdb_name, "-sptlrpc");
3861 ctxt = llog_get_context(mgs->mgs_obd, LLOG_CONFIG_ORIG_CTXT);
3862 LASSERT(ctxt != NULL);
3864 if (mgs_log_is_empty(env, mgs, logname))
3867 rc = llog_open(env, ctxt, &llh, NULL, logname,
3875 rc = llog_init_handle(env, llh, LLOG_F_IS_PLAIN, NULL);
3877 GOTO(out_close, rc);
3879 if (llog_get_size(llh) <= 1)
3880 GOTO(out_close, rc = 0);
3882 msrd.msrd_fsdb = fsdb;
3885 rc = llog_process(env, llh, mgs_srpc_read_handler, (void *)&msrd,
3889 llog_close(env, llh);
3891 llog_ctxt_put(ctxt);
3892 name_destroy(&logname);
3895 CERROR("failed to read sptlrpc config database: %d\n", rc);
3899 static int mgs_write_log_param2(const struct lu_env *env,
3900 struct mgs_device *mgs,
3902 struct mgs_target_info *mti, char *ptr)
3904 struct lustre_cfg_bufs bufs;
3908 CDEBUG(D_MGS, "next param '%s'\n", ptr);
3910 /* PARAM_MGSNODE and PARAM_NETWORK are set only when formating
3911 * or during the inital mount. It can never change after that.
3913 if (!class_match_param(ptr, PARAM_MGSNODE, NULL) ||
3914 !class_match_param(ptr, PARAM_NETWORK, NULL)) {
3919 /* Processed in mgs_write_log_ost. Another value that can't
3920 * be changed by lctl set_param -P.
3922 if (!class_match_param(ptr, PARAM_FAILMODE, NULL)) {
3923 LCONSOLE_ERROR_MSG(0x169,
3924 "%s can only be changed with tunefs.lustre and --writeconf\n",
3930 /* FIXME !!! Support for sptlrpc is incomplete. Currently the change
3931 * doesn't transmit to the client. See LU-7183.
3933 if (!class_match_param(ptr, PARAM_SRPC, NULL)) {
3934 rc = mgs_srpc_set_param(env, mgs, fsdb, mti, ptr);
3938 /* Can't use class_match_param since ptr doesn't start with
3939 * PARAM_FAILNODE. So we look for PARAM_FAILNODE contained in ptr.
3941 if (strstr(ptr, PARAM_FAILNODE)) {
3942 /* Add a failover nidlist. We already processed failovers
3943 * params for new targets in mgs_write_log_target.
3947 /* can't use wildcards with failover.node */
3948 if (strchr(ptr, '*')) {
3953 param = strstr(ptr, PARAM_FAILNODE);
3954 if (strlcpy(mti->mti_params, param, sizeof(mti->mti_params)) >=
3955 sizeof(mti->mti_params)) {
3960 CDEBUG(D_MGS, "Adding failnode with param %s\n",
3962 rc = mgs_write_log_add_failnid(env, mgs, fsdb, mti);
3966 /* root squash parameters must not be set on llite subsystem, this can
3967 * lead to inconsistencies between client and server values
3969 if ((strstr(ptr, PARAM_NOSQUASHNIDS) ||
3970 strstr(ptr, PARAM_ROOTSQUASH)) &&
3971 strncmp(ptr, "llite.", strlen("llite.")) == 0) {
3973 CWARN("%s: cannot add %s param to llite subsystem, use mdt instead: rc=%d\n",
3974 mgs->mgs_obd->obd_name,
3975 strstr(ptr, PARAM_ROOTSQUASH) ?
3976 PARAM_ROOTSQUASH : PARAM_NOSQUASHNIDS,
3981 rc = mgs_wlp_lcfg(env, mgs, fsdb, mti, PARAMS_FILENAME, &bufs,
3982 mti->mti_svname, ptr);
3987 /* Permanent settings of all parameters by writing into the appropriate
3988 * configuration logs.
3989 * A parameter with null value ("<param>='\0'") means to erase it out of
3992 static int mgs_write_log_param(const struct lu_env *env,
3993 struct mgs_device *mgs, struct fs_db *fsdb,
3994 struct mgs_target_info *mti, char *ptr)
3996 struct mgs_thread_info *mgi = mgs_env_info(env);
4002 /* For various parameter settings, we have to figure out which logs
4003 * care about them (e.g. both mdt and client for lov settings)
4005 CDEBUG(D_MGS, "next param '%s'\n", ptr);
4007 /* The params are stored in MOUNT_DATA_FILE and modified via
4008 * tunefs.lustre, or set using lctl conf_param
4011 /* Processed in lustre_start_mgc */
4012 if (class_match_param(ptr, PARAM_MGSNODE, NULL) == 0)
4015 /* Processed in ost/mdt */
4016 if (class_match_param(ptr, PARAM_NETWORK, NULL) == 0)
4019 /* Processed in mgs_write_log_ost */
4020 if (class_match_param(ptr, PARAM_FAILMODE, NULL) == 0) {
4021 if (mti->mti_flags & LDD_F_PARAM) {
4022 LCONSOLE_ERROR_MSG(0x169,
4023 "%s can only be changed with tunefs.lustre and --writeconf\n",
4030 if (class_match_param(ptr, PARAM_SRPC, NULL) == 0) {
4031 rc = mgs_srpc_set_param(env, mgs, fsdb, mti, ptr);
4035 if (class_match_param(ptr, PARAM_FAILNODE, NULL) == 0) {
4036 /* Add a failover nidlist */
4038 /* We already processed failovers params for new
4039 * targets in mgs_write_log_target
4041 if (mti->mti_flags & LDD_F_PARAM) {
4042 CDEBUG(D_MGS, "Adding failnode\n");
4043 rc = mgs_write_log_add_failnid(env, mgs, fsdb, mti);
4048 if (class_match_param(ptr, PARAM_SYS, &tmp) == 0) {
4049 rc = mgs_write_log_sys(env, mgs, fsdb, mti, ptr, tmp);
4053 if (class_match_param(ptr, PARAM_QUOTA, &tmp) == 0) {
4054 rc = mgs_write_log_quota(env, mgs, fsdb, mti, ptr, tmp);
4058 if (class_match_param(ptr, PARAM_OSC PARAM_ACTIVE, &tmp) == 0 ||
4059 class_match_param(ptr, PARAM_MDC PARAM_ACTIVE, &tmp) == 0) {
4060 /* active=0 means off, anything else means on */
4061 int flag = (*tmp == '0') ? CM_EXCLUDE : 0;
4062 bool deactive_osc = memcmp(ptr, PARAM_OSC PARAM_ACTIVE,
4063 strlen(PARAM_OSC PARAM_ACTIVE)) == 0;
4066 if (!deactive_osc) {
4069 rc = server_name2index(mti->mti_svname, &index, NULL);
4074 LCONSOLE_ERROR_MSG(0x144, "%s: MDC0 can not be"
4075 " (de)activated.\n",
4077 GOTO(end, rc = -EPERM);
4081 LCONSOLE_WARN("Permanently %sactivating %s\n",
4082 flag ? "de" : "re", mti->mti_svname);
4084 rc = name_create(&logname, mti->mti_fsname, "-client");
4087 rc = mgs_modify(env, mgs, fsdb, mti, logname,
4089 deactive_osc ? "add osc" : "add mdc", flag);
4090 name_destroy(&logname);
4095 /* Add to all MDT logs for DNE */
4096 for (i = 0; i < INDEX_MAP_SIZE * 8; i++) {
4097 if (!test_bit(i, fsdb->fsdb_mdt_index_map))
4099 rc = name_create_mdt(&logname, mti->mti_fsname, i);
4102 rc = mgs_modify(env, mgs, fsdb, mti, logname,
4104 deactive_osc ? "add osc" : "add osp",
4106 name_destroy(&logname);
4112 LCONSOLE_ERROR_MSG(0x145,
4113 "Couldn't find %s in log (%d). No permanent changes were made to the config log.\n",
4114 mti->mti_svname, rc);
4115 if (test_bit(FSDB_OLDLOG14, &fsdb->fsdb_flags))
4116 LCONSOLE_ERROR_MSG(0x146,
4117 "This may be because the log is in the old 1.4 style. Consider --writeconf to update the logs.\n");
4120 /* Fall through to osc/mdc proc for deactivating live
4121 * OSC/OSP on running MDT / clients.
4124 /* Below here, let obd's XXX_process_config methods handle it */
4126 /* All lov. in proc */
4127 if (class_match_param(ptr, PARAM_LOV, NULL) == 0) {
4130 CDEBUG(D_MGS, "lov param %s\n", ptr);
4131 if (!(mti->mti_flags & LDD_F_SV_TYPE_MDT)) {
4132 LCONSOLE_ERROR_MSG(0x147,
4133 "LOV params must be set on the MDT, not %s. Ignoring.\n",
4139 if (mgs_log_is_empty(env, mgs, mti->mti_svname))
4140 GOTO(end, rc = -ENODEV);
4142 rc = name_create_mdt_and_lov(&logname, &mdtlovname, fsdb,
4143 mti->mti_stripe_index);
4146 rc = mgs_wlp_lcfg(env, mgs, fsdb, mti, mti->mti_svname,
4147 &mgi->mgi_bufs, mdtlovname, ptr);
4148 name_destroy(&logname);
4149 name_destroy(&mdtlovname);
4154 rc = name_create(&logname, mti->mti_fsname, "-client");
4157 rc = mgs_wlp_lcfg(env, mgs, fsdb, mti, logname, &mgi->mgi_bufs,
4158 fsdb->fsdb_clilov, ptr);
4159 name_destroy(&logname);
4163 /* All osc., mdc., llite. params in proc */
4164 if ((class_match_param(ptr, PARAM_OSC, NULL) == 0) ||
4165 (class_match_param(ptr, PARAM_MDC, NULL) == 0) ||
4166 (class_match_param(ptr, PARAM_LLITE, NULL) == 0)) {
4169 if (test_bit(FSDB_OLDLOG14, &fsdb->fsdb_flags)) {
4170 LCONSOLE_ERROR_MSG(0x148, "Upgraded client logs for %s"
4171 " cannot be modified. Consider"
4172 " updating the configuration with"
4175 GOTO(end, rc = -EINVAL);
4177 if (memcmp(ptr, PARAM_LLITE, strlen(PARAM_LLITE)) == 0) {
4178 rc = name_create(&cname, mti->mti_fsname, "-client");
4179 /* Add the client type to match the obdname in
4180 * class_config_llog_handler
4182 } else if (mti->mti_flags & LDD_F_SV_TYPE_MDT) {
4183 rc = name_create(&cname, mti->mti_svname, "-mdc");
4184 } else if (mti->mti_flags & LDD_F_SV_TYPE_OST) {
4185 rc = name_create(&cname, mti->mti_svname, "-osc");
4187 GOTO(end, rc = -EINVAL);
4192 /* Forbid direct update of llite root squash parameters.
4193 * These parameters are indirectly set via the MDT settings.
4195 if ((class_match_param(ptr, PARAM_LLITE, &tmp) == 0) &&
4196 ((memcmp(tmp, "root_squash=", 12) == 0) ||
4197 (memcmp(tmp, "nosquash_nids=", 14) == 0))) {
4198 LCONSOLE_ERROR("%s: root squash parameters can only "
4199 "be updated through MDT component\n",
4201 name_destroy(&cname);
4202 GOTO(end, rc = -EINVAL);
4205 CDEBUG(D_MGS, "%.3s param %s\n", ptr, ptr + 4);
4208 rc = name_create(&logname, mti->mti_fsname, "-client");
4210 name_destroy(&cname);
4213 rc = mgs_wlp_lcfg(env, mgs, fsdb, mti, logname, &mgi->mgi_bufs,
4216 /* osc params affect the MDT as well */
4217 if (!rc && (mti->mti_flags & LDD_F_SV_TYPE_OST)) {
4220 for (i = 0; i < INDEX_MAP_SIZE * 8; i++) {
4221 if (!test_bit(i, fsdb->fsdb_mdt_index_map))
4223 name_destroy(&cname);
4224 rc = name_create_mdt_osc(&cname, mti->mti_svname,
4226 name_destroy(&logname);
4229 rc = name_create_mdt(&logname,
4230 mti->mti_fsname, i);
4233 if (!mgs_log_is_empty(env, mgs, logname)) {
4234 rc = mgs_wlp_lcfg(env, mgs, fsdb,
4244 /* For mdc activate/deactivate, it affects OSP on MDT as well */
4245 if (class_match_param(ptr, PARAM_MDC PARAM_ACTIVE, &tmp) == 0 &&
4248 char *lodname = NULL;
4249 char *param_str = NULL;
4253 /* replace mdc with osp */
4254 memcpy(ptr, PARAM_OSP, strlen(PARAM_OSP));
4255 rc = server_name2index(mti->mti_svname, &index, NULL);
4257 memcpy(ptr, PARAM_MDC, strlen(PARAM_MDC));
4261 for (i = 0; i < INDEX_MAP_SIZE * 8; i++) {
4262 if (!test_bit(i, fsdb->fsdb_mdt_index_map))
4268 name_destroy(&logname);
4269 rc = name_create_mdt(&logname, mti->mti_fsname,
4274 if (mgs_log_is_empty(env, mgs, logname))
4277 snprintf(suffix, sizeof(suffix), "-osp-MDT%04x",
4279 name_destroy(&cname);
4280 rc = name_create(&cname, mti->mti_svname,
4285 rc = mgs_wlp_lcfg(env, mgs, fsdb, mti, logname,
4286 &mgi->mgi_bufs, cname, ptr);
4290 /* Add configuration log for noitfying LOD
4291 * to active/deactive the OSP. */
4292 name_destroy(¶m_str);
4293 rc = name_create(¶m_str, cname,
4294 (*tmp == '0') ? ".active=0" :
4299 name_destroy(&lodname);
4300 rc = name_create(&lodname, logname, "-mdtlov");
4304 rc = mgs_wlp_lcfg(env, mgs, fsdb, mti, logname,
4305 &mgi->mgi_bufs, lodname,
4310 memcpy(ptr, PARAM_MDC, strlen(PARAM_MDC));
4311 name_destroy(&lodname);
4312 name_destroy(¶m_str);
4315 name_destroy(&logname);
4316 name_destroy(&cname);
4320 /* All mdt. params in proc */
4321 if (class_match_param(ptr, PARAM_MDT, &tmp) == 0) {
4325 CDEBUG(D_MGS, "%.3s param %s\n", ptr, ptr + 4);
4326 if (strncmp(mti->mti_svname, mti->mti_fsname,
4327 MTI_NAME_MAXLEN) == 0)
4328 /* device is unspecified completely? */
4329 rc = LDD_F_SV_TYPE_MDT | LDD_F_SV_ALL;
4331 rc = server_name2index(mti->mti_svname, &idx, NULL);
4334 if ((rc & LDD_F_SV_TYPE_MDT) == 0)
4336 if (rc & LDD_F_SV_ALL) {
4337 for (i = 0; i < INDEX_MAP_SIZE * 8; i++) {
4339 fsdb->fsdb_mdt_index_map))
4341 rc = name_create_mdt(&logname,
4342 mti->mti_fsname, i);
4345 rc = mgs_wlp_lcfg(env, mgs, fsdb, mti,
4346 logname, &mgi->mgi_bufs,
4348 name_destroy(&logname);
4353 if ((memcmp(tmp, "root_squash=", 12) == 0) ||
4354 (memcmp(tmp, "nosquash_nids=", 14) == 0)) {
4355 LCONSOLE_ERROR("%s: root squash parameters "
4356 "cannot be applied to a single MDT\n",
4358 GOTO(end, rc = -EINVAL);
4360 rc = mgs_wlp_lcfg(env, mgs, fsdb, mti,
4361 mti->mti_svname, &mgi->mgi_bufs,
4362 mti->mti_svname, ptr);
4367 /* root squash settings are also applied to llite
4368 * config log (see LU-1778) */
4370 ((memcmp(tmp, "root_squash=", 12) == 0) ||
4371 (memcmp(tmp, "nosquash_nids=", 14) == 0))) {
4375 rc = name_create(&cname, mti->mti_fsname, "-client");
4378 rc = name_create(&logname, mti->mti_fsname, "-client");
4380 name_destroy(&cname);
4383 rc = name_create(&ptr2, PARAM_LLITE, tmp);
4385 name_destroy(&cname);
4386 name_destroy(&logname);
4389 rc = mgs_wlp_lcfg(env, mgs, fsdb, mti, logname,
4390 &mgi->mgi_bufs, cname, ptr2);
4391 name_destroy(&ptr2);
4392 name_destroy(&logname);
4393 name_destroy(&cname);
4398 /* All mdd., ost. and osd. params in proc */
4399 if ((class_match_param(ptr, PARAM_MDD, NULL) == 0) ||
4400 (class_match_param(ptr, PARAM_LOD, NULL) == 0) ||
4401 (class_match_param(ptr, PARAM_OST, NULL) == 0) ||
4402 (class_match_param(ptr, PARAM_OSD, NULL) == 0)) {
4403 CDEBUG(D_MGS, "%.3s param %s\n", ptr, ptr + 4);
4404 if (mgs_log_is_empty(env, mgs, mti->mti_svname))
4405 GOTO(end, rc = -ENODEV);
4407 rc = mgs_wlp_lcfg(env, mgs, fsdb, mti, mti->mti_svname,
4408 &mgi->mgi_bufs, mti->mti_svname, ptr);
4412 /* For handling degraded zfs OST */
4413 if (class_match_param(ptr, PARAM_AUTODEGRADE, NULL) == 0)
4416 LCONSOLE_WARN("Ignoring unrecognized param '%s'\n", ptr);
4420 CERROR("err %d on param '%s'\n", rc, ptr);
4425 int mgs_write_log_target(const struct lu_env *env, struct mgs_device *mgs,
4426 struct mgs_target_info *mti, struct fs_db *fsdb)
4433 /* set/check the new target index */
4434 rc = mgs_set_index(env, mgs, mti);
4438 if (rc == EALREADY) {
4439 LCONSOLE_WARN("Found index %d for %s, updating log\n",
4440 mti->mti_stripe_index, mti->mti_svname);
4441 /* We would like to mark old log sections as invalid
4442 and add new log sections in the client and mdt logs.
4443 But if we add new sections, then live clients will
4444 get repeat setup instructions for already running
4445 osc's. So don't update the client/mdt logs. */
4446 mti->mti_flags &= ~LDD_F_UPDATE;
4450 OBD_FAIL_TIMEOUT(OBD_FAIL_MGS_WRITE_TARGET_DELAY, cfs_fail_val > 0 ?
4453 mutex_lock(&fsdb->fsdb_mutex);
4455 if (mti->mti_flags & (LDD_F_VIRGIN | LDD_F_WRITECONF)) {
4456 /* Generate a log from scratch */
4457 if (mti->mti_flags & LDD_F_SV_TYPE_MDT) {
4458 rc = mgs_write_log_mdt(env, mgs, fsdb, mti);
4459 } else if (mti->mti_flags & LDD_F_SV_TYPE_OST) {
4460 rc = mgs_write_log_ost(env, mgs, fsdb, mti);
4462 CERROR("Unknown target type %#x, can't create log for %s\n",
4463 mti->mti_flags, mti->mti_svname);
4466 CERROR("Can't write logs for %s (%d)\n",
4467 mti->mti_svname, rc);
4471 /* Just update the params from tunefs in mgs_write_log_params */
4472 CDEBUG(D_MGS, "Update params for %s\n", mti->mti_svname);
4473 mti->mti_flags |= LDD_F_PARAM;
4476 /* allocate temporary buffer, where class_get_next_param will
4477 * make copy of a current parameter
4479 OBD_ALLOC(buf, strlen(mti->mti_params) + 1);
4481 GOTO(out_up, rc = -ENOMEM);
4482 params = mti->mti_params;
4483 while (params != NULL) {
4484 rc = class_get_next_param(¶ms, buf);
4487 /* there is no next parameter, that is
4493 CDEBUG(D_MGS, "remaining string: '%s', param: '%s'\n",
4495 rc = mgs_write_log_param(env, mgs, fsdb, mti, buf);
4500 OBD_FREE(buf, strlen(mti->mti_params) + 1);
4503 mutex_unlock(&fsdb->fsdb_mutex);
4507 int mgs_erase_log(const struct lu_env *env, struct mgs_device *mgs, char *name)
4509 struct llog_ctxt *ctxt;
4512 ctxt = llog_get_context(mgs->mgs_obd, LLOG_CONFIG_ORIG_CTXT);
4514 CERROR("%s: MGS config context doesn't exist\n",
4515 mgs->mgs_obd->obd_name);
4518 rc = llog_erase(env, ctxt, NULL, name);
4519 /* llog may not exist */
4522 llog_ctxt_put(ctxt);
4526 CERROR("%s: failed to clear log %s: %d\n",
4527 mgs->mgs_obd->obd_name, name, rc);
4532 /* erase all logs for the given fs */
4533 int mgs_erase_logs(const struct lu_env *env, struct mgs_device *mgs,
4536 struct list_head log_list;
4537 struct mgs_direntry *dirent, *n;
4538 char barrier_name[20] = {};
4541 int rc, len = strlen(fsname);
4544 mutex_lock(&mgs->mgs_mutex);
4546 /* Find all the logs in the CONFIGS directory */
4547 rc = class_dentry_readdir(env, mgs, &log_list);
4549 mutex_unlock(&mgs->mgs_mutex);
4553 if (list_empty(&log_list)) {
4554 mutex_unlock(&mgs->mgs_mutex);
4558 snprintf(barrier_name, sizeof(barrier_name) - 1, "%s-%s",
4559 fsname, BARRIER_FILENAME);
4560 /* Delete the barrier fsdb */
4561 mgs_remove_fsdb_by_name(mgs, barrier_name);
4562 /* Delete the fs db */
4563 mgs_remove_fsdb_by_name(mgs, fsname);
4564 mutex_unlock(&mgs->mgs_mutex);
4566 list_for_each_entry_safe(dirent, n, &log_list, mde_list) {
4567 list_del_init(&dirent->mde_list);
4568 suffix = strrchr(dirent->mde_name, '-');
4569 if (suffix != NULL) {
4570 if ((len == suffix - dirent->mde_name) &&
4571 (strncmp(fsname, dirent->mde_name, len) == 0)) {
4572 CDEBUG(D_MGS, "Removing log %s\n",
4574 mgs_erase_log(env, mgs, dirent->mde_name);
4578 mgs_direntry_free(dirent);
4587 /* list all logs for the given fs */
4588 int mgs_list_logs(const struct lu_env *env, struct mgs_device *mgs,
4589 struct obd_ioctl_data *data)
4591 struct list_head log_list;
4592 struct mgs_direntry *dirent, *n;
4593 char *out, *suffix, prefix[] = "config_log: ";
4594 int prefix_len = strlen(prefix);
4595 int len, remains, start = 0, rc;
4599 /* Find all the logs in the CONFIGS directory */
4600 rc = class_dentry_readdir(env, mgs, &log_list);
4604 out = data->ioc_bulk;
4605 remains = data->ioc_inllen1;
4606 /* OBD_FAIL: fetch the config_log records from the specified one */
4607 if (OBD_FAIL_CHECK(OBD_FAIL_CATLIST))
4608 data->ioc_count = cfs_fail_val;
4610 list_for_each_entry_safe(dirent, n, &log_list, mde_list) {
4611 list_del_init(&dirent->mde_list);
4612 suffix = strrchr(dirent->mde_name, '-');
4613 if (suffix != NULL) {
4614 len = prefix_len + dirent->mde_len + 1;
4615 if (remains - len < 0) {
4616 /* No enough space for this record */
4617 mgs_direntry_free(dirent);
4621 if (start < data->ioc_count) {
4622 mgs_direntry_free(dirent);
4625 len = scnprintf(out, remains, "%s%s\n", prefix,
4630 mgs_direntry_free(dirent);
4638 data->ioc_count = start;
4642 struct mgs_lcfg_fork_data {
4643 struct lustre_cfg_bufs mlfd_bufs;
4644 struct mgs_device *mlfd_mgs;
4645 struct llog_handle *mlfd_llh;
4646 const char *mlfd_oldname;
4647 const char *mlfd_newname;
4651 static bool contain_valid_fsname(char *buf, const char *fsname,
4652 int buflen, int namelen)
4654 if (buflen < namelen)
4657 if (memcmp(buf, fsname, namelen) != 0)
4660 if (buf[namelen] != '\0' && buf[namelen] != '-')
4666 static int mgs_lcfg_fork_handler(const struct lu_env *env,
4667 struct llog_handle *o_llh,
4668 struct llog_rec_hdr *o_rec, void *data)
4670 struct mgs_lcfg_fork_data *mlfd = data;
4671 struct lustre_cfg_bufs *n_bufs = &mlfd->mlfd_bufs;
4672 struct lustre_cfg *o_lcfg = (struct lustre_cfg *)(o_rec + 1);
4673 struct llog_cfg_rec *lcr;
4675 char *n_buf = mlfd->mlfd_data;
4677 int o_namelen = strlen(mlfd->mlfd_oldname);
4678 int n_namelen = strlen(mlfd->mlfd_newname);
4679 int diff = n_namelen - o_namelen;
4680 __u32 cmd = o_lcfg->lcfg_command;
4681 __u32 cnt = o_lcfg->lcfg_bufcount;
4687 o_buf = lustre_cfg_buf(o_lcfg, 0);
4688 o_buflen = o_lcfg->lcfg_buflens[0];
4689 if (contain_valid_fsname(o_buf, mlfd->mlfd_oldname, o_buflen,
4691 memcpy(n_buf, mlfd->mlfd_newname, n_namelen);
4692 memcpy(n_buf + n_namelen, o_buf + o_namelen,
4693 o_buflen - o_namelen);
4694 lustre_cfg_bufs_reset(n_bufs, n_buf);
4695 n_buf += cfs_size_round(o_buflen + diff);
4697 lustre_cfg_bufs_reset(n_bufs, o_buflen != 0 ? o_buf : NULL);
4702 struct cfg_marker *o_marker;
4703 struct cfg_marker *n_marker;
4707 CDEBUG(D_MGS, "Unknown cfg marker entry with %d "
4712 /* buf[1] is marker */
4713 o_buf = lustre_cfg_buf(o_lcfg, 1);
4714 o_buflen = o_lcfg->lcfg_buflens[1];
4715 o_marker = (struct cfg_marker *)o_buf;
4716 if (!contain_valid_fsname(o_marker->cm_tgtname,
4718 sizeof(o_marker->cm_tgtname),
4720 lustre_cfg_bufs_set(n_bufs, 1, o_marker,
4725 n_marker = (struct cfg_marker *)n_buf;
4726 *n_marker = *o_marker;
4727 memcpy(n_marker->cm_tgtname, mlfd->mlfd_newname, n_namelen);
4728 tgt_namelen = strlen(o_marker->cm_tgtname);
4729 if (tgt_namelen > o_namelen)
4730 memcpy(n_marker->cm_tgtname + n_namelen,
4731 o_marker->cm_tgtname + o_namelen,
4732 tgt_namelen - o_namelen);
4733 n_marker->cm_tgtname[tgt_namelen + diff] = '\0';
4734 lustre_cfg_bufs_set(n_bufs, 1, n_marker, sizeof(*n_marker));
4738 case LCFG_SET_PARAM: {
4739 for (i = 1; i < cnt; i++)
4740 /* buf[i] is the param value, reuse it directly */
4741 lustre_cfg_bufs_set(n_bufs, i,
4742 lustre_cfg_buf(o_lcfg, i),
4743 o_lcfg->lcfg_buflens[i]);
4749 case LCFG_POOL_DEL: {
4750 if (cnt < 3 || cnt > 4) {
4751 CDEBUG(D_MGS, "Unknown cfg pool (%x) entry with %d "
4752 "buffers\n", cmd, cnt);
4756 /* buf[1] is fsname */
4757 o_buf = lustre_cfg_buf(o_lcfg, 1);
4758 o_buflen = o_lcfg->lcfg_buflens[1];
4759 memcpy(n_buf, mlfd->mlfd_newname, n_namelen);
4760 memcpy(n_buf + n_namelen, o_buf + o_namelen,
4761 o_buflen - o_namelen);
4762 lustre_cfg_bufs_set(n_bufs, 1, n_buf, o_buflen + diff);
4763 n_buf += cfs_size_round(o_buflen + diff);
4765 /* buf[2] is the pool name, reuse it directly */
4766 lustre_cfg_bufs_set(n_bufs, 2, lustre_cfg_buf(o_lcfg, 2),
4767 o_lcfg->lcfg_buflens[2]);
4772 /* buf[3] is ostname */
4773 o_buf = lustre_cfg_buf(o_lcfg, 3);
4774 o_buflen = o_lcfg->lcfg_buflens[3];
4775 memcpy(n_buf, mlfd->mlfd_newname, n_namelen);
4776 memcpy(n_buf + n_namelen, o_buf + o_namelen,
4777 o_buflen - o_namelen);
4778 lustre_cfg_bufs_set(n_bufs, 3, n_buf, o_buflen + diff);
4783 o_buflen = o_lcfg->lcfg_buflens[1];
4784 if (o_buflen == sizeof(struct lov_desc) ||
4785 o_buflen == sizeof(struct lmv_desc)) {
4791 o_buf = lustre_cfg_buf(o_lcfg, 1);
4792 if (o_buflen == sizeof(struct lov_desc)) {
4793 struct lov_desc *o_desc =
4794 (struct lov_desc *)o_buf;
4795 struct lov_desc *n_desc =
4796 (struct lov_desc *)n_buf;
4799 o_uuid = o_desc->ld_uuid.uuid;
4800 n_uuid = n_desc->ld_uuid.uuid;
4801 uuid_len = sizeof(o_desc->ld_uuid.uuid);
4803 struct lmv_desc *o_desc =
4804 (struct lmv_desc *)o_buf;
4805 struct lmv_desc *n_desc =
4806 (struct lmv_desc *)n_buf;
4809 o_uuid = o_desc->ld_uuid.uuid;
4810 n_uuid = n_desc->ld_uuid.uuid;
4811 uuid_len = sizeof(o_desc->ld_uuid.uuid);
4814 if (unlikely(!contain_valid_fsname(o_uuid,
4815 mlfd->mlfd_oldname, uuid_len,
4817 lustre_cfg_bufs_set(n_bufs, 1, o_buf,
4822 memcpy(n_uuid, mlfd->mlfd_newname, n_namelen);
4823 uuid_len = strlen(o_uuid);
4824 if (uuid_len > o_namelen)
4825 memcpy(n_uuid + n_namelen,
4827 uuid_len - o_namelen);
4828 n_uuid[uuid_len + diff] = '\0';
4829 lustre_cfg_bufs_set(n_bufs, 1, n_buf, o_buflen);
4831 } /* else case fall through */
4832 } /* else case fall through */
4836 for (i = 1; i < cnt; i++) {
4837 o_buflen = o_lcfg->lcfg_buflens[i];
4841 o_buf = lustre_cfg_buf(o_lcfg, i);
4842 if (!contain_valid_fsname(o_buf, mlfd->mlfd_oldname,
4843 o_buflen, o_namelen)) {
4844 lustre_cfg_bufs_set(n_bufs, i, o_buf, o_buflen);
4848 memcpy(n_buf, mlfd->mlfd_newname, n_namelen);
4849 if (o_buflen == o_namelen) {
4850 lustre_cfg_bufs_set(n_bufs, i, n_buf,
4852 n_buf += cfs_size_round(n_namelen);
4856 memcpy(n_buf + n_namelen, o_buf + o_namelen,
4857 o_buflen - o_namelen);
4858 lustre_cfg_bufs_set(n_bufs, i, n_buf, o_buflen + diff);
4859 n_buf += cfs_size_round(o_buflen + diff);
4865 lcr = lustre_cfg_rec_new(cmd, n_bufs);
4869 lcr->lcr_cfg = *o_lcfg;
4870 rc = llog_write(env, mlfd->mlfd_llh, &lcr->lcr_hdr, LLOG_NEXT_IDX);
4871 lustre_cfg_rec_free(lcr);
4876 static int mgs_lcfg_fork_one(const struct lu_env *env, struct mgs_device *mgs,
4877 struct mgs_direntry *mde, const char *oldname,
4878 const char *newname)
4880 struct llog_handle *old_llh = NULL;
4881 struct llog_handle *new_llh = NULL;
4882 struct llog_ctxt *ctxt = NULL;
4883 struct mgs_lcfg_fork_data *mlfd = NULL;
4884 char *name_buf = NULL;
4886 int old_namelen = strlen(oldname);
4887 int new_namelen = strlen(newname);
4891 name_buflen = mde->mde_len + new_namelen - old_namelen;
4892 OBD_ALLOC(name_buf, name_buflen);
4896 memcpy(name_buf, newname, new_namelen);
4897 memcpy(name_buf + new_namelen, mde->mde_name + old_namelen,
4898 mde->mde_len - old_namelen);
4900 CDEBUG(D_MGS, "Fork the config-log from %s to %s\n",
4901 mde->mde_name, name_buf);
4903 ctxt = llog_get_context(mgs->mgs_obd, LLOG_CONFIG_ORIG_CTXT);
4906 rc = llog_open_create(env, ctxt, &new_llh, NULL, name_buf);
4910 rc = llog_init_handle(env, new_llh, LLOG_F_IS_PLAIN, NULL);
4914 if (unlikely(mgs_log_is_empty(env, mgs, mde->mde_name)))
4917 rc = llog_open(env, ctxt, &old_llh, NULL, mde->mde_name,
4922 rc = llog_init_handle(env, old_llh, LLOG_F_IS_PLAIN, NULL);
4926 new_llh->lgh_hdr->llh_tgtuuid = old_llh->lgh_hdr->llh_tgtuuid;
4928 OBD_ALLOC(mlfd, LLOG_MIN_CHUNK_SIZE);
4930 GOTO(out, rc = -ENOMEM);
4932 mlfd->mlfd_mgs = mgs;
4933 mlfd->mlfd_llh = new_llh;
4934 mlfd->mlfd_oldname = oldname;
4935 mlfd->mlfd_newname = newname;
4937 rc = llog_process(env, old_llh, mgs_lcfg_fork_handler, mlfd, NULL);
4938 OBD_FREE(mlfd, LLOG_MIN_CHUNK_SIZE);
4944 llog_close(env, old_llh);
4946 llog_close(env, new_llh);
4948 OBD_FREE(name_buf, name_buflen);
4950 llog_ctxt_put(ctxt);
4955 int mgs_lcfg_fork(const struct lu_env *env, struct mgs_device *mgs,
4956 const char *oldname, const char *newname)
4958 struct list_head log_list;
4959 struct mgs_direntry *dirent, *n;
4960 int olen = strlen(oldname);
4961 int nlen = strlen(newname);
4966 if (unlikely(!oldname || oldname[0] == '\0' ||
4967 !newname || newname[0] == '\0'))
4970 if (strcmp(oldname, newname) == 0)
4973 /* lock it to prevent fork/erase/register in parallel. */
4974 mutex_lock(&mgs->mgs_mutex);
4976 rc = class_dentry_readdir(env, mgs, &log_list);
4978 mutex_unlock(&mgs->mgs_mutex);
4982 if (list_empty(&log_list)) {
4983 mutex_unlock(&mgs->mgs_mutex);
4987 list_for_each_entry_safe(dirent, n, &log_list, mde_list) {
4990 ptr = strrchr(dirent->mde_name, '-');
4992 int tlen = ptr - dirent->mde_name;
4995 strncmp(newname, dirent->mde_name, tlen) == 0)
4996 GOTO(out, rc = -EEXIST);
4999 strncmp(oldname, dirent->mde_name, tlen) == 0)
5003 list_del_init(&dirent->mde_list);
5004 mgs_direntry_free(dirent);
5007 if (list_empty(&log_list)) {
5008 mutex_unlock(&mgs->mgs_mutex);
5012 list_for_each_entry(dirent, &log_list, mde_list) {
5013 rc = mgs_lcfg_fork_one(env, mgs, dirent, oldname, newname);
5021 mutex_unlock(&mgs->mgs_mutex);
5023 list_for_each_entry_safe(dirent, n, &log_list, mde_list) {
5024 list_del_init(&dirent->mde_list);
5025 mgs_direntry_free(dirent);
5028 if (rc && count > 0)
5029 mgs_erase_logs(env, mgs, newname);
5034 int mgs_lcfg_erase(const struct lu_env *env, struct mgs_device *mgs,
5040 if (unlikely(!fsname || fsname[0] == '\0'))
5043 rc = mgs_erase_logs(env, mgs, fsname);
5048 static int mgs_xattr_del(const struct lu_env *env, struct dt_object *obj)
5050 struct dt_device *dev;
5051 struct thandle *th = NULL;
5056 dev = container_of(obj->do_lu.lo_dev, struct dt_device, dd_lu_dev);
5057 th = dt_trans_create(env, dev);
5059 RETURN(PTR_ERR(th));
5061 rc = dt_declare_xattr_del(env, obj, XATTR_TARGET_RENAME, th);
5065 rc = dt_trans_start_local(env, dev, th);
5069 dt_write_lock(env, obj, 0);
5070 rc = dt_xattr_del(env, obj, XATTR_TARGET_RENAME, th);
5075 dt_write_unlock(env, obj);
5078 dt_trans_stop(env, dev, th);
5083 int mgs_lcfg_rename(const struct lu_env *env, struct mgs_device *mgs)
5085 struct list_head log_list;
5086 struct mgs_direntry *dirent, *n;
5088 struct lu_buf buf = {
5090 .lb_len = sizeof(fsname)
5096 rc = class_dentry_readdir(env, mgs, &log_list);
5100 if (list_empty(&log_list))
5103 list_for_each_entry_safe(dirent, n, &log_list, mde_list) {
5104 struct dt_object *o = NULL;
5109 list_del_init(&dirent->mde_list);
5110 ptr = strrchr(dirent->mde_name, '-');
5114 len = ptr - dirent->mde_name;
5115 if (unlikely(len >= sizeof(oldname))) {
5116 CDEBUG(D_MGS, "Skip invalid configuration file %s\n",
5121 o = local_file_find(env, mgs->mgs_los, mgs->mgs_configs_dir,
5125 CDEBUG(D_MGS, "Fail to locate file %s: rc = %d\n",
5126 dirent->mde_name, rc);
5130 rc = dt_xattr_get(env, o, &buf, XATTR_TARGET_RENAME);
5136 "Fail to get EA for %s: rc = %d\n",
5137 dirent->mde_name, rc);
5141 if (unlikely(rc == len &&
5142 memcmp(fsname, dirent->mde_name, len) == 0)) {
5143 /* The new fsname is the same as the old one. */
5144 rc = mgs_xattr_del(env, o);
5148 memcpy(oldname, dirent->mde_name, len);
5149 oldname[len] = '\0';
5151 rc = mgs_lcfg_fork_one(env, mgs, dirent, oldname, fsname);
5152 if (rc && rc != -EEXIST) {
5153 CDEBUG(D_MGS, "Fail to fork %s: rc = %d\n",
5154 dirent->mde_name, rc);
5158 rc = mgs_erase_log(env, mgs, dirent->mde_name);
5160 CDEBUG(D_MGS, "Fail to erase old %s: rc = %d\n",
5161 dirent->mde_name, rc);
5162 /* keep it there if failed to remove it. */
5167 if (o && !IS_ERR(o))
5168 lu_object_put(env, &o->do_lu);
5170 mgs_direntry_free(dirent);
5175 list_for_each_entry_safe(dirent, n, &log_list, mde_list) {
5176 list_del_init(&dirent->mde_list);
5177 mgs_direntry_free(dirent);
5183 /* Setup _mgs fsdb and log
5185 int mgs__mgs_fsdb_setup(const struct lu_env *env, struct mgs_device *mgs)
5187 struct fs_db *fsdb = NULL;
5191 rc = mgs_find_or_make_fsdb(env, mgs, MGSSELF_NAME, &fsdb);
5193 mgs_put_fsdb(mgs, fsdb);
5198 /* Setup params fsdb and log
5200 int mgs_params_fsdb_setup(const struct lu_env *env, struct mgs_device *mgs)
5202 struct fs_db *fsdb = NULL;
5203 struct llog_handle *params_llh = NULL;
5207 rc = mgs_find_or_make_fsdb(env, mgs, PARAMS_FILENAME, &fsdb);
5209 mutex_lock(&fsdb->fsdb_mutex);
5210 rc = record_start_log(env, mgs, ¶ms_llh, PARAMS_FILENAME);
5212 rc = record_end_log(env, ¶ms_llh);
5213 mutex_unlock(&fsdb->fsdb_mutex);
5214 mgs_put_fsdb(mgs, fsdb);
5220 /* Cleanup params fsdb and log
5222 int mgs_params_fsdb_cleanup(const struct lu_env *env, struct mgs_device *mgs)
5226 rc = mgs_erase_logs(env, mgs, PARAMS_FILENAME);
5227 return rc == -ENOENT ? 0 : rc;
5231 * Fill in the mgs_target_info based on data devname and param provide.
5233 * @env thread context
5235 * @mti mgs target info. We want to set this based other paramters
5236 * passed to this function. Once setup we write it to the config
5238 * @devname optional OBD device name
5239 * @param string that contains both what tunable to set and the value to
5242 * RETURN 0 for success
5243 * negative error number on failure
5245 static int mgs_set_conf_param(const struct lu_env *env, struct mgs_device *mgs,
5246 struct mgs_target_info *mti, const char *devname,
5249 struct fs_db *fsdb = NULL;
5254 /* lustre, lustre-mdtlov, lustre-client, lustre-MDT0000 */
5258 /* We have two possible cases here:
5260 * 1) the device name embedded in the param:
5261 * lustre-OST0000.osc.max_dirty_mb=32
5263 * 2) the file system name is embedded in
5264 * the param: lustre.sys.at.min=0
5266 len = strcspn(param, ".=");
5267 if (!len || param[len] == '=')
5270 if (len >= sizeof(mti->mti_svname))
5273 snprintf(mti->mti_svname, sizeof(mti->mti_svname),
5274 "%.*s", (int)len, param);
5277 if (strlcpy(mti->mti_svname, devname, sizeof(mti->mti_svname)) >=
5278 sizeof(mti->mti_svname))
5282 if (!strlen(mti->mti_svname)) {
5283 LCONSOLE_ERROR_MSG(0x14d, "No target specified: %s\n", param);
5287 dev_type = mgs_parse_devname(mti->mti_svname, mti->mti_fsname,
5288 &mti->mti_stripe_index);
5290 /* For this case we have an invalid obd device name */
5292 CDEBUG(D_MGS, "%s don't contain an index\n", mti->mti_svname);
5293 strlcpy(mti->mti_fsname, mti->mti_svname, MTI_NAME_MAXLEN);
5296 /* Not an obd device, assume devname is the fsname.
5297 * User might of only provided fsname and not obd device
5300 CDEBUG(D_MGS, "%s is seen as a file system name\n", mti->mti_svname);
5301 strlcpy(mti->mti_fsname, mti->mti_svname, MTI_NAME_MAXLEN);
5306 GOTO(out, rc = dev_type);
5308 /* param related to llite isn't allowed to set by OST or MDT */
5309 if (dev_type & LDD_F_SV_TYPE_OST ||
5310 dev_type & LDD_F_SV_TYPE_MDT) {
5311 /* param related to llite isn't allowed to set by OST
5314 if (!strncmp(param, PARAM_LLITE,
5315 sizeof(PARAM_LLITE) - 1))
5316 GOTO(out, rc = -EINVAL);
5318 /* Strip -osc or -mdc suffix from svname */
5319 if (server_make_name(dev_type, mti->mti_stripe_index,
5320 mti->mti_fsname, mti->mti_svname,
5321 sizeof(mti->mti_svname)))
5322 GOTO(out, rc = -EINVAL);
5327 if (strlcpy(mti->mti_params, param, sizeof(mti->mti_params)) >=
5328 sizeof(mti->mti_params))
5329 GOTO(out, rc = -E2BIG);
5331 CDEBUG(D_MGS, "set_conf_param fs='%s' device='%s' param='%s'\n",
5332 mti->mti_fsname, mti->mti_svname, mti->mti_params);
5334 rc = mgs_find_or_make_fsdb(env, mgs, mti->mti_fsname, &fsdb);
5338 if (!test_bit(FSDB_MGS_SELF, &fsdb->fsdb_flags) &&
5339 test_bit(FSDB_LOG_EMPTY, &fsdb->fsdb_flags)) {
5340 CERROR("No filesystem targets for %s. cfg_device from lctl "
5341 "is '%s'\n", mti->mti_fsname, mti->mti_svname);
5342 mgs_unlink_fsdb(mgs, fsdb);
5343 GOTO(out, rc = -EINVAL);
5347 * Revoke lock so everyone updates. Should be alright if
5348 * someone was already reading while we were updating the logs,
5349 * so we don't really need to hold the lock while we're
5352 mti->mti_flags = dev_type | LDD_F_PARAM;
5353 mutex_lock(&fsdb->fsdb_mutex);
5354 rc = mgs_write_log_param(env, mgs, fsdb, mti, mti->mti_params);
5355 mutex_unlock(&fsdb->fsdb_mutex);
5356 mgs_revoke_lock(mgs, fsdb, MGS_CFG_T_CONFIG);
5360 mgs_put_fsdb(mgs, fsdb);
5365 static int mgs_set_param2(const struct lu_env *env, struct mgs_device *mgs,
5366 struct mgs_target_info *mti, const char *param)
5368 struct fs_db *fsdb = NULL;
5373 if (strlcpy(mti->mti_params, param, sizeof(mti->mti_params)) >=
5374 sizeof(mti->mti_params))
5375 GOTO(out, rc = -E2BIG);
5377 len = strcspn(param, ".=");
5378 if (len && param[len] != '=') {
5379 struct list_head *tmp;
5383 ptr = strchr(param, '.');
5385 len = strlen(param);
5388 if (len >= sizeof(mti->mti_svname))
5389 GOTO(out, rc = -E2BIG);
5391 snprintf(mti->mti_svname, sizeof(mti->mti_svname), "%.*s",
5394 mutex_lock(&mgs->mgs_mutex);
5395 if (unlikely(list_empty(&mgs->mgs_fs_db_list))) {
5396 mutex_unlock(&mgs->mgs_mutex);
5397 GOTO(out, rc = -ENODEV);
5400 list_for_each(tmp, &mgs->mgs_fs_db_list) {
5401 fsdb = list_entry(tmp, struct fs_db, fsdb_list);
5402 if (fsdb->fsdb_has_lproc_entry &&
5403 strcmp(fsdb->fsdb_name, "params") != 0 &&
5404 strstr(param, fsdb->fsdb_name)) {
5405 snprintf(mti->mti_svname,
5406 sizeof(mti->mti_svname), "%s",
5414 snprintf(mti->mti_svname, sizeof(mti->mti_svname),
5417 mutex_unlock(&mgs->mgs_mutex);
5419 snprintf(mti->mti_svname, sizeof(mti->mti_svname), "general");
5422 CDEBUG(D_MGS, "set_param2 fs='%s' device='%s' param='%s'\n",
5423 mti->mti_fsname, mti->mti_svname, mti->mti_params);
5425 /* The return value should be the device type i.e LDD_F_SV_TYPE_XXX.
5426 * A returned error tells us we don't have a target obd device.
5428 dev_type = server_name2index(mti->mti_svname, &mti->mti_stripe_index,
5433 /* the return value should be the device type i.e LDD_F_SV_TYPE_XXX.
5434 * Strip -osc or -mdc suffix from svname
5436 if ((dev_type & LDD_F_SV_TYPE_OST || dev_type & LDD_F_SV_TYPE_MDT) &&
5437 server_make_name(dev_type, mti->mti_stripe_index,
5438 mti->mti_fsname, mti->mti_svname,
5439 sizeof(mti->mti_svname)))
5440 GOTO(out, rc = -EINVAL);
5442 rc = mgs_find_or_make_fsdb(env, mgs, PARAMS_FILENAME, &fsdb);
5446 * Revoke lock so everyone updates. Should be alright if
5447 * someone was already reading while we were updating the logs,
5448 * so we don't really need to hold the lock while we're
5451 mti->mti_flags = dev_type | LDD_F_PARAM2;
5452 mutex_lock(&fsdb->fsdb_mutex);
5453 rc = mgs_write_log_param2(env, mgs, fsdb, mti, mti->mti_params);
5454 mutex_unlock(&fsdb->fsdb_mutex);
5455 mgs_revoke_lock(mgs, fsdb, MGS_CFG_T_PARAMS);
5456 mgs_put_fsdb(mgs, fsdb);
5461 /* Set a permanent (config log) param for a target or fs
5463 * @lcfg buf0 may contain the device (testfs-MDT0000) name
5464 * buf1 contains the single parameter
5466 int mgs_set_param(const struct lu_env *env, struct mgs_device *mgs,
5467 struct lustre_cfg *lcfg)
5469 const char *param = lustre_cfg_string(lcfg, 1);
5470 struct mgs_target_info *mti;
5473 /* Create a fake mti to hold everything */
5478 print_lustre_cfg(lcfg);
5480 if (lcfg->lcfg_command == LCFG_PARAM) {
5481 /* For the case of lctl conf_param devname can be
5482 * lustre, lustre-mdtlov, lustre-client, lustre-MDT0000
5484 const char *devname = lustre_cfg_string(lcfg, 0);
5486 rc = mgs_set_conf_param(env, mgs, mti, devname, param);
5488 /* In the case of lctl set_param -P lcfg[0] will always
5489 * be 'general'. At least for now.
5491 rc = mgs_set_param2(env, mgs, mti, param);
5499 static int mgs_write_log_pool(const struct lu_env *env,
5500 struct mgs_device *mgs, char *logname,
5501 struct fs_db *fsdb, char *tgtname,
5502 enum lcfg_command_type cmd,
5503 char *fsname, char *poolname,
5504 char *ostname, char *comment)
5506 struct llog_handle *llh = NULL;
5509 rc = record_start_log(env, mgs, &llh, logname);
5512 rc = record_marker(env, llh, fsdb, CM_START, tgtname, comment);
5515 rc = record_base(env, llh, tgtname, 0, cmd,
5516 fsname, poolname, ostname, NULL);
5519 rc = record_marker(env, llh, fsdb, CM_END, tgtname, comment);
5521 record_end_log(env, &llh);
5525 int mgs_nodemap_cmd(const struct lu_env *env, struct mgs_device *mgs,
5526 enum lcfg_command_type cmd, const char *nodemap_name,
5537 case LCFG_NODEMAP_ADD:
5538 rc = nodemap_add(nodemap_name);
5540 case LCFG_NODEMAP_DEL:
5541 rc = nodemap_del(nodemap_name);
5543 case LCFG_NODEMAP_ADD_RANGE:
5544 rc = nodemap_parse_range(param, nid);
5547 rc = nodemap_add_range(nodemap_name, nid);
5549 case LCFG_NODEMAP_DEL_RANGE:
5550 rc = nodemap_parse_range(param, nid);
5553 rc = nodemap_del_range(nodemap_name, nid);
5555 case LCFG_NODEMAP_ADMIN:
5556 rc = kstrtobool(param, &bool_switch);
5559 rc = nodemap_set_allow_root(nodemap_name, bool_switch);
5561 case LCFG_NODEMAP_DENY_UNKNOWN:
5562 rc = kstrtobool(param, &bool_switch);
5565 rc = nodemap_set_deny_unknown(nodemap_name, bool_switch);
5567 case LCFG_NODEMAP_AUDIT_MODE:
5568 rc = kstrtobool(param, &bool_switch);
5570 rc = nodemap_set_audit_mode(nodemap_name, bool_switch);
5572 case LCFG_NODEMAP_FORBID_ENCRYPT:
5573 rc = kstrtobool(param, &bool_switch);
5575 rc = nodemap_set_forbid_encryption(nodemap_name,
5578 case LCFG_NODEMAP_READONLY_MOUNT:
5579 rc = kstrtobool(param, &bool_switch);
5581 rc = nodemap_set_readonly_mount(nodemap_name,
5584 case LCFG_NODEMAP_MAP_MODE:
5589 if ((p = strstr(param, "all")) != NULL) {
5590 if ((p == param || *(p-1) == ',') &&
5591 (*(p+3) == '\0' || *(p+3) == ',')) {
5592 map_mode = NODEMAP_MAP_ALL;
5598 while ((p = strsep(¶m, ",")) != NULL) {
5602 if (strcmp("both", p) == 0)
5603 map_mode |= NODEMAP_MAP_BOTH;
5604 else if (strcmp("uid_only", p) == 0 ||
5605 strcmp("uid", p) == 0)
5606 map_mode |= NODEMAP_MAP_UID;
5607 else if (strcmp("gid_only", p) == 0 ||
5608 strcmp("gid", p) == 0)
5609 map_mode |= NODEMAP_MAP_GID;
5610 else if (strcmp("projid_only", p) == 0 ||
5611 strcmp("projid", p) == 0)
5612 map_mode |= NODEMAP_MAP_PROJID;
5622 rc = nodemap_set_mapping_mode(nodemap_name, map_mode);
5625 case LCFG_NODEMAP_RBAC:
5627 enum nodemap_rbac_roles rbac;
5630 if (strcmp(param, "all") == 0) {
5631 rbac = NODEMAP_RBAC_ALL;
5632 } else if (strcmp(param, "none") == 0) {
5633 rbac = NODEMAP_RBAC_NONE;
5635 rbac = NODEMAP_RBAC_NONE;
5636 while ((p = strsep(¶m, ",")) != NULL) {
5642 for (i = 0; i < ARRAY_SIZE(nodemap_rbac_names);
5645 nodemap_rbac_names[i].nrn_name)
5648 nodemap_rbac_names[i].nrn_mode;
5652 if (i == ARRAY_SIZE(nodemap_rbac_names))
5661 rc = nodemap_set_rbac(nodemap_name, rbac);
5664 case LCFG_NODEMAP_TRUSTED:
5665 rc = kstrtobool(param, &bool_switch);
5668 rc = nodemap_set_trust_client_ids(nodemap_name, bool_switch);
5670 case LCFG_NODEMAP_SQUASH_UID:
5671 rc = kstrtouint(param, 10, &int_id);
5674 rc = nodemap_set_squash_uid(nodemap_name, int_id);
5676 case LCFG_NODEMAP_SQUASH_GID:
5677 rc = kstrtouint(param, 10, &int_id);
5680 rc = nodemap_set_squash_gid(nodemap_name, int_id);
5682 case LCFG_NODEMAP_SQUASH_PROJID:
5683 rc = kstrtouint(param, 10, &int_id);
5686 rc = nodemap_set_squash_projid(nodemap_name, int_id);
5688 case LCFG_NODEMAP_ADD_UIDMAP:
5689 case LCFG_NODEMAP_ADD_GIDMAP:
5690 case LCFG_NODEMAP_ADD_PROJIDMAP:
5691 rc = nodemap_parse_idmap(param, idmap);
5694 if (cmd == LCFG_NODEMAP_ADD_UIDMAP)
5695 rc = nodemap_add_idmap(nodemap_name, NODEMAP_UID,
5697 else if (cmd == LCFG_NODEMAP_ADD_GIDMAP)
5698 rc = nodemap_add_idmap(nodemap_name, NODEMAP_GID,
5700 else if (cmd == LCFG_NODEMAP_ADD_PROJIDMAP)
5701 rc = nodemap_add_idmap(nodemap_name, NODEMAP_PROJID,
5706 case LCFG_NODEMAP_DEL_UIDMAP:
5707 case LCFG_NODEMAP_DEL_GIDMAP:
5708 case LCFG_NODEMAP_DEL_PROJIDMAP:
5709 rc = nodemap_parse_idmap(param, idmap);
5712 if (cmd == LCFG_NODEMAP_DEL_UIDMAP)
5713 rc = nodemap_del_idmap(nodemap_name, NODEMAP_UID,
5715 else if (cmd == LCFG_NODEMAP_DEL_GIDMAP)
5716 rc = nodemap_del_idmap(nodemap_name, NODEMAP_GID,
5718 else if (cmd == LCFG_NODEMAP_DEL_PROJIDMAP)
5719 rc = nodemap_del_idmap(nodemap_name, NODEMAP_PROJID,
5724 case LCFG_NODEMAP_SET_FILESET:
5725 rc = nodemap_set_fileset(nodemap_name, param);
5727 case LCFG_NODEMAP_SET_SEPOL:
5728 rc = nodemap_set_sepol(nodemap_name, param);
5737 int mgs_pool_cmd(const struct lu_env *env, struct mgs_device *mgs,
5738 enum lcfg_command_type cmd, char *fsname,
5739 char *poolname, char *ostname)
5744 char *label = NULL, *canceled_label = NULL;
5746 struct mgs_target_info *mti = NULL;
5747 bool checked = false;
5748 bool locked = false;
5753 rc = mgs_find_or_make_fsdb(env, mgs, fsname, &fsdb);
5755 CERROR("Can't get db for %s\n", fsname);
5758 if (test_bit(FSDB_LOG_EMPTY, &fsdb->fsdb_flags)) {
5759 CERROR("%s is not defined\n", fsname);
5761 GOTO(out_fsdb, rc = -EINVAL);
5764 label_sz = 10 + strlen(fsname) + strlen(poolname);
5766 /* check if ostname match fsname */
5767 if (ostname != NULL) {
5770 ptr = strrchr(ostname, '-');
5771 if ((ptr == NULL) ||
5772 (strncmp(fsname, ostname, ptr-ostname) != 0))
5774 label_sz += strlen(ostname);
5777 OBD_ALLOC(label, label_sz);
5779 GOTO(out_fsdb, rc = -ENOMEM);
5783 sprintf(label, "new %s.%s", fsname, poolname);
5786 sprintf(label, "add %s.%s.%s", fsname, poolname, ostname);
5789 OBD_ALLOC(canceled_label, label_sz);
5790 if (canceled_label == NULL)
5791 GOTO(out_label, rc = -ENOMEM);
5792 sprintf(label, "rem %s.%s.%s", fsname, poolname, ostname);
5793 sprintf(canceled_label, "add %s.%s.%s",
5794 fsname, poolname, ostname);
5797 OBD_ALLOC(canceled_label, label_sz);
5798 if (canceled_label == NULL)
5799 GOTO(out_label, rc = -ENOMEM);
5800 sprintf(label, "del %s.%s", fsname, poolname);
5801 sprintf(canceled_label, "new %s.%s", fsname, poolname);
5809 GOTO(out_cancel, rc = -ENOMEM);
5810 strncpy(mti->mti_svname, "lov pool", sizeof(mti->mti_svname));
5812 mutex_lock(&fsdb->fsdb_mutex);
5814 /* write pool def to all MDT logs */
5815 for (i = 0; i < INDEX_MAP_SIZE * 8; i++) {
5816 if (test_bit(i, fsdb->fsdb_mdt_index_map)) {
5817 rc = name_create_mdt_and_lov(&logname, &lovname,
5822 if (!checked && (canceled_label == NULL)) {
5823 rc = mgs_check_marker(env, mgs, fsdb, mti,
5824 logname, lovname, label);
5826 name_destroy(&logname);
5827 name_destroy(&lovname);
5829 rc = (rc == LLOG_PROC_BREAK ?
5834 if (canceled_label != NULL)
5835 rc = mgs_modify(env, mgs, fsdb, mti, logname,
5836 lovname, canceled_label,
5840 rc = mgs_write_log_pool(env, mgs, logname,
5844 name_destroy(&logname);
5845 name_destroy(&lovname);
5851 rc = name_create(&logname, fsname, "-client");
5855 if (!checked && (canceled_label == NULL)) {
5856 rc = mgs_check_marker(env, mgs, fsdb, mti, logname,
5857 fsdb->fsdb_clilov, label);
5859 name_destroy(&logname);
5860 GOTO(out_mti, rc = (rc == LLOG_PROC_BREAK ?
5864 if (canceled_label != NULL) {
5865 rc = mgs_modify(env, mgs, fsdb, mti, logname,
5866 fsdb->fsdb_clilov, canceled_label, CM_SKIP);
5868 name_destroy(&logname);
5873 rc = mgs_write_log_pool(env, mgs, logname, fsdb, fsdb->fsdb_clilov,
5874 cmd, fsname, poolname, ostname, label);
5875 mutex_unlock(&fsdb->fsdb_mutex);
5877 name_destroy(&logname);
5878 /* request for update */
5879 mgs_revoke_lock(mgs, fsdb, MGS_CFG_T_CONFIG);
5885 mutex_unlock(&fsdb->fsdb_mutex);
5889 if (canceled_label != NULL)
5890 OBD_FREE(canceled_label, label_sz);
5892 OBD_FREE(label, label_sz);
5895 mgs_unlink_fsdb(mgs, fsdb);
5896 mgs_put_fsdb(mgs, fsdb);