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 lnet_nid_t nid4 = 0;
1097 if (nid_is_nid4(nid))
1098 nid4 = lnet_nid_to_nid4(nid);
1100 cfg2 = libcfs_nidstr(nid);
1101 return record_base(env, llh, NULL, nid4, LCFG_ADD_UUID, uuid,
1105 static inline int record_add_conn(const struct lu_env *env,
1106 struct llog_handle *llh,
1107 char *devname, char *uuid)
1109 return record_base(env, llh, devname, 0, LCFG_ADD_CONN, uuid,
1113 static inline int record_attach(const struct lu_env *env,
1114 struct llog_handle *llh, char *devname,
1115 char *type, char *uuid)
1117 return record_base(env, llh, devname, 0, LCFG_ATTACH, type, uuid,
1121 static inline int record_setup(const struct lu_env *env,
1122 struct llog_handle *llh, char *devname,
1123 char *s1, char *s2, char *s3, char *s4)
1125 return record_base(env, llh, devname, 0, LCFG_SETUP, s1, s2, s3, s4);
1129 * \retval <0 record processing error
1130 * \retval n record is processed. No need copy original one.
1131 * \retval 0 record is not processed.
1133 static int process_command(const struct lu_env *env, struct lustre_cfg *lcfg,
1134 struct mgs_replace_data *mrd)
1137 struct lnet_nid nid;
1141 if (mrd->state == REPLACE_UUID &&
1142 lcfg->lcfg_command == LCFG_ADD_UUID) {
1143 /* LCFG_ADD_UUID command found. Let's skip original command
1144 and add passed nids */
1145 ptr = mrd->target.mti_params;
1146 while (class_parse_nid(ptr, &nid, &ptr) == 0) {
1147 if (!mrd->nodeuuid) {
1148 rc = name_create(&mrd->nodeuuid,
1149 libcfs_nidstr(&nid), "");
1151 CERROR("Can't create uuid for "
1152 "nid %s, device %s\n",
1153 libcfs_nidstr(&nid),
1154 mrd->target.mti_svname);
1158 CDEBUG(D_MGS, "add nid %s with uuid %s, device %s\n",
1159 libcfs_nidstr(&nid),
1160 mrd->target.mti_params,
1162 rc = record_add_uuid(env,
1163 mrd->temp_llh, &nid,
1166 CWARN("%s: Can't add nid %s for uuid %s :rc=%d\n",
1167 mrd->target.mti_svname,
1168 libcfs_nidstr(&nid),
1174 mrd->failover = ptr;
1179 if (nids_added == 0) {
1180 CERROR("No new nids were added, nid %s with uuid %s, device %s\n",
1181 libcfs_nidstr(&nid),
1182 mrd->nodeuuid ? mrd->nodeuuid : "NULL",
1183 mrd->target.mti_svname);
1184 name_destroy(&mrd->nodeuuid);
1187 mrd->state = REPLACE_SETUP;
1193 if (mrd->state == REPLACE_SETUP && lcfg->lcfg_command == LCFG_SETUP) {
1194 /* LCFG_SETUP command found. UUID should be changed */
1195 rc = record_setup(env,
1197 /* devname the same */
1198 lustre_cfg_string(lcfg, 0),
1199 /* s1 is not changed */
1200 lustre_cfg_string(lcfg, 1),
1202 /* s3 is not changed */
1203 lustre_cfg_string(lcfg, 3),
1204 /* s4 is not changed */
1205 lustre_cfg_string(lcfg, 4));
1207 name_destroy(&mrd->nodeuuid);
1211 if (mrd->failover) {
1212 ptr = mrd->failover;
1213 while (class_parse_nid(ptr, &nid, &ptr) == 0) {
1214 if (mrd->nodeuuid == NULL) {
1215 rc = name_create(&mrd->nodeuuid,
1216 libcfs_nidstr(&nid),
1222 CDEBUG(D_MGS, "add nid %s for failover %s\n",
1223 libcfs_nidstr(&nid), mrd->nodeuuid);
1224 rc = record_add_uuid(env, mrd->temp_llh, &nid,
1227 CWARN("%s: Can't add nid %s for failover %s :rc = %d\n",
1228 mrd->target.mti_svname,
1229 libcfs_nidstr(&nid),
1231 name_destroy(&mrd->nodeuuid);
1235 rc = record_add_conn(env,
1237 lustre_cfg_string(lcfg, 0),
1239 name_destroy(&mrd->nodeuuid);
1244 if (mrd->nodeuuid) {
1245 rc = record_add_conn(env, mrd->temp_llh,
1246 lustre_cfg_string(lcfg, 0),
1248 name_destroy(&mrd->nodeuuid);
1253 mrd->state = REPLACE_DONE;
1257 /* All new UUID are added. Skip. */
1258 if (mrd->state == REPLACE_SETUP &&
1259 lcfg->lcfg_command == LCFG_ADD_UUID)
1262 /* Another commands in target device block */
1267 * Handler that called for every record in llog.
1268 * Records are processed in order they placed in llog.
1270 * \param[in] llh log to be processed
1271 * \param[in] rec current record
1272 * \param[in] data mgs_replace_data structure
1276 static int mgs_replace_nids_handler(const struct lu_env *env,
1277 struct llog_handle *llh,
1278 struct llog_rec_hdr *rec,
1281 struct mgs_replace_data *mrd;
1282 struct lustre_cfg *lcfg = REC_DATA(rec);
1283 int cfg_len = REC_DATA_LEN(rec);
1287 mrd = (struct mgs_replace_data *)data;
1289 if (rec->lrh_type != OBD_CFG_REC) {
1290 CERROR("unhandled lrh_type: %#x, cmd %x %s %s\n",
1291 rec->lrh_type, lcfg->lcfg_command,
1292 lustre_cfg_string(lcfg, 0),
1293 lustre_cfg_string(lcfg, 1));
1297 rc = lustre_cfg_sanity_check(lcfg, cfg_len);
1299 /* Do not copy any invalidated records */
1300 GOTO(skip_out, rc = 0);
1303 rc = check_markers(lcfg, mrd);
1304 if (rc || mrd->state == REPLACE_SKIP)
1305 GOTO(skip_out, rc = 0);
1307 /* Write to new log all commands outside target device block */
1308 if (mrd->state == REPLACE_COPY)
1309 GOTO(copy_out, rc = 0);
1311 if (mrd->state == REPLACE_DONE &&
1312 (lcfg->lcfg_command == LCFG_ADD_UUID ||
1313 lcfg->lcfg_command == LCFG_ADD_CONN)) {
1315 CWARN("Previous failover is deleted, but new one is "
1316 "not set. This means you configure system "
1317 "without failover or passed wrong replace_nids "
1318 "command parameters. Device %s, passed nids %s\n",
1319 mrd->target.mti_svname, mrd->target.mti_params);
1320 GOTO(skip_out, rc = 0);
1323 rc = process_command(env, lcfg, mrd);
1330 /* Record is placed in temporary llog as is */
1331 rc = llog_write(env, mrd->temp_llh, rec, LLOG_NEXT_IDX);
1333 CDEBUG(D_MGS, "Copied idx=%d, rc=%d, len=%d, cmd %x %s %s\n",
1334 rec->lrh_index, rc, rec->lrh_len, lcfg->lcfg_command,
1335 lustre_cfg_string(lcfg, 0), lustre_cfg_string(lcfg, 1));
1339 CDEBUG(D_MGS, "Skipped idx=%d, rc=%d, len=%d, cmd %x %s %s\n",
1340 rec->lrh_index, rc, rec->lrh_len, lcfg->lcfg_command,
1341 lustre_cfg_string(lcfg, 0), lustre_cfg_string(lcfg, 1));
1345 static int mgs_log_is_empty(const struct lu_env *env,
1346 struct mgs_device *mgs, char *name)
1348 struct llog_ctxt *ctxt;
1351 ctxt = llog_get_context(mgs->mgs_obd, LLOG_CONFIG_ORIG_CTXT);
1352 LASSERT(ctxt != NULL);
1354 rc = llog_is_empty(env, ctxt, name);
1355 llog_ctxt_put(ctxt);
1359 static int mgs_replace_log(const struct lu_env *env,
1360 struct obd_device *mgs,
1361 char *logname, char *devname,
1362 llog_cb_t replace_handler, void *data)
1364 struct llog_handle *orig_llh, *backup_llh;
1365 struct llog_ctxt *ctxt;
1366 struct mgs_replace_data *mrd;
1367 struct mgs_device *mgs_dev = lu2mgs_dev(mgs->obd_lu_dev);
1368 static struct obd_uuid cfg_uuid = { .uuid = "config_uuid" };
1370 int rc, rc2, buf_size;
1374 ctxt = llog_get_context(mgs, LLOG_CONFIG_ORIG_CTXT);
1375 LASSERT(ctxt != NULL);
1377 if (mgs_log_is_empty(env, mgs_dev, logname)) {
1378 /* Log is empty. Nothing to replace */
1379 GOTO(out_put, rc = 0);
1382 now = ktime_get_real_seconds();
1384 /* max time64_t in decimal fits into 20 bytes long string */
1385 buf_size = strlen(logname) + 1 + 20 + 1 + strlen(".bak") + 1;
1386 OBD_ALLOC(backup, buf_size);
1388 GOTO(out_put, rc = -ENOMEM);
1390 snprintf(backup, buf_size, "%s.%llu.bak", logname, now);
1392 rc = llog_backup(env, mgs, ctxt, ctxt, logname, backup);
1394 /* Now erase original log file. Connections are not allowed.
1395 Backup is already saved */
1396 rc = llog_erase(env, ctxt, NULL, logname);
1399 } else if (rc != -ENOENT) {
1400 CERROR("%s: can't make backup for %s: rc = %d\n",
1401 mgs->obd_name, logname, rc);
1405 /* open local log */
1406 rc = llog_open_create(env, ctxt, &orig_llh, NULL, logname);
1408 GOTO(out_restore, rc);
1410 rc = llog_init_handle(env, orig_llh, LLOG_F_IS_PLAIN, &cfg_uuid);
1412 GOTO(out_closel, rc);
1414 /* open backup llog */
1415 rc = llog_open(env, ctxt, &backup_llh, NULL, backup,
1418 GOTO(out_closel, rc);
1420 rc = llog_init_handle(env, backup_llh, LLOG_F_IS_PLAIN, NULL);
1422 GOTO(out_close, rc);
1424 if (llog_get_size(backup_llh) <= 1)
1425 GOTO(out_close, rc = 0);
1429 GOTO(out_close, rc = -ENOMEM);
1430 /* devname is only needed information to replace UUID records */
1432 strlcpy(mrd->target.mti_svname, devname,
1433 sizeof(mrd->target.mti_svname));
1434 /* data is parsed in llog callback */
1436 strlcpy(mrd->target.mti_params, data,
1437 sizeof(mrd->target.mti_params));
1438 /* Copy records to this temporary llog */
1439 mrd->temp_llh = orig_llh;
1441 rc = llog_process(env, backup_llh, replace_handler,
1445 rc2 = llog_close(NULL, backup_llh);
1449 rc2 = llog_close(NULL, orig_llh);
1455 CERROR("%s: llog should be restored: rc = %d\n",
1457 rc2 = llog_backup(env, mgs, ctxt, ctxt, backup,
1460 CERROR("%s: can't restore backup %s: rc = %d\n",
1461 mgs->obd_name, logname, rc2);
1465 OBD_FREE(backup, buf_size);
1468 llog_ctxt_put(ctxt);
1471 CERROR("%s: failed to replace log %s: rc = %d\n",
1472 mgs->obd_name, logname, rc);
1477 static int mgs_replace_nids_log(const struct lu_env *env,
1478 struct obd_device *obd,
1479 char *logname, char *devname, char *nids)
1481 CDEBUG(D_MGS, "Replace NIDs for %s in %s\n", devname, logname);
1482 return mgs_replace_log(env, obd, logname, devname,
1483 mgs_replace_nids_handler, nids);
1487 * Parse device name and get file system name and/or device index
1489 * @devname device name (ex. lustre-MDT0000)
1490 * @fsname file system name extracted from @devname and returned
1491 * to the caller (optional)
1492 * @index device index extracted from @devname and returned to
1493 * the caller (optional)
1495 * RETURN 0 success if we are only interested in
1496 * extracting fsname from devname.
1499 * LDD_F_SV_TYPE_* Besides extracting the fsname the
1500 * user also wants the index. Report to
1501 * the user the type of obd device the
1502 * returned index belongs too.
1504 * -EINVAL The obd device name is improper so
1505 * fsname could not be extracted.
1507 * -ENXIO Failed to extract the index out of
1508 * the obd device name. Most likely an
1509 * invalid obd device name
1511 static int mgs_parse_devname(char *devname, char *fsname, u32 *index)
1516 /* Extract fsname */
1518 rc = server_name2fsname(devname, fsname, NULL);
1520 CDEBUG(D_MGS, "Device name %s without fsname\n",
1527 rc = server_name2index(devname, index, NULL);
1529 CDEBUG(D_MGS, "Device name %s with wrong index\n",
1535 /* server_name2index can return LDD_F_SV_TYPE_* so always return rc */
1539 /* This is only called during replace_nids */
1540 static int only_mgs_is_running(struct obd_device *mgs_obd)
1542 /* TDB: Is global variable with devices count exists? */
1543 int num_devices = get_devices_count();
1544 int num_exports = 0;
1545 struct obd_export *exp;
1547 spin_lock(&mgs_obd->obd_dev_lock);
1548 list_for_each_entry(exp, &mgs_obd->obd_exports, exp_obd_chain) {
1549 /* skip self export */
1550 if (exp == mgs_obd->obd_self_export)
1555 if (num_exports > 1)
1556 CERROR("%s: node %s still connected during replace_nids connect_flags:%llx\n",
1558 libcfs_nidstr(&exp->exp_nid_stats->nid),
1559 exp_connect_flags(exp));
1561 spin_unlock(&mgs_obd->obd_dev_lock);
1563 /* osd, MGS and MGC + MGC export (nosvc starts MGC)
1564 * (wc -l /proc/fs/lustre/devices <= 3) && (non self exports == 1)
1566 return (num_devices <= 3) && (num_exports <= 1);
1569 static int name_create_mdt(char **logname, char *fsname, int mdt_idx)
1573 if (mdt_idx > INDEX_MAP_MAX_VALUE)
1576 snprintf(postfix, sizeof(postfix), "-MDT%04x", mdt_idx);
1577 return name_create(logname, fsname, postfix);
1581 * Replace nids for \a device to \a nids values
1583 * \param obd MGS obd device
1584 * \param devname nids need to be replaced for this device
1585 * (ex. lustre-OST0000)
1586 * \param nids nids list (ex. nid1,nid2,nid3)
1590 int mgs_replace_nids(const struct lu_env *env,
1591 struct mgs_device *mgs,
1592 char *devname, char *nids)
1594 /* Assume fsname is part of device name */
1595 char fsname[MTI_NAME_MAXLEN];
1599 struct fs_db *fsdb = NULL;
1602 struct obd_device *mgs_obd = mgs->mgs_obd;
1605 /* We can only change NIDs if no other nodes are connected */
1606 spin_lock(&mgs_obd->obd_dev_lock);
1607 conn_state = mgs_obd->obd_no_conn;
1608 mgs_obd->obd_no_conn = 1;
1609 spin_unlock(&mgs_obd->obd_dev_lock);
1611 /* We can not change nids if not only MGS is started */
1612 if (!only_mgs_is_running(mgs_obd)) {
1613 CERROR("Only MGS is allowed to be started\n");
1614 GOTO(out, rc = -EINPROGRESS);
1617 /* Get fsname and index */
1618 rc = mgs_parse_devname(devname, fsname, &index);
1622 rc = mgs_find_or_make_fsdb(env, mgs, fsname, &fsdb);
1624 CERROR("%s: can't find fsdb: rc = %d\n", fsname, rc);
1628 /* Process client llogs */
1629 rc = name_create(&logname, fsname, "-client");
1632 rc = mgs_replace_nids_log(env, mgs_obd, logname, devname, nids);
1633 name_destroy(&logname);
1635 CERROR("%s: error while replacing NIDs for %s: rc = %d\n",
1636 fsname, devname, rc);
1640 /* Process MDT llogs */
1641 for (i = 0; i < INDEX_MAP_SIZE * 8; i++) {
1642 if (!test_bit(i, fsdb->fsdb_mdt_index_map))
1644 rc = name_create_mdt(&logname, fsname, i);
1647 rc = mgs_replace_nids_log(env, mgs_obd, logname, devname, nids);
1648 name_destroy(&logname);
1654 spin_lock(&mgs_obd->obd_dev_lock);
1655 mgs_obd->obd_no_conn = conn_state;
1656 spin_unlock(&mgs_obd->obd_dev_lock);
1659 mgs_put_fsdb(mgs, fsdb);
1665 * This is called for every record in llog. Some of records are
1666 * skipped, others are copied to new log as is.
1667 * Records to be skipped are
1668 * marker records marked SKIP
1669 * records enclosed between SKIP markers
1671 * \param[in] llh log to be processed
1672 * \param[in] rec current record
1673 * \param[in] data mgs_replace_data structure
1677 static int mgs_clear_config_handler(const struct lu_env *env,
1678 struct llog_handle *llh,
1679 struct llog_rec_hdr *rec, void *data)
1681 struct mgs_replace_data *mrd;
1682 struct lustre_cfg *lcfg = REC_DATA(rec);
1683 int cfg_len = REC_DATA_LEN(rec);
1688 mrd = (struct mgs_replace_data *)data;
1690 if (rec->lrh_type != OBD_CFG_REC) {
1691 CDEBUG(D_MGS, "Config llog Name=%s, Record Index=%u, "
1692 "Unhandled Record Type=%#x\n", llh->lgh_name,
1693 rec->lrh_index, rec->lrh_type);
1697 rc = lustre_cfg_sanity_check(lcfg, cfg_len);
1699 CDEBUG(D_MGS, "Config llog Name=%s, Invalid config file.",
1704 if (lcfg->lcfg_command == LCFG_MARKER) {
1705 struct cfg_marker *marker;
1707 marker = lustre_cfg_buf(lcfg, 1);
1708 if (marker->cm_flags & CM_SKIP) {
1709 if (marker->cm_flags & CM_START)
1710 mrd->state = REPLACE_SKIP;
1711 if (marker->cm_flags & CM_END)
1712 mrd->state = REPLACE_COPY;
1713 /* SKIP section started or finished */
1714 CDEBUG(D_MGS, "Skip idx=%d, rc=%d, len=%d, "
1715 "cmd %x %s %s\n", rec->lrh_index, rc,
1716 rec->lrh_len, lcfg->lcfg_command,
1717 lustre_cfg_string(lcfg, 0),
1718 lustre_cfg_string(lcfg, 1));
1722 if (mrd->state == REPLACE_SKIP) {
1723 /* record enclosed between SKIP markers, skip it */
1724 CDEBUG(D_MGS, "Skip idx=%d, rc=%d, len=%d, "
1725 "cmd %x %s %s\n", rec->lrh_index, rc,
1726 rec->lrh_len, lcfg->lcfg_command,
1727 lustre_cfg_string(lcfg, 0),
1728 lustre_cfg_string(lcfg, 1));
1733 /* Record is placed in temporary llog as is */
1734 rc = llog_write(env, mrd->temp_llh, rec, LLOG_NEXT_IDX);
1736 CDEBUG(D_MGS, "Copied idx=%d, rc=%d, len=%d, cmd %x %s %s\n",
1737 rec->lrh_index, rc, rec->lrh_len, lcfg->lcfg_command,
1738 lustre_cfg_string(lcfg, 0), lustre_cfg_string(lcfg, 1));
1743 * Directory CONFIGS/ may contain files which are not config logs to
1744 * be cleared. Skip any llogs with a non-alphanumeric character after
1745 * the last '-'. For example, fsname-MDT0000.sav, fsname-MDT0000.bak,
1746 * fsname-MDT0000.orig, fsname-MDT0000~, fsname-MDT0000.20150516, etc.
1748 static bool config_to_clear(const char *logname)
1753 str = strrchr(logname, '-');
1758 while (isalnum(str[++i]));
1759 return str[i] == '\0';
1763 * Clear config logs for \a name
1766 * \param mgs MGS device
1767 * \param name name of device or of filesystem
1768 * (ex. lustre-OST0000 or lustre) in later case all logs
1773 int mgs_clear_configs(const struct lu_env *env,
1774 struct mgs_device *mgs, const char *name)
1776 struct list_head dentry_list;
1777 struct mgs_direntry *dirent, *n;
1780 struct obd_device *mgs_obd = mgs->mgs_obd;
1785 /* Prevent clients and servers from connecting to mgs */
1786 spin_lock(&mgs_obd->obd_dev_lock);
1787 conn_state = mgs_obd->obd_no_conn;
1788 mgs_obd->obd_no_conn = 1;
1789 spin_unlock(&mgs_obd->obd_dev_lock);
1792 * config logs cannot be cleaned if anything other than
1795 if (!only_mgs_is_running(mgs_obd)) {
1796 CERROR("Only MGS is allowed to be started\n");
1797 GOTO(out, rc = -EBUSY);
1800 /* Find all the logs in the CONFIGS directory */
1801 rc = class_dentry_readdir(env, mgs, &dentry_list);
1803 CERROR("%s: cannot read config directory '%s': rc = %d\n",
1804 mgs_obd->obd_name, MOUNT_CONFIGS_DIR, rc);
1808 if (list_empty(&dentry_list)) {
1809 CERROR("%s: list empty reading config dir '%s': rc = %d\n",
1810 mgs_obd->obd_name, MOUNT_CONFIGS_DIR, -ENOENT);
1811 GOTO(out, rc = -ENOENT);
1814 OBD_ALLOC(namedash, strlen(name) + 2);
1815 if (namedash == NULL)
1816 GOTO(out, rc = -ENOMEM);
1817 snprintf(namedash, strlen(name) + 2, "%s-", name);
1819 list_for_each_entry(dirent, &dentry_list, mde_list) {
1820 if (strcmp(name, dirent->mde_name) &&
1821 strncmp(namedash, dirent->mde_name, strlen(namedash)))
1823 if (!config_to_clear(dirent->mde_name))
1825 CDEBUG(D_MGS, "%s: Clear config log %s\n",
1826 mgs_obd->obd_name, dirent->mde_name);
1827 rc = mgs_replace_log(env, mgs_obd, dirent->mde_name, NULL,
1828 mgs_clear_config_handler, NULL);
1833 list_for_each_entry_safe(dirent, n, &dentry_list, mde_list) {
1834 list_del_init(&dirent->mde_list);
1835 mgs_direntry_free(dirent);
1837 OBD_FREE(namedash, strlen(name) + 2);
1839 spin_lock(&mgs_obd->obd_dev_lock);
1840 mgs_obd->obd_no_conn = conn_state;
1841 spin_unlock(&mgs_obd->obd_dev_lock);
1846 static int record_lov_setup(const struct lu_env *env, struct llog_handle *llh,
1847 char *devname, struct lov_desc *desc)
1849 struct mgs_thread_info *mgi = mgs_env_info(env);
1850 struct llog_cfg_rec *lcr;
1853 lustre_cfg_bufs_reset(&mgi->mgi_bufs, devname);
1854 lustre_cfg_bufs_set(&mgi->mgi_bufs, 1, desc, sizeof(*desc));
1855 lcr = lustre_cfg_rec_new(LCFG_SETUP, &mgi->mgi_bufs);
1859 rc = llog_write(env, llh, &lcr->lcr_hdr, LLOG_NEXT_IDX);
1860 lustre_cfg_rec_free(lcr);
1864 static int record_lmv_setup(const struct lu_env *env, struct llog_handle *llh,
1865 char *devname, struct lmv_desc *desc)
1867 struct mgs_thread_info *mgi = mgs_env_info(env);
1868 struct llog_cfg_rec *lcr;
1871 lustre_cfg_bufs_reset(&mgi->mgi_bufs, devname);
1872 lustre_cfg_bufs_set(&mgi->mgi_bufs, 1, desc, sizeof(*desc));
1873 lcr = lustre_cfg_rec_new(LCFG_SETUP, &mgi->mgi_bufs);
1877 rc = llog_write(env, llh, &lcr->lcr_hdr, LLOG_NEXT_IDX);
1878 lustre_cfg_rec_free(lcr);
1882 static inline int record_mdc_add(const struct lu_env *env,
1883 struct llog_handle *llh,
1884 char *logname, char *mdcuuid,
1885 char *mdtuuid, char *index,
1888 return record_base(env,llh,logname,0,LCFG_ADD_MDC,
1889 mdtuuid, index, gen, mdcuuid);
1892 static inline int record_lov_add(const struct lu_env *env,
1893 struct llog_handle *llh,
1894 char *lov_name, char *ost_uuid,
1895 char *index, char *gen)
1897 return record_base(env, llh, lov_name, 0, LCFG_LOV_ADD_OBD,
1898 ost_uuid, index, gen, NULL);
1901 static inline int record_mount_opt(const struct lu_env *env,
1902 struct llog_handle *llh,
1903 char *profile, char *lov_name,
1906 return record_base(env, llh, NULL, 0, LCFG_MOUNTOPT,
1907 profile, lov_name, mdc_name, NULL);
1910 static int record_marker(const struct lu_env *env,
1911 struct llog_handle *llh,
1912 struct fs_db *fsdb, __u32 flags,
1913 char *tgtname, char *comment)
1915 struct mgs_thread_info *mgi = mgs_env_info(env);
1916 struct llog_cfg_rec *lcr;
1920 if (flags & CM_START)
1922 mgi->mgi_marker.cm_step = fsdb->fsdb_gen;
1923 mgi->mgi_marker.cm_flags = flags;
1924 mgi->mgi_marker.cm_vers = LUSTRE_VERSION_CODE;
1925 cplen = strlcpy(mgi->mgi_marker.cm_tgtname, tgtname,
1926 sizeof(mgi->mgi_marker.cm_tgtname));
1927 if (cplen >= sizeof(mgi->mgi_marker.cm_tgtname))
1929 cplen = strlcpy(mgi->mgi_marker.cm_comment, comment,
1930 sizeof(mgi->mgi_marker.cm_comment));
1931 if (cplen >= sizeof(mgi->mgi_marker.cm_comment))
1933 mgi->mgi_marker.cm_createtime = ktime_get_real_seconds();
1934 mgi->mgi_marker.cm_canceltime = 0;
1935 lustre_cfg_bufs_reset(&mgi->mgi_bufs, NULL);
1936 lustre_cfg_bufs_set(&mgi->mgi_bufs, 1, &mgi->mgi_marker,
1937 sizeof(mgi->mgi_marker));
1938 lcr = lustre_cfg_rec_new(LCFG_MARKER, &mgi->mgi_bufs);
1942 rc = llog_write(env, llh, &lcr->lcr_hdr, LLOG_NEXT_IDX);
1943 lustre_cfg_rec_free(lcr);
1947 static int record_start_log(const struct lu_env *env, struct mgs_device *mgs,
1948 struct llog_handle **llh, char *name)
1950 static struct obd_uuid cfg_uuid = { .uuid = "config_uuid" };
1951 struct llog_ctxt *ctxt;
1956 GOTO(out, rc = -EBUSY);
1958 ctxt = llog_get_context(mgs->mgs_obd, LLOG_CONFIG_ORIG_CTXT);
1960 GOTO(out, rc = -ENODEV);
1961 LASSERT(ctxt->loc_obd == mgs->mgs_obd);
1963 rc = llog_open_create(env, ctxt, llh, NULL, name);
1966 rc = llog_init_handle(env, *llh, LLOG_F_IS_PLAIN, &cfg_uuid);
1968 llog_close(env, *llh);
1970 llog_ctxt_put(ctxt);
1973 CERROR("%s: can't start log %s: rc = %d\n",
1974 mgs->mgs_obd->obd_name, name, rc);
1980 static int record_end_log(const struct lu_env *env, struct llog_handle **llh)
1984 rc = llog_close(env, *llh);
1990 /******************** config "macros" *********************/
1992 /* write an lcfg directly into a log (with markers) */
1993 static int mgs_write_log_direct(const struct lu_env *env,
1994 struct mgs_device *mgs, struct fs_db *fsdb,
1995 char *logname, struct llog_cfg_rec *lcr,
1996 char *devname, char *comment)
1998 struct llog_handle *llh = NULL;
2003 rc = record_start_log(env, mgs, &llh, logname);
2007 /* FIXME These should be a single journal transaction */
2008 rc = record_marker(env, llh, fsdb, CM_START, devname, comment);
2011 rc = llog_write(env, llh, &lcr->lcr_hdr, LLOG_NEXT_IDX);
2014 rc = record_marker(env, llh, fsdb, CM_END, devname, comment);
2018 record_end_log(env, &llh);
2022 /* write the lcfg in all logs for the given fs */
2023 static int mgs_write_log_direct_all(const struct lu_env *env,
2024 struct mgs_device *mgs,
2026 struct mgs_target_info *mti,
2027 struct llog_cfg_rec *lcr, char *devname,
2028 char *comment, int server_only)
2030 struct list_head log_list;
2031 struct mgs_direntry *dirent, *n;
2032 char *fsname = mti->mti_fsname;
2033 int rc = 0, len = strlen(fsname);
2036 /* Find all the logs in the CONFIGS directory */
2037 rc = class_dentry_readdir(env, mgs, &log_list);
2041 /* Could use fsdb index maps instead of directory listing */
2042 list_for_each_entry_safe(dirent, n, &log_list, mde_list) {
2043 list_del_init(&dirent->mde_list);
2044 /* don't write to sptlrpc rule log */
2045 if (strstr(dirent->mde_name, "-sptlrpc") != NULL)
2048 /* caller wants write server logs only */
2049 if (server_only && strstr(dirent->mde_name, "-client") != NULL)
2052 if (strlen(dirent->mde_name) <= len ||
2053 strncmp(fsname, dirent->mde_name, len) != 0 ||
2054 dirent->mde_name[len] != '-')
2057 CDEBUG(D_MGS, "Changing log %s\n", dirent->mde_name);
2058 /* Erase any old settings of this same parameter */
2059 rc = mgs_modify(env, mgs, fsdb, mti, dirent->mde_name,
2060 devname, comment, CM_SKIP);
2062 CERROR("%s: Can't modify llog %s: rc = %d\n",
2063 mgs->mgs_obd->obd_name, dirent->mde_name, rc);
2066 /* Write the new one */
2067 rc = mgs_write_log_direct(env, mgs, fsdb, dirent->mde_name,
2068 lcr, devname, comment);
2070 CERROR("%s: writing log %s: rc = %d\n",
2071 mgs->mgs_obd->obd_name, dirent->mde_name, rc);
2073 mgs_direntry_free(dirent);
2079 static int mgs_write_log_osp_to_mdt(const struct lu_env *env,
2080 struct mgs_device *mgs,
2082 struct mgs_target_info *mti,
2083 int index, char *logname);
2084 static int mgs_write_log_osc_to_lov(const struct lu_env *env,
2085 struct mgs_device *mgs,
2087 struct mgs_target_info *mti,
2088 char *logname, char *suffix, char *lovname,
2089 enum lustre_sec_part sec_part, int flags);
2090 static int name_create_mdt_and_lov(char **logname, char **lovname,
2091 struct fs_db *fsdb, int i);
2093 static int add_param(char *params, char *key, char *val)
2095 char *start = params + strlen(params);
2096 char *end = params + sizeof(((struct mgs_target_info *)0)->mti_params);
2100 keylen = strlen(key);
2101 if (start + 1 + keylen + strlen(val) >= end) {
2102 CERROR("params are too long: %s %s%s\n",
2103 params, key != NULL ? key : "", val);
2107 sprintf(start, " %s%s", key != NULL ? key : "", val);
2112 * Walk through client config log record and convert the related records
2115 static int mgs_steal_client_llog_handler(const struct lu_env *env,
2116 struct llog_handle *llh,
2117 struct llog_rec_hdr *rec, void *data)
2119 struct mgs_device *mgs;
2120 struct obd_device *obd;
2121 struct mgs_target_info *mti, *tmti;
2123 int cfg_len = rec->lrh_len;
2124 char *cfg_buf = (char *)(rec + 1);
2125 struct lustre_cfg *lcfg;
2127 struct llog_handle *mdt_llh = NULL;
2128 static int got_an_osc_or_mdc = 0;
2129 /* 0: not found any osc/mdc;
2133 static int last_step = -1;
2138 mti = ((struct temp_comp *)data)->comp_mti;
2139 tmti = ((struct temp_comp *)data)->comp_tmti;
2140 fsdb = ((struct temp_comp *)data)->comp_fsdb;
2141 obd = ((struct temp_comp *)data)->comp_obd;
2142 mgs = lu2mgs_dev(obd->obd_lu_dev);
2145 if (rec->lrh_type != OBD_CFG_REC) {
2146 CERROR("unhandled lrh_type: %#x\n", rec->lrh_type);
2150 rc = lustre_cfg_sanity_check(cfg_buf, cfg_len);
2152 CERROR("Insane cfg\n");
2156 lcfg = (struct lustre_cfg *)cfg_buf;
2158 if (lcfg->lcfg_command == LCFG_MARKER) {
2159 struct cfg_marker *marker;
2160 marker = lustre_cfg_buf(lcfg, 1);
2161 if (!strncmp(marker->cm_comment, "add osc", 7) &&
2162 (marker->cm_flags & CM_START) &&
2163 !(marker->cm_flags & CM_SKIP)) {
2164 got_an_osc_or_mdc = 1;
2165 cplen = strlcpy(tmti->mti_svname, marker->cm_tgtname,
2166 sizeof(tmti->mti_svname));
2167 if (cplen >= sizeof(tmti->mti_svname))
2169 rc = record_start_log(env, mgs, &mdt_llh,
2173 rc = record_marker(env, mdt_llh, fsdb, CM_START,
2174 mti->mti_svname, "add osc(copied)");
2175 record_end_log(env, &mdt_llh);
2176 last_step = marker->cm_step;
2179 if (!strncmp(marker->cm_comment, "add osc", 7) &&
2180 (marker->cm_flags & CM_END) &&
2181 !(marker->cm_flags & CM_SKIP)) {
2182 LASSERT(last_step == marker->cm_step);
2184 got_an_osc_or_mdc = 0;
2185 memset(tmti, 0, sizeof(*tmti));
2186 tmti->mti_flags = mti->mti_flags;
2187 rc = record_start_log(env, mgs, &mdt_llh,
2191 rc = record_marker(env, mdt_llh, fsdb, CM_END,
2192 mti->mti_svname, "add osc(copied)");
2193 record_end_log(env, &mdt_llh);
2196 if (!strncmp(marker->cm_comment, "add mdc", 7) &&
2197 (marker->cm_flags & CM_START) &&
2198 !(marker->cm_flags & CM_SKIP)) {
2199 got_an_osc_or_mdc = 2;
2200 last_step = marker->cm_step;
2201 memcpy(tmti->mti_svname, marker->cm_tgtname,
2202 strlen(marker->cm_tgtname));
2206 if (!strncmp(marker->cm_comment, "add mdc", 7) &&
2207 (marker->cm_flags & CM_END) &&
2208 !(marker->cm_flags & CM_SKIP)) {
2209 LASSERT(last_step == marker->cm_step);
2211 got_an_osc_or_mdc = 0;
2212 memset(tmti, 0, sizeof(*tmti));
2213 tmti->mti_flags = mti->mti_flags;
2218 if (got_an_osc_or_mdc == 0 || last_step < 0)
2221 if (lcfg->lcfg_command == LCFG_ADD_UUID) {
2222 lnet_nid_t nodenid = lcfg->lcfg_nid;
2223 char *nidstr = NULL;
2226 nidstr = lustre_cfg_buf(lcfg, 2);
2232 if (strlen(tmti->mti_uuid) == 0) {
2235 if (target_supports_large_nid(mti))
2236 dst = tmti->mti_nidlist[tmti->mti_nid_count];
2238 /* target uuid not set, this config record is before
2239 * LCFG_SETUP, this nid is one of target node nid.
2243 rc = strscpy(dst, nidstr,
2248 tmti->mti_nids[tmti->mti_nid_count] =
2249 libcfs_str2nid(nidstr);
2253 libcfs_nid2str_r(nodenid, dst,
2256 tmti->mti_nids[tmti->mti_nid_count] =
2259 tmti->mti_nid_count++;
2261 char tmp[LNET_NIDSTR_SIZE];
2264 libcfs_nid2str_r(nodenid, tmp,
2268 /* failover node nid */
2269 rc = add_param(tmti->mti_params, PARAM_FAILNODE,
2276 if (lcfg->lcfg_command == LCFG_SETUP) {
2279 target = lustre_cfg_string(lcfg, 1);
2280 memcpy(tmti->mti_uuid, target, strlen(target));
2284 /* ignore client side sptlrpc_conf_log */
2285 if (lcfg->lcfg_command == LCFG_SPTLRPC_CONF)
2288 if (lcfg->lcfg_command == LCFG_ADD_MDC &&
2289 strstr(lustre_cfg_string(lcfg, 0), "-clilmv") != NULL) {
2292 if (sscanf(lustre_cfg_buf(lcfg, 2), "%d", &index) != 1)
2294 if (index == mti->mti_stripe_index) {
2296 "attempt to create MDT%04x->MDT%04x osp device\n",
2300 memcpy(tmti->mti_fsname, mti->mti_fsname,
2301 strlen(mti->mti_fsname));
2302 tmti->mti_stripe_index = index;
2304 rc = mgs_write_log_osp_to_mdt(env, mgs, fsdb, tmti,
2305 mti->mti_stripe_index,
2307 memset(tmti, 0, sizeof(*tmti));
2311 if (lcfg->lcfg_command == LCFG_LOV_ADD_OBD) {
2314 char *logname, *lovname;
2316 rc = name_create_mdt_and_lov(&logname, &lovname, fsdb,
2317 mti->mti_stripe_index);
2320 sprintf(mdt_index, "-MDT%04x", mti->mti_stripe_index);
2322 if (sscanf(lustre_cfg_buf(lcfg, 2), "%d", &index) != 1) {
2323 name_destroy(&logname);
2324 name_destroy(&lovname);
2328 tmti->mti_stripe_index = index;
2329 rc = mgs_write_log_osc_to_lov(env, mgs, fsdb, tmti, logname,
2332 name_destroy(&logname);
2333 name_destroy(&lovname);
2339 /* fsdb->fsdb_mutex is already held in mgs_write_log_target */
2340 /* stealed from mgs_get_fsdb_from_llog */
2341 static int mgs_steal_llog_for_mdt_from_client(const struct lu_env *env,
2342 struct mgs_device *mgs,
2344 struct temp_comp *comp)
2346 size_t mti_len = offsetof(struct mgs_target_info, mti_nidlist);
2347 struct llog_handle *loghandle;
2348 struct mgs_target_info *tmti;
2349 struct llog_ctxt *ctxt;
2354 ctxt = llog_get_context(mgs->mgs_obd, LLOG_CONFIG_ORIG_CTXT);
2355 LASSERT(ctxt != NULL);
2357 /* Create the mti for the osp registered by mgc_write_log_osp_to_mdt().
2358 * The function mgs_steal_client_llog_handle() will fill in the rest.
2360 if (target_supports_large_nid(comp->comp_mti))
2361 mti_len += comp->comp_mti->mti_nid_count * LNET_NIDSTR_SIZE;
2363 OBD_ALLOC(tmti, mti_len);
2365 GOTO(out_ctxt, rc = -ENOMEM);
2367 tmti->mti_flags = comp->comp_mti->mti_flags;
2368 comp->comp_tmti = tmti;
2369 comp->comp_obd = mgs->mgs_obd;
2371 rc = llog_open(env, ctxt, &loghandle, NULL, client_name,
2379 rc = llog_init_handle(env, loghandle, LLOG_F_IS_PLAIN, NULL);
2381 GOTO(out_close, rc);
2383 rc = llog_process_or_fork(env, loghandle, mgs_steal_client_llog_handler,
2384 (void *)comp, NULL, false);
2385 CDEBUG(D_MGS, "steal llog re = %d\n", rc);
2387 llog_close(env, loghandle);
2389 OBD_FREE(tmti, mti_len);
2391 llog_ctxt_put(ctxt);
2395 /* mount opt is the third thing in client logs */
2396 static int mgs_write_log_mount_opt(const struct lu_env *env,
2397 struct mgs_device *mgs, struct fs_db *fsdb,
2400 struct llog_handle *llh = NULL;
2405 CDEBUG(D_MGS, "Writing mount options log for %s\n", logname);
2407 rc = record_start_log(env, mgs, &llh, logname);
2411 rc = record_marker(env, llh, fsdb, CM_START, logname, "mount opts");
2414 rc = record_mount_opt(env, llh, logname, fsdb->fsdb_clilov,
2418 rc = record_marker(env, llh, fsdb, CM_END, logname, "mount opts");
2422 record_end_log(env, &llh);
2426 /* lmv is the second thing for client logs */
2427 /* copied from mgs_write_log_lov. Please refer to that. */
2428 static int mgs_write_log_lmv(const struct lu_env *env,
2429 struct mgs_device *mgs,
2431 struct mgs_target_info *mti,
2432 char *logname, char *lmvname)
2434 struct llog_handle *llh = NULL;
2435 struct lmv_desc *lmvdesc;
2440 CDEBUG(D_MGS, "Writing lmv(%s) log for %s\n", lmvname, logname);
2442 OBD_ALLOC_PTR(lmvdesc);
2443 if (lmvdesc == NULL)
2445 lmvdesc->ld_active_tgt_count = 0;
2446 lmvdesc->ld_tgt_count = 0;
2447 sprintf((char *)lmvdesc->ld_uuid.uuid, "%s_UUID", lmvname);
2448 uuid = (char *)lmvdesc->ld_uuid.uuid;
2450 rc = record_start_log(env, mgs, &llh, logname);
2453 rc = record_marker(env, llh, fsdb, CM_START, lmvname, "lmv setup");
2456 rc = record_attach(env, llh, lmvname, "lmv", uuid);
2459 rc = record_lmv_setup(env, llh, lmvname, lmvdesc);
2462 rc = record_marker(env, llh, fsdb, CM_END, lmvname, "lmv setup");
2466 record_end_log(env, &llh);
2468 OBD_FREE_PTR(lmvdesc);
2472 /* lov is the first thing in the mdt and client logs */
2473 static int mgs_write_log_lov(const struct lu_env *env, struct mgs_device *mgs,
2474 struct fs_db *fsdb, struct mgs_target_info *mti,
2475 char *logname, char *lovname)
2477 struct llog_handle *llh = NULL;
2478 struct lov_desc *lovdesc;
2483 CDEBUG(D_MGS, "Writing lov(%s) log for %s\n", lovname, logname);
2486 * #01 L attach 0:lov_mdsA 1:lov 2:71ccb_lov_mdsA_19f961a9e1
2487 * #02 L lov_setup 0:lov_mdsA 1:(struct lov_desc)
2488 * uuid=lov1_UUID, stripe count=1, size=1048576, offset=0, pattern=0
2491 /* FIXME just make lov_setup accept empty desc (put uuid in buf 2) */
2492 OBD_ALLOC_PTR(lovdesc);
2493 if (lovdesc == NULL)
2495 lovdesc->ld_magic = LOV_DESC_MAGIC;
2496 lovdesc->ld_tgt_count = 0;
2497 /* Defaults. Can be changed later by lcfg config_param */
2498 lovdesc->ld_default_stripe_count = 1;
2499 lovdesc->ld_pattern = LOV_PATTERN_RAID0;
2500 lovdesc->ld_default_stripe_size = LOV_DESC_STRIPE_SIZE_DEFAULT;
2501 lovdesc->ld_default_stripe_offset = -1;
2502 lovdesc->ld_qos_maxage = LOV_DESC_QOS_MAXAGE_DEFAULT;
2503 sprintf((char *)lovdesc->ld_uuid.uuid, "%s_UUID", lovname);
2504 /* can these be the same? */
2505 uuid = (char *)lovdesc->ld_uuid.uuid;
2507 /* This should always be the first entry in a log.
2508 * rc = mgs_clear_log(obd, logname);
2510 rc = record_start_log(env, mgs, &llh, logname);
2513 /* FIXME these should be a single journal transaction */
2514 rc = record_marker(env, llh, fsdb, CM_START, lovname, "lov setup");
2517 rc = record_attach(env, llh, lovname, "lov", uuid);
2520 rc = record_lov_setup(env, llh, lovname, lovdesc);
2523 rc = record_marker(env, llh, fsdb, CM_END, lovname, "lov setup");
2528 record_end_log(env, &llh);
2530 OBD_FREE_PTR(lovdesc);
2534 /* add failnids to open log */
2535 static int mgs_write_log_failnids(const struct lu_env *env,
2536 struct mgs_target_info *mti,
2537 struct llog_handle *llh,
2540 char *failnodeuuid = NULL;
2541 char *ptr = mti->mti_params;
2542 struct lnet_nid nid;
2546 * #03 L add_uuid nid=uml1@tcp(0x20000c0a80201) nal=90 0: 1:uml1_UUID
2547 * #04 L add_uuid nid=1@elan(0x1000000000001) nal=90 0: 1:uml1_UUID
2548 * #05 L setup 0:OSC_uml1_ost1_mdsA 1:ost1_UUID 2:uml1_UUID
2549 * #06 L add_uuid nid=uml2@tcp(0x20000c0a80202) nal=90 0: 1:uml2_UUID
2550 * #0x L add_uuid nid=2@elan(0x1000000000002) nal=90 0: 1:uml2_UUID
2551 * #07 L add_conn 0:OSC_uml1_ost1_mdsA 1:uml2_UUID
2555 * Pull failnid info out of params string, which may contain something
2556 * like "<nid1>,<nid2>:<nid3>,<nid4>". class_parse_nid() does not
2557 * complain about abnormal inputs like ",:<nid1>", "<nid1>:,<nid2>",
2558 * etc. However, convert_hostnames() should have caught those.
2560 while (class_find_param(ptr, PARAM_FAILNODE, &ptr) == 0) {
2561 while (class_parse_nid(ptr, &nid, &ptr) == 0) {
2562 char nidstr[LNET_NIDSTR_SIZE];
2564 if (failnodeuuid == NULL) {
2565 /* We don't know the failover node name,
2566 * so just use the first nid as the uuid */
2567 libcfs_nidstr_r(&nid, nidstr, sizeof(nidstr));
2568 rc = name_create(&failnodeuuid, nidstr, "");
2573 "add nid %s for failover uuid %s, client %s\n",
2574 libcfs_nidstr_r(&nid, nidstr, sizeof(nidstr)),
2575 failnodeuuid, cliname);
2576 rc = record_add_uuid(env, llh, &nid, failnodeuuid);
2578 * If *ptr is ':', we have added all NIDs for
2582 rc = record_add_conn(env, llh, cliname,
2584 name_destroy(&failnodeuuid);
2585 failnodeuuid = NULL;
2589 rc = record_add_conn(env, llh, cliname, failnodeuuid);
2590 name_destroy(&failnodeuuid);
2591 failnodeuuid = NULL;
2598 static int mgs_write_log_mdc_to_lmv(const struct lu_env *env,
2599 struct mgs_device *mgs,
2601 struct mgs_target_info *mti,
2602 char *logname, char *lmvname)
2604 char tmp[LNET_NIDSTR_SIZE], *nidstr;
2605 struct llog_handle *llh = NULL;
2606 char *mdcname = NULL;
2607 char *nodeuuid = NULL;
2608 char *mdcuuid = NULL;
2609 char *lmvuuid = NULL;
2614 if (mgs_log_is_empty(env, mgs, logname)) {
2615 CERROR("log is empty! Logical error\n");
2619 CDEBUG(D_MGS, "adding mdc for %s to log %s:lmv(%s)\n",
2620 mti->mti_svname, logname, lmvname);
2622 if (!target_supports_large_nid(mti)) {
2623 libcfs_nid2str_r(mti->mti_nids[0], tmp, sizeof(tmp));
2626 nidstr = mti->mti_nidlist[0];
2629 rc = name_create(&nodeuuid, nidstr, "");
2632 rc = name_create(&mdcname, mti->mti_svname, "-mdc");
2635 rc = name_create(&mdcuuid, mdcname, "_UUID");
2638 rc = name_create(&lmvuuid, lmvname, "_UUID");
2642 rc = mgs_modify(env, mgs, fsdb, mti, logname, mti->mti_svname,
2643 "add mdc", CM_SKIP);
2647 rc = record_start_log(env, mgs, &llh, logname);
2650 rc = record_marker(env, llh, fsdb, CM_START, mti->mti_svname,
2655 for (i = 0; i < mti->mti_nid_count; i++) {
2656 struct lnet_nid nid;
2658 if (target_supports_large_nid(mti)) {
2659 rc = libcfs_strnid(&nid, mti->mti_nidlist[i]);
2663 lnet_nid4_to_nid(mti->mti_nids[i], &nid);
2666 CDEBUG(D_MGS, "add nid %s for mdt\n", libcfs_nidstr(&nid));
2667 rc = record_add_uuid(env, llh, &nid, nodeuuid);
2672 rc = record_attach(env, llh, mdcname, LUSTRE_MDC_NAME, lmvuuid);
2675 rc = record_setup(env, llh, mdcname, mti->mti_uuid, nodeuuid,
2679 rc = mgs_write_log_failnids(env, mti, llh, mdcname);
2682 snprintf(index, sizeof(index), "%d", mti->mti_stripe_index);
2683 rc = record_mdc_add(env, llh, lmvname, mdcuuid, mti->mti_uuid,
2687 rc = record_marker(env, llh, fsdb, CM_END, mti->mti_svname,
2692 record_end_log(env, &llh);
2694 name_destroy(&lmvuuid);
2695 name_destroy(&mdcuuid);
2696 name_destroy(&mdcname);
2697 name_destroy(&nodeuuid);
2701 static inline int name_create_lov(char **lovname, char *mdtname,
2702 struct fs_db *fsdb, int index)
2705 if (index == 0 && test_bit(FSDB_OSCNAME18, &fsdb->fsdb_flags))
2706 return name_create(lovname, fsdb->fsdb_name, "-mdtlov");
2708 return name_create(lovname, mdtname, "-mdtlov");
2711 static int name_create_mdt_and_lov(char **logname, char **lovname,
2712 struct fs_db *fsdb, int i)
2716 rc = name_create_mdt(logname, fsdb->fsdb_name, i);
2720 if (i == 0 && test_bit(FSDB_OSCNAME18, &fsdb->fsdb_flags))
2721 rc = name_create(lovname, fsdb->fsdb_name, "-mdtlov");
2723 rc = name_create(lovname, *logname, "-mdtlov");
2725 name_destroy(logname);
2731 static inline int name_create_mdt_osc(char **oscname, char *ostname,
2732 struct fs_db *fsdb, int i)
2736 if (i == 0 && test_bit(FSDB_OSCNAME18, &fsdb->fsdb_flags))
2737 sprintf(suffix, "-osc");
2739 sprintf(suffix, "-osc-MDT%04x", i);
2740 return name_create(oscname, ostname, suffix);
2743 /* add new mdc to already existent MDS */
2744 static int mgs_write_log_osp_to_mdt(const struct lu_env *env,
2745 struct mgs_device *mgs,
2747 struct mgs_target_info *mti,
2748 int mdt_index, char *logname)
2750 char tmp[LNET_NIDSTR_SIZE], *nidstr;
2751 struct llog_handle *llh = NULL;
2752 char *nodeuuid = NULL;
2753 char *ospname = NULL;
2754 char *lovuuid = NULL;
2755 char *mdtuuid = NULL;
2756 char *svname = NULL;
2757 char *mdtname = NULL;
2758 char *lovname = NULL;
2763 if (mgs_log_is_empty(env, mgs, mti->mti_svname)) {
2764 CERROR("log is empty! Logical error\n");
2768 CDEBUG(D_MGS, "adding osp index %d to %s\n", mti->mti_stripe_index,
2771 rc = name_create_mdt(&mdtname, fsdb->fsdb_name, mti->mti_stripe_index);
2775 if (!target_supports_large_nid(mti)) {
2776 libcfs_nid2str_r(mti->mti_nids[0], tmp, sizeof(tmp));
2779 nidstr = mti->mti_nidlist[0];
2782 rc = name_create(&nodeuuid, nidstr, "");
2784 GOTO(out_destory, rc);
2786 rc = name_create(&svname, mdtname, "-osp");
2788 GOTO(out_destory, rc);
2790 sprintf(index_str, "-MDT%04x", mdt_index);
2791 rc = name_create(&ospname, svname, index_str);
2793 GOTO(out_destory, rc);
2795 rc = name_create_lov(&lovname, logname, fsdb, mdt_index);
2797 GOTO(out_destory, rc);
2799 rc = name_create(&lovuuid, lovname, "_UUID");
2801 GOTO(out_destory, rc);
2803 rc = name_create(&mdtuuid, mdtname, "_UUID");
2805 GOTO(out_destory, rc);
2807 rc = mgs_modify(env, mgs, fsdb, mti, logname, mti->mti_svname,
2808 "add osp", CM_SKIP);
2810 GOTO(out_destory, rc);
2812 rc = record_start_log(env, mgs, &llh, logname);
2814 GOTO(out_destory, rc);
2816 rc = record_marker(env, llh, fsdb, CM_START, mti->mti_svname,
2819 GOTO(out_destory, rc);
2821 for (i = 0; i < mti->mti_nid_count; i++) {
2822 struct lnet_nid nid;
2824 if (target_supports_large_nid(mti)) {
2825 rc = libcfs_strnid(&nid, mti->mti_nidlist[i]);
2829 lnet_nid4_to_nid(mti->mti_nids[i], &nid);
2832 CDEBUG(D_MGS, "add nid %s for mdt\n", libcfs_nidstr(&nid));
2833 rc = record_add_uuid(env, llh, &nid, nodeuuid);
2838 rc = record_attach(env, llh, ospname, LUSTRE_OSP_NAME, lovuuid);
2842 rc = record_setup(env, llh, ospname, mti->mti_uuid, nodeuuid,
2847 rc = mgs_write_log_failnids(env, mti, llh, ospname);
2851 /* Add mdc(osp) to lod */
2852 snprintf(index_str, sizeof(index_str), "%d", mti->mti_stripe_index);
2853 rc = record_base(env, llh, lovname, 0, LCFG_ADD_MDC, mti->mti_uuid,
2854 index_str, "1", NULL);
2858 rc = record_marker(env, llh, fsdb, CM_END, mti->mti_svname, "add osp");
2863 record_end_log(env, &llh);
2866 name_destroy(&mdtuuid);
2867 name_destroy(&lovuuid);
2868 name_destroy(&lovname);
2869 name_destroy(&ospname);
2870 name_destroy(&svname);
2871 name_destroy(&nodeuuid);
2872 name_destroy(&mdtname);
2876 static int mgs_write_log_mdt0(const struct lu_env *env,
2877 struct mgs_device *mgs,
2879 struct mgs_target_info *mti)
2881 char *log = mti->mti_svname;
2882 struct llog_handle *llh = NULL;
2883 struct obd_uuid *uuid;
2886 char *ptr = mti->mti_params;
2887 int rc = 0, failout = 0;
2890 OBD_ALLOC_PTR(uuid);
2894 if (class_find_param(ptr, PARAM_FAILMODE, &ptr) == 0)
2895 failout = (strncmp(ptr, "failout", 7) == 0);
2897 rc = name_create(&lovname, log, "-mdtlov");
2900 if (mgs_log_is_empty(env, mgs, log)) {
2901 rc = mgs_write_log_lov(env, mgs, fsdb, mti, log, lovname);
2906 sprintf(mdt_index, "%d", mti->mti_stripe_index);
2908 rc = record_start_log(env, mgs, &llh, log);
2912 /* add MDT itself */
2914 /* FIXME this whole fn should be a single journal transaction */
2915 sprintf(uuid->uuid, "%s_UUID", log);
2916 rc = record_marker(env, llh, fsdb, CM_START, log, "add mdt");
2919 rc = record_attach(env, llh, log, LUSTRE_MDT_NAME, uuid->uuid);
2922 rc = record_mount_opt(env, llh, log, lovname, NULL);
2925 rc = record_setup(env, llh, log, uuid->uuid, mdt_index, lovname,
2926 failout ? "n" : "f");
2929 rc = record_marker(env, llh, fsdb, CM_END, log, "add mdt");
2933 record_end_log(env, &llh);
2935 name_destroy(&lovname);
2941 /* envelope method for all layers log */
2942 static int mgs_write_log_mdt(const struct lu_env *env,
2943 struct mgs_device *mgs,
2945 struct mgs_target_info *mti)
2947 struct mgs_thread_info *mgi = mgs_env_info(env);
2948 struct llog_handle *llh = NULL;
2953 CDEBUG(D_MGS, "writing new mdt %s\n", mti->mti_svname);
2955 if (mti->mti_uuid[0] == '\0') {
2956 /* Make up our own uuid */
2957 snprintf(mti->mti_uuid, sizeof(mti->mti_uuid),
2958 "%s_UUID", mti->mti_svname);
2962 rc = mgs_write_log_mdt0(env, mgs, fsdb, mti);
2966 /* Append the mdt info to the client log */
2967 rc = name_create(&cliname, mti->mti_fsname, "-client");
2971 if (mgs_log_is_empty(env, mgs, cliname)) {
2972 /* Start client log */
2973 rc = mgs_write_log_lov(env, mgs, fsdb, mti, cliname,
2977 rc = mgs_write_log_lmv(env, mgs, fsdb, mti, cliname,
2981 rc = mgs_write_log_mount_opt(env, mgs, fsdb, cliname);
2987 * #09 L add_uuid nid=uml1@tcp(0x20000c0a80201) 0: 1:uml1_UUID
2988 * #10 L attach 0:MDC_uml1_mdsA_MNT_client 1:mdc 2:1d834_MNT_client_03f
2989 * #11 L setup 0:MDC_uml1_mdsA_MNT_client 1:mdsA_UUID 2:uml1_UUID
2990 * #12 L add_uuid nid=uml2@tcp(0x20000c0a80202) 0: 1:uml2_UUID
2991 * #13 L add_conn 0:MDC_uml1_mdsA_MNT_client 1:uml2_UUID
2994 /* copy client info about lov/lmv */
2995 mgi->mgi_comp.comp_mti = mti;
2996 mgi->mgi_comp.comp_fsdb = fsdb;
2998 rc = mgs_steal_llog_for_mdt_from_client(env, mgs, cliname,
3002 rc = mgs_write_log_mdc_to_lmv(env, mgs, fsdb, mti, cliname,
3007 rc = record_start_log(env, mgs, &llh, cliname);
3011 /* for_all_existing_mdt except current one */
3012 for (i = 0; i < INDEX_MAP_SIZE * 8; i++) {
3013 if (i != mti->mti_stripe_index &&
3014 test_bit(i, fsdb->fsdb_mdt_index_map)) {
3017 rc = name_create_mdt(&logname, fsdb->fsdb_name, i);
3021 /* NB: If the log for the MDT is empty, it means
3022 * the MDT is only added to the index
3023 * map, and not being process yet, i.e. this
3024 * is an unregistered MDT, see mgs_write_log_target().
3025 * so we should skip it. Otherwise
3027 * 1. MGS get register request for MDT1 and MDT2.
3029 * 2. Then both MDT1 and MDT2 are added into
3030 * fsdb_mdt_index_map. (see mgs_set_index()).
3032 * 3. Then MDT1 get the lock of fsdb_mutex, then
3033 * generate the config log, here, it will regard MDT2
3034 * as an existent MDT, and generate "add osp" for
3035 * lustre-MDT0001-osp-MDT0002. Note: at the moment
3036 * MDT0002 config log is still empty, so it will
3037 * add "add osp" even before "lov setup", which
3038 * will definitly cause trouble.
3040 * 4. MDT1 registeration finished, fsdb_mutex is
3041 * released, then MDT2 get in, then in above
3042 * mgs_steal_llog_for_mdt_from_client(), it will
3043 * add another osp log for lustre-MDT0001-osp-MDT0002,
3044 * which will cause another trouble.*/
3045 if (!mgs_log_is_empty(env, mgs, logname))
3046 rc = mgs_write_log_osp_to_mdt(env, mgs, fsdb,
3049 name_destroy(&logname);
3055 record_end_log(env, &llh);
3057 name_destroy(&cliname);
3061 /* Add the ost info to the client/mdt lov */
3062 static int mgs_write_log_osc_to_lov(const struct lu_env *env,
3063 struct mgs_device *mgs, struct fs_db *fsdb,
3064 struct mgs_target_info *mti,
3065 char *logname, char *suffix, char *lovname,
3066 enum lustre_sec_part sec_part, int flags)
3068 char tmp[LNET_NIDSTR_SIZE], *nidstr;
3069 struct llog_handle *llh = NULL;
3070 char *nodeuuid = NULL;
3071 char *oscname = NULL;
3072 char *oscuuid = NULL;
3073 char *lovuuid = NULL;
3074 char *svname = NULL;
3079 CDEBUG(D_INFO, "adding osc for %s to log %s\n",
3080 mti->mti_svname, logname);
3082 if (mgs_log_is_empty(env, mgs, logname)) {
3083 CERROR("log is empty! Logical error\n");
3087 if (!target_supports_large_nid(mti)) {
3088 libcfs_nid2str_r(mti->mti_nids[0], tmp, sizeof(tmp));
3091 nidstr = mti->mti_nidlist[0];
3094 rc = name_create(&nodeuuid, mti->mti_nidlist[0], "");
3097 rc = name_create(&svname, mti->mti_svname, "-osc");
3101 /* for the system upgraded from old 1.8, keep using the old osc naming
3102 * style for mdt, see name_create_mdt_osc(). LU-1257 */
3103 if (test_bit(FSDB_OSCNAME18, &fsdb->fsdb_flags))
3104 rc = name_create(&oscname, svname, "");
3106 rc = name_create(&oscname, svname, suffix);
3110 rc = name_create(&oscuuid, oscname, "_UUID");
3113 rc = name_create(&lovuuid, lovname, "_UUID");
3118 * #03 L add_uuid nid=uml1@tcp(0x20000c0a80201) 0: 1:uml1_UUID
3120 * #04 L add_uuid nid=1@elan(0x1000000000001) nal=90 0: 1:uml1_UUID
3121 * #04 L attach 0:OSC_uml1_ost1_MNT_client 1:osc 2:89070_lov1_a41dff51a
3122 * #05 L setup 0:OSC_uml1_ost1_MNT_client 1:ost1_UUID 2:uml1_UUID
3124 * #06 L add_uuid nid=uml2@tcp(0x20000c0a80202) 0: 1:uml2_UUID
3125 * #07 L add_conn 0:OSC_uml1_ost1_MNT_client 1:uml2_UUID
3126 * #08 L lov_modify_tgts add 0:lov1 1:ost1_UUID 2(index):0 3(gen):1
3129 rc = record_start_log(env, mgs, &llh, logname);
3133 /* FIXME these should be a single journal transaction */
3134 rc = record_marker(env, llh, fsdb, CM_START | flags, mti->mti_svname,
3139 /* NB: don't change record order, because upon MDT steal OSC config
3140 * from client, it treats all nids before LCFG_SETUP as target nids
3141 * (multiple interfaces), while nids after as failover node nids.
3142 * See mgs_steal_client_llog_handler() LCFG_ADD_UUID.
3144 for (i = 0; i < mti->mti_nid_count; i++) {
3145 struct lnet_nid nid;
3147 rc = libcfs_strnid(&nid, mti->mti_nidlist[i]);
3151 CDEBUG(D_MGS, "add nid %s\n", libcfs_nidstr(&nid));
3152 rc = record_add_uuid(env, llh, &nid, nodeuuid);
3157 rc = record_attach(env, llh, oscname, LUSTRE_OSC_NAME, lovuuid);
3160 rc = record_setup(env, llh, oscname, mti->mti_uuid, nodeuuid,
3164 rc = mgs_write_log_failnids(env, mti, llh, oscname);
3168 snprintf(index, sizeof(index), "%d", mti->mti_stripe_index);
3170 rc = record_lov_add(env, llh, lovname, mti->mti_uuid, index, "1");
3173 rc = record_marker(env, llh, fsdb, CM_END | flags, mti->mti_svname,
3178 record_end_log(env, &llh);
3180 name_destroy(&lovuuid);
3181 name_destroy(&oscuuid);
3182 name_destroy(&oscname);
3183 name_destroy(&svname);
3184 name_destroy(&nodeuuid);
3188 static int mgs_write_log_ost(const struct lu_env *env,
3189 struct mgs_device *mgs, struct fs_db *fsdb,
3190 struct mgs_target_info *mti)
3192 struct llog_handle *llh = NULL;
3193 char *logname, *lovname;
3194 char *ptr = mti->mti_params;
3195 int rc, flags = 0, failout = 0, i;
3198 CDEBUG(D_MGS, "writing new ost %s\n", mti->mti_svname);
3200 /* The ost startup log */
3202 /* If the ost log already exists, that means that someone reformatted
3203 * the ost and it called target_add again.
3205 if (!mgs_log_is_empty(env, mgs, mti->mti_svname)) {
3206 LCONSOLE_ERROR_MSG(0x141,
3207 "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",
3213 * attach obdfilter ost1 ost1_UUID
3214 * setup /dev/loop2 ldiskfs f|n errors=remount-ro,user_xattr
3216 if (class_find_param(ptr, PARAM_FAILMODE, &ptr) == 0)
3217 failout = (strncmp(ptr, "failout", 7) == 0);
3218 rc = record_start_log(env, mgs, &llh, mti->mti_svname);
3221 /* FIXME these should be a single journal transaction */
3222 rc = record_marker(env, llh, fsdb, CM_START, mti->mti_svname,"add ost");
3225 if (*mti->mti_uuid == '\0')
3226 snprintf(mti->mti_uuid, sizeof(mti->mti_uuid),
3227 "%s_UUID", mti->mti_svname);
3228 rc = record_attach(env, llh, mti->mti_svname,
3229 "obdfilter"/*LUSTRE_OST_NAME*/, mti->mti_uuid);
3232 rc = record_setup(env, llh, mti->mti_svname,
3233 "dev"/*ignored*/, "type"/*ignored*/,
3234 failout ? "n" : "f", NULL/*options*/);
3237 rc = record_marker(env, llh, fsdb, CM_END, mti->mti_svname, "add ost");
3241 record_end_log(env, &llh);
3244 /* We also have to update the other logs where this osc is part of
3248 if (test_bit(FSDB_OLDLOG14, &fsdb->fsdb_flags)) {
3249 /* If we're upgrading, the old mdt log already has our
3250 * entry. Let's do a fake one for fun.
3252 /* Note that we can't add any new failnids, since we don't
3253 * know the old osc names.
3255 flags = CM_SKIP | CM_UPGRADE146;
3256 } else if ((mti->mti_flags & LDD_F_UPDATE) != LDD_F_UPDATE) {
3257 /* If the update flag isn't set, don't update client/mdt
3261 LCONSOLE_WARN("Client log for %s was not updated; writeconf the MDT first to regenerate it.\n",
3265 /* Add ost to all MDT lov defs */
3266 for (i = 0; i < INDEX_MAP_SIZE * 8; i++) {
3267 if (test_bit(i, fsdb->fsdb_mdt_index_map)) {
3270 rc = name_create_mdt_and_lov(&logname, &lovname, fsdb,
3275 snprintf(mdt_index, sizeof(mdt_index), "-MDT%04x", i);
3276 rc = mgs_write_log_osc_to_lov(env, mgs, fsdb, mti,
3278 lovname, LUSTRE_SP_MDT,
3280 name_destroy(&logname);
3281 name_destroy(&lovname);
3287 /* Append ost info to the client log */
3288 rc = name_create(&logname, mti->mti_fsname, "-client");
3291 if (mgs_log_is_empty(env, mgs, logname)) {
3292 /* Start client log */
3293 rc = mgs_write_log_lov(env, mgs, fsdb, mti, logname,
3297 rc = mgs_write_log_lmv(env, mgs, fsdb, mti, logname,
3301 rc = mgs_write_log_mount_opt(env, mgs, fsdb, logname);
3305 rc = mgs_write_log_osc_to_lov(env, mgs, fsdb, mti, logname, "",
3306 fsdb->fsdb_clilov, LUSTRE_SP_CLI, flags);
3308 name_destroy(&logname);
3312 static __inline__ int mgs_param_empty(char *ptr)
3314 char *tmp = strchr(ptr, '=');
3316 if (tmp && tmp[1] == '\0')
3321 static int mgs_write_log_failnid_internal(const struct lu_env *env,
3322 struct mgs_device *mgs,
3324 struct mgs_target_info *mti,
3325 char *logname, char *cliname)
3328 struct llog_handle *llh = NULL;
3330 if (mgs_param_empty(mti->mti_params)) {
3331 /* Remove _all_ failnids */
3332 rc = mgs_modify(env, mgs, fsdb, mti, logname,
3333 mti->mti_svname, "add failnid", CM_SKIP);
3334 return rc < 0 ? rc : 0;
3337 /* Otherwise failover nids are additive */
3338 rc = record_start_log(env, mgs, &llh, logname);
3341 /* FIXME this should be a single journal transaction */
3342 rc = record_marker(env, llh, fsdb, CM_START, mti->mti_svname,
3346 rc = mgs_write_log_failnids(env, mti, llh, cliname);
3349 rc = record_marker(env, llh, fsdb, CM_END,
3350 mti->mti_svname, "add failnid");
3352 record_end_log(env, &llh);
3356 /* Add additional failnids to an existing log.
3357 The mdc/osc must have been added to logs first */
3358 /* tcp nids must be in dotted-quad ascii -
3359 we can't resolve hostnames from the kernel. */
3360 static int mgs_write_log_add_failnid(const struct lu_env *env,
3361 struct mgs_device *mgs,
3363 struct mgs_target_info *mti)
3365 char *logname, *cliname;
3369 /* FIXME we currently can't erase the failnids
3370 * given when a target first registers, since they aren't part of
3371 * an "add uuid" stanza
3374 /* Verify that we know about this target */
3375 if (mgs_log_is_empty(env, mgs, mti->mti_svname)) {
3376 LCONSOLE_ERROR_MSG(0x142,
3377 "The target %s has not registered yet. It must be started before failnids can be added.\n",
3382 /* Create mdc/osc client name (e.g. lustre-OST0001-osc) */
3383 if (mti->mti_flags & LDD_F_SV_TYPE_MDT)
3384 rc = name_create(&cliname, mti->mti_svname, "-mdc");
3385 else if (mti->mti_flags & LDD_F_SV_TYPE_OST)
3386 rc = name_create(&cliname, mti->mti_svname, "-osc");
3393 /* Add failover nids to the client log */
3394 rc = name_create(&logname, mti->mti_fsname, "-client");
3396 name_destroy(&cliname);
3400 rc = mgs_write_log_failnid_internal(env, mgs, fsdb,mti,logname,cliname);
3401 name_destroy(&logname);
3402 name_destroy(&cliname);
3406 if (mti->mti_flags & LDD_F_SV_TYPE_OST) {
3407 /* Add OST failover nids to the MDT logs as well */
3410 for (i = 0; i < INDEX_MAP_SIZE * 8; i++) {
3411 if (!test_bit(i, fsdb->fsdb_mdt_index_map))
3413 rc = name_create_mdt(&logname, mti->mti_fsname, i);
3416 rc = name_create_mdt_osc(&cliname, mti->mti_svname,
3419 name_destroy(&logname);
3422 rc = mgs_write_log_failnid_internal(env, mgs, fsdb,
3425 name_destroy(&cliname);
3426 name_destroy(&logname);
3435 static int mgs_wlp_lcfg(const struct lu_env *env,
3436 struct mgs_device *mgs, struct fs_db *fsdb,
3437 struct mgs_target_info *mti,
3438 char *logname, struct lustre_cfg_bufs *bufs,
3439 char *tgtname, char *ptr)
3441 char comment[MTI_NAME_MAXLEN];
3443 struct llog_cfg_rec *lcr;
3446 /* Erase any old settings of this same parameter */
3447 strlcpy(comment, ptr, sizeof(comment));
3448 /* But don't try to match the value. */
3449 tmp = strchr(comment, '=');
3452 /* FIXME we should skip settings that are the same as old values */
3453 rc = mgs_modify(env, mgs, fsdb, mti, logname, tgtname, comment,CM_SKIP);
3456 del = mgs_param_empty(ptr);
3458 LCONSOLE_INFO("%s parameter %s.%s in log %s\n", del ? "Disabling" : rc ?
3459 "Setting" : "Modifying", tgtname, comment, logname);
3461 /* mgs_modify() will return 1 if nothing had to be done */
3467 lustre_cfg_bufs_reset(bufs, tgtname);
3468 lustre_cfg_bufs_set_string(bufs, 1, ptr);
3469 if (mti->mti_flags & LDD_F_PARAM2)
3470 lustre_cfg_bufs_set_string(bufs, 2, LCTL_UPCALL);
3472 lcr = lustre_cfg_rec_new((mti->mti_flags & LDD_F_PARAM2) ?
3473 LCFG_SET_PARAM : LCFG_PARAM, bufs);
3477 rc = mgs_write_log_direct(env, mgs, fsdb, logname, lcr, tgtname,
3479 lustre_cfg_rec_free(lcr);
3483 /* write global variable settings into log */
3484 static int mgs_write_log_sys(const struct lu_env *env,
3485 struct mgs_device *mgs, struct fs_db *fsdb,
3486 struct mgs_target_info *mti, char *sys, char *ptr)
3488 struct mgs_thread_info *mgi = mgs_env_info(env);
3489 struct lustre_cfg *lcfg;
3490 struct llog_cfg_rec *lcr;
3492 int rc, cmd, convert = 1;
3494 if (class_match_param(ptr, PARAM_TIMEOUT, &tmp) == 0) {
3495 cmd = LCFG_SET_TIMEOUT;
3496 } else if (class_match_param(ptr, PARAM_LDLM_TIMEOUT, &tmp) == 0) {
3497 cmd = LCFG_SET_LDLM_TIMEOUT;
3498 /* Check for known params here so we can return error to lctl */
3499 } else if ((class_match_param(ptr, PARAM_AT_MIN, &tmp) == 0) ||
3500 (class_match_param(ptr, PARAM_AT_MAX, &tmp) == 0) ||
3501 (class_match_param(ptr, PARAM_AT_EXTRA, &tmp) == 0) ||
3502 (class_match_param(ptr, PARAM_AT_EARLY_MARGIN, &tmp) == 0) ||
3503 (class_match_param(ptr, PARAM_AT_HISTORY, &tmp) == 0)) {
3505 } else if (class_match_param(ptr, PARAM_JOBID_VAR, &tmp) == 0) {
3506 convert = 0; /* Don't convert string value to integer */
3512 if (mgs_param_empty(ptr))
3513 CDEBUG(D_MGS, "global '%s' removed\n", sys);
3515 CDEBUG(D_MGS, "global '%s' val=%s\n", sys, tmp);
3517 lustre_cfg_bufs_reset(&mgi->mgi_bufs, NULL);
3518 lustre_cfg_bufs_set_string(&mgi->mgi_bufs, 1, sys);
3519 if (!convert && *tmp != '\0')
3520 lustre_cfg_bufs_set_string(&mgi->mgi_bufs, 2, tmp);
3521 lcr = lustre_cfg_rec_new(cmd, &mgi->mgi_bufs);
3525 lcfg = &lcr->lcr_cfg;
3527 rc = kstrtouint(tmp, 0, &lcfg->lcfg_num);
3529 GOTO(out_rec_free, rc);
3534 /* truncate the comment to the parameter name */
3538 /* modify all servers and clients */
3539 rc = mgs_write_log_direct_all(env, mgs, fsdb, mti,
3540 *tmp == '\0' ? NULL : lcr,
3541 mti->mti_fsname, sys, 0);
3542 if (rc == 0 && *tmp != '\0') {
3544 case LCFG_SET_TIMEOUT:
3545 if (!obd_timeout_set || lcfg->lcfg_num > obd_timeout)
3546 class_process_config(lcfg);
3548 case LCFG_SET_LDLM_TIMEOUT:
3549 if (!ldlm_timeout_set || lcfg->lcfg_num > ldlm_timeout)
3550 class_process_config(lcfg);
3558 lustre_cfg_rec_free(lcr);
3562 /* write quota settings into log */
3563 static int mgs_write_log_quota(const struct lu_env *env, struct mgs_device *mgs,
3564 struct fs_db *fsdb, struct mgs_target_info *mti,
3565 char *quota, char *ptr)
3567 struct mgs_thread_info *mgi = mgs_env_info(env);
3568 struct llog_cfg_rec *lcr;
3571 int rc, cmd = LCFG_PARAM;
3573 /* support only 'meta' and 'data' pools so far */
3574 if (class_match_param(ptr, QUOTA_METAPOOL_NAME, &tmp) != 0 &&
3575 class_match_param(ptr, QUOTA_DATAPOOL_NAME, &tmp) != 0) {
3576 CERROR("parameter quota.%s isn't supported (only quota.mdt "
3577 "& quota.ost are)\n", ptr);
3582 CDEBUG(D_MGS, "global '%s' removed\n", quota);
3584 CDEBUG(D_MGS, "global '%s'\n", quota);
3586 if (strchr(tmp, 'u') == NULL && strchr(tmp, 'g') == NULL &&
3587 strchr(tmp, 'p') == NULL &&
3588 strcmp(tmp, "none") != 0) {
3589 CERROR("enable option(%s) isn't supported\n", tmp);
3594 lustre_cfg_bufs_reset(&mgi->mgi_bufs, mti->mti_fsname);
3595 lustre_cfg_bufs_set_string(&mgi->mgi_bufs, 1, quota);
3596 lcr = lustre_cfg_rec_new(cmd, &mgi->mgi_bufs);
3600 /* truncate the comment to the parameter name */
3605 /* XXX we duplicated quota enable information in all server
3606 * config logs, it should be moved to a separate config
3607 * log once we cleanup the config log for global param. */
3608 /* modify all servers */
3609 rc = mgs_write_log_direct_all(env, mgs, fsdb, mti,
3610 *tmp == '\0' ? NULL : lcr,
3611 mti->mti_fsname, quota, 1);
3613 lustre_cfg_rec_free(lcr);
3614 return rc < 0 ? rc : 0;
3617 static int mgs_srpc_set_param_disk(const struct lu_env *env,
3618 struct mgs_device *mgs,
3620 struct mgs_target_info *mti,
3623 struct mgs_thread_info *mgi = mgs_env_info(env);
3624 struct llog_cfg_rec *lcr;
3625 struct llog_handle *llh = NULL;
3627 char *comment, *ptr;
3633 ptr = strchr(param, '=');
3634 LASSERT(ptr != NULL);
3637 OBD_ALLOC(comment, len + 1);
3638 if (comment == NULL)
3640 strncpy(comment, param, len);
3641 comment[len] = '\0';
3644 lustre_cfg_bufs_reset(&mgi->mgi_bufs, mti->mti_svname);
3645 lustre_cfg_bufs_set_string(&mgi->mgi_bufs, 1, param);
3646 lcr = lustre_cfg_rec_new(LCFG_SPTLRPC_CONF, &mgi->mgi_bufs);
3648 GOTO(out_comment, rc = -ENOMEM);
3650 /* construct log name */
3651 rc = name_create(&logname, mti->mti_fsname, "-sptlrpc");
3655 if (mgs_log_is_empty(env, mgs, logname)) {
3656 rc = record_start_log(env, mgs, &llh, logname);
3659 record_end_log(env, &llh);
3662 /* obsolete old one */
3663 rc = mgs_modify(env, mgs, fsdb, mti, logname, mti->mti_svname,
3667 /* write the new one */
3668 rc = mgs_write_log_direct(env, mgs, fsdb, logname, lcr,
3669 mti->mti_svname, comment);
3671 CERROR("%s: error writing log %s: rc = %d\n",
3672 mgs->mgs_obd->obd_name, logname, rc);
3674 name_destroy(&logname);
3676 lustre_cfg_rec_free(lcr);
3678 OBD_FREE(comment, len + 1);
3682 static int mgs_srpc_set_param_udesc_mem(struct fs_db *fsdb,
3687 /* disable the adjustable udesc parameter for now, i.e. use default
3688 * setting that client always ship udesc to MDT if possible. to enable
3689 * it simply remove the following line
3693 ptr = strchr(param, '=');
3698 if (strcmp(param, PARAM_SRPC_UDESC))
3701 if (strcmp(ptr, "yes") == 0) {
3702 set_bit(FSDB_UDESC, &fsdb->fsdb_flags);
3703 CWARN("Enable user descriptor shipping from client to MDT\n");
3704 } else if (strcmp(ptr, "no") == 0) {
3705 clear_bit(FSDB_UDESC, &fsdb->fsdb_flags);
3706 CWARN("Disable user descriptor shipping from client to MDT\n");
3714 CERROR("Invalid param: %s\n", param);
3718 static int mgs_srpc_set_param_mem(struct fs_db *fsdb,
3722 struct sptlrpc_rule rule;
3723 struct sptlrpc_rule_set *rset;
3727 if (strncmp(param, PARAM_SRPC, sizeof(PARAM_SRPC) - 1) != 0) {
3728 CERROR("Invalid sptlrpc parameter: %s\n", param);
3732 if (strncmp(param, PARAM_SRPC_UDESC,
3733 sizeof(PARAM_SRPC_UDESC) - 1) == 0) {
3734 RETURN(mgs_srpc_set_param_udesc_mem(fsdb, param));
3737 if (strncmp(param, PARAM_SRPC_FLVR, sizeof(PARAM_SRPC_FLVR) - 1) != 0) {
3738 CERROR("Invalid sptlrpc flavor parameter: %s\n", param);
3742 param += sizeof(PARAM_SRPC_FLVR) - 1;
3744 rc = sptlrpc_parse_rule(param, &rule);
3748 /* mgs rules implies must be mgc->mgs */
3749 if (test_bit(FSDB_MGS_SELF, &fsdb->fsdb_flags)) {
3750 if ((rule.sr_from != LUSTRE_SP_MGC &&
3751 rule.sr_from != LUSTRE_SP_ANY) ||
3752 (rule.sr_to != LUSTRE_SP_MGS &&
3753 rule.sr_to != LUSTRE_SP_ANY))
3757 /* prepare room for this coming rule. svcname format should be:
3758 * - fsname: general rule
3759 * - fsname-tgtname: target-specific rule
3761 if (strchr(svname, '-')) {
3762 struct mgs_tgt_srpc_conf *tgtconf;
3765 for (tgtconf = fsdb->fsdb_srpc_tgt; tgtconf != NULL;
3766 tgtconf = tgtconf->mtsc_next) {
3767 if (!strcmp(tgtconf->mtsc_tgt, svname)) {
3776 OBD_ALLOC_PTR(tgtconf);
3777 if (tgtconf == NULL)
3780 name_len = strlen(svname);
3782 OBD_ALLOC(tgtconf->mtsc_tgt, name_len + 1);
3783 if (tgtconf->mtsc_tgt == NULL) {
3784 OBD_FREE_PTR(tgtconf);
3787 memcpy(tgtconf->mtsc_tgt, svname, name_len);
3789 tgtconf->mtsc_next = fsdb->fsdb_srpc_tgt;
3790 fsdb->fsdb_srpc_tgt = tgtconf;
3793 rset = &tgtconf->mtsc_rset;
3794 } else if (strcmp(svname, MGSSELF_NAME) == 0) {
3795 /* put _mgs related srpc rule directly in mgs ruleset */
3796 rset = &fsdb->fsdb_mgs->mgs_lut.lut_sptlrpc_rset;
3798 rset = &fsdb->fsdb_srpc_gen;
3801 rc = sptlrpc_rule_set_merge(rset, &rule);
3806 static int mgs_srpc_set_param(const struct lu_env *env,
3807 struct mgs_device *mgs,
3809 struct mgs_target_info *mti,
3819 /* keep a copy of original param, which could be destroyed
3822 copy_size = strlen(param) + 1;
3823 OBD_ALLOC(copy, copy_size);
3826 memcpy(copy, param, copy_size);
3828 rc = mgs_srpc_set_param_mem(fsdb, mti->mti_svname, param);
3832 /* previous steps guaranteed the syntax is correct */
3833 rc = mgs_srpc_set_param_disk(env, mgs, fsdb, mti, copy);
3837 if (test_bit(FSDB_MGS_SELF, &fsdb->fsdb_flags)) {
3839 * for mgs rules, make them effective immediately.
3841 LASSERT(fsdb->fsdb_srpc_tgt == NULL);
3842 sptlrpc_target_update_exp_flavor(mgs->mgs_obd,
3843 &fsdb->fsdb_srpc_gen);
3847 OBD_FREE(copy, copy_size);
3851 struct mgs_srpc_read_data {
3852 struct fs_db *msrd_fsdb;
3856 static int mgs_srpc_read_handler(const struct lu_env *env,
3857 struct llog_handle *llh,
3858 struct llog_rec_hdr *rec, void *data)
3860 struct mgs_srpc_read_data *msrd = data;
3861 struct cfg_marker *marker;
3862 struct lustre_cfg *lcfg = REC_DATA(rec);
3863 char *svname, *param;
3867 if (rec->lrh_type != OBD_CFG_REC) {
3868 CERROR("unhandled lrh_type: %#x\n", rec->lrh_type);
3872 cfg_len = REC_DATA_LEN(rec);
3874 rc = lustre_cfg_sanity_check(lcfg, cfg_len);
3876 CERROR("Insane cfg\n");
3880 if (lcfg->lcfg_command == LCFG_MARKER) {
3881 marker = lustre_cfg_buf(lcfg, 1);
3883 if (marker->cm_flags & CM_START &&
3884 marker->cm_flags & CM_SKIP)
3885 msrd->msrd_skip = 1;
3886 if (marker->cm_flags & CM_END)
3887 msrd->msrd_skip = 0;
3892 if (msrd->msrd_skip)
3895 if (lcfg->lcfg_command != LCFG_SPTLRPC_CONF) {
3896 CERROR("invalid command (%x)\n", lcfg->lcfg_command);
3900 svname = lustre_cfg_string(lcfg, 0);
3901 if (svname == NULL) {
3902 CERROR("svname is empty\n");
3906 param = lustre_cfg_string(lcfg, 1);
3907 if (param == NULL) {
3908 CERROR("param is empty\n");
3912 rc = mgs_srpc_set_param_mem(msrd->msrd_fsdb, svname, param);
3914 CERROR("read sptlrpc record error (%d): %s\n", rc, param);
3919 int mgs_get_fsdb_srpc_from_llog(const struct lu_env *env,
3920 struct mgs_device *mgs,
3923 struct llog_handle *llh = NULL;
3924 struct llog_ctxt *ctxt;
3926 struct mgs_srpc_read_data msrd;
3930 /* construct log name */
3931 rc = name_create(&logname, fsdb->fsdb_name, "-sptlrpc");
3935 ctxt = llog_get_context(mgs->mgs_obd, LLOG_CONFIG_ORIG_CTXT);
3936 LASSERT(ctxt != NULL);
3938 if (mgs_log_is_empty(env, mgs, logname))
3941 rc = llog_open(env, ctxt, &llh, NULL, logname,
3949 rc = llog_init_handle(env, llh, LLOG_F_IS_PLAIN, NULL);
3951 GOTO(out_close, rc);
3953 if (llog_get_size(llh) <= 1)
3954 GOTO(out_close, rc = 0);
3956 msrd.msrd_fsdb = fsdb;
3959 rc = llog_process(env, llh, mgs_srpc_read_handler, (void *)&msrd,
3963 llog_close(env, llh);
3965 llog_ctxt_put(ctxt);
3966 name_destroy(&logname);
3969 CERROR("failed to read sptlrpc config database: %d\n", rc);
3973 static int mgs_write_log_param2(const struct lu_env *env,
3974 struct mgs_device *mgs,
3976 struct mgs_target_info *mti, char *ptr)
3978 struct lustre_cfg_bufs bufs;
3982 CDEBUG(D_MGS, "next param '%s'\n", ptr);
3984 /* PARAM_MGSNODE and PARAM_NETWORK are set only when formating
3985 * or during the inital mount. It can never change after that.
3987 if (!class_match_param(ptr, PARAM_MGSNODE, NULL) ||
3988 !class_match_param(ptr, PARAM_NETWORK, NULL)) {
3993 /* Processed in mgs_write_log_ost. Another value that can't
3994 * be changed by lctl set_param -P.
3996 if (!class_match_param(ptr, PARAM_FAILMODE, NULL)) {
3997 LCONSOLE_ERROR_MSG(0x169,
3998 "%s can only be changed with tunefs.lustre and --writeconf\n",
4004 /* FIXME !!! Support for sptlrpc is incomplete. Currently the change
4005 * doesn't transmit to the client. See LU-7183.
4007 if (!class_match_param(ptr, PARAM_SRPC, NULL)) {
4008 rc = mgs_srpc_set_param(env, mgs, fsdb, mti, ptr);
4012 /* Can't use class_match_param since ptr doesn't start with
4013 * PARAM_FAILNODE. So we look for PARAM_FAILNODE contained in ptr.
4015 if (strstr(ptr, PARAM_FAILNODE)) {
4016 /* Add a failover nidlist. We already processed failovers
4017 * params for new targets in mgs_write_log_target.
4021 /* can't use wildcards with failover.node */
4022 if (strchr(ptr, '*')) {
4027 param = strstr(ptr, PARAM_FAILNODE);
4028 if (strlcpy(mti->mti_params, param, sizeof(mti->mti_params)) >=
4029 sizeof(mti->mti_params)) {
4034 CDEBUG(D_MGS, "Adding failnode with param %s\n",
4036 rc = mgs_write_log_add_failnid(env, mgs, fsdb, mti);
4040 /* root squash parameters must not be set on llite subsystem, this can
4041 * lead to inconsistencies between client and server values
4043 if ((strstr(ptr, PARAM_NOSQUASHNIDS) ||
4044 strstr(ptr, PARAM_ROOTSQUASH)) &&
4045 strncmp(ptr, "llite.", strlen("llite.")) == 0) {
4047 CWARN("%s: cannot add %s param to llite subsystem, use mdt instead: rc=%d\n",
4048 mgs->mgs_obd->obd_name,
4049 strstr(ptr, PARAM_ROOTSQUASH) ?
4050 PARAM_ROOTSQUASH : PARAM_NOSQUASHNIDS,
4055 rc = mgs_wlp_lcfg(env, mgs, fsdb, mti, PARAMS_FILENAME, &bufs,
4056 mti->mti_svname, ptr);
4061 /* Permanent settings of all parameters by writing into the appropriate
4062 * configuration logs.
4063 * A parameter with null value ("<param>='\0'") means to erase it out of
4066 static int mgs_write_log_param(const struct lu_env *env,
4067 struct mgs_device *mgs, struct fs_db *fsdb,
4068 struct mgs_target_info *mti, char *ptr)
4070 struct mgs_thread_info *mgi = mgs_env_info(env);
4076 /* For various parameter settings, we have to figure out which logs
4077 * care about them (e.g. both mdt and client for lov settings)
4079 CDEBUG(D_MGS, "next param '%s'\n", ptr);
4081 /* The params are stored in MOUNT_DATA_FILE and modified via
4082 * tunefs.lustre, or set using lctl conf_param
4085 /* Processed in lustre_start_mgc */
4086 if (class_match_param(ptr, PARAM_MGSNODE, NULL) == 0)
4089 /* Processed in ost/mdt */
4090 if (class_match_param(ptr, PARAM_NETWORK, NULL) == 0)
4093 /* Processed in mgs_write_log_ost */
4094 if (class_match_param(ptr, PARAM_FAILMODE, NULL) == 0) {
4095 if (mti->mti_flags & LDD_F_PARAM) {
4096 LCONSOLE_ERROR_MSG(0x169,
4097 "%s can only be changed with tunefs.lustre and --writeconf\n",
4104 if (class_match_param(ptr, PARAM_SRPC, NULL) == 0) {
4105 rc = mgs_srpc_set_param(env, mgs, fsdb, mti, ptr);
4109 if (class_match_param(ptr, PARAM_FAILNODE, NULL) == 0) {
4110 /* Add a failover nidlist */
4112 /* We already processed failovers params for new
4113 * targets in mgs_write_log_target
4115 if (mti->mti_flags & LDD_F_PARAM) {
4116 CDEBUG(D_MGS, "Adding failnode\n");
4117 rc = mgs_write_log_add_failnid(env, mgs, fsdb, mti);
4122 if (class_match_param(ptr, PARAM_SYS, &tmp) == 0) {
4123 rc = mgs_write_log_sys(env, mgs, fsdb, mti, ptr, tmp);
4127 if (class_match_param(ptr, PARAM_QUOTA, &tmp) == 0) {
4128 rc = mgs_write_log_quota(env, mgs, fsdb, mti, ptr, tmp);
4132 if (class_match_param(ptr, PARAM_OSC PARAM_ACTIVE, &tmp) == 0 ||
4133 class_match_param(ptr, PARAM_MDC PARAM_ACTIVE, &tmp) == 0) {
4134 /* active=0 means off, anything else means on */
4135 int flag = (*tmp == '0') ? CM_EXCLUDE : 0;
4136 bool deactive_osc = memcmp(ptr, PARAM_OSC PARAM_ACTIVE,
4137 strlen(PARAM_OSC PARAM_ACTIVE)) == 0;
4140 if (!deactive_osc) {
4143 rc = server_name2index(mti->mti_svname, &index, NULL);
4148 LCONSOLE_ERROR_MSG(0x144, "%s: MDC0 can not be"
4149 " (de)activated.\n",
4151 GOTO(end, rc = -EPERM);
4155 LCONSOLE_WARN("Permanently %sactivating %s\n",
4156 flag ? "de" : "re", mti->mti_svname);
4158 rc = name_create(&logname, mti->mti_fsname, "-client");
4161 rc = mgs_modify(env, mgs, fsdb, mti, logname,
4163 deactive_osc ? "add osc" : "add mdc", flag);
4164 name_destroy(&logname);
4169 /* Add to all MDT logs for DNE */
4170 for (i = 0; i < INDEX_MAP_SIZE * 8; i++) {
4171 if (!test_bit(i, fsdb->fsdb_mdt_index_map))
4173 rc = name_create_mdt(&logname, mti->mti_fsname, i);
4176 rc = mgs_modify(env, mgs, fsdb, mti, logname,
4178 deactive_osc ? "add osc" : "add osp",
4180 name_destroy(&logname);
4186 LCONSOLE_ERROR_MSG(0x145,
4187 "Couldn't find %s in log (%d). No permanent changes were made to the config log.\n",
4188 mti->mti_svname, rc);
4189 if (test_bit(FSDB_OLDLOG14, &fsdb->fsdb_flags))
4190 LCONSOLE_ERROR_MSG(0x146,
4191 "This may be because the log is in the old 1.4 style. Consider --writeconf to update the logs.\n");
4194 /* Fall through to osc/mdc proc for deactivating live
4195 * OSC/OSP on running MDT / clients.
4198 /* Below here, let obd's XXX_process_config methods handle it */
4200 /* All lov. in proc */
4201 if (class_match_param(ptr, PARAM_LOV, NULL) == 0) {
4204 CDEBUG(D_MGS, "lov param %s\n", ptr);
4205 if (!(mti->mti_flags & LDD_F_SV_TYPE_MDT)) {
4206 LCONSOLE_ERROR_MSG(0x147,
4207 "LOV params must be set on the MDT, not %s. Ignoring.\n",
4213 if (mgs_log_is_empty(env, mgs, mti->mti_svname))
4214 GOTO(end, rc = -ENODEV);
4216 rc = name_create_mdt_and_lov(&logname, &mdtlovname, fsdb,
4217 mti->mti_stripe_index);
4220 rc = mgs_wlp_lcfg(env, mgs, fsdb, mti, mti->mti_svname,
4221 &mgi->mgi_bufs, mdtlovname, ptr);
4222 name_destroy(&logname);
4223 name_destroy(&mdtlovname);
4228 rc = name_create(&logname, mti->mti_fsname, "-client");
4231 rc = mgs_wlp_lcfg(env, mgs, fsdb, mti, logname, &mgi->mgi_bufs,
4232 fsdb->fsdb_clilov, ptr);
4233 name_destroy(&logname);
4237 /* All osc., mdc., llite. params in proc */
4238 if ((class_match_param(ptr, PARAM_OSC, NULL) == 0) ||
4239 (class_match_param(ptr, PARAM_MDC, NULL) == 0) ||
4240 (class_match_param(ptr, PARAM_LLITE, NULL) == 0)) {
4243 if (test_bit(FSDB_OLDLOG14, &fsdb->fsdb_flags)) {
4244 LCONSOLE_ERROR_MSG(0x148, "Upgraded client logs for %s"
4245 " cannot be modified. Consider"
4246 " updating the configuration with"
4249 GOTO(end, rc = -EINVAL);
4251 if (memcmp(ptr, PARAM_LLITE, strlen(PARAM_LLITE)) == 0) {
4252 rc = name_create(&cname, mti->mti_fsname, "-client");
4253 /* Add the client type to match the obdname in
4254 * class_config_llog_handler
4256 } else if (mti->mti_flags & LDD_F_SV_TYPE_MDT) {
4257 rc = name_create(&cname, mti->mti_svname, "-mdc");
4258 } else if (mti->mti_flags & LDD_F_SV_TYPE_OST) {
4259 rc = name_create(&cname, mti->mti_svname, "-osc");
4261 GOTO(end, rc = -EINVAL);
4266 /* Forbid direct update of llite root squash parameters.
4267 * These parameters are indirectly set via the MDT settings.
4269 if ((class_match_param(ptr, PARAM_LLITE, &tmp) == 0) &&
4270 ((memcmp(tmp, "root_squash=", 12) == 0) ||
4271 (memcmp(tmp, "nosquash_nids=", 14) == 0))) {
4272 LCONSOLE_ERROR("%s: root squash parameters can only "
4273 "be updated through MDT component\n",
4275 name_destroy(&cname);
4276 GOTO(end, rc = -EINVAL);
4279 CDEBUG(D_MGS, "%.3s param %s\n", ptr, ptr + 4);
4282 rc = name_create(&logname, mti->mti_fsname, "-client");
4284 name_destroy(&cname);
4287 rc = mgs_wlp_lcfg(env, mgs, fsdb, mti, logname, &mgi->mgi_bufs,
4290 /* osc params affect the MDT as well */
4291 if (!rc && (mti->mti_flags & LDD_F_SV_TYPE_OST)) {
4294 for (i = 0; i < INDEX_MAP_SIZE * 8; i++) {
4295 if (!test_bit(i, fsdb->fsdb_mdt_index_map))
4297 name_destroy(&cname);
4298 rc = name_create_mdt_osc(&cname, mti->mti_svname,
4300 name_destroy(&logname);
4303 rc = name_create_mdt(&logname,
4304 mti->mti_fsname, i);
4307 if (!mgs_log_is_empty(env, mgs, logname)) {
4308 rc = mgs_wlp_lcfg(env, mgs, fsdb,
4318 /* For mdc activate/deactivate, it affects OSP on MDT as well */
4319 if (class_match_param(ptr, PARAM_MDC PARAM_ACTIVE, &tmp) == 0 &&
4322 char *lodname = NULL;
4323 char *param_str = NULL;
4327 /* replace mdc with osp */
4328 memcpy(ptr, PARAM_OSP, strlen(PARAM_OSP));
4329 rc = server_name2index(mti->mti_svname, &index, NULL);
4331 memcpy(ptr, PARAM_MDC, strlen(PARAM_MDC));
4335 for (i = 0; i < INDEX_MAP_SIZE * 8; i++) {
4336 if (!test_bit(i, fsdb->fsdb_mdt_index_map))
4342 name_destroy(&logname);
4343 rc = name_create_mdt(&logname, mti->mti_fsname,
4348 if (mgs_log_is_empty(env, mgs, logname))
4351 snprintf(suffix, sizeof(suffix), "-osp-MDT%04x",
4353 name_destroy(&cname);
4354 rc = name_create(&cname, mti->mti_svname,
4359 rc = mgs_wlp_lcfg(env, mgs, fsdb, mti, logname,
4360 &mgi->mgi_bufs, cname, ptr);
4364 /* Add configuration log for noitfying LOD
4365 * to active/deactive the OSP. */
4366 name_destroy(¶m_str);
4367 rc = name_create(¶m_str, cname,
4368 (*tmp == '0') ? ".active=0" :
4373 name_destroy(&lodname);
4374 rc = name_create(&lodname, logname, "-mdtlov");
4378 rc = mgs_wlp_lcfg(env, mgs, fsdb, mti, logname,
4379 &mgi->mgi_bufs, lodname,
4384 memcpy(ptr, PARAM_MDC, strlen(PARAM_MDC));
4385 name_destroy(&lodname);
4386 name_destroy(¶m_str);
4389 name_destroy(&logname);
4390 name_destroy(&cname);
4394 /* All mdt. params in proc */
4395 if (class_match_param(ptr, PARAM_MDT, &tmp) == 0) {
4399 CDEBUG(D_MGS, "%.3s param %s\n", ptr, ptr + 4);
4400 if (strncmp(mti->mti_svname, mti->mti_fsname,
4401 MTI_NAME_MAXLEN) == 0)
4402 /* device is unspecified completely? */
4403 rc = LDD_F_SV_TYPE_MDT | LDD_F_SV_ALL;
4405 rc = server_name2index(mti->mti_svname, &idx, NULL);
4408 if ((rc & LDD_F_SV_TYPE_MDT) == 0)
4410 if (rc & LDD_F_SV_ALL) {
4411 for (i = 0; i < INDEX_MAP_SIZE * 8; i++) {
4413 fsdb->fsdb_mdt_index_map))
4415 rc = name_create_mdt(&logname,
4416 mti->mti_fsname, i);
4419 rc = mgs_wlp_lcfg(env, mgs, fsdb, mti,
4420 logname, &mgi->mgi_bufs,
4422 name_destroy(&logname);
4427 if ((memcmp(tmp, "root_squash=", 12) == 0) ||
4428 (memcmp(tmp, "nosquash_nids=", 14) == 0)) {
4429 LCONSOLE_ERROR("%s: root squash parameters "
4430 "cannot be applied to a single MDT\n",
4432 GOTO(end, rc = -EINVAL);
4434 rc = mgs_wlp_lcfg(env, mgs, fsdb, mti,
4435 mti->mti_svname, &mgi->mgi_bufs,
4436 mti->mti_svname, ptr);
4441 /* root squash settings are also applied to llite
4442 * config log (see LU-1778) */
4444 ((memcmp(tmp, "root_squash=", 12) == 0) ||
4445 (memcmp(tmp, "nosquash_nids=", 14) == 0))) {
4449 rc = name_create(&cname, mti->mti_fsname, "-client");
4452 rc = name_create(&logname, mti->mti_fsname, "-client");
4454 name_destroy(&cname);
4457 rc = name_create(&ptr2, PARAM_LLITE, tmp);
4459 name_destroy(&cname);
4460 name_destroy(&logname);
4463 rc = mgs_wlp_lcfg(env, mgs, fsdb, mti, logname,
4464 &mgi->mgi_bufs, cname, ptr2);
4465 name_destroy(&ptr2);
4466 name_destroy(&logname);
4467 name_destroy(&cname);
4472 /* All mdd., ost. and osd. params in proc */
4473 if ((class_match_param(ptr, PARAM_MDD, NULL) == 0) ||
4474 (class_match_param(ptr, PARAM_LOD, NULL) == 0) ||
4475 (class_match_param(ptr, PARAM_OST, NULL) == 0) ||
4476 (class_match_param(ptr, PARAM_OSD, NULL) == 0)) {
4477 CDEBUG(D_MGS, "%.3s param %s\n", ptr, ptr + 4);
4478 if (mgs_log_is_empty(env, mgs, mti->mti_svname))
4479 GOTO(end, rc = -ENODEV);
4481 rc = mgs_wlp_lcfg(env, mgs, fsdb, mti, mti->mti_svname,
4482 &mgi->mgi_bufs, mti->mti_svname, ptr);
4486 /* For handling degraded zfs OST */
4487 if (class_match_param(ptr, PARAM_AUTODEGRADE, NULL) == 0)
4490 LCONSOLE_WARN("Ignoring unrecognized param '%s'\n", ptr);
4494 CERROR("err %d on param '%s'\n", rc, ptr);
4499 int mgs_write_log_target(const struct lu_env *env, struct mgs_device *mgs,
4500 struct mgs_target_info *mti, struct fs_db *fsdb)
4507 /* set/check the new target index */
4508 rc = mgs_set_index(env, mgs, mti);
4512 if (rc == EALREADY) {
4513 LCONSOLE_WARN("Found index %d for %s, updating log\n",
4514 mti->mti_stripe_index, mti->mti_svname);
4515 /* We would like to mark old log sections as invalid
4516 and add new log sections in the client and mdt logs.
4517 But if we add new sections, then live clients will
4518 get repeat setup instructions for already running
4519 osc's. So don't update the client/mdt logs. */
4520 mti->mti_flags &= ~LDD_F_UPDATE;
4524 CFS_FAIL_TIMEOUT(OBD_FAIL_MGS_WRITE_TARGET_DELAY, cfs_fail_val > 0 ?
4527 mutex_lock(&fsdb->fsdb_mutex);
4529 if (mti->mti_flags & (LDD_F_VIRGIN | LDD_F_WRITECONF)) {
4530 /* Generate a log from scratch */
4531 if (mti->mti_flags & LDD_F_SV_TYPE_MDT) {
4532 rc = mgs_write_log_mdt(env, mgs, fsdb, mti);
4533 } else if (mti->mti_flags & LDD_F_SV_TYPE_OST) {
4534 rc = mgs_write_log_ost(env, mgs, fsdb, mti);
4536 CERROR("Unknown target type %#x, can't create log for %s\n",
4537 mti->mti_flags, mti->mti_svname);
4540 CERROR("Can't write logs for %s (%d)\n",
4541 mti->mti_svname, rc);
4545 /* Just update the params from tunefs in mgs_write_log_params */
4546 CDEBUG(D_MGS, "Update params for %s\n", mti->mti_svname);
4547 mti->mti_flags |= LDD_F_PARAM;
4550 /* allocate temporary buffer, where class_get_next_param will
4551 * make copy of a current parameter
4553 OBD_ALLOC(buf, strlen(mti->mti_params) + 1);
4555 GOTO(out_up, rc = -ENOMEM);
4556 params = mti->mti_params;
4557 while (params != NULL) {
4558 rc = class_get_next_param(¶ms, buf);
4561 /* there is no next parameter, that is
4567 CDEBUG(D_MGS, "remaining string: '%s', param: '%s'\n",
4569 rc = mgs_write_log_param(env, mgs, fsdb, mti, buf);
4574 OBD_FREE(buf, strlen(mti->mti_params) + 1);
4577 mutex_unlock(&fsdb->fsdb_mutex);
4581 int mgs_erase_log(const struct lu_env *env, struct mgs_device *mgs, char *name)
4583 struct llog_ctxt *ctxt;
4586 ctxt = llog_get_context(mgs->mgs_obd, LLOG_CONFIG_ORIG_CTXT);
4588 CERROR("%s: MGS config context doesn't exist\n",
4589 mgs->mgs_obd->obd_name);
4592 rc = llog_erase(env, ctxt, NULL, name);
4593 /* llog may not exist */
4596 llog_ctxt_put(ctxt);
4600 CERROR("%s: failed to clear log %s: %d\n",
4601 mgs->mgs_obd->obd_name, name, rc);
4606 /* erase all logs for the given fs */
4607 int mgs_erase_logs(const struct lu_env *env, struct mgs_device *mgs,
4610 struct list_head log_list;
4611 struct mgs_direntry *dirent, *n;
4612 char barrier_name[20] = {};
4615 int rc, len = strlen(fsname);
4618 mutex_lock(&mgs->mgs_mutex);
4620 /* Find all the logs in the CONFIGS directory */
4621 rc = class_dentry_readdir(env, mgs, &log_list);
4623 mutex_unlock(&mgs->mgs_mutex);
4627 if (list_empty(&log_list)) {
4628 mutex_unlock(&mgs->mgs_mutex);
4632 snprintf(barrier_name, sizeof(barrier_name) - 1, "%s-%s",
4633 fsname, BARRIER_FILENAME);
4634 /* Delete the barrier fsdb */
4635 mgs_remove_fsdb_by_name(mgs, barrier_name);
4636 /* Delete the fs db */
4637 mgs_remove_fsdb_by_name(mgs, fsname);
4638 mutex_unlock(&mgs->mgs_mutex);
4640 list_for_each_entry_safe(dirent, n, &log_list, mde_list) {
4641 list_del_init(&dirent->mde_list);
4642 suffix = strrchr(dirent->mde_name, '-');
4643 if (suffix != NULL) {
4644 if ((len == suffix - dirent->mde_name) &&
4645 (strncmp(fsname, dirent->mde_name, len) == 0)) {
4646 CDEBUG(D_MGS, "Removing log %s\n",
4648 mgs_erase_log(env, mgs, dirent->mde_name);
4652 mgs_direntry_free(dirent);
4661 /* list all logs for the given fs */
4662 int mgs_list_logs(const struct lu_env *env, struct mgs_device *mgs,
4663 struct obd_ioctl_data *data)
4665 struct list_head log_list;
4666 struct mgs_direntry *dirent, *n;
4667 char *out, *suffix, prefix[] = "config_log: ";
4668 int prefix_len = strlen(prefix);
4669 int len, remains, start = 0, rc;
4673 /* Find all the logs in the CONFIGS directory */
4674 rc = class_dentry_readdir(env, mgs, &log_list);
4678 out = data->ioc_bulk;
4679 remains = data->ioc_inllen1;
4680 /* OBD_FAIL: fetch the config_log records from the specified one */
4681 if (CFS_FAIL_CHECK(OBD_FAIL_CATLIST))
4682 data->ioc_count = cfs_fail_val;
4684 list_for_each_entry_safe(dirent, n, &log_list, mde_list) {
4685 list_del_init(&dirent->mde_list);
4686 suffix = strrchr(dirent->mde_name, '-');
4687 if (suffix != NULL) {
4688 len = prefix_len + dirent->mde_len + 1;
4689 if (remains - len < 0) {
4690 /* No enough space for this record */
4691 mgs_direntry_free(dirent);
4695 if (start < data->ioc_count) {
4696 mgs_direntry_free(dirent);
4699 len = scnprintf(out, remains, "%s%s\n", prefix,
4704 mgs_direntry_free(dirent);
4712 data->ioc_count = start;
4716 struct mgs_lcfg_fork_data {
4717 struct lustre_cfg_bufs mlfd_bufs;
4718 struct mgs_device *mlfd_mgs;
4719 struct llog_handle *mlfd_llh;
4720 const char *mlfd_oldname;
4721 const char *mlfd_newname;
4725 static bool contain_valid_fsname(char *buf, const char *fsname,
4726 int buflen, int namelen)
4728 if (buflen < namelen)
4731 if (memcmp(buf, fsname, namelen) != 0)
4734 if (buf[namelen] != '\0' && buf[namelen] != '-')
4740 static int mgs_lcfg_fork_handler(const struct lu_env *env,
4741 struct llog_handle *o_llh,
4742 struct llog_rec_hdr *o_rec, void *data)
4744 struct mgs_lcfg_fork_data *mlfd = data;
4745 struct lustre_cfg_bufs *n_bufs = &mlfd->mlfd_bufs;
4746 struct lustre_cfg *o_lcfg = (struct lustre_cfg *)(o_rec + 1);
4747 struct llog_cfg_rec *lcr;
4749 char *n_buf = mlfd->mlfd_data;
4751 int o_namelen = strlen(mlfd->mlfd_oldname);
4752 int n_namelen = strlen(mlfd->mlfd_newname);
4753 int diff = n_namelen - o_namelen;
4754 __u32 cmd = o_lcfg->lcfg_command;
4755 __u32 cnt = o_lcfg->lcfg_bufcount;
4761 o_buf = lustre_cfg_buf(o_lcfg, 0);
4762 o_buflen = o_lcfg->lcfg_buflens[0];
4763 if (contain_valid_fsname(o_buf, mlfd->mlfd_oldname, o_buflen,
4765 memcpy(n_buf, mlfd->mlfd_newname, n_namelen);
4766 memcpy(n_buf + n_namelen, o_buf + o_namelen,
4767 o_buflen - o_namelen);
4768 lustre_cfg_bufs_reset(n_bufs, n_buf);
4769 n_buf += round_up(o_buflen + diff, 8);
4771 lustre_cfg_bufs_reset(n_bufs, o_buflen != 0 ? o_buf : NULL);
4776 struct cfg_marker *o_marker;
4777 struct cfg_marker *n_marker;
4781 CDEBUG(D_MGS, "Unknown cfg marker entry with %d "
4786 /* buf[1] is marker */
4787 o_buf = lustre_cfg_buf(o_lcfg, 1);
4788 o_buflen = o_lcfg->lcfg_buflens[1];
4789 o_marker = (struct cfg_marker *)o_buf;
4790 if (!contain_valid_fsname(o_marker->cm_tgtname,
4792 sizeof(o_marker->cm_tgtname),
4794 lustre_cfg_bufs_set(n_bufs, 1, o_marker,
4799 n_marker = (struct cfg_marker *)n_buf;
4800 *n_marker = *o_marker;
4801 memcpy(n_marker->cm_tgtname, mlfd->mlfd_newname, n_namelen);
4802 tgt_namelen = strlen(o_marker->cm_tgtname);
4803 if (tgt_namelen > o_namelen)
4804 memcpy(n_marker->cm_tgtname + n_namelen,
4805 o_marker->cm_tgtname + o_namelen,
4806 tgt_namelen - o_namelen);
4807 n_marker->cm_tgtname[tgt_namelen + diff] = '\0';
4808 lustre_cfg_bufs_set(n_bufs, 1, n_marker, sizeof(*n_marker));
4812 case LCFG_SET_PARAM: {
4813 for (i = 1; i < cnt; i++)
4814 /* buf[i] is the param value, reuse it directly */
4815 lustre_cfg_bufs_set(n_bufs, i,
4816 lustre_cfg_buf(o_lcfg, i),
4817 o_lcfg->lcfg_buflens[i]);
4823 case LCFG_POOL_DEL: {
4824 if (cnt < 3 || cnt > 4) {
4825 CDEBUG(D_MGS, "Unknown cfg pool (%x) entry with %d "
4826 "buffers\n", cmd, cnt);
4830 /* buf[1] is fsname */
4831 o_buf = lustre_cfg_buf(o_lcfg, 1);
4832 o_buflen = o_lcfg->lcfg_buflens[1];
4833 memcpy(n_buf, mlfd->mlfd_newname, n_namelen);
4834 memcpy(n_buf + n_namelen, o_buf + o_namelen,
4835 o_buflen - o_namelen);
4836 lustre_cfg_bufs_set(n_bufs, 1, n_buf, o_buflen + diff);
4837 n_buf += round_up(o_buflen + diff, 8);
4839 /* buf[2] is the pool name, reuse it directly */
4840 lustre_cfg_bufs_set(n_bufs, 2, lustre_cfg_buf(o_lcfg, 2),
4841 o_lcfg->lcfg_buflens[2]);
4846 /* buf[3] is ostname */
4847 o_buf = lustre_cfg_buf(o_lcfg, 3);
4848 o_buflen = o_lcfg->lcfg_buflens[3];
4849 memcpy(n_buf, mlfd->mlfd_newname, n_namelen);
4850 memcpy(n_buf + n_namelen, o_buf + o_namelen,
4851 o_buflen - o_namelen);
4852 lustre_cfg_bufs_set(n_bufs, 3, n_buf, o_buflen + diff);
4857 o_buflen = o_lcfg->lcfg_buflens[1];
4858 if (o_buflen == sizeof(struct lov_desc) ||
4859 o_buflen == sizeof(struct lmv_desc)) {
4865 o_buf = lustre_cfg_buf(o_lcfg, 1);
4866 if (o_buflen == sizeof(struct lov_desc)) {
4867 struct lov_desc *o_desc =
4868 (struct lov_desc *)o_buf;
4869 struct lov_desc *n_desc =
4870 (struct lov_desc *)n_buf;
4873 o_uuid = o_desc->ld_uuid.uuid;
4874 n_uuid = n_desc->ld_uuid.uuid;
4875 uuid_len = sizeof(o_desc->ld_uuid.uuid);
4877 struct lmv_desc *o_desc =
4878 (struct lmv_desc *)o_buf;
4879 struct lmv_desc *n_desc =
4880 (struct lmv_desc *)n_buf;
4883 o_uuid = o_desc->ld_uuid.uuid;
4884 n_uuid = n_desc->ld_uuid.uuid;
4885 uuid_len = sizeof(o_desc->ld_uuid.uuid);
4888 if (unlikely(!contain_valid_fsname(o_uuid,
4889 mlfd->mlfd_oldname, uuid_len,
4891 lustre_cfg_bufs_set(n_bufs, 1, o_buf,
4896 memcpy(n_uuid, mlfd->mlfd_newname, n_namelen);
4897 uuid_len = strlen(o_uuid);
4898 if (uuid_len > o_namelen)
4899 memcpy(n_uuid + n_namelen,
4901 uuid_len - o_namelen);
4902 n_uuid[uuid_len + diff] = '\0';
4903 lustre_cfg_bufs_set(n_bufs, 1, n_buf, o_buflen);
4905 } /* else case fall through */
4906 } /* else case fall through */
4910 for (i = 1; i < cnt; i++) {
4911 o_buflen = o_lcfg->lcfg_buflens[i];
4915 o_buf = lustre_cfg_buf(o_lcfg, i);
4916 if (!contain_valid_fsname(o_buf, mlfd->mlfd_oldname,
4917 o_buflen, o_namelen)) {
4918 lustre_cfg_bufs_set(n_bufs, i, o_buf, o_buflen);
4922 memcpy(n_buf, mlfd->mlfd_newname, n_namelen);
4923 if (o_buflen == o_namelen) {
4924 lustre_cfg_bufs_set(n_bufs, i, n_buf,
4926 n_buf += round_up(n_namelen, 8);
4930 memcpy(n_buf + n_namelen, o_buf + o_namelen,
4931 o_buflen - o_namelen);
4932 lustre_cfg_bufs_set(n_bufs, i, n_buf, o_buflen + diff);
4933 n_buf += round_up(o_buflen + diff, 8);
4939 lcr = lustre_cfg_rec_new(cmd, n_bufs);
4943 lcr->lcr_cfg = *o_lcfg;
4944 rc = llog_write(env, mlfd->mlfd_llh, &lcr->lcr_hdr, LLOG_NEXT_IDX);
4945 lustre_cfg_rec_free(lcr);
4950 static int mgs_lcfg_fork_one(const struct lu_env *env, struct mgs_device *mgs,
4951 struct mgs_direntry *mde, const char *oldname,
4952 const char *newname)
4954 struct llog_handle *old_llh = NULL;
4955 struct llog_handle *new_llh = NULL;
4956 struct llog_ctxt *ctxt = NULL;
4957 struct mgs_lcfg_fork_data *mlfd = NULL;
4958 char *name_buf = NULL;
4960 int old_namelen = strlen(oldname);
4961 int new_namelen = strlen(newname);
4965 name_buflen = mde->mde_len + new_namelen - old_namelen;
4966 OBD_ALLOC(name_buf, name_buflen);
4970 memcpy(name_buf, newname, new_namelen);
4971 memcpy(name_buf + new_namelen, mde->mde_name + old_namelen,
4972 mde->mde_len - old_namelen);
4974 CDEBUG(D_MGS, "Fork the config-log from %s to %s\n",
4975 mde->mde_name, name_buf);
4977 ctxt = llog_get_context(mgs->mgs_obd, LLOG_CONFIG_ORIG_CTXT);
4980 rc = llog_open_create(env, ctxt, &new_llh, NULL, name_buf);
4984 rc = llog_init_handle(env, new_llh, LLOG_F_IS_PLAIN, NULL);
4988 if (unlikely(mgs_log_is_empty(env, mgs, mde->mde_name)))
4991 rc = llog_open(env, ctxt, &old_llh, NULL, mde->mde_name,
4996 rc = llog_init_handle(env, old_llh, LLOG_F_IS_PLAIN, NULL);
5000 new_llh->lgh_hdr->llh_tgtuuid = old_llh->lgh_hdr->llh_tgtuuid;
5002 OBD_ALLOC(mlfd, LLOG_MIN_CHUNK_SIZE);
5004 GOTO(out, rc = -ENOMEM);
5006 mlfd->mlfd_mgs = mgs;
5007 mlfd->mlfd_llh = new_llh;
5008 mlfd->mlfd_oldname = oldname;
5009 mlfd->mlfd_newname = newname;
5011 rc = llog_process(env, old_llh, mgs_lcfg_fork_handler, mlfd, NULL);
5012 OBD_FREE(mlfd, LLOG_MIN_CHUNK_SIZE);
5018 llog_close(env, old_llh);
5020 llog_close(env, new_llh);
5022 OBD_FREE(name_buf, name_buflen);
5024 llog_ctxt_put(ctxt);
5029 int mgs_lcfg_fork(const struct lu_env *env, struct mgs_device *mgs,
5030 const char *oldname, const char *newname)
5032 struct list_head log_list;
5033 struct mgs_direntry *dirent, *n;
5034 int olen = strlen(oldname);
5035 int nlen = strlen(newname);
5040 if (unlikely(!oldname || oldname[0] == '\0' ||
5041 !newname || newname[0] == '\0'))
5044 if (strcmp(oldname, newname) == 0)
5047 /* lock it to prevent fork/erase/register in parallel. */
5048 mutex_lock(&mgs->mgs_mutex);
5050 rc = class_dentry_readdir(env, mgs, &log_list);
5052 mutex_unlock(&mgs->mgs_mutex);
5056 if (list_empty(&log_list)) {
5057 mutex_unlock(&mgs->mgs_mutex);
5061 list_for_each_entry_safe(dirent, n, &log_list, mde_list) {
5064 ptr = strrchr(dirent->mde_name, '-');
5066 int tlen = ptr - dirent->mde_name;
5069 strncmp(newname, dirent->mde_name, tlen) == 0)
5070 GOTO(out, rc = -EEXIST);
5073 strncmp(oldname, dirent->mde_name, tlen) == 0)
5077 list_del_init(&dirent->mde_list);
5078 mgs_direntry_free(dirent);
5081 if (list_empty(&log_list)) {
5082 mutex_unlock(&mgs->mgs_mutex);
5086 list_for_each_entry(dirent, &log_list, mde_list) {
5087 rc = mgs_lcfg_fork_one(env, mgs, dirent, oldname, newname);
5095 mutex_unlock(&mgs->mgs_mutex);
5097 list_for_each_entry_safe(dirent, n, &log_list, mde_list) {
5098 list_del_init(&dirent->mde_list);
5099 mgs_direntry_free(dirent);
5102 if (rc && count > 0)
5103 mgs_erase_logs(env, mgs, newname);
5108 int mgs_lcfg_erase(const struct lu_env *env, struct mgs_device *mgs,
5114 if (unlikely(!fsname || fsname[0] == '\0'))
5117 rc = mgs_erase_logs(env, mgs, fsname);
5122 static int mgs_xattr_del(const struct lu_env *env, struct dt_object *obj)
5124 struct dt_device *dev;
5125 struct thandle *th = NULL;
5130 dev = container_of(obj->do_lu.lo_dev, struct dt_device, dd_lu_dev);
5131 th = dt_trans_create(env, dev);
5133 RETURN(PTR_ERR(th));
5135 rc = dt_declare_xattr_del(env, obj, XATTR_TARGET_RENAME, th);
5139 rc = dt_trans_start_local(env, dev, th);
5143 dt_write_lock(env, obj, 0);
5144 rc = dt_xattr_del(env, obj, XATTR_TARGET_RENAME, th);
5149 dt_write_unlock(env, obj);
5152 dt_trans_stop(env, dev, th);
5157 int mgs_lcfg_rename(const struct lu_env *env, struct mgs_device *mgs)
5159 struct list_head log_list;
5160 struct mgs_direntry *dirent, *n;
5162 struct lu_buf buf = {
5164 .lb_len = sizeof(fsname)
5170 rc = class_dentry_readdir(env, mgs, &log_list);
5174 if (list_empty(&log_list))
5177 list_for_each_entry_safe(dirent, n, &log_list, mde_list) {
5178 struct dt_object *o = NULL;
5183 list_del_init(&dirent->mde_list);
5184 ptr = strrchr(dirent->mde_name, '-');
5188 len = ptr - dirent->mde_name;
5189 if (unlikely(len >= sizeof(oldname))) {
5190 CDEBUG(D_MGS, "Skip invalid configuration file %s\n",
5195 o = local_file_find(env, mgs->mgs_los, mgs->mgs_configs_dir,
5199 CDEBUG(D_MGS, "Fail to locate file %s: rc = %d\n",
5200 dirent->mde_name, rc);
5204 rc = dt_xattr_get(env, o, &buf, XATTR_TARGET_RENAME);
5210 "Fail to get EA for %s: rc = %d\n",
5211 dirent->mde_name, rc);
5215 if (unlikely(rc == len &&
5216 memcmp(fsname, dirent->mde_name, len) == 0)) {
5217 /* The new fsname is the same as the old one. */
5218 rc = mgs_xattr_del(env, o);
5222 memcpy(oldname, dirent->mde_name, len);
5223 oldname[len] = '\0';
5225 rc = mgs_lcfg_fork_one(env, mgs, dirent, oldname, fsname);
5226 if (rc && rc != -EEXIST) {
5227 CDEBUG(D_MGS, "Fail to fork %s: rc = %d\n",
5228 dirent->mde_name, rc);
5232 rc = mgs_erase_log(env, mgs, dirent->mde_name);
5234 CDEBUG(D_MGS, "Fail to erase old %s: rc = %d\n",
5235 dirent->mde_name, rc);
5236 /* keep it there if failed to remove it. */
5241 if (o && !IS_ERR(o))
5242 lu_object_put(env, &o->do_lu);
5244 mgs_direntry_free(dirent);
5249 list_for_each_entry_safe(dirent, n, &log_list, mde_list) {
5250 list_del_init(&dirent->mde_list);
5251 mgs_direntry_free(dirent);
5257 /* Setup _mgs fsdb and log
5259 int mgs__mgs_fsdb_setup(const struct lu_env *env, struct mgs_device *mgs)
5261 struct fs_db *fsdb = NULL;
5265 rc = mgs_find_or_make_fsdb(env, mgs, MGSSELF_NAME, &fsdb);
5267 mgs_put_fsdb(mgs, fsdb);
5272 /* Setup params fsdb and log
5274 int mgs_params_fsdb_setup(const struct lu_env *env, struct mgs_device *mgs)
5276 struct fs_db *fsdb = NULL;
5277 struct llog_handle *params_llh = NULL;
5281 rc = mgs_find_or_make_fsdb(env, mgs, PARAMS_FILENAME, &fsdb);
5283 mutex_lock(&fsdb->fsdb_mutex);
5284 rc = record_start_log(env, mgs, ¶ms_llh, PARAMS_FILENAME);
5286 rc = record_end_log(env, ¶ms_llh);
5287 mutex_unlock(&fsdb->fsdb_mutex);
5288 mgs_put_fsdb(mgs, fsdb);
5294 /* Cleanup params fsdb and log
5296 int mgs_params_fsdb_cleanup(const struct lu_env *env, struct mgs_device *mgs)
5300 rc = mgs_erase_logs(env, mgs, PARAMS_FILENAME);
5301 return rc == -ENOENT ? 0 : rc;
5305 * Fill in the mgs_target_info based on data devname and param provide.
5307 * @env thread context
5309 * @mti mgs target info. We want to set this based other paramters
5310 * passed to this function. Once setup we write it to the config
5312 * @devname optional OBD device name
5313 * @param string that contains both what tunable to set and the value to
5316 * RETURN 0 for success
5317 * negative error number on failure
5319 static int mgs_set_conf_param(const struct lu_env *env, struct mgs_device *mgs,
5320 struct mgs_target_info *mti, const char *devname,
5323 struct fs_db *fsdb = NULL;
5328 /* lustre, lustre-mdtlov, lustre-client, lustre-MDT0000 */
5332 /* We have two possible cases here:
5334 * 1) the device name embedded in the param:
5335 * lustre-OST0000.osc.max_dirty_mb=32
5337 * 2) the file system name is embedded in
5338 * the param: lustre.sys.at.min=0
5340 len = strcspn(param, ".=");
5341 if (!len || param[len] == '=')
5344 if (len >= sizeof(mti->mti_svname))
5347 snprintf(mti->mti_svname, sizeof(mti->mti_svname),
5348 "%.*s", (int)len, param);
5351 if (strlcpy(mti->mti_svname, devname, sizeof(mti->mti_svname)) >=
5352 sizeof(mti->mti_svname))
5356 if (!strlen(mti->mti_svname)) {
5357 LCONSOLE_ERROR_MSG(0x14d, "No target specified: %s\n", param);
5361 dev_type = mgs_parse_devname(mti->mti_svname, mti->mti_fsname,
5362 &mti->mti_stripe_index);
5364 /* For this case we have an invalid obd device name */
5366 CDEBUG(D_MGS, "%s don't contain an index\n", mti->mti_svname);
5367 strlcpy(mti->mti_fsname, mti->mti_svname, MTI_NAME_MAXLEN);
5370 /* Not an obd device, assume devname is the fsname.
5371 * User might of only provided fsname and not obd device
5374 CDEBUG(D_MGS, "%s is seen as a file system name\n", mti->mti_svname);
5375 strlcpy(mti->mti_fsname, mti->mti_svname, MTI_NAME_MAXLEN);
5380 GOTO(out, rc = dev_type);
5382 /* param related to llite isn't allowed to set by OST or MDT */
5383 if (dev_type & LDD_F_SV_TYPE_OST ||
5384 dev_type & LDD_F_SV_TYPE_MDT) {
5385 /* param related to llite isn't allowed to set by OST
5388 if (!strncmp(param, PARAM_LLITE,
5389 sizeof(PARAM_LLITE) - 1))
5390 GOTO(out, rc = -EINVAL);
5392 /* Strip -osc or -mdc suffix from svname */
5393 if (server_make_name(dev_type, mti->mti_stripe_index,
5394 mti->mti_fsname, mti->mti_svname,
5395 sizeof(mti->mti_svname)))
5396 GOTO(out, rc = -EINVAL);
5401 if (strlcpy(mti->mti_params, param, sizeof(mti->mti_params)) >=
5402 sizeof(mti->mti_params))
5403 GOTO(out, rc = -E2BIG);
5405 CDEBUG(D_MGS, "set_conf_param fs='%s' device='%s' param='%s'\n",
5406 mti->mti_fsname, mti->mti_svname, mti->mti_params);
5408 rc = mgs_find_or_make_fsdb(env, mgs, mti->mti_fsname, &fsdb);
5412 if (!test_bit(FSDB_MGS_SELF, &fsdb->fsdb_flags) &&
5413 test_bit(FSDB_LOG_EMPTY, &fsdb->fsdb_flags)) {
5414 CERROR("No filesystem targets for %s. cfg_device from lctl "
5415 "is '%s'\n", mti->mti_fsname, mti->mti_svname);
5416 mgs_unlink_fsdb(mgs, fsdb);
5417 GOTO(out, rc = -EINVAL);
5421 * Revoke lock so everyone updates. Should be alright if
5422 * someone was already reading while we were updating the logs,
5423 * so we don't really need to hold the lock while we're
5426 mti->mti_flags = dev_type | LDD_F_PARAM;
5427 mutex_lock(&fsdb->fsdb_mutex);
5428 rc = mgs_write_log_param(env, mgs, fsdb, mti, mti->mti_params);
5429 mutex_unlock(&fsdb->fsdb_mutex);
5430 mgs_revoke_lock(mgs, fsdb, MGS_CFG_T_CONFIG);
5434 mgs_put_fsdb(mgs, fsdb);
5439 static int mgs_set_param2(const struct lu_env *env, struct mgs_device *mgs,
5440 struct mgs_target_info *mti, const char *param)
5442 struct fs_db *fsdb = NULL;
5447 if (strlcpy(mti->mti_params, param, sizeof(mti->mti_params)) >=
5448 sizeof(mti->mti_params))
5449 GOTO(out, rc = -E2BIG);
5451 len = strcspn(param, ".=");
5452 if (len && param[len] != '=') {
5453 struct list_head *tmp;
5457 ptr = strchr(param, '.');
5459 len = strlen(param);
5462 if (len >= sizeof(mti->mti_svname))
5463 GOTO(out, rc = -E2BIG);
5465 snprintf(mti->mti_svname, sizeof(mti->mti_svname), "%.*s",
5468 mutex_lock(&mgs->mgs_mutex);
5469 if (unlikely(list_empty(&mgs->mgs_fs_db_list))) {
5470 mutex_unlock(&mgs->mgs_mutex);
5471 GOTO(out, rc = -ENODEV);
5474 list_for_each(tmp, &mgs->mgs_fs_db_list) {
5475 fsdb = list_entry(tmp, struct fs_db, fsdb_list);
5476 if (fsdb->fsdb_has_lproc_entry &&
5477 strcmp(fsdb->fsdb_name, "params") != 0 &&
5478 strstr(param, fsdb->fsdb_name)) {
5479 snprintf(mti->mti_svname,
5480 sizeof(mti->mti_svname), "%s",
5488 snprintf(mti->mti_svname, sizeof(mti->mti_svname),
5491 mutex_unlock(&mgs->mgs_mutex);
5493 snprintf(mti->mti_svname, sizeof(mti->mti_svname), "general");
5496 CDEBUG(D_MGS, "set_param2 fs='%s' device='%s' param='%s'\n",
5497 mti->mti_fsname, mti->mti_svname, mti->mti_params);
5499 /* The return value should be the device type i.e LDD_F_SV_TYPE_XXX.
5500 * A returned error tells us we don't have a target obd device.
5502 dev_type = server_name2index(mti->mti_svname, &mti->mti_stripe_index,
5507 /* the return value should be the device type i.e LDD_F_SV_TYPE_XXX.
5508 * Strip -osc or -mdc suffix from svname
5510 if ((dev_type & LDD_F_SV_TYPE_OST || dev_type & LDD_F_SV_TYPE_MDT) &&
5511 server_make_name(dev_type, mti->mti_stripe_index,
5512 mti->mti_fsname, mti->mti_svname,
5513 sizeof(mti->mti_svname)))
5514 GOTO(out, rc = -EINVAL);
5516 rc = mgs_find_or_make_fsdb(env, mgs, PARAMS_FILENAME, &fsdb);
5520 * Revoke lock so everyone updates. Should be alright if
5521 * someone was already reading while we were updating the logs,
5522 * so we don't really need to hold the lock while we're
5525 mti->mti_flags = dev_type | LDD_F_PARAM2;
5526 mutex_lock(&fsdb->fsdb_mutex);
5527 rc = mgs_write_log_param2(env, mgs, fsdb, mti, mti->mti_params);
5528 mutex_unlock(&fsdb->fsdb_mutex);
5529 mgs_revoke_lock(mgs, fsdb, MGS_CFG_T_PARAMS);
5530 mgs_put_fsdb(mgs, fsdb);
5535 /* Set a permanent (config log) param for a target or fs
5537 * @lcfg buf0 may contain the device (testfs-MDT0000) name
5538 * buf1 contains the single parameter
5540 int mgs_set_param(const struct lu_env *env, struct mgs_device *mgs,
5541 struct lustre_cfg *lcfg)
5543 const char *param = lustre_cfg_string(lcfg, 1);
5544 struct mgs_target_info *mti;
5547 /* Create a fake mti to hold everything */
5552 print_lustre_cfg(lcfg);
5554 if (lcfg->lcfg_command == LCFG_PARAM) {
5555 /* For the case of lctl conf_param devname can be
5556 * lustre, lustre-mdtlov, lustre-client, lustre-MDT0000
5558 const char *devname = lustre_cfg_string(lcfg, 0);
5560 rc = mgs_set_conf_param(env, mgs, mti, devname, param);
5562 /* In the case of lctl set_param -P lcfg[0] will always
5563 * be 'general'. At least for now.
5565 rc = mgs_set_param2(env, mgs, mti, param);
5573 static int mgs_write_log_pool(const struct lu_env *env,
5574 struct mgs_device *mgs, char *logname,
5575 struct fs_db *fsdb, char *tgtname,
5576 enum lcfg_command_type cmd,
5577 char *fsname, char *poolname,
5578 char *ostname, char *comment)
5580 struct llog_handle *llh = NULL;
5583 rc = record_start_log(env, mgs, &llh, logname);
5586 rc = record_marker(env, llh, fsdb, CM_START, tgtname, comment);
5589 rc = record_base(env, llh, tgtname, 0, cmd,
5590 fsname, poolname, ostname, NULL);
5593 rc = record_marker(env, llh, fsdb, CM_END, tgtname, comment);
5595 record_end_log(env, &llh);
5599 int mgs_nodemap_cmd(const struct lu_env *env, struct mgs_device *mgs,
5600 enum lcfg_command_type cmd, const char *nodemap_name,
5611 case LCFG_NODEMAP_ADD:
5612 rc = nodemap_add(nodemap_name);
5614 case LCFG_NODEMAP_DEL:
5615 rc = nodemap_del(nodemap_name);
5617 case LCFG_NODEMAP_ADD_RANGE:
5618 rc = nodemap_parse_range(param, nid);
5621 rc = nodemap_add_range(nodemap_name, nid);
5623 case LCFG_NODEMAP_DEL_RANGE:
5624 rc = nodemap_parse_range(param, nid);
5627 rc = nodemap_del_range(nodemap_name, nid);
5629 case LCFG_NODEMAP_ADMIN:
5630 rc = kstrtobool(param, &bool_switch);
5633 rc = nodemap_set_allow_root(nodemap_name, bool_switch);
5635 case LCFG_NODEMAP_DENY_UNKNOWN:
5636 rc = kstrtobool(param, &bool_switch);
5639 rc = nodemap_set_deny_unknown(nodemap_name, bool_switch);
5641 case LCFG_NODEMAP_AUDIT_MODE:
5642 rc = kstrtobool(param, &bool_switch);
5644 rc = nodemap_set_audit_mode(nodemap_name, bool_switch);
5646 case LCFG_NODEMAP_FORBID_ENCRYPT:
5647 rc = kstrtobool(param, &bool_switch);
5649 rc = nodemap_set_forbid_encryption(nodemap_name,
5652 case LCFG_NODEMAP_READONLY_MOUNT:
5653 rc = kstrtobool(param, &bool_switch);
5655 rc = nodemap_set_readonly_mount(nodemap_name,
5658 case LCFG_NODEMAP_MAP_MODE:
5663 if ((p = strstr(param, "all")) != NULL) {
5664 if ((p == param || *(p-1) == ',') &&
5665 (*(p+3) == '\0' || *(p+3) == ',')) {
5666 map_mode = NODEMAP_MAP_ALL;
5672 while ((p = strsep(¶m, ",")) != NULL) {
5676 if (strcmp("both", p) == 0)
5677 map_mode |= NODEMAP_MAP_BOTH;
5678 else if (strcmp("uid_only", p) == 0 ||
5679 strcmp("uid", p) == 0)
5680 map_mode |= NODEMAP_MAP_UID;
5681 else if (strcmp("gid_only", p) == 0 ||
5682 strcmp("gid", p) == 0)
5683 map_mode |= NODEMAP_MAP_GID;
5684 else if (strcmp("projid_only", p) == 0 ||
5685 strcmp("projid", p) == 0)
5686 map_mode |= NODEMAP_MAP_PROJID;
5696 rc = nodemap_set_mapping_mode(nodemap_name, map_mode);
5699 case LCFG_NODEMAP_RBAC:
5701 enum nodemap_rbac_roles rbac;
5704 if (strcmp(param, "all") == 0) {
5705 rbac = NODEMAP_RBAC_ALL;
5706 } else if (strcmp(param, "none") == 0) {
5707 rbac = NODEMAP_RBAC_NONE;
5709 rbac = NODEMAP_RBAC_NONE;
5710 while ((p = strsep(¶m, ",")) != NULL) {
5716 for (i = 0; i < ARRAY_SIZE(nodemap_rbac_names);
5719 nodemap_rbac_names[i].nrn_name)
5722 nodemap_rbac_names[i].nrn_mode;
5726 if (i == ARRAY_SIZE(nodemap_rbac_names))
5735 rc = nodemap_set_rbac(nodemap_name, rbac);
5738 case LCFG_NODEMAP_TRUSTED:
5739 rc = kstrtobool(param, &bool_switch);
5742 rc = nodemap_set_trust_client_ids(nodemap_name, bool_switch);
5744 case LCFG_NODEMAP_SQUASH_UID:
5745 rc = kstrtouint(param, 10, &int_id);
5748 rc = nodemap_set_squash_uid(nodemap_name, int_id);
5750 case LCFG_NODEMAP_SQUASH_GID:
5751 rc = kstrtouint(param, 10, &int_id);
5754 rc = nodemap_set_squash_gid(nodemap_name, int_id);
5756 case LCFG_NODEMAP_SQUASH_PROJID:
5757 rc = kstrtouint(param, 10, &int_id);
5760 rc = nodemap_set_squash_projid(nodemap_name, int_id);
5762 case LCFG_NODEMAP_ADD_UIDMAP:
5763 case LCFG_NODEMAP_ADD_GIDMAP:
5764 case LCFG_NODEMAP_ADD_PROJIDMAP:
5765 rc = nodemap_parse_idmap(param, idmap);
5768 if (cmd == LCFG_NODEMAP_ADD_UIDMAP)
5769 rc = nodemap_add_idmap(nodemap_name, NODEMAP_UID,
5771 else if (cmd == LCFG_NODEMAP_ADD_GIDMAP)
5772 rc = nodemap_add_idmap(nodemap_name, NODEMAP_GID,
5774 else if (cmd == LCFG_NODEMAP_ADD_PROJIDMAP)
5775 rc = nodemap_add_idmap(nodemap_name, NODEMAP_PROJID,
5780 case LCFG_NODEMAP_DEL_UIDMAP:
5781 case LCFG_NODEMAP_DEL_GIDMAP:
5782 case LCFG_NODEMAP_DEL_PROJIDMAP:
5783 rc = nodemap_parse_idmap(param, idmap);
5786 if (cmd == LCFG_NODEMAP_DEL_UIDMAP)
5787 rc = nodemap_del_idmap(nodemap_name, NODEMAP_UID,
5789 else if (cmd == LCFG_NODEMAP_DEL_GIDMAP)
5790 rc = nodemap_del_idmap(nodemap_name, NODEMAP_GID,
5792 else if (cmd == LCFG_NODEMAP_DEL_PROJIDMAP)
5793 rc = nodemap_del_idmap(nodemap_name, NODEMAP_PROJID,
5798 case LCFG_NODEMAP_SET_FILESET:
5799 rc = nodemap_set_fileset(nodemap_name, param);
5801 case LCFG_NODEMAP_SET_SEPOL:
5802 rc = nodemap_set_sepol(nodemap_name, param);
5811 int mgs_pool_cmd(const struct lu_env *env, struct mgs_device *mgs,
5812 enum lcfg_command_type cmd, char *fsname,
5813 char *poolname, char *ostname)
5818 char *label = NULL, *canceled_label = NULL;
5820 struct mgs_target_info *mti = NULL;
5821 bool checked = false;
5822 bool locked = false;
5827 rc = mgs_find_or_make_fsdb(env, mgs, fsname, &fsdb);
5829 CERROR("Can't get db for %s\n", fsname);
5832 if (test_bit(FSDB_LOG_EMPTY, &fsdb->fsdb_flags)) {
5833 CERROR("%s is not defined\n", fsname);
5835 GOTO(out_fsdb, rc = -EINVAL);
5838 label_sz = 10 + strlen(fsname) + strlen(poolname);
5840 /* check if ostname match fsname */
5841 if (ostname != NULL) {
5844 ptr = strrchr(ostname, '-');
5845 if ((ptr == NULL) ||
5846 (strncmp(fsname, ostname, ptr-ostname) != 0))
5848 label_sz += strlen(ostname);
5851 OBD_ALLOC(label, label_sz);
5853 GOTO(out_fsdb, rc = -ENOMEM);
5857 sprintf(label, "new %s.%s", fsname, poolname);
5860 sprintf(label, "add %s.%s.%s", fsname, poolname, ostname);
5863 OBD_ALLOC(canceled_label, label_sz);
5864 if (canceled_label == NULL)
5865 GOTO(out_label, rc = -ENOMEM);
5866 sprintf(label, "rem %s.%s.%s", fsname, poolname, ostname);
5867 sprintf(canceled_label, "add %s.%s.%s",
5868 fsname, poolname, ostname);
5871 OBD_ALLOC(canceled_label, label_sz);
5872 if (canceled_label == NULL)
5873 GOTO(out_label, rc = -ENOMEM);
5874 sprintf(label, "del %s.%s", fsname, poolname);
5875 sprintf(canceled_label, "new %s.%s", fsname, poolname);
5883 GOTO(out_cancel, rc = -ENOMEM);
5884 strncpy(mti->mti_svname, "lov pool", sizeof(mti->mti_svname));
5886 mutex_lock(&fsdb->fsdb_mutex);
5888 /* write pool def to all MDT logs */
5889 for (i = 0; i < INDEX_MAP_SIZE * 8; i++) {
5890 if (test_bit(i, fsdb->fsdb_mdt_index_map)) {
5891 rc = name_create_mdt_and_lov(&logname, &lovname,
5896 if (!checked && (canceled_label == NULL)) {
5897 rc = mgs_check_marker(env, mgs, fsdb, mti,
5898 logname, lovname, label);
5900 name_destroy(&logname);
5901 name_destroy(&lovname);
5903 rc = (rc == LLOG_PROC_BREAK ?
5908 if (canceled_label != NULL)
5909 rc = mgs_modify(env, mgs, fsdb, mti, logname,
5910 lovname, canceled_label,
5914 rc = mgs_write_log_pool(env, mgs, logname,
5918 name_destroy(&logname);
5919 name_destroy(&lovname);
5925 rc = name_create(&logname, fsname, "-client");
5929 if (!checked && (canceled_label == NULL)) {
5930 rc = mgs_check_marker(env, mgs, fsdb, mti, logname,
5931 fsdb->fsdb_clilov, label);
5933 name_destroy(&logname);
5934 GOTO(out_mti, rc = (rc == LLOG_PROC_BREAK ?
5938 if (canceled_label != NULL) {
5939 rc = mgs_modify(env, mgs, fsdb, mti, logname,
5940 fsdb->fsdb_clilov, canceled_label, CM_SKIP);
5942 name_destroy(&logname);
5947 rc = mgs_write_log_pool(env, mgs, logname, fsdb, fsdb->fsdb_clilov,
5948 cmd, fsname, poolname, ostname, label);
5949 mutex_unlock(&fsdb->fsdb_mutex);
5951 name_destroy(&logname);
5952 /* request for update */
5953 mgs_revoke_lock(mgs, fsdb, MGS_CFG_T_CONFIG);
5959 mutex_unlock(&fsdb->fsdb_mutex);
5963 if (canceled_label != NULL)
5964 OBD_FREE(canceled_label, label_sz);
5966 OBD_FREE(label, label_sz);
5969 mgs_unlink_fsdb(mgs, fsdb);
5970 mgs_put_fsdb(mgs, fsdb);