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)
1133 struct lnet_nid nid;
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_nid(ptr, &nid, &ptr) == 0) {
1143 if (!mrd->nodeuuid) {
1144 rc = name_create(&mrd->nodeuuid,
1145 libcfs_nidstr(&nid), "");
1147 CERROR("Can't create uuid for "
1148 "nid %s, device %s\n",
1149 libcfs_nidstr(&nid),
1150 mrd->target.mti_svname);
1154 CDEBUG(D_MGS, "add nid %s with uuid %s, device %s\n",
1155 libcfs_nidstr(&nid),
1156 mrd->target.mti_params,
1158 rc = record_add_uuid(env,
1159 mrd->temp_llh, &nid,
1162 CWARN("%s: Can't add nid %s for uuid %s :rc=%d\n",
1163 mrd->target.mti_svname,
1164 libcfs_nidstr(&nid),
1170 mrd->failover = ptr;
1175 if (nids_added == 0) {
1176 CERROR("No new nids were added, nid %s with uuid %s, device %s\n",
1177 libcfs_nidstr(&nid),
1178 mrd->nodeuuid ? mrd->nodeuuid : "NULL",
1179 mrd->target.mti_svname);
1180 name_destroy(&mrd->nodeuuid);
1183 mrd->state = REPLACE_SETUP;
1189 if (mrd->state == REPLACE_SETUP && lcfg->lcfg_command == LCFG_SETUP) {
1190 /* LCFG_SETUP command found. UUID should be changed */
1191 rc = record_setup(env,
1193 /* devname the same */
1194 lustre_cfg_string(lcfg, 0),
1195 /* s1 is not changed */
1196 lustre_cfg_string(lcfg, 1),
1198 /* s3 is not changed */
1199 lustre_cfg_string(lcfg, 3),
1200 /* s4 is not changed */
1201 lustre_cfg_string(lcfg, 4));
1203 name_destroy(&mrd->nodeuuid);
1207 if (mrd->failover) {
1208 ptr = mrd->failover;
1209 while (class_parse_nid(ptr, &nid, &ptr) == 0) {
1210 if (mrd->nodeuuid == NULL) {
1211 rc = name_create(&mrd->nodeuuid,
1212 libcfs_nidstr(&nid),
1218 CDEBUG(D_MGS, "add nid %s for failover %s\n",
1219 libcfs_nidstr(&nid), mrd->nodeuuid);
1220 rc = record_add_uuid(env, mrd->temp_llh, &nid,
1223 CWARN("%s: Can't add nid %s for failover %s :rc = %d\n",
1224 mrd->target.mti_svname,
1225 libcfs_nidstr(&nid),
1227 name_destroy(&mrd->nodeuuid);
1231 rc = record_add_conn(env,
1233 lustre_cfg_string(lcfg, 0),
1235 name_destroy(&mrd->nodeuuid);
1240 if (mrd->nodeuuid) {
1241 rc = record_add_conn(env, mrd->temp_llh,
1242 lustre_cfg_string(lcfg, 0),
1244 name_destroy(&mrd->nodeuuid);
1249 mrd->state = REPLACE_DONE;
1253 /* All new UUID are added. Skip. */
1254 if (mrd->state == REPLACE_SETUP &&
1255 lcfg->lcfg_command == LCFG_ADD_UUID)
1258 /* Another commands in target device block */
1263 * Handler that called for every record in llog.
1264 * Records are processed in order they placed in llog.
1266 * \param[in] llh log to be processed
1267 * \param[in] rec current record
1268 * \param[in] data mgs_replace_data structure
1272 static int mgs_replace_nids_handler(const struct lu_env *env,
1273 struct llog_handle *llh,
1274 struct llog_rec_hdr *rec,
1277 struct mgs_replace_data *mrd;
1278 struct lustre_cfg *lcfg = REC_DATA(rec);
1279 int cfg_len = REC_DATA_LEN(rec);
1283 mrd = (struct mgs_replace_data *)data;
1285 if (rec->lrh_type != OBD_CFG_REC) {
1286 CERROR("unhandled lrh_type: %#x, cmd %x %s %s\n",
1287 rec->lrh_type, lcfg->lcfg_command,
1288 lustre_cfg_string(lcfg, 0),
1289 lustre_cfg_string(lcfg, 1));
1293 rc = lustre_cfg_sanity_check(lcfg, cfg_len);
1295 /* Do not copy any invalidated records */
1296 GOTO(skip_out, rc = 0);
1299 rc = check_markers(lcfg, mrd);
1300 if (rc || mrd->state == REPLACE_SKIP)
1301 GOTO(skip_out, rc = 0);
1303 /* Write to new log all commands outside target device block */
1304 if (mrd->state == REPLACE_COPY)
1305 GOTO(copy_out, rc = 0);
1307 if (mrd->state == REPLACE_DONE &&
1308 (lcfg->lcfg_command == LCFG_ADD_UUID ||
1309 lcfg->lcfg_command == LCFG_ADD_CONN)) {
1311 CWARN("Previous failover is deleted, but new one is "
1312 "not set. This means you configure system "
1313 "without failover or passed wrong replace_nids "
1314 "command parameters. Device %s, passed nids %s\n",
1315 mrd->target.mti_svname, mrd->target.mti_params);
1316 GOTO(skip_out, rc = 0);
1319 rc = process_command(env, lcfg, mrd);
1326 /* Record is placed in temporary llog as is */
1327 rc = llog_write(env, mrd->temp_llh, rec, LLOG_NEXT_IDX);
1329 CDEBUG(D_MGS, "Copied idx=%d, rc=%d, len=%d, cmd %x %s %s\n",
1330 rec->lrh_index, rc, rec->lrh_len, lcfg->lcfg_command,
1331 lustre_cfg_string(lcfg, 0), lustre_cfg_string(lcfg, 1));
1335 CDEBUG(D_MGS, "Skipped 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 static int mgs_log_is_empty(const struct lu_env *env,
1342 struct mgs_device *mgs, char *name)
1344 struct llog_ctxt *ctxt;
1347 ctxt = llog_get_context(mgs->mgs_obd, LLOG_CONFIG_ORIG_CTXT);
1348 LASSERT(ctxt != NULL);
1350 rc = llog_is_empty(env, ctxt, name);
1351 llog_ctxt_put(ctxt);
1355 static int mgs_replace_log(const struct lu_env *env,
1356 struct obd_device *mgs,
1357 char *logname, char *devname,
1358 llog_cb_t replace_handler, void *data)
1360 struct llog_handle *orig_llh, *backup_llh;
1361 struct llog_ctxt *ctxt;
1362 struct mgs_replace_data *mrd;
1363 struct mgs_device *mgs_dev = lu2mgs_dev(mgs->obd_lu_dev);
1364 static struct obd_uuid cfg_uuid = { .uuid = "config_uuid" };
1366 int rc, rc2, buf_size;
1370 ctxt = llog_get_context(mgs, LLOG_CONFIG_ORIG_CTXT);
1371 LASSERT(ctxt != NULL);
1373 if (mgs_log_is_empty(env, mgs_dev, logname)) {
1374 /* Log is empty. Nothing to replace */
1375 GOTO(out_put, rc = 0);
1378 now = ktime_get_real_seconds();
1380 /* max time64_t in decimal fits into 20 bytes long string */
1381 buf_size = strlen(logname) + 1 + 20 + 1 + strlen(".bak") + 1;
1382 OBD_ALLOC(backup, buf_size);
1384 GOTO(out_put, rc = -ENOMEM);
1386 snprintf(backup, buf_size, "%s.%llu.bak", logname, now);
1388 rc = llog_backup(env, mgs, ctxt, ctxt, logname, backup);
1390 /* Now erase original log file. Connections are not allowed.
1391 Backup is already saved */
1392 rc = llog_erase(env, ctxt, NULL, logname);
1395 } else if (rc != -ENOENT) {
1396 CERROR("%s: can't make backup for %s: rc = %d\n",
1397 mgs->obd_name, logname, rc);
1401 /* open local log */
1402 rc = llog_open_create(env, ctxt, &orig_llh, NULL, logname);
1404 GOTO(out_restore, rc);
1406 rc = llog_init_handle(env, orig_llh, LLOG_F_IS_PLAIN, &cfg_uuid);
1408 GOTO(out_closel, rc);
1410 /* open backup llog */
1411 rc = llog_open(env, ctxt, &backup_llh, NULL, backup,
1414 GOTO(out_closel, rc);
1416 rc = llog_init_handle(env, backup_llh, LLOG_F_IS_PLAIN, NULL);
1418 GOTO(out_close, rc);
1420 if (llog_get_size(backup_llh) <= 1)
1421 GOTO(out_close, rc = 0);
1425 GOTO(out_close, rc = -ENOMEM);
1426 /* devname is only needed information to replace UUID records */
1428 strlcpy(mrd->target.mti_svname, devname,
1429 sizeof(mrd->target.mti_svname));
1430 /* data is parsed in llog callback */
1432 strlcpy(mrd->target.mti_params, data,
1433 sizeof(mrd->target.mti_params));
1434 /* Copy records to this temporary llog */
1435 mrd->temp_llh = orig_llh;
1437 rc = llog_process(env, backup_llh, replace_handler,
1441 rc2 = llog_close(NULL, backup_llh);
1445 rc2 = llog_close(NULL, orig_llh);
1451 CERROR("%s: llog should be restored: rc = %d\n",
1453 rc2 = llog_backup(env, mgs, ctxt, ctxt, backup,
1456 CERROR("%s: can't restore backup %s: rc = %d\n",
1457 mgs->obd_name, logname, rc2);
1461 OBD_FREE(backup, buf_size);
1464 llog_ctxt_put(ctxt);
1467 CERROR("%s: failed to replace log %s: rc = %d\n",
1468 mgs->obd_name, logname, rc);
1473 static int mgs_replace_nids_log(const struct lu_env *env,
1474 struct obd_device *obd,
1475 char *logname, char *devname, char *nids)
1477 CDEBUG(D_MGS, "Replace NIDs for %s in %s\n", devname, logname);
1478 return mgs_replace_log(env, obd, logname, devname,
1479 mgs_replace_nids_handler, nids);
1483 * Parse device name and get file system name and/or device index
1485 * @devname device name (ex. lustre-MDT0000)
1486 * @fsname file system name extracted from @devname and returned
1487 * to the caller (optional)
1488 * @index device index extracted from @devname and returned to
1489 * the caller (optional)
1491 * RETURN 0 success if we are only interested in
1492 * extracting fsname from devname.
1495 * LDD_F_SV_TYPE_* Besides extracting the fsname the
1496 * user also wants the index. Report to
1497 * the user the type of obd device the
1498 * returned index belongs too.
1500 * -EINVAL The obd device name is improper so
1501 * fsname could not be extracted.
1503 * -ENXIO Failed to extract the index out of
1504 * the obd device name. Most likely an
1505 * invalid obd device name
1507 static int mgs_parse_devname(char *devname, char *fsname, u32 *index)
1512 /* Extract fsname */
1514 rc = server_name2fsname(devname, fsname, NULL);
1516 CDEBUG(D_MGS, "Device name %s without fsname\n",
1523 rc = server_name2index(devname, index, NULL);
1525 CDEBUG(D_MGS, "Device name %s with wrong index\n",
1531 /* server_name2index can return LDD_F_SV_TYPE_* so always return rc */
1535 /* This is only called during replace_nids */
1536 static int only_mgs_is_running(struct obd_device *mgs_obd)
1538 /* TDB: Is global variable with devices count exists? */
1539 int num_devices = get_devices_count();
1540 int num_exports = 0;
1541 struct obd_export *exp;
1543 spin_lock(&mgs_obd->obd_dev_lock);
1544 list_for_each_entry(exp, &mgs_obd->obd_exports, exp_obd_chain) {
1545 /* skip self export */
1546 if (exp == mgs_obd->obd_self_export)
1551 if (num_exports > 1)
1552 CERROR("%s: node %s still connected during replace_nids connect_flags:%llx\n",
1554 libcfs_nidstr(&exp->exp_nid_stats->nid),
1555 exp_connect_flags(exp));
1557 spin_unlock(&mgs_obd->obd_dev_lock);
1559 /* osd, MGS and MGC + MGC export (nosvc starts MGC)
1560 * (wc -l /proc/fs/lustre/devices <= 3) && (non self exports == 1)
1562 return (num_devices <= 3) && (num_exports <= 1);
1565 static int name_create_mdt(char **logname, char *fsname, int mdt_idx)
1569 if (mdt_idx > INDEX_MAP_MAX_VALUE)
1572 snprintf(postfix, sizeof(postfix), "-MDT%04x", mdt_idx);
1573 return name_create(logname, fsname, postfix);
1577 * Replace nids for \a device to \a nids values
1579 * \param obd MGS obd device
1580 * \param devname nids need to be replaced for this device
1581 * (ex. lustre-OST0000)
1582 * \param nids nids list (ex. nid1,nid2,nid3)
1586 int mgs_replace_nids(const struct lu_env *env,
1587 struct mgs_device *mgs,
1588 char *devname, char *nids)
1590 /* Assume fsname is part of device name */
1591 char fsname[MTI_NAME_MAXLEN];
1595 struct fs_db *fsdb = NULL;
1598 struct obd_device *mgs_obd = mgs->mgs_obd;
1601 /* We can only change NIDs if no other nodes are connected */
1602 spin_lock(&mgs_obd->obd_dev_lock);
1603 conn_state = mgs_obd->obd_no_conn;
1604 mgs_obd->obd_no_conn = 1;
1605 spin_unlock(&mgs_obd->obd_dev_lock);
1607 /* We can not change nids if not only MGS is started */
1608 if (!only_mgs_is_running(mgs_obd)) {
1609 CERROR("Only MGS is allowed to be started\n");
1610 GOTO(out, rc = -EINPROGRESS);
1613 /* Get fsname and index */
1614 rc = mgs_parse_devname(devname, fsname, &index);
1618 rc = mgs_find_or_make_fsdb(env, mgs, fsname, &fsdb);
1620 CERROR("%s: can't find fsdb: rc = %d\n", fsname, rc);
1624 /* Process client llogs */
1625 rc = name_create(&logname, fsname, "-client");
1628 rc = mgs_replace_nids_log(env, mgs_obd, logname, devname, nids);
1629 name_destroy(&logname);
1631 CERROR("%s: error while replacing NIDs for %s: rc = %d\n",
1632 fsname, devname, rc);
1636 /* Process MDT llogs */
1637 for (i = 0; i < INDEX_MAP_SIZE * 8; i++) {
1638 if (!test_bit(i, fsdb->fsdb_mdt_index_map))
1640 rc = name_create_mdt(&logname, fsname, i);
1643 rc = mgs_replace_nids_log(env, mgs_obd, logname, devname, nids);
1644 name_destroy(&logname);
1650 spin_lock(&mgs_obd->obd_dev_lock);
1651 mgs_obd->obd_no_conn = conn_state;
1652 spin_unlock(&mgs_obd->obd_dev_lock);
1655 mgs_put_fsdb(mgs, fsdb);
1661 * This is called for every record in llog. Some of records are
1662 * skipped, others are copied to new log as is.
1663 * Records to be skipped are
1664 * marker records marked SKIP
1665 * records enclosed between SKIP markers
1667 * \param[in] llh log to be processed
1668 * \param[in] rec current record
1669 * \param[in] data mgs_replace_data structure
1673 static int mgs_clear_config_handler(const struct lu_env *env,
1674 struct llog_handle *llh,
1675 struct llog_rec_hdr *rec, void *data)
1677 struct mgs_replace_data *mrd;
1678 struct lustre_cfg *lcfg = REC_DATA(rec);
1679 int cfg_len = REC_DATA_LEN(rec);
1684 mrd = (struct mgs_replace_data *)data;
1686 if (rec->lrh_type != OBD_CFG_REC) {
1687 CDEBUG(D_MGS, "Config llog Name=%s, Record Index=%u, "
1688 "Unhandled Record Type=%#x\n", llh->lgh_name,
1689 rec->lrh_index, rec->lrh_type);
1693 rc = lustre_cfg_sanity_check(lcfg, cfg_len);
1695 CDEBUG(D_MGS, "Config llog Name=%s, Invalid config file.",
1700 if (lcfg->lcfg_command == LCFG_MARKER) {
1701 struct cfg_marker *marker;
1703 marker = lustre_cfg_buf(lcfg, 1);
1704 if (marker->cm_flags & CM_SKIP) {
1705 if (marker->cm_flags & CM_START)
1706 mrd->state = REPLACE_SKIP;
1707 if (marker->cm_flags & CM_END)
1708 mrd->state = REPLACE_COPY;
1709 /* SKIP section started or finished */
1710 CDEBUG(D_MGS, "Skip idx=%d, rc=%d, len=%d, "
1711 "cmd %x %s %s\n", rec->lrh_index, rc,
1712 rec->lrh_len, lcfg->lcfg_command,
1713 lustre_cfg_string(lcfg, 0),
1714 lustre_cfg_string(lcfg, 1));
1718 if (mrd->state == REPLACE_SKIP) {
1719 /* record enclosed between SKIP markers, skip it */
1720 CDEBUG(D_MGS, "Skip idx=%d, rc=%d, len=%d, "
1721 "cmd %x %s %s\n", rec->lrh_index, rc,
1722 rec->lrh_len, lcfg->lcfg_command,
1723 lustre_cfg_string(lcfg, 0),
1724 lustre_cfg_string(lcfg, 1));
1729 /* Record is placed in temporary llog as is */
1730 rc = llog_write(env, mrd->temp_llh, rec, LLOG_NEXT_IDX);
1732 CDEBUG(D_MGS, "Copied idx=%d, rc=%d, len=%d, cmd %x %s %s\n",
1733 rec->lrh_index, rc, rec->lrh_len, lcfg->lcfg_command,
1734 lustre_cfg_string(lcfg, 0), lustre_cfg_string(lcfg, 1));
1739 * Directory CONFIGS/ may contain files which are not config logs to
1740 * be cleared. Skip any llogs with a non-alphanumeric character after
1741 * the last '-'. For example, fsname-MDT0000.sav, fsname-MDT0000.bak,
1742 * fsname-MDT0000.orig, fsname-MDT0000~, fsname-MDT0000.20150516, etc.
1744 static bool config_to_clear(const char *logname)
1749 str = strrchr(logname, '-');
1754 while (isalnum(str[++i]));
1755 return str[i] == '\0';
1759 * Clear config logs for \a name
1762 * \param mgs MGS device
1763 * \param name name of device or of filesystem
1764 * (ex. lustre-OST0000 or lustre) in later case all logs
1769 int mgs_clear_configs(const struct lu_env *env,
1770 struct mgs_device *mgs, const char *name)
1772 struct list_head dentry_list;
1773 struct mgs_direntry *dirent, *n;
1776 struct obd_device *mgs_obd = mgs->mgs_obd;
1781 /* Prevent clients and servers from connecting to mgs */
1782 spin_lock(&mgs_obd->obd_dev_lock);
1783 conn_state = mgs_obd->obd_no_conn;
1784 mgs_obd->obd_no_conn = 1;
1785 spin_unlock(&mgs_obd->obd_dev_lock);
1788 * config logs cannot be cleaned if anything other than
1791 if (!only_mgs_is_running(mgs_obd)) {
1792 CERROR("Only MGS is allowed to be started\n");
1793 GOTO(out, rc = -EBUSY);
1796 /* Find all the logs in the CONFIGS directory */
1797 rc = class_dentry_readdir(env, mgs, &dentry_list);
1799 CERROR("%s: cannot read config directory '%s': rc = %d\n",
1800 mgs_obd->obd_name, MOUNT_CONFIGS_DIR, rc);
1804 if (list_empty(&dentry_list)) {
1805 CERROR("%s: list empty reading config dir '%s': rc = %d\n",
1806 mgs_obd->obd_name, MOUNT_CONFIGS_DIR, -ENOENT);
1807 GOTO(out, rc = -ENOENT);
1810 OBD_ALLOC(namedash, strlen(name) + 2);
1811 if (namedash == NULL)
1812 GOTO(out, rc = -ENOMEM);
1813 snprintf(namedash, strlen(name) + 2, "%s-", name);
1815 list_for_each_entry(dirent, &dentry_list, mde_list) {
1816 if (strcmp(name, dirent->mde_name) &&
1817 strncmp(namedash, dirent->mde_name, strlen(namedash)))
1819 if (!config_to_clear(dirent->mde_name))
1821 CDEBUG(D_MGS, "%s: Clear config log %s\n",
1822 mgs_obd->obd_name, dirent->mde_name);
1823 rc = mgs_replace_log(env, mgs_obd, dirent->mde_name, NULL,
1824 mgs_clear_config_handler, NULL);
1829 list_for_each_entry_safe(dirent, n, &dentry_list, mde_list) {
1830 list_del_init(&dirent->mde_list);
1831 mgs_direntry_free(dirent);
1833 OBD_FREE(namedash, strlen(name) + 2);
1835 spin_lock(&mgs_obd->obd_dev_lock);
1836 mgs_obd->obd_no_conn = conn_state;
1837 spin_unlock(&mgs_obd->obd_dev_lock);
1842 static int record_lov_setup(const struct lu_env *env, struct llog_handle *llh,
1843 char *devname, struct lov_desc *desc)
1845 struct mgs_thread_info *mgi = mgs_env_info(env);
1846 struct llog_cfg_rec *lcr;
1849 lustre_cfg_bufs_reset(&mgi->mgi_bufs, devname);
1850 lustre_cfg_bufs_set(&mgi->mgi_bufs, 1, desc, sizeof(*desc));
1851 lcr = lustre_cfg_rec_new(LCFG_SETUP, &mgi->mgi_bufs);
1855 rc = llog_write(env, llh, &lcr->lcr_hdr, LLOG_NEXT_IDX);
1856 lustre_cfg_rec_free(lcr);
1860 static int record_lmv_setup(const struct lu_env *env, struct llog_handle *llh,
1861 char *devname, struct lmv_desc *desc)
1863 struct mgs_thread_info *mgi = mgs_env_info(env);
1864 struct llog_cfg_rec *lcr;
1867 lustre_cfg_bufs_reset(&mgi->mgi_bufs, devname);
1868 lustre_cfg_bufs_set(&mgi->mgi_bufs, 1, desc, sizeof(*desc));
1869 lcr = lustre_cfg_rec_new(LCFG_SETUP, &mgi->mgi_bufs);
1873 rc = llog_write(env, llh, &lcr->lcr_hdr, LLOG_NEXT_IDX);
1874 lustre_cfg_rec_free(lcr);
1878 static inline int record_mdc_add(const struct lu_env *env,
1879 struct llog_handle *llh,
1880 char *logname, char *mdcuuid,
1881 char *mdtuuid, char *index,
1884 return record_base(env,llh,logname,0,LCFG_ADD_MDC,
1885 mdtuuid, index, gen, mdcuuid);
1888 static inline int record_lov_add(const struct lu_env *env,
1889 struct llog_handle *llh,
1890 char *lov_name, char *ost_uuid,
1891 char *index, char *gen)
1893 return record_base(env, llh, lov_name, 0, LCFG_LOV_ADD_OBD,
1894 ost_uuid, index, gen, NULL);
1897 static inline int record_mount_opt(const struct lu_env *env,
1898 struct llog_handle *llh,
1899 char *profile, char *lov_name,
1902 return record_base(env, llh, NULL, 0, LCFG_MOUNTOPT,
1903 profile, lov_name, mdc_name, NULL);
1906 static int record_marker(const struct lu_env *env,
1907 struct llog_handle *llh,
1908 struct fs_db *fsdb, __u32 flags,
1909 char *tgtname, char *comment)
1911 struct mgs_thread_info *mgi = mgs_env_info(env);
1912 struct llog_cfg_rec *lcr;
1916 if (flags & CM_START)
1918 mgi->mgi_marker.cm_step = fsdb->fsdb_gen;
1919 mgi->mgi_marker.cm_flags = flags;
1920 mgi->mgi_marker.cm_vers = LUSTRE_VERSION_CODE;
1921 cplen = strlcpy(mgi->mgi_marker.cm_tgtname, tgtname,
1922 sizeof(mgi->mgi_marker.cm_tgtname));
1923 if (cplen >= sizeof(mgi->mgi_marker.cm_tgtname))
1925 cplen = strlcpy(mgi->mgi_marker.cm_comment, comment,
1926 sizeof(mgi->mgi_marker.cm_comment));
1927 if (cplen >= sizeof(mgi->mgi_marker.cm_comment))
1929 mgi->mgi_marker.cm_createtime = ktime_get_real_seconds();
1930 mgi->mgi_marker.cm_canceltime = 0;
1931 lustre_cfg_bufs_reset(&mgi->mgi_bufs, NULL);
1932 lustre_cfg_bufs_set(&mgi->mgi_bufs, 1, &mgi->mgi_marker,
1933 sizeof(mgi->mgi_marker));
1934 lcr = lustre_cfg_rec_new(LCFG_MARKER, &mgi->mgi_bufs);
1938 rc = llog_write(env, llh, &lcr->lcr_hdr, LLOG_NEXT_IDX);
1939 lustre_cfg_rec_free(lcr);
1943 static int record_start_log(const struct lu_env *env, struct mgs_device *mgs,
1944 struct llog_handle **llh, char *name)
1946 static struct obd_uuid cfg_uuid = { .uuid = "config_uuid" };
1947 struct llog_ctxt *ctxt;
1952 GOTO(out, rc = -EBUSY);
1954 ctxt = llog_get_context(mgs->mgs_obd, LLOG_CONFIG_ORIG_CTXT);
1956 GOTO(out, rc = -ENODEV);
1957 LASSERT(ctxt->loc_obd == mgs->mgs_obd);
1959 rc = llog_open_create(env, ctxt, llh, NULL, name);
1962 rc = llog_init_handle(env, *llh, LLOG_F_IS_PLAIN, &cfg_uuid);
1964 llog_close(env, *llh);
1966 llog_ctxt_put(ctxt);
1969 CERROR("%s: can't start log %s: rc = %d\n",
1970 mgs->mgs_obd->obd_name, name, rc);
1976 static int record_end_log(const struct lu_env *env, struct llog_handle **llh)
1980 rc = llog_close(env, *llh);
1986 /******************** config "macros" *********************/
1988 /* write an lcfg directly into a log (with markers) */
1989 static int mgs_write_log_direct(const struct lu_env *env,
1990 struct mgs_device *mgs, struct fs_db *fsdb,
1991 char *logname, struct llog_cfg_rec *lcr,
1992 char *devname, char *comment)
1994 struct llog_handle *llh = NULL;
1999 rc = record_start_log(env, mgs, &llh, logname);
2003 /* FIXME These should be a single journal transaction */
2004 rc = record_marker(env, llh, fsdb, CM_START, devname, comment);
2007 rc = llog_write(env, llh, &lcr->lcr_hdr, LLOG_NEXT_IDX);
2010 rc = record_marker(env, llh, fsdb, CM_END, devname, comment);
2014 record_end_log(env, &llh);
2018 /* write the lcfg in all logs for the given fs */
2019 static int mgs_write_log_direct_all(const struct lu_env *env,
2020 struct mgs_device *mgs,
2022 struct mgs_target_info *mti,
2023 struct llog_cfg_rec *lcr, char *devname,
2024 char *comment, int server_only)
2026 struct list_head log_list;
2027 struct mgs_direntry *dirent, *n;
2028 char *fsname = mti->mti_fsname;
2029 int rc = 0, len = strlen(fsname);
2032 /* Find all the logs in the CONFIGS directory */
2033 rc = class_dentry_readdir(env, mgs, &log_list);
2037 /* Could use fsdb index maps instead of directory listing */
2038 list_for_each_entry_safe(dirent, n, &log_list, mde_list) {
2039 list_del_init(&dirent->mde_list);
2040 /* don't write to sptlrpc rule log */
2041 if (strstr(dirent->mde_name, "-sptlrpc") != NULL)
2044 /* caller wants write server logs only */
2045 if (server_only && strstr(dirent->mde_name, "-client") != NULL)
2048 if (strlen(dirent->mde_name) <= len ||
2049 strncmp(fsname, dirent->mde_name, len) != 0 ||
2050 dirent->mde_name[len] != '-')
2053 CDEBUG(D_MGS, "Changing log %s\n", dirent->mde_name);
2054 /* Erase any old settings of this same parameter */
2055 rc = mgs_modify(env, mgs, fsdb, mti, dirent->mde_name,
2056 devname, comment, CM_SKIP);
2058 CERROR("%s: Can't modify llog %s: rc = %d\n",
2059 mgs->mgs_obd->obd_name, dirent->mde_name, rc);
2062 /* Write the new one */
2063 rc = mgs_write_log_direct(env, mgs, fsdb, dirent->mde_name,
2064 lcr, devname, comment);
2066 CERROR("%s: writing log %s: rc = %d\n",
2067 mgs->mgs_obd->obd_name, dirent->mde_name, rc);
2069 mgs_direntry_free(dirent);
2075 static int mgs_write_log_osp_to_mdt(const struct lu_env *env,
2076 struct mgs_device *mgs,
2078 struct mgs_target_info *mti,
2079 int index, char *logname);
2080 static int mgs_write_log_osc_to_lov(const struct lu_env *env,
2081 struct mgs_device *mgs,
2083 struct mgs_target_info *mti,
2084 char *logname, char *suffix, char *lovname,
2085 enum lustre_sec_part sec_part, int flags);
2086 static int name_create_mdt_and_lov(char **logname, char **lovname,
2087 struct fs_db *fsdb, int i);
2089 static int add_param(char *params, char *key, char *val)
2091 char *start = params + strlen(params);
2092 char *end = params + sizeof(((struct mgs_target_info *)0)->mti_params);
2096 keylen = strlen(key);
2097 if (start + 1 + keylen + strlen(val) >= end) {
2098 CERROR("params are too long: %s %s%s\n",
2099 params, key != NULL ? key : "", val);
2103 sprintf(start, " %s%s", key != NULL ? key : "", val);
2108 * Walk through client config log record and convert the related records
2111 static int mgs_steal_client_llog_handler(const struct lu_env *env,
2112 struct llog_handle *llh,
2113 struct llog_rec_hdr *rec, void *data)
2115 struct mgs_device *mgs;
2116 struct obd_device *obd;
2117 struct mgs_target_info *mti, *tmti;
2119 int cfg_len = rec->lrh_len;
2120 char *cfg_buf = (char *)(rec + 1);
2121 struct lustre_cfg *lcfg;
2123 struct llog_handle *mdt_llh = NULL;
2124 static int got_an_osc_or_mdc = 0;
2125 /* 0: not found any osc/mdc;
2129 static int last_step = -1;
2134 mti = ((struct temp_comp *)data)->comp_mti;
2135 tmti = ((struct temp_comp *)data)->comp_tmti;
2136 fsdb = ((struct temp_comp *)data)->comp_fsdb;
2137 obd = ((struct temp_comp *)data)->comp_obd;
2138 mgs = lu2mgs_dev(obd->obd_lu_dev);
2141 if (rec->lrh_type != OBD_CFG_REC) {
2142 CERROR("unhandled lrh_type: %#x\n", rec->lrh_type);
2146 rc = lustre_cfg_sanity_check(cfg_buf, cfg_len);
2148 CERROR("Insane cfg\n");
2152 lcfg = (struct lustre_cfg *)cfg_buf;
2154 if (lcfg->lcfg_command == LCFG_MARKER) {
2155 struct cfg_marker *marker;
2156 marker = lustre_cfg_buf(lcfg, 1);
2157 if (!strncmp(marker->cm_comment, "add osc", 7) &&
2158 (marker->cm_flags & CM_START) &&
2159 !(marker->cm_flags & CM_SKIP)) {
2160 got_an_osc_or_mdc = 1;
2161 cplen = strlcpy(tmti->mti_svname, marker->cm_tgtname,
2162 sizeof(tmti->mti_svname));
2163 if (cplen >= sizeof(tmti->mti_svname))
2165 rc = record_start_log(env, mgs, &mdt_llh,
2169 rc = record_marker(env, mdt_llh, fsdb, CM_START,
2170 mti->mti_svname, "add osc(copied)");
2171 record_end_log(env, &mdt_llh);
2172 last_step = marker->cm_step;
2175 if (!strncmp(marker->cm_comment, "add osc", 7) &&
2176 (marker->cm_flags & CM_END) &&
2177 !(marker->cm_flags & CM_SKIP)) {
2178 LASSERT(last_step == marker->cm_step);
2180 got_an_osc_or_mdc = 0;
2181 memset(tmti, 0, sizeof(*tmti));
2182 rc = record_start_log(env, mgs, &mdt_llh,
2186 rc = record_marker(env, mdt_llh, fsdb, CM_END,
2187 mti->mti_svname, "add osc(copied)");
2188 record_end_log(env, &mdt_llh);
2191 if (!strncmp(marker->cm_comment, "add mdc", 7) &&
2192 (marker->cm_flags & CM_START) &&
2193 !(marker->cm_flags & CM_SKIP)) {
2194 got_an_osc_or_mdc = 2;
2195 last_step = marker->cm_step;
2196 memcpy(tmti->mti_svname, marker->cm_tgtname,
2197 strlen(marker->cm_tgtname));
2201 if (!strncmp(marker->cm_comment, "add mdc", 7) &&
2202 (marker->cm_flags & CM_END) &&
2203 !(marker->cm_flags & CM_SKIP)) {
2204 LASSERT(last_step == marker->cm_step);
2206 got_an_osc_or_mdc = 0;
2207 memset(tmti, 0, sizeof(*tmti));
2212 if (got_an_osc_or_mdc == 0 || last_step < 0)
2215 if (lcfg->lcfg_command == LCFG_ADD_UUID) {
2216 __u64 nodenid = lcfg->lcfg_nid;
2218 if (strlen(tmti->mti_uuid) == 0) {
2219 /* target uuid not set, this config record is before
2220 * LCFG_SETUP, this nid is one of target node nid.
2222 tmti->mti_nids[tmti->mti_nid_count] = nodenid;
2223 tmti->mti_nid_count++;
2225 char nidstr[LNET_NIDSTR_SIZE];
2227 /* failover node nid */
2228 libcfs_nid2str_r(nodenid, nidstr, sizeof(nidstr));
2229 rc = add_param(tmti->mti_params, PARAM_FAILNODE,
2236 if (lcfg->lcfg_command == LCFG_SETUP) {
2239 target = lustre_cfg_string(lcfg, 1);
2240 memcpy(tmti->mti_uuid, target, strlen(target));
2244 /* ignore client side sptlrpc_conf_log */
2245 if (lcfg->lcfg_command == LCFG_SPTLRPC_CONF)
2248 if (lcfg->lcfg_command == LCFG_ADD_MDC &&
2249 strstr(lustre_cfg_string(lcfg, 0), "-clilmv") != NULL) {
2252 if (sscanf(lustre_cfg_buf(lcfg, 2), "%d", &index) != 1)
2254 if (index == mti->mti_stripe_index) {
2256 "attempt to create MDT%04x->MDT%04x osp device\n",
2260 memcpy(tmti->mti_fsname, mti->mti_fsname,
2261 strlen(mti->mti_fsname));
2262 tmti->mti_stripe_index = index;
2264 rc = mgs_write_log_osp_to_mdt(env, mgs, fsdb, tmti,
2265 mti->mti_stripe_index,
2267 memset(tmti, 0, sizeof(*tmti));
2271 if (lcfg->lcfg_command == LCFG_LOV_ADD_OBD) {
2274 char *logname, *lovname;
2276 rc = name_create_mdt_and_lov(&logname, &lovname, fsdb,
2277 mti->mti_stripe_index);
2280 sprintf(mdt_index, "-MDT%04x", mti->mti_stripe_index);
2282 if (sscanf(lustre_cfg_buf(lcfg, 2), "%d", &index) != 1) {
2283 name_destroy(&logname);
2284 name_destroy(&lovname);
2288 tmti->mti_stripe_index = index;
2289 rc = mgs_write_log_osc_to_lov(env, mgs, fsdb, tmti, logname,
2292 name_destroy(&logname);
2293 name_destroy(&lovname);
2299 /* fsdb->fsdb_mutex is already held in mgs_write_log_target*/
2300 /* stealed from mgs_get_fsdb_from_llog*/
2301 static int mgs_steal_llog_for_mdt_from_client(const struct lu_env *env,
2302 struct mgs_device *mgs,
2304 struct temp_comp *comp)
2306 struct llog_handle *loghandle;
2307 struct mgs_target_info *tmti;
2308 struct llog_ctxt *ctxt;
2313 ctxt = llog_get_context(mgs->mgs_obd, LLOG_CONFIG_ORIG_CTXT);
2314 LASSERT(ctxt != NULL);
2316 OBD_ALLOC_PTR(tmti);
2318 GOTO(out_ctxt, rc = -ENOMEM);
2320 comp->comp_tmti = tmti;
2321 comp->comp_obd = mgs->mgs_obd;
2323 rc = llog_open(env, ctxt, &loghandle, NULL, client_name,
2331 rc = llog_init_handle(env, loghandle, LLOG_F_IS_PLAIN, NULL);
2333 GOTO(out_close, rc);
2335 rc = llog_process_or_fork(env, loghandle, mgs_steal_client_llog_handler,
2336 (void *)comp, NULL, false);
2337 CDEBUG(D_MGS, "steal llog re = %d\n", rc);
2339 llog_close(env, loghandle);
2343 llog_ctxt_put(ctxt);
2347 /* mount opt is the third thing in client logs */
2348 static int mgs_write_log_mount_opt(const struct lu_env *env,
2349 struct mgs_device *mgs, struct fs_db *fsdb,
2352 struct llog_handle *llh = NULL;
2357 CDEBUG(D_MGS, "Writing mount options log for %s\n", logname);
2359 rc = record_start_log(env, mgs, &llh, logname);
2363 rc = record_marker(env, llh, fsdb, CM_START, logname, "mount opts");
2366 rc = record_mount_opt(env, llh, logname, fsdb->fsdb_clilov,
2370 rc = record_marker(env, llh, fsdb, CM_END, logname, "mount opts");
2374 record_end_log(env, &llh);
2378 /* lmv is the second thing for client logs */
2379 /* copied from mgs_write_log_lov. Please refer to that. */
2380 static int mgs_write_log_lmv(const struct lu_env *env,
2381 struct mgs_device *mgs,
2383 struct mgs_target_info *mti,
2384 char *logname, char *lmvname)
2386 struct llog_handle *llh = NULL;
2387 struct lmv_desc *lmvdesc;
2392 CDEBUG(D_MGS, "Writing lmv(%s) log for %s\n", lmvname, logname);
2394 OBD_ALLOC_PTR(lmvdesc);
2395 if (lmvdesc == NULL)
2397 lmvdesc->ld_active_tgt_count = 0;
2398 lmvdesc->ld_tgt_count = 0;
2399 sprintf((char *)lmvdesc->ld_uuid.uuid, "%s_UUID", lmvname);
2400 uuid = (char *)lmvdesc->ld_uuid.uuid;
2402 rc = record_start_log(env, mgs, &llh, logname);
2405 rc = record_marker(env, llh, fsdb, CM_START, lmvname, "lmv setup");
2408 rc = record_attach(env, llh, lmvname, "lmv", uuid);
2411 rc = record_lmv_setup(env, llh, lmvname, lmvdesc);
2414 rc = record_marker(env, llh, fsdb, CM_END, lmvname, "lmv setup");
2418 record_end_log(env, &llh);
2420 OBD_FREE_PTR(lmvdesc);
2424 /* lov is the first thing in the mdt and client logs */
2425 static int mgs_write_log_lov(const struct lu_env *env, struct mgs_device *mgs,
2426 struct fs_db *fsdb, struct mgs_target_info *mti,
2427 char *logname, char *lovname)
2429 struct llog_handle *llh = NULL;
2430 struct lov_desc *lovdesc;
2435 CDEBUG(D_MGS, "Writing lov(%s) log for %s\n", lovname, logname);
2438 * #01 L attach 0:lov_mdsA 1:lov 2:71ccb_lov_mdsA_19f961a9e1
2439 * #02 L lov_setup 0:lov_mdsA 1:(struct lov_desc)
2440 * uuid=lov1_UUID, stripe count=1, size=1048576, offset=0, pattern=0
2443 /* FIXME just make lov_setup accept empty desc (put uuid in buf 2) */
2444 OBD_ALLOC_PTR(lovdesc);
2445 if (lovdesc == NULL)
2447 lovdesc->ld_magic = LOV_DESC_MAGIC;
2448 lovdesc->ld_tgt_count = 0;
2449 /* Defaults. Can be changed later by lcfg config_param */
2450 lovdesc->ld_default_stripe_count = 1;
2451 lovdesc->ld_pattern = LOV_PATTERN_RAID0;
2452 lovdesc->ld_default_stripe_size = LOV_DESC_STRIPE_SIZE_DEFAULT;
2453 lovdesc->ld_default_stripe_offset = -1;
2454 lovdesc->ld_qos_maxage = LOV_DESC_QOS_MAXAGE_DEFAULT;
2455 sprintf((char *)lovdesc->ld_uuid.uuid, "%s_UUID", lovname);
2456 /* can these be the same? */
2457 uuid = (char *)lovdesc->ld_uuid.uuid;
2459 /* This should always be the first entry in a log.
2460 * rc = mgs_clear_log(obd, logname);
2462 rc = record_start_log(env, mgs, &llh, logname);
2465 /* FIXME these should be a single journal transaction */
2466 rc = record_marker(env, llh, fsdb, CM_START, lovname, "lov setup");
2469 rc = record_attach(env, llh, lovname, "lov", uuid);
2472 rc = record_lov_setup(env, llh, lovname, lovdesc);
2475 rc = record_marker(env, llh, fsdb, CM_END, lovname, "lov setup");
2480 record_end_log(env, &llh);
2482 OBD_FREE_PTR(lovdesc);
2486 /* add failnids to open log */
2487 static int mgs_write_log_failnids(const struct lu_env *env,
2488 struct mgs_target_info *mti,
2489 struct llog_handle *llh,
2492 char *failnodeuuid = NULL;
2493 char *ptr = mti->mti_params;
2494 struct lnet_nid nid;
2498 * #03 L add_uuid nid=uml1@tcp(0x20000c0a80201) nal=90 0: 1:uml1_UUID
2499 * #04 L add_uuid nid=1@elan(0x1000000000001) nal=90 0: 1:uml1_UUID
2500 * #05 L setup 0:OSC_uml1_ost1_mdsA 1:ost1_UUID 2:uml1_UUID
2501 * #06 L add_uuid nid=uml2@tcp(0x20000c0a80202) nal=90 0: 1:uml2_UUID
2502 * #0x L add_uuid nid=2@elan(0x1000000000002) nal=90 0: 1:uml2_UUID
2503 * #07 L add_conn 0:OSC_uml1_ost1_mdsA 1:uml2_UUID
2507 * Pull failnid info out of params string, which may contain something
2508 * like "<nid1>,<nid2>:<nid3>,<nid4>". class_parse_nid() does not
2509 * complain about abnormal inputs like ",:<nid1>", "<nid1>:,<nid2>",
2510 * etc. However, convert_hostnames() should have caught those.
2512 while (class_find_param(ptr, PARAM_FAILNODE, &ptr) == 0) {
2513 while (class_parse_nid(ptr, &nid, &ptr) == 0) {
2514 char nidstr[LNET_NIDSTR_SIZE];
2516 if (failnodeuuid == NULL) {
2517 /* We don't know the failover node name,
2518 * so just use the first nid as the uuid */
2519 libcfs_nidstr_r(&nid, nidstr, sizeof(nidstr));
2520 rc = name_create(&failnodeuuid, nidstr, "");
2525 "add nid %s for failover uuid %s, client %s\n",
2526 libcfs_nidstr_r(&nid, nidstr, sizeof(nidstr)),
2527 failnodeuuid, cliname);
2528 rc = record_add_uuid(env, llh, &nid, failnodeuuid);
2530 * If *ptr is ':', we have added all NIDs for
2534 rc = record_add_conn(env, llh, cliname,
2536 name_destroy(&failnodeuuid);
2537 failnodeuuid = NULL;
2541 rc = record_add_conn(env, llh, cliname, failnodeuuid);
2542 name_destroy(&failnodeuuid);
2543 failnodeuuid = NULL;
2550 static int mgs_write_log_mdc_to_lmv(const struct lu_env *env,
2551 struct mgs_device *mgs,
2553 struct mgs_target_info *mti,
2554 char *logname, char *lmvname)
2556 struct llog_handle *llh = NULL;
2557 char *mdcname = NULL;
2558 char *nodeuuid = NULL;
2559 char *mdcuuid = NULL;
2560 char *lmvuuid = NULL;
2562 char nidstr[LNET_NIDSTR_SIZE];
2566 if (mgs_log_is_empty(env, mgs, logname)) {
2567 CERROR("log is empty! Logical error\n");
2571 CDEBUG(D_MGS, "adding mdc for %s to log %s:lmv(%s)\n",
2572 mti->mti_svname, logname, lmvname);
2574 libcfs_nid2str_r(mti->mti_nids[0], nidstr, sizeof(nidstr));
2575 rc = name_create(&nodeuuid, nidstr, "");
2578 rc = name_create(&mdcname, mti->mti_svname, "-mdc");
2581 rc = name_create(&mdcuuid, mdcname, "_UUID");
2584 rc = name_create(&lmvuuid, lmvname, "_UUID");
2588 rc = mgs_modify(env, mgs, fsdb, mti, logname, mti->mti_svname,
2589 "add mdc", CM_SKIP);
2593 rc = record_start_log(env, mgs, &llh, logname);
2596 rc = record_marker(env, llh, fsdb, CM_START, mti->mti_svname,
2600 for (i = 0; i < mti->mti_nid_count; i++) {
2601 struct lnet_nid nid;
2603 lnet_nid4_to_nid(mti->mti_nids[i], &nid);
2604 CDEBUG(D_MGS, "add nid %s for mdt\n",
2605 libcfs_nidstr_r(&nid, nidstr, sizeof(nidstr)));
2607 rc = record_add_uuid(env, llh, &nid, nodeuuid);
2612 rc = record_attach(env, llh, mdcname, LUSTRE_MDC_NAME, lmvuuid);
2615 rc = record_setup(env, llh, mdcname, mti->mti_uuid, nodeuuid,
2619 rc = mgs_write_log_failnids(env, mti, llh, mdcname);
2622 snprintf(index, sizeof(index), "%d", mti->mti_stripe_index);
2623 rc = record_mdc_add(env, llh, lmvname, mdcuuid, mti->mti_uuid,
2627 rc = record_marker(env, llh, fsdb, CM_END, mti->mti_svname,
2632 record_end_log(env, &llh);
2634 name_destroy(&lmvuuid);
2635 name_destroy(&mdcuuid);
2636 name_destroy(&mdcname);
2637 name_destroy(&nodeuuid);
2641 static inline int name_create_lov(char **lovname, char *mdtname,
2642 struct fs_db *fsdb, int index)
2645 if (index == 0 && test_bit(FSDB_OSCNAME18, &fsdb->fsdb_flags))
2646 return name_create(lovname, fsdb->fsdb_name, "-mdtlov");
2648 return name_create(lovname, mdtname, "-mdtlov");
2651 static int name_create_mdt_and_lov(char **logname, char **lovname,
2652 struct fs_db *fsdb, int i)
2656 rc = name_create_mdt(logname, fsdb->fsdb_name, i);
2660 if (i == 0 && test_bit(FSDB_OSCNAME18, &fsdb->fsdb_flags))
2661 rc = name_create(lovname, fsdb->fsdb_name, "-mdtlov");
2663 rc = name_create(lovname, *logname, "-mdtlov");
2665 name_destroy(logname);
2671 static inline int name_create_mdt_osc(char **oscname, char *ostname,
2672 struct fs_db *fsdb, int i)
2676 if (i == 0 && test_bit(FSDB_OSCNAME18, &fsdb->fsdb_flags))
2677 sprintf(suffix, "-osc");
2679 sprintf(suffix, "-osc-MDT%04x", i);
2680 return name_create(oscname, ostname, suffix);
2683 /* add new mdc to already existent MDS */
2684 static int mgs_write_log_osp_to_mdt(const struct lu_env *env,
2685 struct mgs_device *mgs,
2687 struct mgs_target_info *mti,
2688 int mdt_index, char *logname)
2690 struct llog_handle *llh = NULL;
2691 char *nodeuuid = NULL;
2692 char *ospname = NULL;
2693 char *lovuuid = NULL;
2694 char *mdtuuid = NULL;
2695 char *svname = NULL;
2696 char *mdtname = NULL;
2697 char *lovname = NULL;
2699 char nidstr[LNET_NIDSTR_SIZE];
2703 if (mgs_log_is_empty(env, mgs, mti->mti_svname)) {
2704 CERROR("log is empty! Logical error\n");
2708 CDEBUG(D_MGS, "adding osp index %d to %s\n", mti->mti_stripe_index,
2711 rc = name_create_mdt(&mdtname, fsdb->fsdb_name, mti->mti_stripe_index);
2715 libcfs_nid2str_r(mti->mti_nids[0], nidstr, sizeof(nidstr));
2716 rc = name_create(&nodeuuid, nidstr, "");
2718 GOTO(out_destory, rc);
2720 rc = name_create(&svname, mdtname, "-osp");
2722 GOTO(out_destory, rc);
2724 sprintf(index_str, "-MDT%04x", mdt_index);
2725 rc = name_create(&ospname, svname, index_str);
2727 GOTO(out_destory, rc);
2729 rc = name_create_lov(&lovname, logname, fsdb, mdt_index);
2731 GOTO(out_destory, rc);
2733 rc = name_create(&lovuuid, lovname, "_UUID");
2735 GOTO(out_destory, rc);
2737 rc = name_create(&mdtuuid, mdtname, "_UUID");
2739 GOTO(out_destory, rc);
2741 rc = mgs_modify(env, mgs, fsdb, mti, logname, mti->mti_svname,
2742 "add osp", CM_SKIP);
2744 GOTO(out_destory, rc);
2746 rc = record_start_log(env, mgs, &llh, logname);
2748 GOTO(out_destory, rc);
2750 rc = record_marker(env, llh, fsdb, CM_START, mti->mti_svname,
2753 GOTO(out_destory, rc);
2755 for (i = 0; i < mti->mti_nid_count; i++) {
2756 struct lnet_nid nid;
2758 lnet_nid4_to_nid(mti->mti_nids[i], &nid);
2759 CDEBUG(D_MGS, "add nid %s for mdt\n",
2760 libcfs_nidstr_r(&nid, nidstr, sizeof(nidstr)));
2761 rc = record_add_uuid(env, llh, &nid, nodeuuid);
2766 rc = record_attach(env, llh, ospname, LUSTRE_OSP_NAME, lovuuid);
2770 rc = record_setup(env, llh, ospname, mti->mti_uuid, nodeuuid,
2775 rc = mgs_write_log_failnids(env, mti, llh, ospname);
2779 /* Add mdc(osp) to lod */
2780 snprintf(index_str, sizeof(index_str), "%d", mti->mti_stripe_index);
2781 rc = record_base(env, llh, lovname, 0, LCFG_ADD_MDC, mti->mti_uuid,
2782 index_str, "1", NULL);
2786 rc = record_marker(env, llh, fsdb, CM_END, mti->mti_svname, "add osp");
2791 record_end_log(env, &llh);
2794 name_destroy(&mdtuuid);
2795 name_destroy(&lovuuid);
2796 name_destroy(&lovname);
2797 name_destroy(&ospname);
2798 name_destroy(&svname);
2799 name_destroy(&nodeuuid);
2800 name_destroy(&mdtname);
2804 static int mgs_write_log_mdt0(const struct lu_env *env,
2805 struct mgs_device *mgs,
2807 struct mgs_target_info *mti)
2809 char *log = mti->mti_svname;
2810 struct llog_handle *llh = NULL;
2811 struct obd_uuid *uuid;
2814 char *ptr = mti->mti_params;
2815 int rc = 0, failout = 0;
2818 OBD_ALLOC_PTR(uuid);
2822 if (class_find_param(ptr, PARAM_FAILMODE, &ptr) == 0)
2823 failout = (strncmp(ptr, "failout", 7) == 0);
2825 rc = name_create(&lovname, log, "-mdtlov");
2828 if (mgs_log_is_empty(env, mgs, log)) {
2829 rc = mgs_write_log_lov(env, mgs, fsdb, mti, log, lovname);
2834 sprintf(mdt_index, "%d", mti->mti_stripe_index);
2836 rc = record_start_log(env, mgs, &llh, log);
2840 /* add MDT itself */
2842 /* FIXME this whole fn should be a single journal transaction */
2843 sprintf(uuid->uuid, "%s_UUID", log);
2844 rc = record_marker(env, llh, fsdb, CM_START, log, "add mdt");
2847 rc = record_attach(env, llh, log, LUSTRE_MDT_NAME, uuid->uuid);
2850 rc = record_mount_opt(env, llh, log, lovname, NULL);
2853 rc = record_setup(env, llh, log, uuid->uuid, mdt_index, lovname,
2854 failout ? "n" : "f");
2857 rc = record_marker(env, llh, fsdb, CM_END, log, "add mdt");
2861 record_end_log(env, &llh);
2863 name_destroy(&lovname);
2869 /* envelope method for all layers log */
2870 static int mgs_write_log_mdt(const struct lu_env *env,
2871 struct mgs_device *mgs,
2873 struct mgs_target_info *mti)
2875 struct mgs_thread_info *mgi = mgs_env_info(env);
2876 struct llog_handle *llh = NULL;
2881 CDEBUG(D_MGS, "writing new mdt %s\n", mti->mti_svname);
2883 if (mti->mti_uuid[0] == '\0') {
2884 /* Make up our own uuid */
2885 snprintf(mti->mti_uuid, sizeof(mti->mti_uuid),
2886 "%s_UUID", mti->mti_svname);
2890 rc = mgs_write_log_mdt0(env, mgs, fsdb, mti);
2893 /* Append the mdt info to the client log */
2894 rc = name_create(&cliname, mti->mti_fsname, "-client");
2898 if (mgs_log_is_empty(env, mgs, cliname)) {
2899 /* Start client log */
2900 rc = mgs_write_log_lov(env, mgs, fsdb, mti, cliname,
2904 rc = mgs_write_log_lmv(env, mgs, fsdb, mti, cliname,
2908 rc = mgs_write_log_mount_opt(env, mgs, fsdb, cliname);
2914 * #09 L add_uuid nid=uml1@tcp(0x20000c0a80201) 0: 1:uml1_UUID
2915 * #10 L attach 0:MDC_uml1_mdsA_MNT_client 1:mdc 2:1d834_MNT_client_03f
2916 * #11 L setup 0:MDC_uml1_mdsA_MNT_client 1:mdsA_UUID 2:uml1_UUID
2917 * #12 L add_uuid nid=uml2@tcp(0x20000c0a80202) 0: 1:uml2_UUID
2918 * #13 L add_conn 0:MDC_uml1_mdsA_MNT_client 1:uml2_UUID
2921 /* copy client info about lov/lmv */
2922 mgi->mgi_comp.comp_mti = mti;
2923 mgi->mgi_comp.comp_fsdb = fsdb;
2925 rc = mgs_steal_llog_for_mdt_from_client(env, mgs, cliname,
2929 rc = mgs_write_log_mdc_to_lmv(env, mgs, fsdb, mti, cliname,
2934 rc = record_start_log(env, mgs, &llh, cliname);
2938 /* for_all_existing_mdt except current one */
2939 for (i = 0; i < INDEX_MAP_SIZE * 8; i++) {
2940 if (i != mti->mti_stripe_index &&
2941 test_bit(i, fsdb->fsdb_mdt_index_map)) {
2944 rc = name_create_mdt(&logname, fsdb->fsdb_name, i);
2948 /* NB: If the log for the MDT is empty, it means
2949 * the MDT is only added to the index
2950 * map, and not being process yet, i.e. this
2951 * is an unregistered MDT, see mgs_write_log_target().
2952 * so we should skip it. Otherwise
2954 * 1. MGS get register request for MDT1 and MDT2.
2956 * 2. Then both MDT1 and MDT2 are added into
2957 * fsdb_mdt_index_map. (see mgs_set_index()).
2959 * 3. Then MDT1 get the lock of fsdb_mutex, then
2960 * generate the config log, here, it will regard MDT2
2961 * as an existent MDT, and generate "add osp" for
2962 * lustre-MDT0001-osp-MDT0002. Note: at the moment
2963 * MDT0002 config log is still empty, so it will
2964 * add "add osp" even before "lov setup", which
2965 * will definitly cause trouble.
2967 * 4. MDT1 registeration finished, fsdb_mutex is
2968 * released, then MDT2 get in, then in above
2969 * mgs_steal_llog_for_mdt_from_client(), it will
2970 * add another osp log for lustre-MDT0001-osp-MDT0002,
2971 * which will cause another trouble.*/
2972 if (!mgs_log_is_empty(env, mgs, logname))
2973 rc = mgs_write_log_osp_to_mdt(env, mgs, fsdb,
2976 name_destroy(&logname);
2982 record_end_log(env, &llh);
2984 name_destroy(&cliname);
2988 /* Add the ost info to the client/mdt lov */
2989 static int mgs_write_log_osc_to_lov(const struct lu_env *env,
2990 struct mgs_device *mgs, struct fs_db *fsdb,
2991 struct mgs_target_info *mti,
2992 char *logname, char *suffix, char *lovname,
2993 enum lustre_sec_part sec_part, int flags)
2995 struct llog_handle *llh = NULL;
2996 char *nodeuuid = NULL;
2997 char *oscname = NULL;
2998 char *oscuuid = NULL;
2999 char *lovuuid = NULL;
3000 char *svname = NULL;
3002 char nidstr[LNET_NIDSTR_SIZE];
3006 CDEBUG(D_INFO, "adding osc for %s to log %s\n",
3007 mti->mti_svname, logname);
3009 if (mgs_log_is_empty(env, mgs, logname)) {
3010 CERROR("log is empty! Logical error\n");
3014 libcfs_nid2str_r(mti->mti_nids[0], nidstr, sizeof(nidstr));
3015 rc = name_create(&nodeuuid, nidstr, "");
3018 rc = name_create(&svname, mti->mti_svname, "-osc");
3022 /* for the system upgraded from old 1.8, keep using the old osc naming
3023 * style for mdt, see name_create_mdt_osc(). LU-1257 */
3024 if (test_bit(FSDB_OSCNAME18, &fsdb->fsdb_flags))
3025 rc = name_create(&oscname, svname, "");
3027 rc = name_create(&oscname, svname, suffix);
3031 rc = name_create(&oscuuid, oscname, "_UUID");
3034 rc = name_create(&lovuuid, lovname, "_UUID");
3039 * #03 L add_uuid nid=uml1@tcp(0x20000c0a80201) 0: 1:uml1_UUID
3041 * #04 L add_uuid nid=1@elan(0x1000000000001) nal=90 0: 1:uml1_UUID
3042 * #04 L attach 0:OSC_uml1_ost1_MNT_client 1:osc 2:89070_lov1_a41dff51a
3043 * #05 L setup 0:OSC_uml1_ost1_MNT_client 1:ost1_UUID 2:uml1_UUID
3045 * #06 L add_uuid nid=uml2@tcp(0x20000c0a80202) 0: 1:uml2_UUID
3046 * #07 L add_conn 0:OSC_uml1_ost1_MNT_client 1:uml2_UUID
3047 * #08 L lov_modify_tgts add 0:lov1 1:ost1_UUID 2(index):0 3(gen):1
3050 rc = record_start_log(env, mgs, &llh, logname);
3054 /* FIXME these should be a single journal transaction */
3055 rc = record_marker(env, llh, fsdb, CM_START | flags, mti->mti_svname,
3060 /* NB: don't change record order, because upon MDT steal OSC config
3061 * from client, it treats all nids before LCFG_SETUP as target nids
3062 * (multiple interfaces), while nids after as failover node nids.
3063 * See mgs_steal_client_llog_handler() LCFG_ADD_UUID.
3065 for (i = 0; i < mti->mti_nid_count; i++) {
3066 struct lnet_nid nid;
3068 lnet_nid4_to_nid(mti->mti_nids[i], &nid);
3069 CDEBUG(D_MGS, "add nid %s\n",
3070 libcfs_nidstr_r(&nid, nidstr, sizeof(nidstr)));
3071 rc = record_add_uuid(env, llh, &nid, nodeuuid);
3075 rc = record_attach(env, llh, oscname, LUSTRE_OSC_NAME, lovuuid);
3078 rc = record_setup(env, llh, oscname, mti->mti_uuid, nodeuuid,
3082 rc = mgs_write_log_failnids(env, mti, llh, oscname);
3086 snprintf(index, sizeof(index), "%d", mti->mti_stripe_index);
3088 rc = record_lov_add(env, llh, lovname, mti->mti_uuid, index, "1");
3091 rc = record_marker(env, llh, fsdb, CM_END | flags, mti->mti_svname,
3096 record_end_log(env, &llh);
3098 name_destroy(&lovuuid);
3099 name_destroy(&oscuuid);
3100 name_destroy(&oscname);
3101 name_destroy(&svname);
3102 name_destroy(&nodeuuid);
3106 static int mgs_write_log_ost(const struct lu_env *env,
3107 struct mgs_device *mgs, struct fs_db *fsdb,
3108 struct mgs_target_info *mti)
3110 struct llog_handle *llh = NULL;
3111 char *logname, *lovname;
3112 char *ptr = mti->mti_params;
3113 int rc, flags = 0, failout = 0, i;
3116 CDEBUG(D_MGS, "writing new ost %s\n", mti->mti_svname);
3118 /* The ost startup log */
3120 /* If the ost log already exists, that means that someone reformatted
3121 * the ost and it called target_add again.
3123 if (!mgs_log_is_empty(env, mgs, mti->mti_svname)) {
3124 LCONSOLE_ERROR_MSG(0x141,
3125 "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",
3131 * attach obdfilter ost1 ost1_UUID
3132 * setup /dev/loop2 ldiskfs f|n errors=remount-ro,user_xattr
3134 if (class_find_param(ptr, PARAM_FAILMODE, &ptr) == 0)
3135 failout = (strncmp(ptr, "failout", 7) == 0);
3136 rc = record_start_log(env, mgs, &llh, mti->mti_svname);
3139 /* FIXME these should be a single journal transaction */
3140 rc = record_marker(env, llh, fsdb, CM_START, mti->mti_svname,"add ost");
3143 if (*mti->mti_uuid == '\0')
3144 snprintf(mti->mti_uuid, sizeof(mti->mti_uuid),
3145 "%s_UUID", mti->mti_svname);
3146 rc = record_attach(env, llh, mti->mti_svname,
3147 "obdfilter"/*LUSTRE_OST_NAME*/, mti->mti_uuid);
3150 rc = record_setup(env, llh, mti->mti_svname,
3151 "dev"/*ignored*/, "type"/*ignored*/,
3152 failout ? "n" : "f", NULL/*options*/);
3155 rc = record_marker(env, llh, fsdb, CM_END, mti->mti_svname, "add ost");
3159 record_end_log(env, &llh);
3162 /* We also have to update the other logs where this osc is part of
3166 if (test_bit(FSDB_OLDLOG14, &fsdb->fsdb_flags)) {
3167 /* If we're upgrading, the old mdt log already has our
3168 * entry. Let's do a fake one for fun.
3170 /* Note that we can't add any new failnids, since we don't
3171 * know the old osc names.
3173 flags = CM_SKIP | CM_UPGRADE146;
3174 } else if ((mti->mti_flags & LDD_F_UPDATE) != LDD_F_UPDATE) {
3175 /* If the update flag isn't set, don't update client/mdt
3179 LCONSOLE_WARN("Client log for %s was not updated; writeconf the MDT first to regenerate it.\n",
3183 /* Add ost to all MDT lov defs */
3184 for (i = 0; i < INDEX_MAP_SIZE * 8; i++) {
3185 if (test_bit(i, fsdb->fsdb_mdt_index_map)) {
3188 rc = name_create_mdt_and_lov(&logname, &lovname, fsdb,
3193 snprintf(mdt_index, sizeof(mdt_index), "-MDT%04x", i);
3194 rc = mgs_write_log_osc_to_lov(env, mgs, fsdb, mti,
3196 lovname, LUSTRE_SP_MDT,
3198 name_destroy(&logname);
3199 name_destroy(&lovname);
3205 /* Append ost info to the client log */
3206 rc = name_create(&logname, mti->mti_fsname, "-client");
3209 if (mgs_log_is_empty(env, mgs, logname)) {
3210 /* Start client log */
3211 rc = mgs_write_log_lov(env, mgs, fsdb, mti, logname,
3215 rc = mgs_write_log_lmv(env, mgs, fsdb, mti, logname,
3219 rc = mgs_write_log_mount_opt(env, mgs, fsdb, logname);
3223 rc = mgs_write_log_osc_to_lov(env, mgs, fsdb, mti, logname, "",
3224 fsdb->fsdb_clilov, LUSTRE_SP_CLI, flags);
3226 name_destroy(&logname);
3230 static __inline__ int mgs_param_empty(char *ptr)
3232 char *tmp = strchr(ptr, '=');
3234 if (tmp && tmp[1] == '\0')
3239 static int mgs_write_log_failnid_internal(const struct lu_env *env,
3240 struct mgs_device *mgs,
3242 struct mgs_target_info *mti,
3243 char *logname, char *cliname)
3246 struct llog_handle *llh = NULL;
3248 if (mgs_param_empty(mti->mti_params)) {
3249 /* Remove _all_ failnids */
3250 rc = mgs_modify(env, mgs, fsdb, mti, logname,
3251 mti->mti_svname, "add failnid", CM_SKIP);
3252 return rc < 0 ? rc : 0;
3255 /* Otherwise failover nids are additive */
3256 rc = record_start_log(env, mgs, &llh, logname);
3259 /* FIXME this should be a single journal transaction */
3260 rc = record_marker(env, llh, fsdb, CM_START, mti->mti_svname,
3264 rc = mgs_write_log_failnids(env, mti, llh, cliname);
3267 rc = record_marker(env, llh, fsdb, CM_END,
3268 mti->mti_svname, "add failnid");
3270 record_end_log(env, &llh);
3274 /* Add additional failnids to an existing log.
3275 The mdc/osc must have been added to logs first */
3276 /* tcp nids must be in dotted-quad ascii -
3277 we can't resolve hostnames from the kernel. */
3278 static int mgs_write_log_add_failnid(const struct lu_env *env,
3279 struct mgs_device *mgs,
3281 struct mgs_target_info *mti)
3283 char *logname, *cliname;
3287 /* FIXME we currently can't erase the failnids
3288 * given when a target first registers, since they aren't part of
3289 * an "add uuid" stanza
3292 /* Verify that we know about this target */
3293 if (mgs_log_is_empty(env, mgs, mti->mti_svname)) {
3294 LCONSOLE_ERROR_MSG(0x142,
3295 "The target %s has not registered yet. It must be started before failnids can be added.\n",
3300 /* Create mdc/osc client name (e.g. lustre-OST0001-osc) */
3301 if (mti->mti_flags & LDD_F_SV_TYPE_MDT)
3302 rc = name_create(&cliname, mti->mti_svname, "-mdc");
3303 else if (mti->mti_flags & LDD_F_SV_TYPE_OST)
3304 rc = name_create(&cliname, mti->mti_svname, "-osc");
3311 /* Add failover nids to the client log */
3312 rc = name_create(&logname, mti->mti_fsname, "-client");
3314 name_destroy(&cliname);
3318 rc = mgs_write_log_failnid_internal(env, mgs, fsdb,mti,logname,cliname);
3319 name_destroy(&logname);
3320 name_destroy(&cliname);
3324 if (mti->mti_flags & LDD_F_SV_TYPE_OST) {
3325 /* Add OST failover nids to the MDT logs as well */
3328 for (i = 0; i < INDEX_MAP_SIZE * 8; i++) {
3329 if (!test_bit(i, fsdb->fsdb_mdt_index_map))
3331 rc = name_create_mdt(&logname, mti->mti_fsname, i);
3334 rc = name_create_mdt_osc(&cliname, mti->mti_svname,
3337 name_destroy(&logname);
3340 rc = mgs_write_log_failnid_internal(env, mgs, fsdb,
3343 name_destroy(&cliname);
3344 name_destroy(&logname);
3353 static int mgs_wlp_lcfg(const struct lu_env *env,
3354 struct mgs_device *mgs, struct fs_db *fsdb,
3355 struct mgs_target_info *mti,
3356 char *logname, struct lustre_cfg_bufs *bufs,
3357 char *tgtname, char *ptr)
3359 char comment[MTI_NAME_MAXLEN];
3361 struct llog_cfg_rec *lcr;
3364 /* Erase any old settings of this same parameter */
3365 strlcpy(comment, ptr, sizeof(comment));
3366 /* But don't try to match the value. */
3367 tmp = strchr(comment, '=');
3370 /* FIXME we should skip settings that are the same as old values */
3371 rc = mgs_modify(env, mgs, fsdb, mti, logname, tgtname, comment,CM_SKIP);
3374 del = mgs_param_empty(ptr);
3376 LCONSOLE_INFO("%s parameter %s.%s in log %s\n", del ? "Disabling" : rc ?
3377 "Setting" : "Modifying", tgtname, comment, logname);
3379 /* mgs_modify() will return 1 if nothing had to be done */
3385 lustre_cfg_bufs_reset(bufs, tgtname);
3386 lustre_cfg_bufs_set_string(bufs, 1, ptr);
3387 if (mti->mti_flags & LDD_F_PARAM2)
3388 lustre_cfg_bufs_set_string(bufs, 2, LCTL_UPCALL);
3390 lcr = lustre_cfg_rec_new((mti->mti_flags & LDD_F_PARAM2) ?
3391 LCFG_SET_PARAM : LCFG_PARAM, bufs);
3395 rc = mgs_write_log_direct(env, mgs, fsdb, logname, lcr, tgtname,
3397 lustre_cfg_rec_free(lcr);
3401 /* write global variable settings into log */
3402 static int mgs_write_log_sys(const struct lu_env *env,
3403 struct mgs_device *mgs, struct fs_db *fsdb,
3404 struct mgs_target_info *mti, char *sys, char *ptr)
3406 struct mgs_thread_info *mgi = mgs_env_info(env);
3407 struct lustre_cfg *lcfg;
3408 struct llog_cfg_rec *lcr;
3410 int rc, cmd, convert = 1;
3412 if (class_match_param(ptr, PARAM_TIMEOUT, &tmp) == 0) {
3413 cmd = LCFG_SET_TIMEOUT;
3414 } else if (class_match_param(ptr, PARAM_LDLM_TIMEOUT, &tmp) == 0) {
3415 cmd = LCFG_SET_LDLM_TIMEOUT;
3416 /* Check for known params here so we can return error to lctl */
3417 } else if ((class_match_param(ptr, PARAM_AT_MIN, &tmp) == 0) ||
3418 (class_match_param(ptr, PARAM_AT_MAX, &tmp) == 0) ||
3419 (class_match_param(ptr, PARAM_AT_EXTRA, &tmp) == 0) ||
3420 (class_match_param(ptr, PARAM_AT_EARLY_MARGIN, &tmp) == 0) ||
3421 (class_match_param(ptr, PARAM_AT_HISTORY, &tmp) == 0)) {
3423 } else if (class_match_param(ptr, PARAM_JOBID_VAR, &tmp) == 0) {
3424 convert = 0; /* Don't convert string value to integer */
3430 if (mgs_param_empty(ptr))
3431 CDEBUG(D_MGS, "global '%s' removed\n", sys);
3433 CDEBUG(D_MGS, "global '%s' val=%s\n", sys, tmp);
3435 lustre_cfg_bufs_reset(&mgi->mgi_bufs, NULL);
3436 lustre_cfg_bufs_set_string(&mgi->mgi_bufs, 1, sys);
3437 if (!convert && *tmp != '\0')
3438 lustre_cfg_bufs_set_string(&mgi->mgi_bufs, 2, tmp);
3439 lcr = lustre_cfg_rec_new(cmd, &mgi->mgi_bufs);
3443 lcfg = &lcr->lcr_cfg;
3445 rc = kstrtouint(tmp, 0, &lcfg->lcfg_num);
3447 GOTO(out_rec_free, rc);
3452 /* truncate the comment to the parameter name */
3456 /* modify all servers and clients */
3457 rc = mgs_write_log_direct_all(env, mgs, fsdb, mti,
3458 *tmp == '\0' ? NULL : lcr,
3459 mti->mti_fsname, sys, 0);
3460 if (rc == 0 && *tmp != '\0') {
3462 case LCFG_SET_TIMEOUT:
3463 if (!obd_timeout_set || lcfg->lcfg_num > obd_timeout)
3464 class_process_config(lcfg);
3466 case LCFG_SET_LDLM_TIMEOUT:
3467 if (!ldlm_timeout_set || lcfg->lcfg_num > ldlm_timeout)
3468 class_process_config(lcfg);
3476 lustre_cfg_rec_free(lcr);
3480 /* write quota settings into log */
3481 static int mgs_write_log_quota(const struct lu_env *env, struct mgs_device *mgs,
3482 struct fs_db *fsdb, struct mgs_target_info *mti,
3483 char *quota, char *ptr)
3485 struct mgs_thread_info *mgi = mgs_env_info(env);
3486 struct llog_cfg_rec *lcr;
3489 int rc, cmd = LCFG_PARAM;
3491 /* support only 'meta' and 'data' pools so far */
3492 if (class_match_param(ptr, QUOTA_METAPOOL_NAME, &tmp) != 0 &&
3493 class_match_param(ptr, QUOTA_DATAPOOL_NAME, &tmp) != 0) {
3494 CERROR("parameter quota.%s isn't supported (only quota.mdt "
3495 "& quota.ost are)\n", ptr);
3500 CDEBUG(D_MGS, "global '%s' removed\n", quota);
3502 CDEBUG(D_MGS, "global '%s'\n", quota);
3504 if (strchr(tmp, 'u') == NULL && strchr(tmp, 'g') == NULL &&
3505 strchr(tmp, 'p') == NULL &&
3506 strcmp(tmp, "none") != 0) {
3507 CERROR("enable option(%s) isn't supported\n", tmp);
3512 lustre_cfg_bufs_reset(&mgi->mgi_bufs, mti->mti_fsname);
3513 lustre_cfg_bufs_set_string(&mgi->mgi_bufs, 1, quota);
3514 lcr = lustre_cfg_rec_new(cmd, &mgi->mgi_bufs);
3518 /* truncate the comment to the parameter name */
3523 /* XXX we duplicated quota enable information in all server
3524 * config logs, it should be moved to a separate config
3525 * log once we cleanup the config log for global param. */
3526 /* modify all servers */
3527 rc = mgs_write_log_direct_all(env, mgs, fsdb, mti,
3528 *tmp == '\0' ? NULL : lcr,
3529 mti->mti_fsname, quota, 1);
3531 lustre_cfg_rec_free(lcr);
3532 return rc < 0 ? rc : 0;
3535 static int mgs_srpc_set_param_disk(const struct lu_env *env,
3536 struct mgs_device *mgs,
3538 struct mgs_target_info *mti,
3541 struct mgs_thread_info *mgi = mgs_env_info(env);
3542 struct llog_cfg_rec *lcr;
3543 struct llog_handle *llh = NULL;
3545 char *comment, *ptr;
3551 ptr = strchr(param, '=');
3552 LASSERT(ptr != NULL);
3555 OBD_ALLOC(comment, len + 1);
3556 if (comment == NULL)
3558 strncpy(comment, param, len);
3559 comment[len] = '\0';
3562 lustre_cfg_bufs_reset(&mgi->mgi_bufs, mti->mti_svname);
3563 lustre_cfg_bufs_set_string(&mgi->mgi_bufs, 1, param);
3564 lcr = lustre_cfg_rec_new(LCFG_SPTLRPC_CONF, &mgi->mgi_bufs);
3566 GOTO(out_comment, rc = -ENOMEM);
3568 /* construct log name */
3569 rc = name_create(&logname, mti->mti_fsname, "-sptlrpc");
3573 if (mgs_log_is_empty(env, mgs, logname)) {
3574 rc = record_start_log(env, mgs, &llh, logname);
3577 record_end_log(env, &llh);
3580 /* obsolete old one */
3581 rc = mgs_modify(env, mgs, fsdb, mti, logname, mti->mti_svname,
3585 /* write the new one */
3586 rc = mgs_write_log_direct(env, mgs, fsdb, logname, lcr,
3587 mti->mti_svname, comment);
3589 CERROR("%s: error writing log %s: rc = %d\n",
3590 mgs->mgs_obd->obd_name, logname, rc);
3592 name_destroy(&logname);
3594 lustre_cfg_rec_free(lcr);
3596 OBD_FREE(comment, len + 1);
3600 static int mgs_srpc_set_param_udesc_mem(struct fs_db *fsdb,
3605 /* disable the adjustable udesc parameter for now, i.e. use default
3606 * setting that client always ship udesc to MDT if possible. to enable
3607 * it simply remove the following line
3611 ptr = strchr(param, '=');
3616 if (strcmp(param, PARAM_SRPC_UDESC))
3619 if (strcmp(ptr, "yes") == 0) {
3620 set_bit(FSDB_UDESC, &fsdb->fsdb_flags);
3621 CWARN("Enable user descriptor shipping from client to MDT\n");
3622 } else if (strcmp(ptr, "no") == 0) {
3623 clear_bit(FSDB_UDESC, &fsdb->fsdb_flags);
3624 CWARN("Disable user descriptor shipping from client to MDT\n");
3632 CERROR("Invalid param: %s\n", param);
3636 static int mgs_srpc_set_param_mem(struct fs_db *fsdb,
3640 struct sptlrpc_rule rule;
3641 struct sptlrpc_rule_set *rset;
3645 if (strncmp(param, PARAM_SRPC, sizeof(PARAM_SRPC) - 1) != 0) {
3646 CERROR("Invalid sptlrpc parameter: %s\n", param);
3650 if (strncmp(param, PARAM_SRPC_UDESC,
3651 sizeof(PARAM_SRPC_UDESC) - 1) == 0) {
3652 RETURN(mgs_srpc_set_param_udesc_mem(fsdb, param));
3655 if (strncmp(param, PARAM_SRPC_FLVR, sizeof(PARAM_SRPC_FLVR) - 1) != 0) {
3656 CERROR("Invalid sptlrpc flavor parameter: %s\n", param);
3660 param += sizeof(PARAM_SRPC_FLVR) - 1;
3662 rc = sptlrpc_parse_rule(param, &rule);
3666 /* mgs rules implies must be mgc->mgs */
3667 if (test_bit(FSDB_MGS_SELF, &fsdb->fsdb_flags)) {
3668 if ((rule.sr_from != LUSTRE_SP_MGC &&
3669 rule.sr_from != LUSTRE_SP_ANY) ||
3670 (rule.sr_to != LUSTRE_SP_MGS &&
3671 rule.sr_to != LUSTRE_SP_ANY))
3675 /* prepare room for this coming rule. svcname format should be:
3676 * - fsname: general rule
3677 * - fsname-tgtname: target-specific rule
3679 if (strchr(svname, '-')) {
3680 struct mgs_tgt_srpc_conf *tgtconf;
3683 for (tgtconf = fsdb->fsdb_srpc_tgt; tgtconf != NULL;
3684 tgtconf = tgtconf->mtsc_next) {
3685 if (!strcmp(tgtconf->mtsc_tgt, svname)) {
3694 OBD_ALLOC_PTR(tgtconf);
3695 if (tgtconf == NULL)
3698 name_len = strlen(svname);
3700 OBD_ALLOC(tgtconf->mtsc_tgt, name_len + 1);
3701 if (tgtconf->mtsc_tgt == NULL) {
3702 OBD_FREE_PTR(tgtconf);
3705 memcpy(tgtconf->mtsc_tgt, svname, name_len);
3707 tgtconf->mtsc_next = fsdb->fsdb_srpc_tgt;
3708 fsdb->fsdb_srpc_tgt = tgtconf;
3711 rset = &tgtconf->mtsc_rset;
3712 } else if (strcmp(svname, MGSSELF_NAME) == 0) {
3713 /* put _mgs related srpc rule directly in mgs ruleset */
3714 rset = &fsdb->fsdb_mgs->mgs_lut.lut_sptlrpc_rset;
3716 rset = &fsdb->fsdb_srpc_gen;
3719 rc = sptlrpc_rule_set_merge(rset, &rule);
3724 static int mgs_srpc_set_param(const struct lu_env *env,
3725 struct mgs_device *mgs,
3727 struct mgs_target_info *mti,
3737 /* keep a copy of original param, which could be destroyed
3740 copy_size = strlen(param) + 1;
3741 OBD_ALLOC(copy, copy_size);
3744 memcpy(copy, param, copy_size);
3746 rc = mgs_srpc_set_param_mem(fsdb, mti->mti_svname, param);
3750 /* previous steps guaranteed the syntax is correct */
3751 rc = mgs_srpc_set_param_disk(env, mgs, fsdb, mti, copy);
3755 if (test_bit(FSDB_MGS_SELF, &fsdb->fsdb_flags)) {
3757 * for mgs rules, make them effective immediately.
3759 LASSERT(fsdb->fsdb_srpc_tgt == NULL);
3760 sptlrpc_target_update_exp_flavor(mgs->mgs_obd,
3761 &fsdb->fsdb_srpc_gen);
3765 OBD_FREE(copy, copy_size);
3769 struct mgs_srpc_read_data {
3770 struct fs_db *msrd_fsdb;
3774 static int mgs_srpc_read_handler(const struct lu_env *env,
3775 struct llog_handle *llh,
3776 struct llog_rec_hdr *rec, void *data)
3778 struct mgs_srpc_read_data *msrd = data;
3779 struct cfg_marker *marker;
3780 struct lustre_cfg *lcfg = REC_DATA(rec);
3781 char *svname, *param;
3785 if (rec->lrh_type != OBD_CFG_REC) {
3786 CERROR("unhandled lrh_type: %#x\n", rec->lrh_type);
3790 cfg_len = REC_DATA_LEN(rec);
3792 rc = lustre_cfg_sanity_check(lcfg, cfg_len);
3794 CERROR("Insane cfg\n");
3798 if (lcfg->lcfg_command == LCFG_MARKER) {
3799 marker = lustre_cfg_buf(lcfg, 1);
3801 if (marker->cm_flags & CM_START &&
3802 marker->cm_flags & CM_SKIP)
3803 msrd->msrd_skip = 1;
3804 if (marker->cm_flags & CM_END)
3805 msrd->msrd_skip = 0;
3810 if (msrd->msrd_skip)
3813 if (lcfg->lcfg_command != LCFG_SPTLRPC_CONF) {
3814 CERROR("invalid command (%x)\n", lcfg->lcfg_command);
3818 svname = lustre_cfg_string(lcfg, 0);
3819 if (svname == NULL) {
3820 CERROR("svname is empty\n");
3824 param = lustre_cfg_string(lcfg, 1);
3825 if (param == NULL) {
3826 CERROR("param is empty\n");
3830 rc = mgs_srpc_set_param_mem(msrd->msrd_fsdb, svname, param);
3832 CERROR("read sptlrpc record error (%d): %s\n", rc, param);
3837 int mgs_get_fsdb_srpc_from_llog(const struct lu_env *env,
3838 struct mgs_device *mgs,
3841 struct llog_handle *llh = NULL;
3842 struct llog_ctxt *ctxt;
3844 struct mgs_srpc_read_data msrd;
3848 /* construct log name */
3849 rc = name_create(&logname, fsdb->fsdb_name, "-sptlrpc");
3853 ctxt = llog_get_context(mgs->mgs_obd, LLOG_CONFIG_ORIG_CTXT);
3854 LASSERT(ctxt != NULL);
3856 if (mgs_log_is_empty(env, mgs, logname))
3859 rc = llog_open(env, ctxt, &llh, NULL, logname,
3867 rc = llog_init_handle(env, llh, LLOG_F_IS_PLAIN, NULL);
3869 GOTO(out_close, rc);
3871 if (llog_get_size(llh) <= 1)
3872 GOTO(out_close, rc = 0);
3874 msrd.msrd_fsdb = fsdb;
3877 rc = llog_process(env, llh, mgs_srpc_read_handler, (void *)&msrd,
3881 llog_close(env, llh);
3883 llog_ctxt_put(ctxt);
3884 name_destroy(&logname);
3887 CERROR("failed to read sptlrpc config database: %d\n", rc);
3891 static int mgs_write_log_param2(const struct lu_env *env,
3892 struct mgs_device *mgs,
3894 struct mgs_target_info *mti, char *ptr)
3896 struct lustre_cfg_bufs bufs;
3900 CDEBUG(D_MGS, "next param '%s'\n", ptr);
3902 /* PARAM_MGSNODE and PARAM_NETWORK are set only when formating
3903 * or during the inital mount. It can never change after that.
3905 if (!class_match_param(ptr, PARAM_MGSNODE, NULL) ||
3906 !class_match_param(ptr, PARAM_NETWORK, NULL)) {
3911 /* Processed in mgs_write_log_ost. Another value that can't
3912 * be changed by lctl set_param -P.
3914 if (!class_match_param(ptr, PARAM_FAILMODE, NULL)) {
3915 LCONSOLE_ERROR_MSG(0x169,
3916 "%s can only be changed with tunefs.lustre and --writeconf\n",
3922 /* FIXME !!! Support for sptlrpc is incomplete. Currently the change
3923 * doesn't transmit to the client. See LU-7183.
3925 if (!class_match_param(ptr, PARAM_SRPC, NULL)) {
3926 rc = mgs_srpc_set_param(env, mgs, fsdb, mti, ptr);
3930 /* Can't use class_match_param since ptr doesn't start with
3931 * PARAM_FAILNODE. So we look for PARAM_FAILNODE contained in ptr.
3933 if (strstr(ptr, PARAM_FAILNODE)) {
3934 /* Add a failover nidlist. We already processed failovers
3935 * params for new targets in mgs_write_log_target.
3939 /* can't use wildcards with failover.node */
3940 if (strchr(ptr, '*')) {
3945 param = strstr(ptr, PARAM_FAILNODE);
3946 if (strlcpy(mti->mti_params, param, sizeof(mti->mti_params)) >=
3947 sizeof(mti->mti_params)) {
3952 CDEBUG(D_MGS, "Adding failnode with param %s\n",
3954 rc = mgs_write_log_add_failnid(env, mgs, fsdb, mti);
3958 /* root squash parameters must not be set on llite subsystem, this can
3959 * lead to inconsistencies between client and server values
3961 if ((strstr(ptr, PARAM_NOSQUASHNIDS) ||
3962 strstr(ptr, PARAM_ROOTSQUASH)) &&
3963 strncmp(ptr, "llite.", strlen("llite.")) == 0) {
3965 CWARN("%s: cannot add %s param to llite subsystem, use mdt instead: rc=%d\n",
3966 mgs->mgs_obd->obd_name,
3967 strstr(ptr, PARAM_ROOTSQUASH) ?
3968 PARAM_ROOTSQUASH : PARAM_NOSQUASHNIDS,
3973 rc = mgs_wlp_lcfg(env, mgs, fsdb, mti, PARAMS_FILENAME, &bufs,
3974 mti->mti_svname, ptr);
3979 /* Permanent settings of all parameters by writing into the appropriate
3980 * configuration logs.
3981 * A parameter with null value ("<param>='\0'") means to erase it out of
3984 static int mgs_write_log_param(const struct lu_env *env,
3985 struct mgs_device *mgs, struct fs_db *fsdb,
3986 struct mgs_target_info *mti, char *ptr)
3988 struct mgs_thread_info *mgi = mgs_env_info(env);
3994 /* For various parameter settings, we have to figure out which logs
3995 * care about them (e.g. both mdt and client for lov settings)
3997 CDEBUG(D_MGS, "next param '%s'\n", ptr);
3999 /* The params are stored in MOUNT_DATA_FILE and modified via
4000 * tunefs.lustre, or set using lctl conf_param
4003 /* Processed in lustre_start_mgc */
4004 if (class_match_param(ptr, PARAM_MGSNODE, NULL) == 0)
4007 /* Processed in ost/mdt */
4008 if (class_match_param(ptr, PARAM_NETWORK, NULL) == 0)
4011 /* Processed in mgs_write_log_ost */
4012 if (class_match_param(ptr, PARAM_FAILMODE, NULL) == 0) {
4013 if (mti->mti_flags & LDD_F_PARAM) {
4014 LCONSOLE_ERROR_MSG(0x169,
4015 "%s can only be changed with tunefs.lustre and --writeconf\n",
4022 if (class_match_param(ptr, PARAM_SRPC, NULL) == 0) {
4023 rc = mgs_srpc_set_param(env, mgs, fsdb, mti, ptr);
4027 if (class_match_param(ptr, PARAM_FAILNODE, NULL) == 0) {
4028 /* Add a failover nidlist */
4030 /* We already processed failovers params for new
4031 * targets in mgs_write_log_target
4033 if (mti->mti_flags & LDD_F_PARAM) {
4034 CDEBUG(D_MGS, "Adding failnode\n");
4035 rc = mgs_write_log_add_failnid(env, mgs, fsdb, mti);
4040 if (class_match_param(ptr, PARAM_SYS, &tmp) == 0) {
4041 rc = mgs_write_log_sys(env, mgs, fsdb, mti, ptr, tmp);
4045 if (class_match_param(ptr, PARAM_QUOTA, &tmp) == 0) {
4046 rc = mgs_write_log_quota(env, mgs, fsdb, mti, ptr, tmp);
4050 if (class_match_param(ptr, PARAM_OSC PARAM_ACTIVE, &tmp) == 0 ||
4051 class_match_param(ptr, PARAM_MDC PARAM_ACTIVE, &tmp) == 0) {
4052 /* active=0 means off, anything else means on */
4053 int flag = (*tmp == '0') ? CM_EXCLUDE : 0;
4054 bool deactive_osc = memcmp(ptr, PARAM_OSC PARAM_ACTIVE,
4055 strlen(PARAM_OSC PARAM_ACTIVE)) == 0;
4058 if (!deactive_osc) {
4061 rc = server_name2index(mti->mti_svname, &index, NULL);
4066 LCONSOLE_ERROR_MSG(0x144, "%s: MDC0 can not be"
4067 " (de)activated.\n",
4069 GOTO(end, rc = -EPERM);
4073 LCONSOLE_WARN("Permanently %sactivating %s\n",
4074 flag ? "de" : "re", mti->mti_svname);
4076 rc = name_create(&logname, mti->mti_fsname, "-client");
4079 rc = mgs_modify(env, mgs, fsdb, mti, logname,
4081 deactive_osc ? "add osc" : "add mdc", flag);
4082 name_destroy(&logname);
4087 /* Add to all MDT logs for DNE */
4088 for (i = 0; i < INDEX_MAP_SIZE * 8; i++) {
4089 if (!test_bit(i, fsdb->fsdb_mdt_index_map))
4091 rc = name_create_mdt(&logname, mti->mti_fsname, i);
4094 rc = mgs_modify(env, mgs, fsdb, mti, logname,
4096 deactive_osc ? "add osc" : "add osp",
4098 name_destroy(&logname);
4104 LCONSOLE_ERROR_MSG(0x145,
4105 "Couldn't find %s in log (%d). No permanent changes were made to the config log.\n",
4106 mti->mti_svname, rc);
4107 if (test_bit(FSDB_OLDLOG14, &fsdb->fsdb_flags))
4108 LCONSOLE_ERROR_MSG(0x146,
4109 "This may be because the log is in the old 1.4 style. Consider --writeconf to update the logs.\n");
4112 /* Fall through to osc/mdc proc for deactivating live
4113 * OSC/OSP on running MDT / clients.
4116 /* Below here, let obd's XXX_process_config methods handle it */
4118 /* All lov. in proc */
4119 if (class_match_param(ptr, PARAM_LOV, NULL) == 0) {
4122 CDEBUG(D_MGS, "lov param %s\n", ptr);
4123 if (!(mti->mti_flags & LDD_F_SV_TYPE_MDT)) {
4124 LCONSOLE_ERROR_MSG(0x147,
4125 "LOV params must be set on the MDT, not %s. Ignoring.\n",
4131 if (mgs_log_is_empty(env, mgs, mti->mti_svname))
4132 GOTO(end, rc = -ENODEV);
4134 rc = name_create_mdt_and_lov(&logname, &mdtlovname, fsdb,
4135 mti->mti_stripe_index);
4138 rc = mgs_wlp_lcfg(env, mgs, fsdb, mti, mti->mti_svname,
4139 &mgi->mgi_bufs, mdtlovname, ptr);
4140 name_destroy(&logname);
4141 name_destroy(&mdtlovname);
4146 rc = name_create(&logname, mti->mti_fsname, "-client");
4149 rc = mgs_wlp_lcfg(env, mgs, fsdb, mti, logname, &mgi->mgi_bufs,
4150 fsdb->fsdb_clilov, ptr);
4151 name_destroy(&logname);
4155 /* All osc., mdc., llite. params in proc */
4156 if ((class_match_param(ptr, PARAM_OSC, NULL) == 0) ||
4157 (class_match_param(ptr, PARAM_MDC, NULL) == 0) ||
4158 (class_match_param(ptr, PARAM_LLITE, NULL) == 0)) {
4161 if (test_bit(FSDB_OLDLOG14, &fsdb->fsdb_flags)) {
4162 LCONSOLE_ERROR_MSG(0x148, "Upgraded client logs for %s"
4163 " cannot be modified. Consider"
4164 " updating the configuration with"
4167 GOTO(end, rc = -EINVAL);
4169 if (memcmp(ptr, PARAM_LLITE, strlen(PARAM_LLITE)) == 0) {
4170 rc = name_create(&cname, mti->mti_fsname, "-client");
4171 /* Add the client type to match the obdname in
4172 * class_config_llog_handler
4174 } else if (mti->mti_flags & LDD_F_SV_TYPE_MDT) {
4175 rc = name_create(&cname, mti->mti_svname, "-mdc");
4176 } else if (mti->mti_flags & LDD_F_SV_TYPE_OST) {
4177 rc = name_create(&cname, mti->mti_svname, "-osc");
4179 GOTO(end, rc = -EINVAL);
4184 /* Forbid direct update of llite root squash parameters.
4185 * These parameters are indirectly set via the MDT settings.
4187 if ((class_match_param(ptr, PARAM_LLITE, &tmp) == 0) &&
4188 ((memcmp(tmp, "root_squash=", 12) == 0) ||
4189 (memcmp(tmp, "nosquash_nids=", 14) == 0))) {
4190 LCONSOLE_ERROR("%s: root squash parameters can only "
4191 "be updated through MDT component\n",
4193 name_destroy(&cname);
4194 GOTO(end, rc = -EINVAL);
4197 CDEBUG(D_MGS, "%.3s param %s\n", ptr, ptr + 4);
4200 rc = name_create(&logname, mti->mti_fsname, "-client");
4202 name_destroy(&cname);
4205 rc = mgs_wlp_lcfg(env, mgs, fsdb, mti, logname, &mgi->mgi_bufs,
4208 /* osc params affect the MDT as well */
4209 if (!rc && (mti->mti_flags & LDD_F_SV_TYPE_OST)) {
4212 for (i = 0; i < INDEX_MAP_SIZE * 8; i++) {
4213 if (!test_bit(i, fsdb->fsdb_mdt_index_map))
4215 name_destroy(&cname);
4216 rc = name_create_mdt_osc(&cname, mti->mti_svname,
4218 name_destroy(&logname);
4221 rc = name_create_mdt(&logname,
4222 mti->mti_fsname, i);
4225 if (!mgs_log_is_empty(env, mgs, logname)) {
4226 rc = mgs_wlp_lcfg(env, mgs, fsdb,
4236 /* For mdc activate/deactivate, it affects OSP on MDT as well */
4237 if (class_match_param(ptr, PARAM_MDC PARAM_ACTIVE, &tmp) == 0 &&
4240 char *lodname = NULL;
4241 char *param_str = NULL;
4245 /* replace mdc with osp */
4246 memcpy(ptr, PARAM_OSP, strlen(PARAM_OSP));
4247 rc = server_name2index(mti->mti_svname, &index, NULL);
4249 memcpy(ptr, PARAM_MDC, strlen(PARAM_MDC));
4253 for (i = 0; i < INDEX_MAP_SIZE * 8; i++) {
4254 if (!test_bit(i, fsdb->fsdb_mdt_index_map))
4260 name_destroy(&logname);
4261 rc = name_create_mdt(&logname, mti->mti_fsname,
4266 if (mgs_log_is_empty(env, mgs, logname))
4269 snprintf(suffix, sizeof(suffix), "-osp-MDT%04x",
4271 name_destroy(&cname);
4272 rc = name_create(&cname, mti->mti_svname,
4277 rc = mgs_wlp_lcfg(env, mgs, fsdb, mti, logname,
4278 &mgi->mgi_bufs, cname, ptr);
4282 /* Add configuration log for noitfying LOD
4283 * to active/deactive the OSP. */
4284 name_destroy(¶m_str);
4285 rc = name_create(¶m_str, cname,
4286 (*tmp == '0') ? ".active=0" :
4291 name_destroy(&lodname);
4292 rc = name_create(&lodname, logname, "-mdtlov");
4296 rc = mgs_wlp_lcfg(env, mgs, fsdb, mti, logname,
4297 &mgi->mgi_bufs, lodname,
4302 memcpy(ptr, PARAM_MDC, strlen(PARAM_MDC));
4303 name_destroy(&lodname);
4304 name_destroy(¶m_str);
4307 name_destroy(&logname);
4308 name_destroy(&cname);
4312 /* All mdt. params in proc */
4313 if (class_match_param(ptr, PARAM_MDT, &tmp) == 0) {
4317 CDEBUG(D_MGS, "%.3s param %s\n", ptr, ptr + 4);
4318 if (strncmp(mti->mti_svname, mti->mti_fsname,
4319 MTI_NAME_MAXLEN) == 0)
4320 /* device is unspecified completely? */
4321 rc = LDD_F_SV_TYPE_MDT | LDD_F_SV_ALL;
4323 rc = server_name2index(mti->mti_svname, &idx, NULL);
4326 if ((rc & LDD_F_SV_TYPE_MDT) == 0)
4328 if (rc & LDD_F_SV_ALL) {
4329 for (i = 0; i < INDEX_MAP_SIZE * 8; i++) {
4331 fsdb->fsdb_mdt_index_map))
4333 rc = name_create_mdt(&logname,
4334 mti->mti_fsname, i);
4337 rc = mgs_wlp_lcfg(env, mgs, fsdb, mti,
4338 logname, &mgi->mgi_bufs,
4340 name_destroy(&logname);
4345 if ((memcmp(tmp, "root_squash=", 12) == 0) ||
4346 (memcmp(tmp, "nosquash_nids=", 14) == 0)) {
4347 LCONSOLE_ERROR("%s: root squash parameters "
4348 "cannot be applied to a single MDT\n",
4350 GOTO(end, rc = -EINVAL);
4352 rc = mgs_wlp_lcfg(env, mgs, fsdb, mti,
4353 mti->mti_svname, &mgi->mgi_bufs,
4354 mti->mti_svname, ptr);
4359 /* root squash settings are also applied to llite
4360 * config log (see LU-1778) */
4362 ((memcmp(tmp, "root_squash=", 12) == 0) ||
4363 (memcmp(tmp, "nosquash_nids=", 14) == 0))) {
4367 rc = name_create(&cname, mti->mti_fsname, "-client");
4370 rc = name_create(&logname, mti->mti_fsname, "-client");
4372 name_destroy(&cname);
4375 rc = name_create(&ptr2, PARAM_LLITE, tmp);
4377 name_destroy(&cname);
4378 name_destroy(&logname);
4381 rc = mgs_wlp_lcfg(env, mgs, fsdb, mti, logname,
4382 &mgi->mgi_bufs, cname, ptr2);
4383 name_destroy(&ptr2);
4384 name_destroy(&logname);
4385 name_destroy(&cname);
4390 /* All mdd., ost. and osd. params in proc */
4391 if ((class_match_param(ptr, PARAM_MDD, NULL) == 0) ||
4392 (class_match_param(ptr, PARAM_LOD, NULL) == 0) ||
4393 (class_match_param(ptr, PARAM_OST, NULL) == 0) ||
4394 (class_match_param(ptr, PARAM_OSD, NULL) == 0)) {
4395 CDEBUG(D_MGS, "%.3s param %s\n", ptr, ptr + 4);
4396 if (mgs_log_is_empty(env, mgs, mti->mti_svname))
4397 GOTO(end, rc = -ENODEV);
4399 rc = mgs_wlp_lcfg(env, mgs, fsdb, mti, mti->mti_svname,
4400 &mgi->mgi_bufs, mti->mti_svname, ptr);
4404 /* For handling degraded zfs OST */
4405 if (class_match_param(ptr, PARAM_AUTODEGRADE, NULL) == 0)
4408 LCONSOLE_WARN("Ignoring unrecognized param '%s'\n", ptr);
4412 CERROR("err %d on param '%s'\n", rc, ptr);
4417 int mgs_write_log_target(const struct lu_env *env, struct mgs_device *mgs,
4418 struct mgs_target_info *mti, struct fs_db *fsdb)
4425 /* set/check the new target index */
4426 rc = mgs_set_index(env, mgs, mti);
4430 if (rc == EALREADY) {
4431 LCONSOLE_WARN("Found index %d for %s, updating log\n",
4432 mti->mti_stripe_index, mti->mti_svname);
4433 /* We would like to mark old log sections as invalid
4434 and add new log sections in the client and mdt logs.
4435 But if we add new sections, then live clients will
4436 get repeat setup instructions for already running
4437 osc's. So don't update the client/mdt logs. */
4438 mti->mti_flags &= ~LDD_F_UPDATE;
4442 OBD_FAIL_TIMEOUT(OBD_FAIL_MGS_WRITE_TARGET_DELAY, cfs_fail_val > 0 ?
4445 mutex_lock(&fsdb->fsdb_mutex);
4447 if (mti->mti_flags & (LDD_F_VIRGIN | LDD_F_WRITECONF)) {
4448 /* Generate a log from scratch */
4449 if (mti->mti_flags & LDD_F_SV_TYPE_MDT) {
4450 rc = mgs_write_log_mdt(env, mgs, fsdb, mti);
4451 } else if (mti->mti_flags & LDD_F_SV_TYPE_OST) {
4452 rc = mgs_write_log_ost(env, mgs, fsdb, mti);
4454 CERROR("Unknown target type %#x, can't create log for %s\n",
4455 mti->mti_flags, mti->mti_svname);
4458 CERROR("Can't write logs for %s (%d)\n",
4459 mti->mti_svname, rc);
4463 /* Just update the params from tunefs in mgs_write_log_params */
4464 CDEBUG(D_MGS, "Update params for %s\n", mti->mti_svname);
4465 mti->mti_flags |= LDD_F_PARAM;
4468 /* allocate temporary buffer, where class_get_next_param will
4469 * make copy of a current parameter
4471 OBD_ALLOC(buf, strlen(mti->mti_params) + 1);
4473 GOTO(out_up, rc = -ENOMEM);
4474 params = mti->mti_params;
4475 while (params != NULL) {
4476 rc = class_get_next_param(¶ms, buf);
4479 /* there is no next parameter, that is
4485 CDEBUG(D_MGS, "remaining string: '%s', param: '%s'\n",
4487 rc = mgs_write_log_param(env, mgs, fsdb, mti, buf);
4492 OBD_FREE(buf, strlen(mti->mti_params) + 1);
4495 mutex_unlock(&fsdb->fsdb_mutex);
4499 int mgs_erase_log(const struct lu_env *env, struct mgs_device *mgs, char *name)
4501 struct llog_ctxt *ctxt;
4504 ctxt = llog_get_context(mgs->mgs_obd, LLOG_CONFIG_ORIG_CTXT);
4506 CERROR("%s: MGS config context doesn't exist\n",
4507 mgs->mgs_obd->obd_name);
4510 rc = llog_erase(env, ctxt, NULL, name);
4511 /* llog may not exist */
4514 llog_ctxt_put(ctxt);
4518 CERROR("%s: failed to clear log %s: %d\n",
4519 mgs->mgs_obd->obd_name, name, rc);
4524 /* erase all logs for the given fs */
4525 int mgs_erase_logs(const struct lu_env *env, struct mgs_device *mgs,
4528 struct list_head log_list;
4529 struct mgs_direntry *dirent, *n;
4530 char barrier_name[20] = {};
4533 int rc, len = strlen(fsname);
4536 mutex_lock(&mgs->mgs_mutex);
4538 /* Find all the logs in the CONFIGS directory */
4539 rc = class_dentry_readdir(env, mgs, &log_list);
4541 mutex_unlock(&mgs->mgs_mutex);
4545 if (list_empty(&log_list)) {
4546 mutex_unlock(&mgs->mgs_mutex);
4550 snprintf(barrier_name, sizeof(barrier_name) - 1, "%s-%s",
4551 fsname, BARRIER_FILENAME);
4552 /* Delete the barrier fsdb */
4553 mgs_remove_fsdb_by_name(mgs, barrier_name);
4554 /* Delete the fs db */
4555 mgs_remove_fsdb_by_name(mgs, fsname);
4556 mutex_unlock(&mgs->mgs_mutex);
4558 list_for_each_entry_safe(dirent, n, &log_list, mde_list) {
4559 list_del_init(&dirent->mde_list);
4560 suffix = strrchr(dirent->mde_name, '-');
4561 if (suffix != NULL) {
4562 if ((len == suffix - dirent->mde_name) &&
4563 (strncmp(fsname, dirent->mde_name, len) == 0)) {
4564 CDEBUG(D_MGS, "Removing log %s\n",
4566 mgs_erase_log(env, mgs, dirent->mde_name);
4570 mgs_direntry_free(dirent);
4579 /* list all logs for the given fs */
4580 int mgs_list_logs(const struct lu_env *env, struct mgs_device *mgs,
4581 struct obd_ioctl_data *data)
4583 struct list_head log_list;
4584 struct mgs_direntry *dirent, *n;
4585 char *out, *suffix, prefix[] = "config_log: ";
4586 int prefix_len = strlen(prefix);
4587 int len, remains, start = 0, rc;
4591 /* Find all the logs in the CONFIGS directory */
4592 rc = class_dentry_readdir(env, mgs, &log_list);
4596 out = data->ioc_bulk;
4597 remains = data->ioc_inllen1;
4598 /* OBD_FAIL: fetch the config_log records from the specified one */
4599 if (OBD_FAIL_CHECK(OBD_FAIL_CATLIST))
4600 data->ioc_count = cfs_fail_val;
4602 list_for_each_entry_safe(dirent, n, &log_list, mde_list) {
4603 list_del_init(&dirent->mde_list);
4604 suffix = strrchr(dirent->mde_name, '-');
4605 if (suffix != NULL) {
4606 len = prefix_len + dirent->mde_len + 1;
4607 if (remains - len < 0) {
4608 /* No enough space for this record */
4609 mgs_direntry_free(dirent);
4613 if (start < data->ioc_count) {
4614 mgs_direntry_free(dirent);
4617 len = scnprintf(out, remains, "%s%s\n", prefix,
4622 mgs_direntry_free(dirent);
4630 data->ioc_count = start;
4634 struct mgs_lcfg_fork_data {
4635 struct lustre_cfg_bufs mlfd_bufs;
4636 struct mgs_device *mlfd_mgs;
4637 struct llog_handle *mlfd_llh;
4638 const char *mlfd_oldname;
4639 const char *mlfd_newname;
4643 static bool contain_valid_fsname(char *buf, const char *fsname,
4644 int buflen, int namelen)
4646 if (buflen < namelen)
4649 if (memcmp(buf, fsname, namelen) != 0)
4652 if (buf[namelen] != '\0' && buf[namelen] != '-')
4658 static int mgs_lcfg_fork_handler(const struct lu_env *env,
4659 struct llog_handle *o_llh,
4660 struct llog_rec_hdr *o_rec, void *data)
4662 struct mgs_lcfg_fork_data *mlfd = data;
4663 struct lustre_cfg_bufs *n_bufs = &mlfd->mlfd_bufs;
4664 struct lustre_cfg *o_lcfg = (struct lustre_cfg *)(o_rec + 1);
4665 struct llog_cfg_rec *lcr;
4667 char *n_buf = mlfd->mlfd_data;
4669 int o_namelen = strlen(mlfd->mlfd_oldname);
4670 int n_namelen = strlen(mlfd->mlfd_newname);
4671 int diff = n_namelen - o_namelen;
4672 __u32 cmd = o_lcfg->lcfg_command;
4673 __u32 cnt = o_lcfg->lcfg_bufcount;
4679 o_buf = lustre_cfg_buf(o_lcfg, 0);
4680 o_buflen = o_lcfg->lcfg_buflens[0];
4681 if (contain_valid_fsname(o_buf, mlfd->mlfd_oldname, o_buflen,
4683 memcpy(n_buf, mlfd->mlfd_newname, n_namelen);
4684 memcpy(n_buf + n_namelen, o_buf + o_namelen,
4685 o_buflen - o_namelen);
4686 lustre_cfg_bufs_reset(n_bufs, n_buf);
4687 n_buf += round_up(o_buflen + diff, 8);
4689 lustre_cfg_bufs_reset(n_bufs, o_buflen != 0 ? o_buf : NULL);
4694 struct cfg_marker *o_marker;
4695 struct cfg_marker *n_marker;
4699 CDEBUG(D_MGS, "Unknown cfg marker entry with %d "
4704 /* buf[1] is marker */
4705 o_buf = lustre_cfg_buf(o_lcfg, 1);
4706 o_buflen = o_lcfg->lcfg_buflens[1];
4707 o_marker = (struct cfg_marker *)o_buf;
4708 if (!contain_valid_fsname(o_marker->cm_tgtname,
4710 sizeof(o_marker->cm_tgtname),
4712 lustre_cfg_bufs_set(n_bufs, 1, o_marker,
4717 n_marker = (struct cfg_marker *)n_buf;
4718 *n_marker = *o_marker;
4719 memcpy(n_marker->cm_tgtname, mlfd->mlfd_newname, n_namelen);
4720 tgt_namelen = strlen(o_marker->cm_tgtname);
4721 if (tgt_namelen > o_namelen)
4722 memcpy(n_marker->cm_tgtname + n_namelen,
4723 o_marker->cm_tgtname + o_namelen,
4724 tgt_namelen - o_namelen);
4725 n_marker->cm_tgtname[tgt_namelen + diff] = '\0';
4726 lustre_cfg_bufs_set(n_bufs, 1, n_marker, sizeof(*n_marker));
4730 case LCFG_SET_PARAM: {
4731 for (i = 1; i < cnt; i++)
4732 /* buf[i] is the param value, reuse it directly */
4733 lustre_cfg_bufs_set(n_bufs, i,
4734 lustre_cfg_buf(o_lcfg, i),
4735 o_lcfg->lcfg_buflens[i]);
4741 case LCFG_POOL_DEL: {
4742 if (cnt < 3 || cnt > 4) {
4743 CDEBUG(D_MGS, "Unknown cfg pool (%x) entry with %d "
4744 "buffers\n", cmd, cnt);
4748 /* buf[1] is fsname */
4749 o_buf = lustre_cfg_buf(o_lcfg, 1);
4750 o_buflen = o_lcfg->lcfg_buflens[1];
4751 memcpy(n_buf, mlfd->mlfd_newname, n_namelen);
4752 memcpy(n_buf + n_namelen, o_buf + o_namelen,
4753 o_buflen - o_namelen);
4754 lustre_cfg_bufs_set(n_bufs, 1, n_buf, o_buflen + diff);
4755 n_buf += round_up(o_buflen + diff, 8);
4757 /* buf[2] is the pool name, reuse it directly */
4758 lustre_cfg_bufs_set(n_bufs, 2, lustre_cfg_buf(o_lcfg, 2),
4759 o_lcfg->lcfg_buflens[2]);
4764 /* buf[3] is ostname */
4765 o_buf = lustre_cfg_buf(o_lcfg, 3);
4766 o_buflen = o_lcfg->lcfg_buflens[3];
4767 memcpy(n_buf, mlfd->mlfd_newname, n_namelen);
4768 memcpy(n_buf + n_namelen, o_buf + o_namelen,
4769 o_buflen - o_namelen);
4770 lustre_cfg_bufs_set(n_bufs, 3, n_buf, o_buflen + diff);
4775 o_buflen = o_lcfg->lcfg_buflens[1];
4776 if (o_buflen == sizeof(struct lov_desc) ||
4777 o_buflen == sizeof(struct lmv_desc)) {
4783 o_buf = lustre_cfg_buf(o_lcfg, 1);
4784 if (o_buflen == sizeof(struct lov_desc)) {
4785 struct lov_desc *o_desc =
4786 (struct lov_desc *)o_buf;
4787 struct lov_desc *n_desc =
4788 (struct lov_desc *)n_buf;
4791 o_uuid = o_desc->ld_uuid.uuid;
4792 n_uuid = n_desc->ld_uuid.uuid;
4793 uuid_len = sizeof(o_desc->ld_uuid.uuid);
4795 struct lmv_desc *o_desc =
4796 (struct lmv_desc *)o_buf;
4797 struct lmv_desc *n_desc =
4798 (struct lmv_desc *)n_buf;
4801 o_uuid = o_desc->ld_uuid.uuid;
4802 n_uuid = n_desc->ld_uuid.uuid;
4803 uuid_len = sizeof(o_desc->ld_uuid.uuid);
4806 if (unlikely(!contain_valid_fsname(o_uuid,
4807 mlfd->mlfd_oldname, uuid_len,
4809 lustre_cfg_bufs_set(n_bufs, 1, o_buf,
4814 memcpy(n_uuid, mlfd->mlfd_newname, n_namelen);
4815 uuid_len = strlen(o_uuid);
4816 if (uuid_len > o_namelen)
4817 memcpy(n_uuid + n_namelen,
4819 uuid_len - o_namelen);
4820 n_uuid[uuid_len + diff] = '\0';
4821 lustre_cfg_bufs_set(n_bufs, 1, n_buf, o_buflen);
4823 } /* else case fall through */
4824 } /* else case fall through */
4828 for (i = 1; i < cnt; i++) {
4829 o_buflen = o_lcfg->lcfg_buflens[i];
4833 o_buf = lustre_cfg_buf(o_lcfg, i);
4834 if (!contain_valid_fsname(o_buf, mlfd->mlfd_oldname,
4835 o_buflen, o_namelen)) {
4836 lustre_cfg_bufs_set(n_bufs, i, o_buf, o_buflen);
4840 memcpy(n_buf, mlfd->mlfd_newname, n_namelen);
4841 if (o_buflen == o_namelen) {
4842 lustre_cfg_bufs_set(n_bufs, i, n_buf,
4844 n_buf += round_up(n_namelen, 8);
4848 memcpy(n_buf + n_namelen, o_buf + o_namelen,
4849 o_buflen - o_namelen);
4850 lustre_cfg_bufs_set(n_bufs, i, n_buf, o_buflen + diff);
4851 n_buf += round_up(o_buflen + diff, 8);
4857 lcr = lustre_cfg_rec_new(cmd, n_bufs);
4861 lcr->lcr_cfg = *o_lcfg;
4862 rc = llog_write(env, mlfd->mlfd_llh, &lcr->lcr_hdr, LLOG_NEXT_IDX);
4863 lustre_cfg_rec_free(lcr);
4868 static int mgs_lcfg_fork_one(const struct lu_env *env, struct mgs_device *mgs,
4869 struct mgs_direntry *mde, const char *oldname,
4870 const char *newname)
4872 struct llog_handle *old_llh = NULL;
4873 struct llog_handle *new_llh = NULL;
4874 struct llog_ctxt *ctxt = NULL;
4875 struct mgs_lcfg_fork_data *mlfd = NULL;
4876 char *name_buf = NULL;
4878 int old_namelen = strlen(oldname);
4879 int new_namelen = strlen(newname);
4883 name_buflen = mde->mde_len + new_namelen - old_namelen;
4884 OBD_ALLOC(name_buf, name_buflen);
4888 memcpy(name_buf, newname, new_namelen);
4889 memcpy(name_buf + new_namelen, mde->mde_name + old_namelen,
4890 mde->mde_len - old_namelen);
4892 CDEBUG(D_MGS, "Fork the config-log from %s to %s\n",
4893 mde->mde_name, name_buf);
4895 ctxt = llog_get_context(mgs->mgs_obd, LLOG_CONFIG_ORIG_CTXT);
4898 rc = llog_open_create(env, ctxt, &new_llh, NULL, name_buf);
4902 rc = llog_init_handle(env, new_llh, LLOG_F_IS_PLAIN, NULL);
4906 if (unlikely(mgs_log_is_empty(env, mgs, mde->mde_name)))
4909 rc = llog_open(env, ctxt, &old_llh, NULL, mde->mde_name,
4914 rc = llog_init_handle(env, old_llh, LLOG_F_IS_PLAIN, NULL);
4918 new_llh->lgh_hdr->llh_tgtuuid = old_llh->lgh_hdr->llh_tgtuuid;
4920 OBD_ALLOC(mlfd, LLOG_MIN_CHUNK_SIZE);
4922 GOTO(out, rc = -ENOMEM);
4924 mlfd->mlfd_mgs = mgs;
4925 mlfd->mlfd_llh = new_llh;
4926 mlfd->mlfd_oldname = oldname;
4927 mlfd->mlfd_newname = newname;
4929 rc = llog_process(env, old_llh, mgs_lcfg_fork_handler, mlfd, NULL);
4930 OBD_FREE(mlfd, LLOG_MIN_CHUNK_SIZE);
4936 llog_close(env, old_llh);
4938 llog_close(env, new_llh);
4940 OBD_FREE(name_buf, name_buflen);
4942 llog_ctxt_put(ctxt);
4947 int mgs_lcfg_fork(const struct lu_env *env, struct mgs_device *mgs,
4948 const char *oldname, const char *newname)
4950 struct list_head log_list;
4951 struct mgs_direntry *dirent, *n;
4952 int olen = strlen(oldname);
4953 int nlen = strlen(newname);
4958 if (unlikely(!oldname || oldname[0] == '\0' ||
4959 !newname || newname[0] == '\0'))
4962 if (strcmp(oldname, newname) == 0)
4965 /* lock it to prevent fork/erase/register in parallel. */
4966 mutex_lock(&mgs->mgs_mutex);
4968 rc = class_dentry_readdir(env, mgs, &log_list);
4970 mutex_unlock(&mgs->mgs_mutex);
4974 if (list_empty(&log_list)) {
4975 mutex_unlock(&mgs->mgs_mutex);
4979 list_for_each_entry_safe(dirent, n, &log_list, mde_list) {
4982 ptr = strrchr(dirent->mde_name, '-');
4984 int tlen = ptr - dirent->mde_name;
4987 strncmp(newname, dirent->mde_name, tlen) == 0)
4988 GOTO(out, rc = -EEXIST);
4991 strncmp(oldname, dirent->mde_name, tlen) == 0)
4995 list_del_init(&dirent->mde_list);
4996 mgs_direntry_free(dirent);
4999 if (list_empty(&log_list)) {
5000 mutex_unlock(&mgs->mgs_mutex);
5004 list_for_each_entry(dirent, &log_list, mde_list) {
5005 rc = mgs_lcfg_fork_one(env, mgs, dirent, oldname, newname);
5013 mutex_unlock(&mgs->mgs_mutex);
5015 list_for_each_entry_safe(dirent, n, &log_list, mde_list) {
5016 list_del_init(&dirent->mde_list);
5017 mgs_direntry_free(dirent);
5020 if (rc && count > 0)
5021 mgs_erase_logs(env, mgs, newname);
5026 int mgs_lcfg_erase(const struct lu_env *env, struct mgs_device *mgs,
5032 if (unlikely(!fsname || fsname[0] == '\0'))
5035 rc = mgs_erase_logs(env, mgs, fsname);
5040 static int mgs_xattr_del(const struct lu_env *env, struct dt_object *obj)
5042 struct dt_device *dev;
5043 struct thandle *th = NULL;
5048 dev = container_of(obj->do_lu.lo_dev, struct dt_device, dd_lu_dev);
5049 th = dt_trans_create(env, dev);
5051 RETURN(PTR_ERR(th));
5053 rc = dt_declare_xattr_del(env, obj, XATTR_TARGET_RENAME, th);
5057 rc = dt_trans_start_local(env, dev, th);
5061 dt_write_lock(env, obj, 0);
5062 rc = dt_xattr_del(env, obj, XATTR_TARGET_RENAME, th);
5067 dt_write_unlock(env, obj);
5070 dt_trans_stop(env, dev, th);
5075 int mgs_lcfg_rename(const struct lu_env *env, struct mgs_device *mgs)
5077 struct list_head log_list;
5078 struct mgs_direntry *dirent, *n;
5080 struct lu_buf buf = {
5082 .lb_len = sizeof(fsname)
5088 rc = class_dentry_readdir(env, mgs, &log_list);
5092 if (list_empty(&log_list))
5095 list_for_each_entry_safe(dirent, n, &log_list, mde_list) {
5096 struct dt_object *o = NULL;
5101 list_del_init(&dirent->mde_list);
5102 ptr = strrchr(dirent->mde_name, '-');
5106 len = ptr - dirent->mde_name;
5107 if (unlikely(len >= sizeof(oldname))) {
5108 CDEBUG(D_MGS, "Skip invalid configuration file %s\n",
5113 o = local_file_find(env, mgs->mgs_los, mgs->mgs_configs_dir,
5117 CDEBUG(D_MGS, "Fail to locate file %s: rc = %d\n",
5118 dirent->mde_name, rc);
5122 rc = dt_xattr_get(env, o, &buf, XATTR_TARGET_RENAME);
5128 "Fail to get EA for %s: rc = %d\n",
5129 dirent->mde_name, rc);
5133 if (unlikely(rc == len &&
5134 memcmp(fsname, dirent->mde_name, len) == 0)) {
5135 /* The new fsname is the same as the old one. */
5136 rc = mgs_xattr_del(env, o);
5140 memcpy(oldname, dirent->mde_name, len);
5141 oldname[len] = '\0';
5143 rc = mgs_lcfg_fork_one(env, mgs, dirent, oldname, fsname);
5144 if (rc && rc != -EEXIST) {
5145 CDEBUG(D_MGS, "Fail to fork %s: rc = %d\n",
5146 dirent->mde_name, rc);
5150 rc = mgs_erase_log(env, mgs, dirent->mde_name);
5152 CDEBUG(D_MGS, "Fail to erase old %s: rc = %d\n",
5153 dirent->mde_name, rc);
5154 /* keep it there if failed to remove it. */
5159 if (o && !IS_ERR(o))
5160 lu_object_put(env, &o->do_lu);
5162 mgs_direntry_free(dirent);
5167 list_for_each_entry_safe(dirent, n, &log_list, mde_list) {
5168 list_del_init(&dirent->mde_list);
5169 mgs_direntry_free(dirent);
5175 /* Setup _mgs fsdb and log
5177 int mgs__mgs_fsdb_setup(const struct lu_env *env, struct mgs_device *mgs)
5179 struct fs_db *fsdb = NULL;
5183 rc = mgs_find_or_make_fsdb(env, mgs, MGSSELF_NAME, &fsdb);
5185 mgs_put_fsdb(mgs, fsdb);
5190 /* Setup params fsdb and log
5192 int mgs_params_fsdb_setup(const struct lu_env *env, struct mgs_device *mgs)
5194 struct fs_db *fsdb = NULL;
5195 struct llog_handle *params_llh = NULL;
5199 rc = mgs_find_or_make_fsdb(env, mgs, PARAMS_FILENAME, &fsdb);
5201 mutex_lock(&fsdb->fsdb_mutex);
5202 rc = record_start_log(env, mgs, ¶ms_llh, PARAMS_FILENAME);
5204 rc = record_end_log(env, ¶ms_llh);
5205 mutex_unlock(&fsdb->fsdb_mutex);
5206 mgs_put_fsdb(mgs, fsdb);
5212 /* Cleanup params fsdb and log
5214 int mgs_params_fsdb_cleanup(const struct lu_env *env, struct mgs_device *mgs)
5218 rc = mgs_erase_logs(env, mgs, PARAMS_FILENAME);
5219 return rc == -ENOENT ? 0 : rc;
5223 * Fill in the mgs_target_info based on data devname and param provide.
5225 * @env thread context
5227 * @mti mgs target info. We want to set this based other paramters
5228 * passed to this function. Once setup we write it to the config
5230 * @devname optional OBD device name
5231 * @param string that contains both what tunable to set and the value to
5234 * RETURN 0 for success
5235 * negative error number on failure
5237 static int mgs_set_conf_param(const struct lu_env *env, struct mgs_device *mgs,
5238 struct mgs_target_info *mti, const char *devname,
5241 struct fs_db *fsdb = NULL;
5246 /* lustre, lustre-mdtlov, lustre-client, lustre-MDT0000 */
5250 /* We have two possible cases here:
5252 * 1) the device name embedded in the param:
5253 * lustre-OST0000.osc.max_dirty_mb=32
5255 * 2) the file system name is embedded in
5256 * the param: lustre.sys.at.min=0
5258 len = strcspn(param, ".=");
5259 if (!len || param[len] == '=')
5262 if (len >= sizeof(mti->mti_svname))
5265 snprintf(mti->mti_svname, sizeof(mti->mti_svname),
5266 "%.*s", (int)len, param);
5269 if (strlcpy(mti->mti_svname, devname, sizeof(mti->mti_svname)) >=
5270 sizeof(mti->mti_svname))
5274 if (!strlen(mti->mti_svname)) {
5275 LCONSOLE_ERROR_MSG(0x14d, "No target specified: %s\n", param);
5279 dev_type = mgs_parse_devname(mti->mti_svname, mti->mti_fsname,
5280 &mti->mti_stripe_index);
5282 /* For this case we have an invalid obd device name */
5284 CDEBUG(D_MGS, "%s don't contain an index\n", mti->mti_svname);
5285 strlcpy(mti->mti_fsname, mti->mti_svname, MTI_NAME_MAXLEN);
5288 /* Not an obd device, assume devname is the fsname.
5289 * User might of only provided fsname and not obd device
5292 CDEBUG(D_MGS, "%s is seen as a file system name\n", mti->mti_svname);
5293 strlcpy(mti->mti_fsname, mti->mti_svname, MTI_NAME_MAXLEN);
5298 GOTO(out, rc = dev_type);
5300 /* param related to llite isn't allowed to set by OST or MDT */
5301 if (dev_type & LDD_F_SV_TYPE_OST ||
5302 dev_type & LDD_F_SV_TYPE_MDT) {
5303 /* param related to llite isn't allowed to set by OST
5306 if (!strncmp(param, PARAM_LLITE,
5307 sizeof(PARAM_LLITE) - 1))
5308 GOTO(out, rc = -EINVAL);
5310 /* Strip -osc or -mdc suffix from svname */
5311 if (server_make_name(dev_type, mti->mti_stripe_index,
5312 mti->mti_fsname, mti->mti_svname,
5313 sizeof(mti->mti_svname)))
5314 GOTO(out, rc = -EINVAL);
5319 if (strlcpy(mti->mti_params, param, sizeof(mti->mti_params)) >=
5320 sizeof(mti->mti_params))
5321 GOTO(out, rc = -E2BIG);
5323 CDEBUG(D_MGS, "set_conf_param fs='%s' device='%s' param='%s'\n",
5324 mti->mti_fsname, mti->mti_svname, mti->mti_params);
5326 rc = mgs_find_or_make_fsdb(env, mgs, mti->mti_fsname, &fsdb);
5330 if (!test_bit(FSDB_MGS_SELF, &fsdb->fsdb_flags) &&
5331 test_bit(FSDB_LOG_EMPTY, &fsdb->fsdb_flags)) {
5332 CERROR("No filesystem targets for %s. cfg_device from lctl "
5333 "is '%s'\n", mti->mti_fsname, mti->mti_svname);
5334 mgs_unlink_fsdb(mgs, fsdb);
5335 GOTO(out, rc = -EINVAL);
5339 * Revoke lock so everyone updates. Should be alright if
5340 * someone was already reading while we were updating the logs,
5341 * so we don't really need to hold the lock while we're
5344 mti->mti_flags = dev_type | LDD_F_PARAM;
5345 mutex_lock(&fsdb->fsdb_mutex);
5346 rc = mgs_write_log_param(env, mgs, fsdb, mti, mti->mti_params);
5347 mutex_unlock(&fsdb->fsdb_mutex);
5348 mgs_revoke_lock(mgs, fsdb, MGS_CFG_T_CONFIG);
5352 mgs_put_fsdb(mgs, fsdb);
5357 static int mgs_set_param2(const struct lu_env *env, struct mgs_device *mgs,
5358 struct mgs_target_info *mti, const char *param)
5360 struct fs_db *fsdb = NULL;
5365 if (strlcpy(mti->mti_params, param, sizeof(mti->mti_params)) >=
5366 sizeof(mti->mti_params))
5367 GOTO(out, rc = -E2BIG);
5369 len = strcspn(param, ".=");
5370 if (len && param[len] != '=') {
5371 struct list_head *tmp;
5375 ptr = strchr(param, '.');
5377 len = strlen(param);
5380 if (len >= sizeof(mti->mti_svname))
5381 GOTO(out, rc = -E2BIG);
5383 snprintf(mti->mti_svname, sizeof(mti->mti_svname), "%.*s",
5386 mutex_lock(&mgs->mgs_mutex);
5387 if (unlikely(list_empty(&mgs->mgs_fs_db_list))) {
5388 mutex_unlock(&mgs->mgs_mutex);
5389 GOTO(out, rc = -ENODEV);
5392 list_for_each(tmp, &mgs->mgs_fs_db_list) {
5393 fsdb = list_entry(tmp, struct fs_db, fsdb_list);
5394 if (fsdb->fsdb_has_lproc_entry &&
5395 strcmp(fsdb->fsdb_name, "params") != 0 &&
5396 strstr(param, fsdb->fsdb_name)) {
5397 snprintf(mti->mti_svname,
5398 sizeof(mti->mti_svname), "%s",
5406 snprintf(mti->mti_svname, sizeof(mti->mti_svname),
5409 mutex_unlock(&mgs->mgs_mutex);
5411 snprintf(mti->mti_svname, sizeof(mti->mti_svname), "general");
5414 CDEBUG(D_MGS, "set_param2 fs='%s' device='%s' param='%s'\n",
5415 mti->mti_fsname, mti->mti_svname, mti->mti_params);
5417 /* The return value should be the device type i.e LDD_F_SV_TYPE_XXX.
5418 * A returned error tells us we don't have a target obd device.
5420 dev_type = server_name2index(mti->mti_svname, &mti->mti_stripe_index,
5425 /* the return value should be the device type i.e LDD_F_SV_TYPE_XXX.
5426 * Strip -osc or -mdc suffix from svname
5428 if ((dev_type & LDD_F_SV_TYPE_OST || dev_type & LDD_F_SV_TYPE_MDT) &&
5429 server_make_name(dev_type, mti->mti_stripe_index,
5430 mti->mti_fsname, mti->mti_svname,
5431 sizeof(mti->mti_svname)))
5432 GOTO(out, rc = -EINVAL);
5434 rc = mgs_find_or_make_fsdb(env, mgs, PARAMS_FILENAME, &fsdb);
5438 * Revoke lock so everyone updates. Should be alright if
5439 * someone was already reading while we were updating the logs,
5440 * so we don't really need to hold the lock while we're
5443 mti->mti_flags = dev_type | LDD_F_PARAM2;
5444 mutex_lock(&fsdb->fsdb_mutex);
5445 rc = mgs_write_log_param2(env, mgs, fsdb, mti, mti->mti_params);
5446 mutex_unlock(&fsdb->fsdb_mutex);
5447 mgs_revoke_lock(mgs, fsdb, MGS_CFG_T_PARAMS);
5448 mgs_put_fsdb(mgs, fsdb);
5453 /* Set a permanent (config log) param for a target or fs
5455 * @lcfg buf0 may contain the device (testfs-MDT0000) name
5456 * buf1 contains the single parameter
5458 int mgs_set_param(const struct lu_env *env, struct mgs_device *mgs,
5459 struct lustre_cfg *lcfg)
5461 const char *param = lustre_cfg_string(lcfg, 1);
5462 struct mgs_target_info *mti;
5465 /* Create a fake mti to hold everything */
5470 print_lustre_cfg(lcfg);
5472 if (lcfg->lcfg_command == LCFG_PARAM) {
5473 /* For the case of lctl conf_param devname can be
5474 * lustre, lustre-mdtlov, lustre-client, lustre-MDT0000
5476 const char *devname = lustre_cfg_string(lcfg, 0);
5478 rc = mgs_set_conf_param(env, mgs, mti, devname, param);
5480 /* In the case of lctl set_param -P lcfg[0] will always
5481 * be 'general'. At least for now.
5483 rc = mgs_set_param2(env, mgs, mti, param);
5491 static int mgs_write_log_pool(const struct lu_env *env,
5492 struct mgs_device *mgs, char *logname,
5493 struct fs_db *fsdb, char *tgtname,
5494 enum lcfg_command_type cmd,
5495 char *fsname, char *poolname,
5496 char *ostname, char *comment)
5498 struct llog_handle *llh = NULL;
5501 rc = record_start_log(env, mgs, &llh, logname);
5504 rc = record_marker(env, llh, fsdb, CM_START, tgtname, comment);
5507 rc = record_base(env, llh, tgtname, 0, cmd,
5508 fsname, poolname, ostname, NULL);
5511 rc = record_marker(env, llh, fsdb, CM_END, tgtname, comment);
5513 record_end_log(env, &llh);
5517 int mgs_nodemap_cmd(const struct lu_env *env, struct mgs_device *mgs,
5518 enum lcfg_command_type cmd, const char *nodemap_name,
5529 case LCFG_NODEMAP_ADD:
5530 rc = nodemap_add(nodemap_name);
5532 case LCFG_NODEMAP_DEL:
5533 rc = nodemap_del(nodemap_name);
5535 case LCFG_NODEMAP_ADD_RANGE:
5536 rc = nodemap_parse_range(param, nid);
5539 rc = nodemap_add_range(nodemap_name, nid);
5541 case LCFG_NODEMAP_DEL_RANGE:
5542 rc = nodemap_parse_range(param, nid);
5545 rc = nodemap_del_range(nodemap_name, nid);
5547 case LCFG_NODEMAP_ADMIN:
5548 rc = kstrtobool(param, &bool_switch);
5551 rc = nodemap_set_allow_root(nodemap_name, bool_switch);
5553 case LCFG_NODEMAP_DENY_UNKNOWN:
5554 rc = kstrtobool(param, &bool_switch);
5557 rc = nodemap_set_deny_unknown(nodemap_name, bool_switch);
5559 case LCFG_NODEMAP_AUDIT_MODE:
5560 rc = kstrtobool(param, &bool_switch);
5562 rc = nodemap_set_audit_mode(nodemap_name, bool_switch);
5564 case LCFG_NODEMAP_FORBID_ENCRYPT:
5565 rc = kstrtobool(param, &bool_switch);
5567 rc = nodemap_set_forbid_encryption(nodemap_name,
5570 case LCFG_NODEMAP_READONLY_MOUNT:
5571 rc = kstrtobool(param, &bool_switch);
5573 rc = nodemap_set_readonly_mount(nodemap_name,
5576 case LCFG_NODEMAP_MAP_MODE:
5581 if ((p = strstr(param, "all")) != NULL) {
5582 if ((p == param || *(p-1) == ',') &&
5583 (*(p+3) == '\0' || *(p+3) == ',')) {
5584 map_mode = NODEMAP_MAP_ALL;
5590 while ((p = strsep(¶m, ",")) != NULL) {
5594 if (strcmp("both", p) == 0)
5595 map_mode |= NODEMAP_MAP_BOTH;
5596 else if (strcmp("uid_only", p) == 0 ||
5597 strcmp("uid", p) == 0)
5598 map_mode |= NODEMAP_MAP_UID;
5599 else if (strcmp("gid_only", p) == 0 ||
5600 strcmp("gid", p) == 0)
5601 map_mode |= NODEMAP_MAP_GID;
5602 else if (strcmp("projid_only", p) == 0 ||
5603 strcmp("projid", p) == 0)
5604 map_mode |= NODEMAP_MAP_PROJID;
5614 rc = nodemap_set_mapping_mode(nodemap_name, map_mode);
5617 case LCFG_NODEMAP_RBAC:
5619 enum nodemap_rbac_roles rbac;
5622 if (strcmp(param, "all") == 0) {
5623 rbac = NODEMAP_RBAC_ALL;
5624 } else if (strcmp(param, "none") == 0) {
5625 rbac = NODEMAP_RBAC_NONE;
5627 rbac = NODEMAP_RBAC_NONE;
5628 while ((p = strsep(¶m, ",")) != NULL) {
5634 for (i = 0; i < ARRAY_SIZE(nodemap_rbac_names);
5637 nodemap_rbac_names[i].nrn_name)
5640 nodemap_rbac_names[i].nrn_mode;
5644 if (i == ARRAY_SIZE(nodemap_rbac_names))
5653 rc = nodemap_set_rbac(nodemap_name, rbac);
5656 case LCFG_NODEMAP_TRUSTED:
5657 rc = kstrtobool(param, &bool_switch);
5660 rc = nodemap_set_trust_client_ids(nodemap_name, bool_switch);
5662 case LCFG_NODEMAP_SQUASH_UID:
5663 rc = kstrtouint(param, 10, &int_id);
5666 rc = nodemap_set_squash_uid(nodemap_name, int_id);
5668 case LCFG_NODEMAP_SQUASH_GID:
5669 rc = kstrtouint(param, 10, &int_id);
5672 rc = nodemap_set_squash_gid(nodemap_name, int_id);
5674 case LCFG_NODEMAP_SQUASH_PROJID:
5675 rc = kstrtouint(param, 10, &int_id);
5678 rc = nodemap_set_squash_projid(nodemap_name, int_id);
5680 case LCFG_NODEMAP_ADD_UIDMAP:
5681 case LCFG_NODEMAP_ADD_GIDMAP:
5682 case LCFG_NODEMAP_ADD_PROJIDMAP:
5683 rc = nodemap_parse_idmap(param, idmap);
5686 if (cmd == LCFG_NODEMAP_ADD_UIDMAP)
5687 rc = nodemap_add_idmap(nodemap_name, NODEMAP_UID,
5689 else if (cmd == LCFG_NODEMAP_ADD_GIDMAP)
5690 rc = nodemap_add_idmap(nodemap_name, NODEMAP_GID,
5692 else if (cmd == LCFG_NODEMAP_ADD_PROJIDMAP)
5693 rc = nodemap_add_idmap(nodemap_name, NODEMAP_PROJID,
5698 case LCFG_NODEMAP_DEL_UIDMAP:
5699 case LCFG_NODEMAP_DEL_GIDMAP:
5700 case LCFG_NODEMAP_DEL_PROJIDMAP:
5701 rc = nodemap_parse_idmap(param, idmap);
5704 if (cmd == LCFG_NODEMAP_DEL_UIDMAP)
5705 rc = nodemap_del_idmap(nodemap_name, NODEMAP_UID,
5707 else if (cmd == LCFG_NODEMAP_DEL_GIDMAP)
5708 rc = nodemap_del_idmap(nodemap_name, NODEMAP_GID,
5710 else if (cmd == LCFG_NODEMAP_DEL_PROJIDMAP)
5711 rc = nodemap_del_idmap(nodemap_name, NODEMAP_PROJID,
5716 case LCFG_NODEMAP_SET_FILESET:
5717 rc = nodemap_set_fileset(nodemap_name, param);
5719 case LCFG_NODEMAP_SET_SEPOL:
5720 rc = nodemap_set_sepol(nodemap_name, param);
5729 int mgs_pool_cmd(const struct lu_env *env, struct mgs_device *mgs,
5730 enum lcfg_command_type cmd, char *fsname,
5731 char *poolname, char *ostname)
5736 char *label = NULL, *canceled_label = NULL;
5738 struct mgs_target_info *mti = NULL;
5739 bool checked = false;
5740 bool locked = false;
5745 rc = mgs_find_or_make_fsdb(env, mgs, fsname, &fsdb);
5747 CERROR("Can't get db for %s\n", fsname);
5750 if (test_bit(FSDB_LOG_EMPTY, &fsdb->fsdb_flags)) {
5751 CERROR("%s is not defined\n", fsname);
5753 GOTO(out_fsdb, rc = -EINVAL);
5756 label_sz = 10 + strlen(fsname) + strlen(poolname);
5758 /* check if ostname match fsname */
5759 if (ostname != NULL) {
5762 ptr = strrchr(ostname, '-');
5763 if ((ptr == NULL) ||
5764 (strncmp(fsname, ostname, ptr-ostname) != 0))
5766 label_sz += strlen(ostname);
5769 OBD_ALLOC(label, label_sz);
5771 GOTO(out_fsdb, rc = -ENOMEM);
5775 sprintf(label, "new %s.%s", fsname, poolname);
5778 sprintf(label, "add %s.%s.%s", fsname, poolname, ostname);
5781 OBD_ALLOC(canceled_label, label_sz);
5782 if (canceled_label == NULL)
5783 GOTO(out_label, rc = -ENOMEM);
5784 sprintf(label, "rem %s.%s.%s", fsname, poolname, ostname);
5785 sprintf(canceled_label, "add %s.%s.%s",
5786 fsname, poolname, ostname);
5789 OBD_ALLOC(canceled_label, label_sz);
5790 if (canceled_label == NULL)
5791 GOTO(out_label, rc = -ENOMEM);
5792 sprintf(label, "del %s.%s", fsname, poolname);
5793 sprintf(canceled_label, "new %s.%s", fsname, poolname);
5801 GOTO(out_cancel, rc = -ENOMEM);
5802 strncpy(mti->mti_svname, "lov pool", sizeof(mti->mti_svname));
5804 mutex_lock(&fsdb->fsdb_mutex);
5806 /* write pool def to all MDT logs */
5807 for (i = 0; i < INDEX_MAP_SIZE * 8; i++) {
5808 if (test_bit(i, fsdb->fsdb_mdt_index_map)) {
5809 rc = name_create_mdt_and_lov(&logname, &lovname,
5814 if (!checked && (canceled_label == NULL)) {
5815 rc = mgs_check_marker(env, mgs, fsdb, mti,
5816 logname, lovname, label);
5818 name_destroy(&logname);
5819 name_destroy(&lovname);
5821 rc = (rc == LLOG_PROC_BREAK ?
5826 if (canceled_label != NULL)
5827 rc = mgs_modify(env, mgs, fsdb, mti, logname,
5828 lovname, canceled_label,
5832 rc = mgs_write_log_pool(env, mgs, logname,
5836 name_destroy(&logname);
5837 name_destroy(&lovname);
5843 rc = name_create(&logname, fsname, "-client");
5847 if (!checked && (canceled_label == NULL)) {
5848 rc = mgs_check_marker(env, mgs, fsdb, mti, logname,
5849 fsdb->fsdb_clilov, label);
5851 name_destroy(&logname);
5852 GOTO(out_mti, rc = (rc == LLOG_PROC_BREAK ?
5856 if (canceled_label != NULL) {
5857 rc = mgs_modify(env, mgs, fsdb, mti, logname,
5858 fsdb->fsdb_clilov, canceled_label, CM_SKIP);
5860 name_destroy(&logname);
5865 rc = mgs_write_log_pool(env, mgs, logname, fsdb, fsdb->fsdb_clilov,
5866 cmd, fsname, poolname, ostname, label);
5867 mutex_unlock(&fsdb->fsdb_mutex);
5869 name_destroy(&logname);
5870 /* request for update */
5871 mgs_revoke_lock(mgs, fsdb, MGS_CFG_T_CONFIG);
5877 mutex_unlock(&fsdb->fsdb_mutex);
5881 if (canceled_label != NULL)
5882 OBD_FREE(canceled_label, label_sz);
5884 OBD_FREE(label, label_sz);
5887 mgs_unlink_fsdb(mgs, fsdb);
5888 mgs_put_fsdb(mgs, fsdb);