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 enum mgs_search_pool_status {
752 POOL_STATUS_NONE = 0,
754 POOL_STATUS_OST_EXIST,
757 struct mgs_search_pool_data {
762 enum mgs_search_pool_status msp_status;
766 static int mgs_search_pool_cb(const struct lu_env *env,
767 struct llog_handle *llh,
768 struct llog_rec_hdr *rec, void *data)
770 struct mgs_search_pool_data *d = data;
771 struct lustre_cfg *lcfg = REC_DATA(rec);
772 int cfg_len = REC_DATA_LEN(rec);
775 char *ostname = NULL;
779 if (rec->lrh_type != OBD_CFG_REC) {
780 CDEBUG(D_ERROR, "Unhandled lrh_type: %#x\n", rec->lrh_type);
784 rc = lustre_cfg_sanity_check(lcfg, cfg_len);
786 CDEBUG(D_ERROR, "Insane cfg\n");
790 /* check if section is skipped */
791 if (lcfg->lcfg_command == LCFG_MARKER) {
792 struct cfg_marker *marker = lustre_cfg_buf(lcfg, 1);
794 if (!(marker->cm_flags & CM_END))
797 d->msp_skip = (marker->cm_flags & CM_SKIP) ||
798 strcmp(d->msp_tgt, marker->cm_tgtname) != 0;
806 switch (lcfg->lcfg_command) {
809 ostname = lustre_cfg_string(lcfg, 3);
813 fsname = lustre_cfg_string(lcfg, 1);
814 poolname = lustre_cfg_string(lcfg, 2);
820 if (strcmp(d->msp_fs, fsname) != 0)
822 if (strcmp(d->msp_pool, poolname) != 0)
824 if (ostname && d->msp_ost && (strcmp(d->msp_ost, ostname) != 0))
827 /* Found a non-skipped marker match */
828 CDEBUG(D_MGS, "Matched pool rec %u cmd:0x%x %s.%s %s\n",
829 rec->lrh_index, lcfg->lcfg_command, fsname, poolname,
830 ostname ? ostname : "");
832 switch (lcfg->lcfg_command) {
834 d->msp_status = POOL_STATUS_OST_EXIST;
835 RETURN(LLOG_PROC_BREAK);
837 d->msp_status = POOL_STATUS_EXIST;
838 RETURN(LLOG_PROC_BREAK);
840 d->msp_status = POOL_STATUS_EXIST;
841 RETURN(LLOG_PROC_BREAK);
843 d->msp_status = POOL_STATUS_NONE;
844 RETURN(LLOG_PROC_BREAK);
853 * Search a pool in a MGS configuration.
855 * positive - return the status of the pool,
859 int mgs_search_pool(const struct lu_env *env, struct mgs_device *mgs,
860 struct fs_db *fsdb, struct mgs_target_info *mti,
861 char *logname, char *devname, char *fsname, char *poolname,
864 struct llog_handle *loghandle;
865 struct llog_ctxt *ctxt;
866 struct mgs_search_pool_data d;
867 int status = POOL_STATUS_NONE;
872 LASSERT(mutex_is_locked(&fsdb->fsdb_mutex));
877 d.msp_pool = poolname;
879 d.msp_status = POOL_STATUS_NONE;
882 ctxt = llog_get_context(mgs->mgs_obd, LLOG_CONFIG_ORIG_CTXT);
883 LASSERT(ctxt != NULL);
884 rc = llog_open(env, ctxt, &loghandle, NULL, logname, LLOG_OPEN_EXISTS);
891 rc = llog_init_handle(env, loghandle, LLOG_F_IS_PLAIN, NULL);
895 if (llog_get_size(loghandle) <= 1)
896 GOTO(out_close, rc = 0);
898 rc = llog_reverse_process(env, loghandle, mgs_search_pool_cb, &d, NULL);
899 if (rc == LLOG_PROC_BREAK)
900 status = d.msp_status;
903 llog_close(env, loghandle);
907 RETURN(rc < 0 ? rc : status);
910 static int mgs_modify_handler(const struct lu_env *env,
911 struct llog_handle *llh,
912 struct llog_rec_hdr *rec, void *data)
914 struct mgs_modify_lookup *mml = data;
915 struct cfg_marker *marker;
916 struct lustre_cfg *lcfg = REC_DATA(rec);
917 int cfg_len = REC_DATA_LEN(rec);
921 if (rec->lrh_type != OBD_CFG_REC) {
922 CERROR("unhandled lrh_type: %#x\n", rec->lrh_type);
926 rc = lustre_cfg_sanity_check(lcfg, cfg_len);
928 CERROR("Insane cfg\n");
932 /* We only care about markers */
933 if (lcfg->lcfg_command != LCFG_MARKER)
936 marker = lustre_cfg_buf(lcfg, 1);
937 if ((strcmp(mml->mml_marker.cm_comment, marker->cm_comment) == 0) &&
938 (strcmp(mml->mml_marker.cm_tgtname, marker->cm_tgtname) == 0) &&
939 !(marker->cm_flags & CM_SKIP)) {
940 /* Found a non-skipped marker match */
941 CDEBUG(D_MGS, "Changing rec %u marker %d %x->%x: %s %s\n",
942 rec->lrh_index, marker->cm_step,
943 marker->cm_flags, mml->mml_marker.cm_flags,
944 marker->cm_tgtname, marker->cm_comment);
945 /* Overwrite the old marker llog entry */
946 marker->cm_flags &= ~CM_EXCLUDE; /* in case we're unexcluding */
947 marker->cm_flags |= mml->mml_marker.cm_flags;
948 marker->cm_canceltime = mml->mml_marker.cm_canceltime;
949 rc = llog_write(env, llh, rec, rec->lrh_index);
958 * Modify an existing config log record (for CM_SKIP or CM_EXCLUDE)
960 * 0 - modified successfully,
961 * 1 - no modification was done
964 static int mgs_modify(const struct lu_env *env, struct mgs_device *mgs,
965 struct fs_db *fsdb, struct mgs_target_info *mti,
966 char *logname, char *devname, char *comment, int flags)
968 struct llog_handle *loghandle;
969 struct llog_ctxt *ctxt;
970 struct mgs_modify_lookup *mml;
975 LASSERT(mutex_is_locked(&fsdb->fsdb_mutex));
976 CDEBUG(D_MGS, "modify %s/%s/%s fl=%x\n", logname, devname, comment,
979 ctxt = llog_get_context(mgs->mgs_obd, LLOG_CONFIG_ORIG_CTXT);
980 LASSERT(ctxt != NULL);
981 rc = llog_open(env, ctxt, &loghandle, NULL, logname, LLOG_OPEN_EXISTS);
988 rc = llog_init_handle(env, loghandle, LLOG_F_IS_PLAIN, NULL);
992 if (llog_get_size(loghandle) <= 1)
993 GOTO(out_close, rc = 0);
997 GOTO(out_close, rc = -ENOMEM);
998 rc = strscpy(mml->mml_marker.cm_comment, comment,
999 sizeof(mml->mml_marker.cm_comment));
1002 rc = strscpy(mml->mml_marker.cm_tgtname, devname,
1003 sizeof(mml->mml_marker.cm_tgtname));
1006 /* Modify mostly means cancel */
1007 mml->mml_marker.cm_flags = flags;
1008 mml->mml_marker.cm_canceltime = flags ? ktime_get_real_seconds() : 0;
1009 mml->mml_modified = 0;
1010 rc = llog_process(env, loghandle, mgs_modify_handler, (void *)mml,
1012 if (!rc && !mml->mml_modified)
1019 llog_close(env, loghandle);
1022 CERROR("%s: modify %s/%s failed: rc = %d\n",
1023 mgs->mgs_obd->obd_name, mti->mti_svname, comment, rc);
1024 llog_ctxt_put(ctxt);
1028 enum replace_state {
1036 /** This structure is passed to mgs_replace_handler */
1037 struct mgs_replace_data {
1038 /* Nids are replaced for this target device */
1039 struct mgs_target_info target;
1040 /* Temporary modified llog */
1041 struct llog_handle *temp_llh;
1042 enum replace_state state;
1048 * Check: a) if block should be skipped
1049 * b) is it target block
1054 * \retval 0 should not to be skipped
1055 * \retval 1 should to be skipped
1057 static int check_markers(struct lustre_cfg *lcfg,
1058 struct mgs_replace_data *mrd)
1060 struct cfg_marker *marker;
1062 /* Track markers. Find given device */
1063 if (lcfg->lcfg_command == LCFG_MARKER) {
1064 marker = lustre_cfg_buf(lcfg, 1);
1065 /* Clean llog from records marked as CM_SKIP.
1066 CM_EXCLUDE records are used for "active" command
1067 and can be restored if needed */
1068 if ((marker->cm_flags & (CM_SKIP | CM_START)) ==
1069 (CM_SKIP | CM_START)) {
1070 mrd->state = REPLACE_SKIP;
1074 if ((marker->cm_flags & (CM_SKIP | CM_END)) ==
1075 (CM_SKIP | CM_END)) {
1076 mrd->state = REPLACE_COPY;
1080 if (strcmp(mrd->target.mti_svname, marker->cm_tgtname) == 0) {
1081 LASSERT(!(marker->cm_flags & CM_START) ||
1082 !(marker->cm_flags & CM_END));
1083 if (marker->cm_flags & CM_START) {
1084 if (!strncmp(marker->cm_comment,
1085 "add failnid", 11)) {
1086 mrd->state = REPLACE_SKIP;
1088 mrd->state = REPLACE_UUID;
1089 mrd->failover = NULL;
1091 } else if (marker->cm_flags & CM_END)
1092 mrd->state = REPLACE_COPY;
1094 if (!strncmp(marker->cm_comment,
1103 static int record_base(const struct lu_env *env, struct llog_handle *llh,
1104 char *cfgname, lnet_nid_t nid, int cmd,
1105 char *s1, char *s2, char *s3, char *s4)
1107 struct mgs_thread_info *mgi = mgs_env_info(env);
1108 struct llog_cfg_rec *lcr;
1111 CDEBUG(D_MGS, "lcfg %s %#x %s %s %s %s\n", cfgname,
1112 cmd, s1, s2, s3, s4);
1114 lustre_cfg_bufs_reset(&mgi->mgi_bufs, cfgname);
1116 lustre_cfg_bufs_set_string(&mgi->mgi_bufs, 1, s1);
1118 lustre_cfg_bufs_set_string(&mgi->mgi_bufs, 2, s2);
1120 lustre_cfg_bufs_set_string(&mgi->mgi_bufs, 3, s3);
1122 lustre_cfg_bufs_set_string(&mgi->mgi_bufs, 4, s4);
1124 lcr = lustre_cfg_rec_new(cmd, &mgi->mgi_bufs);
1128 lcr->lcr_cfg.lcfg_nid = nid;
1129 rc = llog_write(env, llh, &lcr->lcr_hdr, LLOG_NEXT_IDX);
1131 lustre_cfg_rec_free(lcr);
1135 "failed to write lcfg %s %#x %s %s %s %s: rc = %d\n",
1136 cfgname, cmd, s1, s2, s3, s4, rc);
1140 static inline int record_add_uuid(const struct lu_env *env,
1141 struct llog_handle *llh,
1142 struct lnet_nid *nid, char *uuid)
1144 lnet_nid_t nid4 = 0;
1147 if (nid_is_nid4(nid))
1148 nid4 = lnet_nid_to_nid4(nid);
1150 cfg2 = libcfs_nidstr(nid);
1151 return record_base(env, llh, NULL, nid4, LCFG_ADD_UUID, uuid,
1155 static inline int record_add_conn(const struct lu_env *env,
1156 struct llog_handle *llh,
1157 char *devname, char *uuid)
1159 return record_base(env, llh, devname, 0, LCFG_ADD_CONN, uuid,
1163 static inline int record_attach(const struct lu_env *env,
1164 struct llog_handle *llh, char *devname,
1165 char *type, char *uuid)
1167 return record_base(env, llh, devname, 0, LCFG_ATTACH, type, uuid,
1171 static inline int record_setup(const struct lu_env *env,
1172 struct llog_handle *llh, char *devname,
1173 char *s1, char *s2, char *s3, char *s4)
1175 return record_base(env, llh, devname, 0, LCFG_SETUP, s1, s2, s3, s4);
1179 * \retval <0 record processing error
1180 * \retval n record is processed. No need copy original one.
1181 * \retval 0 record is not processed.
1183 static int process_command(const struct lu_env *env, struct lustre_cfg *lcfg,
1184 struct mgs_replace_data *mrd)
1187 struct lnet_nid nid;
1191 if (mrd->state == REPLACE_UUID &&
1192 lcfg->lcfg_command == LCFG_ADD_UUID) {
1193 /* LCFG_ADD_UUID command found. Let's skip original command
1194 and add passed nids */
1195 ptr = mrd->target.mti_params;
1196 while (class_parse_nid(ptr, &nid, &ptr) == 0) {
1197 if (!mrd->nodeuuid) {
1198 rc = name_create(&mrd->nodeuuid,
1199 libcfs_nidstr(&nid), "");
1201 CERROR("Can't create uuid for "
1202 "nid %s, device %s\n",
1203 libcfs_nidstr(&nid),
1204 mrd->target.mti_svname);
1208 CDEBUG(D_MGS, "add nid %s with uuid %s, device %s\n",
1209 libcfs_nidstr(&nid),
1210 mrd->target.mti_params,
1212 rc = record_add_uuid(env,
1213 mrd->temp_llh, &nid,
1216 CWARN("%s: Can't add nid %s for uuid %s :rc=%d\n",
1217 mrd->target.mti_svname,
1218 libcfs_nidstr(&nid),
1224 mrd->failover = ptr;
1229 if (nids_added == 0) {
1230 CERROR("No new nids were added, nid %s with uuid %s, device %s\n",
1231 libcfs_nidstr(&nid),
1232 mrd->nodeuuid ? mrd->nodeuuid : "NULL",
1233 mrd->target.mti_svname);
1234 name_destroy(&mrd->nodeuuid);
1237 mrd->state = REPLACE_SETUP;
1243 if (mrd->state == REPLACE_SETUP && lcfg->lcfg_command == LCFG_SETUP) {
1244 /* LCFG_SETUP command found. UUID should be changed */
1245 rc = record_setup(env,
1247 /* devname the same */
1248 lustre_cfg_string(lcfg, 0),
1249 /* s1 is not changed */
1250 lustre_cfg_string(lcfg, 1),
1252 /* s3 is not changed */
1253 lustre_cfg_string(lcfg, 3),
1254 /* s4 is not changed */
1255 lustre_cfg_string(lcfg, 4));
1257 name_destroy(&mrd->nodeuuid);
1261 if (mrd->failover) {
1262 ptr = mrd->failover;
1263 while (class_parse_nid(ptr, &nid, &ptr) == 0) {
1264 if (mrd->nodeuuid == NULL) {
1265 rc = name_create(&mrd->nodeuuid,
1266 libcfs_nidstr(&nid),
1272 CDEBUG(D_MGS, "add nid %s for failover %s\n",
1273 libcfs_nidstr(&nid), mrd->nodeuuid);
1274 rc = record_add_uuid(env, mrd->temp_llh, &nid,
1277 CWARN("%s: Can't add nid %s for failover %s :rc = %d\n",
1278 mrd->target.mti_svname,
1279 libcfs_nidstr(&nid),
1281 name_destroy(&mrd->nodeuuid);
1285 rc = record_add_conn(env,
1287 lustre_cfg_string(lcfg, 0),
1289 name_destroy(&mrd->nodeuuid);
1294 if (mrd->nodeuuid) {
1295 rc = record_add_conn(env, mrd->temp_llh,
1296 lustre_cfg_string(lcfg, 0),
1298 name_destroy(&mrd->nodeuuid);
1303 mrd->state = REPLACE_DONE;
1307 /* All new UUID are added. Skip. */
1308 if (mrd->state == REPLACE_SETUP &&
1309 lcfg->lcfg_command == LCFG_ADD_UUID)
1312 /* Another commands in target device block */
1317 * Handler that called for every record in llog.
1318 * Records are processed in order they placed in llog.
1320 * \param[in] llh log to be processed
1321 * \param[in] rec current record
1322 * \param[in] data mgs_replace_data structure
1326 static int mgs_replace_nids_handler(const struct lu_env *env,
1327 struct llog_handle *llh,
1328 struct llog_rec_hdr *rec,
1331 struct mgs_replace_data *mrd;
1332 struct lustre_cfg *lcfg = REC_DATA(rec);
1333 int cfg_len = REC_DATA_LEN(rec);
1337 mrd = (struct mgs_replace_data *)data;
1339 if (rec->lrh_type != OBD_CFG_REC) {
1340 CERROR("unhandled lrh_type: %#x, cmd %x %s %s\n",
1341 rec->lrh_type, lcfg->lcfg_command,
1342 lustre_cfg_string(lcfg, 0),
1343 lustre_cfg_string(lcfg, 1));
1347 rc = lustre_cfg_sanity_check(lcfg, cfg_len);
1349 /* Do not copy any invalidated records */
1350 GOTO(skip_out, rc = 0);
1353 rc = check_markers(lcfg, mrd);
1354 if (rc || mrd->state == REPLACE_SKIP)
1355 GOTO(skip_out, rc = 0);
1357 /* Write to new log all commands outside target device block */
1358 if (mrd->state == REPLACE_COPY)
1359 GOTO(copy_out, rc = 0);
1361 if (mrd->state == REPLACE_DONE &&
1362 (lcfg->lcfg_command == LCFG_ADD_UUID ||
1363 lcfg->lcfg_command == LCFG_ADD_CONN)) {
1365 CWARN("Previous failover is deleted, but new one is "
1366 "not set. This means you configure system "
1367 "without failover or passed wrong replace_nids "
1368 "command parameters. Device %s, passed nids %s\n",
1369 mrd->target.mti_svname, mrd->target.mti_params);
1370 GOTO(skip_out, rc = 0);
1373 rc = process_command(env, lcfg, mrd);
1380 /* Record is placed in temporary llog as is */
1381 rc = llog_write(env, mrd->temp_llh, rec, LLOG_NEXT_IDX);
1383 CDEBUG(D_MGS, "Copied idx=%d, rc=%d, len=%d, cmd %x %s %s\n",
1384 rec->lrh_index, rc, rec->lrh_len, lcfg->lcfg_command,
1385 lustre_cfg_string(lcfg, 0), lustre_cfg_string(lcfg, 1));
1389 CDEBUG(D_MGS, "Skipped idx=%d, rc=%d, len=%d, cmd %x %s %s\n",
1390 rec->lrh_index, rc, rec->lrh_len, lcfg->lcfg_command,
1391 lustre_cfg_string(lcfg, 0), lustre_cfg_string(lcfg, 1));
1395 static int mgs_log_is_empty(const struct lu_env *env,
1396 struct mgs_device *mgs, char *name)
1398 struct llog_ctxt *ctxt;
1401 ctxt = llog_get_context(mgs->mgs_obd, LLOG_CONFIG_ORIG_CTXT);
1402 LASSERT(ctxt != NULL);
1404 rc = llog_is_empty(env, ctxt, name);
1405 llog_ctxt_put(ctxt);
1409 static int mgs_replace_log(const struct lu_env *env,
1410 struct obd_device *mgs,
1411 char *logname, char *devname,
1412 llog_cb_t replace_handler, void *data)
1414 struct llog_handle *orig_llh, *backup_llh;
1415 struct llog_ctxt *ctxt;
1416 struct mgs_replace_data *mrd;
1417 struct mgs_device *mgs_dev = lu2mgs_dev(mgs->obd_lu_dev);
1418 static struct obd_uuid cfg_uuid = { .uuid = "config_uuid" };
1420 int rc, rc2, buf_size;
1424 ctxt = llog_get_context(mgs, LLOG_CONFIG_ORIG_CTXT);
1425 LASSERT(ctxt != NULL);
1427 if (mgs_log_is_empty(env, mgs_dev, logname)) {
1428 /* Log is empty. Nothing to replace */
1429 GOTO(out_put, rc = 0);
1432 now = ktime_get_real_seconds();
1434 /* max time64_t in decimal fits into 20 bytes long string */
1435 buf_size = strlen(logname) + 1 + 20 + 1 + strlen(".bak") + 1;
1436 OBD_ALLOC(backup, buf_size);
1438 GOTO(out_put, rc = -ENOMEM);
1440 snprintf(backup, buf_size, "%s.%llu.bak", logname, now);
1442 rc = llog_backup(env, mgs, ctxt, ctxt, logname, backup);
1444 /* Now erase original log file. Connections are not allowed.
1445 Backup is already saved */
1446 rc = llog_erase(env, ctxt, NULL, logname);
1449 } else if (rc != -ENOENT) {
1450 CERROR("%s: can't make backup for %s: rc = %d\n",
1451 mgs->obd_name, logname, rc);
1455 /* open local log */
1456 rc = llog_open_create(env, ctxt, &orig_llh, NULL, logname);
1458 GOTO(out_restore, rc);
1460 rc = llog_init_handle(env, orig_llh, LLOG_F_IS_PLAIN, &cfg_uuid);
1462 GOTO(out_closel, rc);
1464 /* open backup llog */
1465 rc = llog_open(env, ctxt, &backup_llh, NULL, backup,
1468 GOTO(out_closel, rc);
1470 rc = llog_init_handle(env, backup_llh, LLOG_F_IS_PLAIN, NULL);
1472 GOTO(out_close, rc);
1474 if (llog_get_size(backup_llh) <= 1)
1475 GOTO(out_close, rc = 0);
1479 GOTO(out_close, rc = -ENOMEM);
1480 /* devname is only needed information to replace UUID records */
1482 strscpy(mrd->target.mti_svname, devname,
1483 sizeof(mrd->target.mti_svname));
1484 /* data is parsed in llog callback */
1486 strscpy(mrd->target.mti_params, data,
1487 sizeof(mrd->target.mti_params));
1488 /* Copy records to this temporary llog */
1489 mrd->temp_llh = orig_llh;
1491 rc = llog_process(env, backup_llh, replace_handler,
1495 rc2 = llog_close(NULL, backup_llh);
1499 rc2 = llog_close(NULL, orig_llh);
1505 CERROR("%s: llog should be restored: rc = %d\n",
1507 rc2 = llog_backup(env, mgs, ctxt, ctxt, backup,
1510 CERROR("%s: can't restore backup %s: rc = %d\n",
1511 mgs->obd_name, logname, rc2);
1515 OBD_FREE(backup, buf_size);
1518 llog_ctxt_put(ctxt);
1521 CERROR("%s: failed to replace log %s: rc = %d\n",
1522 mgs->obd_name, logname, rc);
1527 static int mgs_replace_nids_log(const struct lu_env *env,
1528 struct obd_device *obd,
1529 char *logname, char *devname, char *nids)
1531 CDEBUG(D_MGS, "Replace NIDs for %s in %s\n", devname, logname);
1532 return mgs_replace_log(env, obd, logname, devname,
1533 mgs_replace_nids_handler, nids);
1537 * Parse device name and get file system name and/or device index
1539 * @devname device name (ex. lustre-MDT0000)
1540 * @fsname file system name extracted from @devname and returned
1541 * to the caller (optional)
1542 * @index device index extracted from @devname and returned to
1543 * the caller (optional)
1545 * RETURN 0 success if we are only interested in
1546 * extracting fsname from devname.
1549 * LDD_F_SV_TYPE_* Besides extracting the fsname the
1550 * user also wants the index. Report to
1551 * the user the type of obd device the
1552 * returned index belongs too.
1554 * -EINVAL The obd device name is improper so
1555 * fsname could not be extracted.
1557 * -ENXIO Failed to extract the index out of
1558 * the obd device name. Most likely an
1559 * invalid obd device name
1561 static int mgs_parse_devname(char *devname, char *fsname, u32 *index)
1566 /* Extract fsname */
1568 rc = server_name2fsname(devname, fsname, NULL);
1570 CDEBUG(D_MGS, "Device name %s without fsname\n",
1577 rc = server_name2index(devname, index, NULL);
1579 CDEBUG(D_MGS, "Device name %s with wrong index\n",
1585 /* server_name2index can return LDD_F_SV_TYPE_* so always return rc */
1589 /* This is only called during replace_nids */
1590 static int only_mgs_is_running(struct obd_device *mgs_obd)
1592 int num_devices = class_obd_devs_count();
1593 int num_exports = 0;
1594 struct obd_export *exp;
1596 spin_lock(&mgs_obd->obd_dev_lock);
1597 list_for_each_entry(exp, &mgs_obd->obd_exports, exp_obd_chain) {
1598 /* skip self export */
1599 if (exp == mgs_obd->obd_self_export)
1604 if (num_exports > 1)
1605 CERROR("%s: node %s still connected during replace_nids connect_flags:%llx\n",
1607 libcfs_nidstr(&exp->exp_nid_stats->nid),
1608 exp_connect_flags(exp));
1610 spin_unlock(&mgs_obd->obd_dev_lock);
1612 /* osd, MGS and MGC + MGC export (nosvc starts MGC)
1613 * (wc -l /proc/fs/lustre/devices <= 3) && (non self exports == 1)
1615 return (num_devices <= 3) && (num_exports <= 1);
1618 static int name_create_mdt(char **logname, char *fsname, int mdt_idx)
1622 if (mdt_idx > INDEX_MAP_MAX_VALUE)
1625 snprintf(postfix, sizeof(postfix), "-MDT%04x", mdt_idx);
1626 return name_create(logname, fsname, postfix);
1630 * Replace nids for \a device to \a nids values
1632 * \param obd MGS obd device
1633 * \param devname nids need to be replaced for this device
1634 * (ex. lustre-OST0000)
1635 * \param nids nids list (ex. nid1,nid2,nid3)
1639 int mgs_replace_nids(const struct lu_env *env,
1640 struct mgs_device *mgs,
1641 char *devname, char *nids)
1643 /* Assume fsname is part of device name */
1644 char fsname[MTI_NAME_MAXLEN];
1648 struct fs_db *fsdb = NULL;
1651 struct obd_device *mgs_obd = mgs->mgs_obd;
1654 /* We can only change NIDs if no other nodes are connected */
1655 spin_lock(&mgs_obd->obd_dev_lock);
1656 conn_state = mgs_obd->obd_no_conn;
1657 mgs_obd->obd_no_conn = 1;
1658 spin_unlock(&mgs_obd->obd_dev_lock);
1660 /* We can not change nids if not only MGS is started */
1661 if (!only_mgs_is_running(mgs_obd)) {
1662 CERROR("Only MGS is allowed to be started\n");
1663 GOTO(out, rc = -EINPROGRESS);
1666 /* Get fsname and index */
1667 rc = mgs_parse_devname(devname, fsname, &index);
1671 rc = mgs_find_or_make_fsdb(env, mgs, fsname, &fsdb);
1673 CERROR("%s: can't find fsdb: rc = %d\n", fsname, rc);
1677 /* Process client llogs */
1678 rc = name_create(&logname, fsname, "-client");
1681 rc = mgs_replace_nids_log(env, mgs_obd, logname, devname, nids);
1682 name_destroy(&logname);
1684 CERROR("%s: error while replacing NIDs for %s: rc = %d\n",
1685 fsname, devname, rc);
1689 /* Process MDT llogs */
1690 for (i = 0; i < INDEX_MAP_SIZE * 8; i++) {
1691 if (!test_bit(i, fsdb->fsdb_mdt_index_map))
1693 rc = name_create_mdt(&logname, fsname, i);
1696 rc = mgs_replace_nids_log(env, mgs_obd, logname, devname, nids);
1697 name_destroy(&logname);
1703 spin_lock(&mgs_obd->obd_dev_lock);
1704 mgs_obd->obd_no_conn = conn_state;
1705 spin_unlock(&mgs_obd->obd_dev_lock);
1708 mgs_put_fsdb(mgs, fsdb);
1714 * This is called for every record in llog. Some of records are
1715 * skipped, others are copied to new log as is.
1716 * Records to be skipped are
1717 * marker records marked SKIP
1718 * records enclosed between SKIP markers
1720 * \param[in] llh log to be processed
1721 * \param[in] rec current record
1722 * \param[in] data mgs_replace_data structure
1726 static int mgs_clear_config_handler(const struct lu_env *env,
1727 struct llog_handle *llh,
1728 struct llog_rec_hdr *rec, void *data)
1730 struct mgs_replace_data *mrd;
1731 struct lustre_cfg *lcfg = REC_DATA(rec);
1732 int cfg_len = REC_DATA_LEN(rec);
1737 mrd = (struct mgs_replace_data *)data;
1739 if (rec->lrh_type != OBD_CFG_REC) {
1740 CDEBUG(D_MGS, "Config llog Name=%s, Record Index=%u, "
1741 "Unhandled Record Type=%#x\n", llh->lgh_name,
1742 rec->lrh_index, rec->lrh_type);
1746 rc = lustre_cfg_sanity_check(lcfg, cfg_len);
1748 CDEBUG(D_MGS, "Config llog Name=%s, Invalid config file.",
1753 if (lcfg->lcfg_command == LCFG_MARKER) {
1754 struct cfg_marker *marker;
1756 marker = lustre_cfg_buf(lcfg, 1);
1757 if (marker->cm_flags & CM_SKIP) {
1758 if (marker->cm_flags & CM_START)
1759 mrd->state = REPLACE_SKIP;
1760 if (marker->cm_flags & CM_END)
1761 mrd->state = REPLACE_COPY;
1762 /* SKIP section started or finished */
1763 CDEBUG(D_MGS, "Skip idx=%d, rc=%d, len=%d, "
1764 "cmd %x %s %s\n", rec->lrh_index, rc,
1765 rec->lrh_len, lcfg->lcfg_command,
1766 lustre_cfg_string(lcfg, 0),
1767 lustre_cfg_string(lcfg, 1));
1771 if (mrd->state == REPLACE_SKIP) {
1772 /* record enclosed between SKIP markers, skip it */
1773 CDEBUG(D_MGS, "Skip idx=%d, rc=%d, len=%d, "
1774 "cmd %x %s %s\n", rec->lrh_index, rc,
1775 rec->lrh_len, lcfg->lcfg_command,
1776 lustre_cfg_string(lcfg, 0),
1777 lustre_cfg_string(lcfg, 1));
1782 /* Record is placed in temporary llog as is */
1783 rc = llog_write(env, mrd->temp_llh, rec, LLOG_NEXT_IDX);
1785 CDEBUG(D_MGS, "Copied idx=%d, rc=%d, len=%d, cmd %x %s %s\n",
1786 rec->lrh_index, rc, rec->lrh_len, lcfg->lcfg_command,
1787 lustre_cfg_string(lcfg, 0), lustre_cfg_string(lcfg, 1));
1792 * Directory CONFIGS/ may contain files which are not config logs to
1793 * be cleared. Skip any llogs with a non-alphanumeric character after
1794 * the last '-'. For example, fsname-MDT0000.sav, fsname-MDT0000.bak,
1795 * fsname-MDT0000.orig, fsname-MDT0000~, fsname-MDT0000.20150516, etc.
1797 static bool config_to_clear(const char *logname)
1802 str = strrchr(logname, '-');
1807 while (isalnum(str[++i]));
1808 return str[i] == '\0';
1812 * Clear config logs for \a name
1815 * \param mgs MGS device
1816 * \param name name of device or of filesystem
1817 * (ex. lustre-OST0000 or lustre) in later case all logs
1822 int mgs_clear_configs(const struct lu_env *env,
1823 struct mgs_device *mgs, const char *name)
1825 struct list_head dentry_list;
1826 struct mgs_direntry *dirent, *n;
1829 struct obd_device *mgs_obd = mgs->mgs_obd;
1834 /* Prevent clients and servers from connecting to mgs */
1835 spin_lock(&mgs_obd->obd_dev_lock);
1836 conn_state = mgs_obd->obd_no_conn;
1837 mgs_obd->obd_no_conn = 1;
1838 spin_unlock(&mgs_obd->obd_dev_lock);
1841 * config logs cannot be cleaned if anything other than
1844 if (!only_mgs_is_running(mgs_obd)) {
1845 CERROR("Only MGS is allowed to be started\n");
1846 GOTO(out, rc = -EBUSY);
1849 /* Find all the logs in the CONFIGS directory */
1850 rc = class_dentry_readdir(env, mgs, &dentry_list);
1852 CERROR("%s: cannot read config directory '%s': rc = %d\n",
1853 mgs_obd->obd_name, MOUNT_CONFIGS_DIR, rc);
1857 if (list_empty(&dentry_list)) {
1858 CERROR("%s: list empty reading config dir '%s': rc = %d\n",
1859 mgs_obd->obd_name, MOUNT_CONFIGS_DIR, -ENOENT);
1860 GOTO(out, rc = -ENOENT);
1863 OBD_ALLOC(namedash, strlen(name) + 2);
1864 if (namedash == NULL)
1865 GOTO(out, rc = -ENOMEM);
1866 snprintf(namedash, strlen(name) + 2, "%s-", name);
1868 list_for_each_entry(dirent, &dentry_list, mde_list) {
1869 if (strcmp(name, dirent->mde_name) &&
1870 strncmp(namedash, dirent->mde_name, strlen(namedash)))
1872 if (!config_to_clear(dirent->mde_name))
1874 CDEBUG(D_MGS, "%s: Clear config log %s\n",
1875 mgs_obd->obd_name, dirent->mde_name);
1876 rc = mgs_replace_log(env, mgs_obd, dirent->mde_name, NULL,
1877 mgs_clear_config_handler, NULL);
1882 list_for_each_entry_safe(dirent, n, &dentry_list, mde_list) {
1883 list_del_init(&dirent->mde_list);
1884 mgs_direntry_free(dirent);
1886 OBD_FREE(namedash, strlen(name) + 2);
1888 spin_lock(&mgs_obd->obd_dev_lock);
1889 mgs_obd->obd_no_conn = conn_state;
1890 spin_unlock(&mgs_obd->obd_dev_lock);
1895 static int record_lov_setup(const struct lu_env *env, struct llog_handle *llh,
1896 char *devname, struct lov_desc *desc)
1898 struct mgs_thread_info *mgi = mgs_env_info(env);
1899 struct llog_cfg_rec *lcr;
1902 lustre_cfg_bufs_reset(&mgi->mgi_bufs, devname);
1903 lustre_cfg_bufs_set(&mgi->mgi_bufs, 1, desc, sizeof(*desc));
1904 lcr = lustre_cfg_rec_new(LCFG_SETUP, &mgi->mgi_bufs);
1908 rc = llog_write(env, llh, &lcr->lcr_hdr, LLOG_NEXT_IDX);
1909 lustre_cfg_rec_free(lcr);
1913 static int record_lmv_setup(const struct lu_env *env, struct llog_handle *llh,
1914 char *devname, struct lmv_desc *desc)
1916 struct mgs_thread_info *mgi = mgs_env_info(env);
1917 struct llog_cfg_rec *lcr;
1920 lustre_cfg_bufs_reset(&mgi->mgi_bufs, devname);
1921 lustre_cfg_bufs_set(&mgi->mgi_bufs, 1, desc, sizeof(*desc));
1922 lcr = lustre_cfg_rec_new(LCFG_SETUP, &mgi->mgi_bufs);
1926 rc = llog_write(env, llh, &lcr->lcr_hdr, LLOG_NEXT_IDX);
1927 lustre_cfg_rec_free(lcr);
1931 static inline int record_mdc_add(const struct lu_env *env,
1932 struct llog_handle *llh,
1933 char *logname, char *mdcuuid,
1934 char *mdtuuid, char *index,
1937 return record_base(env,llh,logname,0,LCFG_ADD_MDC,
1938 mdtuuid, index, gen, mdcuuid);
1941 static inline int record_lov_add(const struct lu_env *env,
1942 struct llog_handle *llh,
1943 char *lov_name, char *ost_uuid,
1944 char *index, char *gen)
1946 return record_base(env, llh, lov_name, 0, LCFG_LOV_ADD_OBD,
1947 ost_uuid, index, gen, NULL);
1950 static inline int record_mount_opt(const struct lu_env *env,
1951 struct llog_handle *llh,
1952 char *profile, char *lov_name,
1955 return record_base(env, llh, NULL, 0, LCFG_MOUNTOPT,
1956 profile, lov_name, mdc_name, NULL);
1959 static int record_marker(const struct lu_env *env,
1960 struct llog_handle *llh,
1961 struct fs_db *fsdb, __u32 flags,
1962 char *tgtname, char *comment)
1964 struct mgs_thread_info *mgi = mgs_env_info(env);
1965 struct llog_cfg_rec *lcr;
1969 if (flags & CM_START)
1971 mgi->mgi_marker.cm_step = fsdb->fsdb_gen;
1972 mgi->mgi_marker.cm_flags = flags;
1973 mgi->mgi_marker.cm_vers = LUSTRE_VERSION_CODE;
1974 cplen = strscpy(mgi->mgi_marker.cm_tgtname, tgtname,
1975 sizeof(mgi->mgi_marker.cm_tgtname));
1978 cplen = strscpy(mgi->mgi_marker.cm_comment, comment,
1979 sizeof(mgi->mgi_marker.cm_comment));
1982 mgi->mgi_marker.cm_createtime = ktime_get_real_seconds();
1983 mgi->mgi_marker.cm_canceltime = 0;
1984 lustre_cfg_bufs_reset(&mgi->mgi_bufs, NULL);
1985 lustre_cfg_bufs_set(&mgi->mgi_bufs, 1, &mgi->mgi_marker,
1986 sizeof(mgi->mgi_marker));
1987 lcr = lustre_cfg_rec_new(LCFG_MARKER, &mgi->mgi_bufs);
1991 rc = llog_write(env, llh, &lcr->lcr_hdr, LLOG_NEXT_IDX);
1992 lustre_cfg_rec_free(lcr);
1996 static int record_start_log(const struct lu_env *env, struct mgs_device *mgs,
1997 struct llog_handle **llh, char *name)
1999 static struct obd_uuid cfg_uuid = { .uuid = "config_uuid" };
2000 struct llog_ctxt *ctxt;
2005 GOTO(out, rc = -EBUSY);
2007 ctxt = llog_get_context(mgs->mgs_obd, LLOG_CONFIG_ORIG_CTXT);
2009 GOTO(out, rc = -ENODEV);
2010 LASSERT(ctxt->loc_obd == mgs->mgs_obd);
2012 rc = llog_open_create(env, ctxt, llh, NULL, name);
2015 rc = llog_init_handle(env, *llh, LLOG_F_IS_PLAIN, &cfg_uuid);
2017 llog_close(env, *llh);
2019 llog_ctxt_put(ctxt);
2022 CERROR("%s: can't start log %s: rc = %d\n",
2023 mgs->mgs_obd->obd_name, name, rc);
2029 static int record_end_log(const struct lu_env *env, struct llog_handle **llh)
2033 rc = llog_close(env, *llh);
2039 /******************** config "macros" *********************/
2041 /* write an lcfg directly into a log (with markers) */
2042 static int mgs_write_log_direct(const struct lu_env *env,
2043 struct mgs_device *mgs, struct fs_db *fsdb,
2044 char *logname, struct llog_cfg_rec *lcr,
2045 char *devname, char *comment)
2047 struct llog_handle *llh = NULL;
2052 rc = record_start_log(env, mgs, &llh, logname);
2056 /* FIXME These should be a single journal transaction */
2057 rc = record_marker(env, llh, fsdb, CM_START, devname, comment);
2060 rc = llog_write(env, llh, &lcr->lcr_hdr, LLOG_NEXT_IDX);
2063 rc = record_marker(env, llh, fsdb, CM_END, devname, comment);
2067 record_end_log(env, &llh);
2071 /* write the lcfg in all logs for the given fs */
2072 static int mgs_write_log_direct_all(const struct lu_env *env,
2073 struct mgs_device *mgs,
2075 struct mgs_target_info *mti,
2076 struct llog_cfg_rec *lcr, char *devname,
2077 char *comment, int server_only)
2079 struct list_head log_list;
2080 struct mgs_direntry *dirent, *n;
2081 char *fsname = mti->mti_fsname;
2082 int rc = 0, len = strlen(fsname);
2085 /* Find all the logs in the CONFIGS directory */
2086 rc = class_dentry_readdir(env, mgs, &log_list);
2090 /* Could use fsdb index maps instead of directory listing */
2091 list_for_each_entry_safe(dirent, n, &log_list, mde_list) {
2092 list_del_init(&dirent->mde_list);
2093 /* don't write to sptlrpc rule log */
2094 if (strstr(dirent->mde_name, "-sptlrpc") != NULL)
2097 /* caller wants write server logs only */
2098 if (server_only && strstr(dirent->mde_name, "-client") != NULL)
2101 if (strlen(dirent->mde_name) <= len ||
2102 strncmp(fsname, dirent->mde_name, len) != 0 ||
2103 dirent->mde_name[len] != '-')
2106 CDEBUG(D_MGS, "Changing log %s\n", dirent->mde_name);
2107 /* Erase any old settings of this same parameter */
2108 rc = mgs_modify(env, mgs, fsdb, mti, dirent->mde_name,
2109 devname, comment, CM_SKIP);
2111 CERROR("%s: Can't modify llog %s: rc = %d\n",
2112 mgs->mgs_obd->obd_name, dirent->mde_name, rc);
2115 /* Write the new one */
2116 rc = mgs_write_log_direct(env, mgs, fsdb, dirent->mde_name,
2117 lcr, devname, comment);
2119 CERROR("%s: writing log %s: rc = %d\n",
2120 mgs->mgs_obd->obd_name, dirent->mde_name, rc);
2122 mgs_direntry_free(dirent);
2128 static int mgs_write_log_osp_to_mdt(const struct lu_env *env,
2129 struct mgs_device *mgs,
2131 struct mgs_target_info *mti,
2132 int index, char *logname);
2133 static int mgs_write_log_osc_to_lov(const struct lu_env *env,
2134 struct mgs_device *mgs,
2136 struct mgs_target_info *mti,
2137 char *logname, char *suffix, char *lovname,
2138 enum lustre_sec_part sec_part, int flags);
2139 static int name_create_mdt_and_lov(char **logname, char **lovname,
2140 struct fs_db *fsdb, int i);
2142 static int add_param(char *params, char *key, char *val)
2144 char *start = params + strlen(params);
2145 char *end = params + sizeof(((struct mgs_target_info *)0)->mti_params);
2149 keylen = strlen(key);
2150 if (start + 1 + keylen + strlen(val) >= end) {
2151 CERROR("params are too long: %s %s%s\n",
2152 params, key != NULL ? key : "", val);
2156 sprintf(start, " %s%s", key != NULL ? key : "", val);
2161 * Walk through client config log record and convert the related records
2164 static int mgs_steal_client_llog_handler(const struct lu_env *env,
2165 struct llog_handle *llh,
2166 struct llog_rec_hdr *rec, void *data)
2168 struct mgs_device *mgs;
2169 struct obd_device *obd;
2170 struct mgs_target_info *mti, *tmti;
2172 int cfg_len = rec->lrh_len;
2173 char *cfg_buf = (char *)(rec + 1);
2174 struct lustre_cfg *lcfg;
2176 struct llog_handle *mdt_llh = NULL;
2177 static int got_an_osc_or_mdc = 0;
2178 /* 0: not found any osc/mdc;
2182 static int last_step = -1;
2187 mti = ((struct temp_comp *)data)->comp_mti;
2188 tmti = ((struct temp_comp *)data)->comp_tmti;
2189 fsdb = ((struct temp_comp *)data)->comp_fsdb;
2190 obd = ((struct temp_comp *)data)->comp_obd;
2191 mgs = lu2mgs_dev(obd->obd_lu_dev);
2194 if (rec->lrh_type != OBD_CFG_REC) {
2195 CERROR("unhandled lrh_type: %#x\n", rec->lrh_type);
2199 rc = lustre_cfg_sanity_check(cfg_buf, cfg_len);
2201 CERROR("Insane cfg\n");
2205 lcfg = (struct lustre_cfg *)cfg_buf;
2207 if (lcfg->lcfg_command == LCFG_MARKER) {
2208 struct cfg_marker *marker;
2209 marker = lustre_cfg_buf(lcfg, 1);
2210 if (!strncmp(marker->cm_comment, "add osc", 7) &&
2211 (marker->cm_flags & CM_START) &&
2212 !(marker->cm_flags & CM_SKIP)) {
2213 got_an_osc_or_mdc = 1;
2214 cplen = strscpy(tmti->mti_svname, marker->cm_tgtname,
2215 sizeof(tmti->mti_svname));
2218 rc = record_start_log(env, mgs, &mdt_llh,
2222 rc = record_marker(env, mdt_llh, fsdb, CM_START,
2223 mti->mti_svname, "add osc(copied)");
2224 record_end_log(env, &mdt_llh);
2225 last_step = marker->cm_step;
2228 if (!strncmp(marker->cm_comment, "add osc", 7) &&
2229 (marker->cm_flags & CM_END) &&
2230 !(marker->cm_flags & CM_SKIP)) {
2231 LASSERT(last_step == marker->cm_step);
2233 got_an_osc_or_mdc = 0;
2234 memset(tmti, 0, sizeof(*tmti));
2235 tmti->mti_flags = mti->mti_flags;
2236 rc = record_start_log(env, mgs, &mdt_llh,
2240 rc = record_marker(env, mdt_llh, fsdb, CM_END,
2241 mti->mti_svname, "add osc(copied)");
2242 record_end_log(env, &mdt_llh);
2245 if (!strncmp(marker->cm_comment, "add mdc", 7) &&
2246 (marker->cm_flags & CM_START) &&
2247 !(marker->cm_flags & CM_SKIP)) {
2248 got_an_osc_or_mdc = 2;
2249 last_step = marker->cm_step;
2250 memcpy(tmti->mti_svname, marker->cm_tgtname,
2251 strlen(marker->cm_tgtname));
2255 if (!strncmp(marker->cm_comment, "add mdc", 7) &&
2256 (marker->cm_flags & CM_END) &&
2257 !(marker->cm_flags & CM_SKIP)) {
2258 LASSERT(last_step == marker->cm_step);
2260 got_an_osc_or_mdc = 0;
2261 memset(tmti, 0, sizeof(*tmti));
2262 tmti->mti_flags = mti->mti_flags;
2267 if (got_an_osc_or_mdc == 0 || last_step < 0)
2270 if (lcfg->lcfg_command == LCFG_ADD_UUID) {
2271 lnet_nid_t nodenid = lcfg->lcfg_nid;
2272 char *nidstr = NULL;
2274 BUILD_BUG_ON(sizeof(tmti->mti_nidlist[0]) != LNET_NIDSTR_SIZE);
2276 nidstr = lustre_cfg_buf(lcfg, 2);
2278 if (!nidstr || !strlen(nidstr))
2282 if (strlen(tmti->mti_uuid) == 0) {
2285 if (target_supports_large_nid(mti))
2286 dst = tmti->mti_nidlist[tmti->mti_nid_count];
2288 /* target uuid not set, this config record is before
2289 * LCFG_SETUP, this nid is one of target node nid.
2293 rc = strscpy(dst, nidstr,
2299 tmti->mti_nids[tmti->mti_nid_count] =
2300 libcfs_str2nid(nidstr);
2304 libcfs_nid2str_r(nodenid, dst,
2307 tmti->mti_nids[tmti->mti_nid_count] =
2310 tmti->mti_nid_count++;
2312 char tmp[LNET_NIDSTR_SIZE];
2315 libcfs_nid2str_r(nodenid, tmp,
2319 /* failover node nid */
2320 rc = add_param(tmti->mti_params, PARAM_FAILNODE,
2327 if (lcfg->lcfg_command == LCFG_SETUP) {
2330 target = lustre_cfg_string(lcfg, 1);
2331 memcpy(tmti->mti_uuid, target, strlen(target));
2335 /* ignore client side sptlrpc_conf_log */
2336 if (lcfg->lcfg_command == LCFG_SPTLRPC_CONF)
2339 if (lcfg->lcfg_command == LCFG_ADD_MDC &&
2340 strstr(lustre_cfg_string(lcfg, 0), "-clilmv") != NULL) {
2343 if (sscanf(lustre_cfg_buf(lcfg, 2), "%d", &index) != 1)
2345 if (index == mti->mti_stripe_index) {
2347 "attempt to create MDT%04x->MDT%04x osp device\n",
2351 memcpy(tmti->mti_fsname, mti->mti_fsname,
2352 strlen(mti->mti_fsname));
2353 tmti->mti_stripe_index = index;
2355 rc = mgs_write_log_osp_to_mdt(env, mgs, fsdb, tmti,
2356 mti->mti_stripe_index,
2358 memset(tmti, 0, sizeof(*tmti));
2362 if (lcfg->lcfg_command == LCFG_LOV_ADD_OBD) {
2365 char *logname, *lovname;
2367 rc = name_create_mdt_and_lov(&logname, &lovname, fsdb,
2368 mti->mti_stripe_index);
2371 sprintf(mdt_index, "-MDT%04x", mti->mti_stripe_index);
2373 if (sscanf(lustre_cfg_buf(lcfg, 2), "%d", &index) != 1) {
2374 name_destroy(&logname);
2375 name_destroy(&lovname);
2379 tmti->mti_stripe_index = index;
2380 rc = mgs_write_log_osc_to_lov(env, mgs, fsdb, tmti, logname,
2383 name_destroy(&logname);
2384 name_destroy(&lovname);
2390 /* fsdb->fsdb_mutex is already held in mgs_write_log_target */
2391 /* stealed from mgs_get_fsdb_from_llog */
2392 static int mgs_steal_llog_for_mdt_from_client(const struct lu_env *env,
2393 struct mgs_device *mgs,
2395 struct temp_comp *comp)
2397 size_t mti_len = offsetof(struct mgs_target_info, mti_nidlist);
2398 struct llog_handle *loghandle;
2399 struct mgs_target_info *tmti;
2400 struct llog_ctxt *ctxt;
2405 ctxt = llog_get_context(mgs->mgs_obd, LLOG_CONFIG_ORIG_CTXT);
2406 LASSERT(ctxt != NULL);
2408 /* Create the mti for the osp registered by mgc_write_log_osp_to_mdt().
2409 * The function mgs_steal_client_llog_handle() will fill in the rest.
2411 if (target_supports_large_nid(comp->comp_mti))
2412 mti_len += comp->comp_mti->mti_nid_count * LNET_NIDSTR_SIZE;
2414 OBD_ALLOC(tmti, mti_len);
2416 GOTO(out_ctxt, rc = -ENOMEM);
2418 tmti->mti_flags = comp->comp_mti->mti_flags;
2419 comp->comp_tmti = tmti;
2420 comp->comp_obd = mgs->mgs_obd;
2422 rc = llog_open(env, ctxt, &loghandle, NULL, client_name,
2430 rc = llog_init_handle(env, loghandle, LLOG_F_IS_PLAIN, NULL);
2432 GOTO(out_close, rc);
2434 rc = llog_process_or_fork(env, loghandle, mgs_steal_client_llog_handler,
2435 (void *)comp, NULL, false);
2436 CDEBUG(D_MGS, "steal llog re = %d\n", rc);
2438 llog_close(env, loghandle);
2440 OBD_FREE(tmti, mti_len);
2442 llog_ctxt_put(ctxt);
2446 /* mount opt is the third thing in client logs */
2447 static int mgs_write_log_mount_opt(const struct lu_env *env,
2448 struct mgs_device *mgs, struct fs_db *fsdb,
2451 struct llog_handle *llh = NULL;
2456 CDEBUG(D_MGS, "Writing mount options log for %s\n", logname);
2458 rc = record_start_log(env, mgs, &llh, logname);
2462 rc = record_marker(env, llh, fsdb, CM_START, logname, "mount opts");
2465 rc = record_mount_opt(env, llh, logname, fsdb->fsdb_clilov,
2469 rc = record_marker(env, llh, fsdb, CM_END, logname, "mount opts");
2473 record_end_log(env, &llh);
2477 /* lmv is the second thing for client logs */
2478 /* copied from mgs_write_log_lov. Please refer to that. */
2479 static int mgs_write_log_lmv(const struct lu_env *env,
2480 struct mgs_device *mgs,
2482 struct mgs_target_info *mti,
2483 char *logname, char *lmvname)
2485 struct llog_handle *llh = NULL;
2486 struct lmv_desc *lmvdesc;
2491 CDEBUG(D_MGS, "Writing lmv(%s) log for %s\n", lmvname, logname);
2493 OBD_ALLOC_PTR(lmvdesc);
2494 if (lmvdesc == NULL)
2496 lmvdesc->ld_active_tgt_count = 0;
2497 lmvdesc->ld_tgt_count = 0;
2498 sprintf((char *)lmvdesc->ld_uuid.uuid, "%s_UUID", lmvname);
2499 uuid = (char *)lmvdesc->ld_uuid.uuid;
2501 rc = record_start_log(env, mgs, &llh, logname);
2504 rc = record_marker(env, llh, fsdb, CM_START, lmvname, "lmv setup");
2507 rc = record_attach(env, llh, lmvname, "lmv", uuid);
2510 rc = record_lmv_setup(env, llh, lmvname, lmvdesc);
2513 rc = record_marker(env, llh, fsdb, CM_END, lmvname, "lmv setup");
2517 record_end_log(env, &llh);
2519 OBD_FREE_PTR(lmvdesc);
2523 /* lov is the first thing in the mdt and client logs */
2524 static int mgs_write_log_lov(const struct lu_env *env, struct mgs_device *mgs,
2525 struct fs_db *fsdb, struct mgs_target_info *mti,
2526 char *logname, char *lovname)
2528 struct llog_handle *llh = NULL;
2529 struct lov_desc *lovdesc;
2534 CDEBUG(D_MGS, "Writing lov(%s) log for %s\n", lovname, logname);
2537 * #01 L attach 0:lov_mdsA 1:lov 2:71ccb_lov_mdsA_19f961a9e1
2538 * #02 L lov_setup 0:lov_mdsA 1:(struct lov_desc)
2539 * uuid=lov1_UUID, stripe count=1, size=1048576, offset=0, pattern=0
2542 /* FIXME just make lov_setup accept empty desc (put uuid in buf 2) */
2543 OBD_ALLOC_PTR(lovdesc);
2544 if (lovdesc == NULL)
2546 lovdesc->ld_magic = LOV_DESC_MAGIC;
2547 lovdesc->ld_tgt_count = 0;
2548 /* Defaults. Can be changed later by lcfg config_param */
2549 lovdesc->ld_default_stripe_count = 1;
2550 lovdesc->ld_pattern = LOV_PATTERN_RAID0;
2551 lovdesc->ld_default_stripe_size = LOV_DESC_STRIPE_SIZE_DEFAULT;
2552 lovdesc->ld_default_stripe_offset = -1;
2553 lovdesc->ld_qos_maxage = LOV_DESC_QOS_MAXAGE_DEFAULT;
2554 sprintf((char *)lovdesc->ld_uuid.uuid, "%s_UUID", lovname);
2555 /* can these be the same? */
2556 uuid = (char *)lovdesc->ld_uuid.uuid;
2558 /* This should always be the first entry in a log.
2559 * rc = mgs_clear_log(obd, logname);
2561 rc = record_start_log(env, mgs, &llh, logname);
2564 /* FIXME these should be a single journal transaction */
2565 rc = record_marker(env, llh, fsdb, CM_START, lovname, "lov setup");
2568 rc = record_attach(env, llh, lovname, "lov", uuid);
2571 rc = record_lov_setup(env, llh, lovname, lovdesc);
2574 rc = record_marker(env, llh, fsdb, CM_END, lovname, "lov setup");
2579 record_end_log(env, &llh);
2581 OBD_FREE_PTR(lovdesc);
2585 /* add failnids to open log */
2586 static int mgs_write_log_failnids(const struct lu_env *env,
2587 struct mgs_target_info *mti,
2588 struct llog_handle *llh,
2591 char *failnodeuuid = NULL;
2592 char *ptr = mti->mti_params;
2593 struct lnet_nid nid;
2597 * #03 L add_uuid nid=uml1@tcp(0x20000c0a80201) nal=90 0: 1:uml1_UUID
2598 * #04 L add_uuid nid=1@elan(0x1000000000001) nal=90 0: 1:uml1_UUID
2599 * #05 L setup 0:OSC_uml1_ost1_mdsA 1:ost1_UUID 2:uml1_UUID
2600 * #06 L add_uuid nid=uml2@tcp(0x20000c0a80202) nal=90 0: 1:uml2_UUID
2601 * #0x L add_uuid nid=2@elan(0x1000000000002) nal=90 0: 1:uml2_UUID
2602 * #07 L add_conn 0:OSC_uml1_ost1_mdsA 1:uml2_UUID
2606 * Pull failnid info out of params string, which may contain something
2607 * like "<nid1>,<nid2>:<nid3>,<nid4>". class_parse_nid() does not
2608 * complain about abnormal inputs like ",:<nid1>", "<nid1>:,<nid2>",
2609 * etc. However, convert_hostnames() should have caught those.
2611 while (class_find_param(ptr, PARAM_FAILNODE, &ptr) == 0) {
2612 while (class_parse_nid(ptr, &nid, &ptr) == 0) {
2613 char nidstr[LNET_NIDSTR_SIZE];
2615 if (failnodeuuid == NULL) {
2616 /* We don't know the failover node name,
2617 * so just use the first nid as the uuid */
2618 libcfs_nidstr_r(&nid, nidstr, sizeof(nidstr));
2619 rc = name_create(&failnodeuuid, nidstr, "");
2624 "add nid %s for failover uuid %s, client %s\n",
2625 libcfs_nidstr_r(&nid, nidstr, sizeof(nidstr)),
2626 failnodeuuid, cliname);
2627 rc = record_add_uuid(env, llh, &nid, failnodeuuid);
2629 * If *ptr is ':', we have added all NIDs for
2633 rc = record_add_conn(env, llh, cliname,
2635 name_destroy(&failnodeuuid);
2636 failnodeuuid = NULL;
2640 rc = record_add_conn(env, llh, cliname, failnodeuuid);
2641 name_destroy(&failnodeuuid);
2642 failnodeuuid = NULL;
2649 static int mgs_write_log_mdc_to_lmv(const struct lu_env *env,
2650 struct mgs_device *mgs,
2652 struct mgs_target_info *mti,
2653 char *logname, char *lmvname)
2655 char tmp[LNET_NIDSTR_SIZE], *nidstr;
2656 struct llog_handle *llh = NULL;
2657 char *mdcname = NULL;
2658 char *nodeuuid = NULL;
2659 char *mdcuuid = NULL;
2660 char *lmvuuid = NULL;
2665 if (mgs_log_is_empty(env, mgs, logname)) {
2666 CERROR("log is empty! Logical error\n");
2670 CDEBUG(D_MGS, "adding mdc for %s to log %s:lmv(%s)\n",
2671 mti->mti_svname, logname, lmvname);
2673 if (!target_supports_large_nid(mti)) {
2674 libcfs_nid2str_r(mti->mti_nids[0], tmp, sizeof(tmp));
2677 nidstr = mti->mti_nidlist[0];
2680 rc = name_create(&nodeuuid, nidstr, "");
2683 rc = name_create(&mdcname, mti->mti_svname, "-mdc");
2686 rc = name_create(&mdcuuid, mdcname, "_UUID");
2689 rc = name_create(&lmvuuid, lmvname, "_UUID");
2693 rc = mgs_modify(env, mgs, fsdb, mti, logname, mti->mti_svname,
2694 "add mdc", CM_SKIP);
2698 rc = record_start_log(env, mgs, &llh, logname);
2701 rc = record_marker(env, llh, fsdb, CM_START, mti->mti_svname,
2706 for (i = 0; i < mti->mti_nid_count; i++) {
2707 struct lnet_nid nid;
2709 if (target_supports_large_nid(mti)) {
2710 rc = libcfs_strnid(&nid, mti->mti_nidlist[i]);
2714 lnet_nid4_to_nid(mti->mti_nids[i], &nid);
2717 CDEBUG(D_MGS, "add nid %s for mdt\n", libcfs_nidstr(&nid));
2718 rc = record_add_uuid(env, llh, &nid, nodeuuid);
2723 rc = record_attach(env, llh, mdcname, LUSTRE_MDC_NAME, lmvuuid);
2726 rc = record_setup(env, llh, mdcname, mti->mti_uuid, nodeuuid,
2730 rc = mgs_write_log_failnids(env, mti, llh, mdcname);
2733 snprintf(index, sizeof(index), "%d", mti->mti_stripe_index);
2734 rc = record_mdc_add(env, llh, lmvname, mdcuuid, mti->mti_uuid,
2738 rc = record_marker(env, llh, fsdb, CM_END, mti->mti_svname,
2743 record_end_log(env, &llh);
2745 name_destroy(&lmvuuid);
2746 name_destroy(&mdcuuid);
2747 name_destroy(&mdcname);
2748 name_destroy(&nodeuuid);
2752 static inline int name_create_lov(char **lovname, char *mdtname,
2753 struct fs_db *fsdb, int index)
2756 if (index == 0 && test_bit(FSDB_OSCNAME18, &fsdb->fsdb_flags))
2757 return name_create(lovname, fsdb->fsdb_name, "-mdtlov");
2759 return name_create(lovname, mdtname, "-mdtlov");
2762 static int name_create_mdt_and_lov(char **logname, char **lovname,
2763 struct fs_db *fsdb, int i)
2767 rc = name_create_mdt(logname, fsdb->fsdb_name, i);
2771 if (i == 0 && test_bit(FSDB_OSCNAME18, &fsdb->fsdb_flags))
2772 rc = name_create(lovname, fsdb->fsdb_name, "-mdtlov");
2774 rc = name_create(lovname, *logname, "-mdtlov");
2776 name_destroy(logname);
2782 static inline int name_create_mdt_osc(char **oscname, char *ostname,
2783 struct fs_db *fsdb, int i)
2787 if (i == 0 && test_bit(FSDB_OSCNAME18, &fsdb->fsdb_flags))
2788 sprintf(suffix, "-osc");
2790 sprintf(suffix, "-osc-MDT%04x", i);
2791 return name_create(oscname, ostname, suffix);
2794 /* add new mdc to already existent MDS */
2795 static int mgs_write_log_osp_to_mdt(const struct lu_env *env,
2796 struct mgs_device *mgs,
2798 struct mgs_target_info *mti,
2799 int mdt_index, char *logname)
2801 char tmp[LNET_NIDSTR_SIZE], *nidstr;
2802 struct llog_handle *llh = NULL;
2803 char *nodeuuid = NULL;
2804 char *ospname = NULL;
2805 char *lovuuid = NULL;
2806 char *mdtuuid = NULL;
2807 char *svname = NULL;
2808 char *mdtname = NULL;
2809 char *lovname = NULL;
2814 if (mgs_log_is_empty(env, mgs, mti->mti_svname)) {
2815 CERROR("log is empty! Logical error\n");
2819 CDEBUG(D_MGS, "adding osp index %d to %s\n", mti->mti_stripe_index,
2822 rc = name_create_mdt(&mdtname, fsdb->fsdb_name, mti->mti_stripe_index);
2826 if (!target_supports_large_nid(mti)) {
2827 libcfs_nid2str_r(mti->mti_nids[0], tmp, sizeof(tmp));
2830 nidstr = mti->mti_nidlist[0];
2833 rc = name_create(&nodeuuid, nidstr, "");
2835 GOTO(out_destory, rc);
2837 rc = name_create(&svname, mdtname, "-osp");
2839 GOTO(out_destory, rc);
2841 sprintf(index_str, "-MDT%04x", mdt_index);
2842 rc = name_create(&ospname, svname, index_str);
2844 GOTO(out_destory, rc);
2846 rc = name_create_lov(&lovname, logname, fsdb, mdt_index);
2848 GOTO(out_destory, rc);
2850 rc = name_create(&lovuuid, lovname, "_UUID");
2852 GOTO(out_destory, rc);
2854 rc = name_create(&mdtuuid, mdtname, "_UUID");
2856 GOTO(out_destory, rc);
2858 rc = mgs_modify(env, mgs, fsdb, mti, logname, mti->mti_svname,
2859 "add osp", CM_SKIP);
2861 GOTO(out_destory, rc);
2863 rc = record_start_log(env, mgs, &llh, logname);
2865 GOTO(out_destory, rc);
2867 rc = record_marker(env, llh, fsdb, CM_START, mti->mti_svname,
2870 GOTO(out_destory, rc);
2872 for (i = 0; i < mti->mti_nid_count; i++) {
2873 struct lnet_nid nid;
2875 if (target_supports_large_nid(mti)) {
2876 rc = libcfs_strnid(&nid, mti->mti_nidlist[i]);
2880 lnet_nid4_to_nid(mti->mti_nids[i], &nid);
2883 CDEBUG(D_MGS, "add nid %s for mdt\n", libcfs_nidstr(&nid));
2884 rc = record_add_uuid(env, llh, &nid, nodeuuid);
2889 rc = record_attach(env, llh, ospname, LUSTRE_OSP_NAME, lovuuid);
2893 rc = record_setup(env, llh, ospname, mti->mti_uuid, nodeuuid,
2898 rc = mgs_write_log_failnids(env, mti, llh, ospname);
2902 /* Add mdc(osp) to lod */
2903 snprintf(index_str, sizeof(index_str), "%d", mti->mti_stripe_index);
2904 rc = record_base(env, llh, lovname, 0, LCFG_ADD_MDC, mti->mti_uuid,
2905 index_str, "1", NULL);
2909 rc = record_marker(env, llh, fsdb, CM_END, mti->mti_svname, "add osp");
2914 record_end_log(env, &llh);
2917 name_destroy(&mdtuuid);
2918 name_destroy(&lovuuid);
2919 name_destroy(&lovname);
2920 name_destroy(&ospname);
2921 name_destroy(&svname);
2922 name_destroy(&nodeuuid);
2923 name_destroy(&mdtname);
2927 static int mgs_write_log_mdt0(const struct lu_env *env,
2928 struct mgs_device *mgs,
2930 struct mgs_target_info *mti)
2932 char *log = mti->mti_svname;
2933 struct llog_handle *llh = NULL;
2934 struct obd_uuid *uuid;
2937 char *ptr = mti->mti_params;
2938 int rc = 0, failout = 0;
2941 OBD_ALLOC_PTR(uuid);
2945 if (class_find_param(ptr, PARAM_FAILMODE, &ptr) == 0)
2946 failout = (strncmp(ptr, "failout", 7) == 0);
2948 rc = name_create(&lovname, log, "-mdtlov");
2951 if (mgs_log_is_empty(env, mgs, log)) {
2952 rc = mgs_write_log_lov(env, mgs, fsdb, mti, log, lovname);
2957 sprintf(mdt_index, "%d", mti->mti_stripe_index);
2959 rc = record_start_log(env, mgs, &llh, log);
2963 /* add MDT itself */
2965 /* FIXME this whole fn should be a single journal transaction */
2966 sprintf(uuid->uuid, "%s_UUID", log);
2967 rc = record_marker(env, llh, fsdb, CM_START, log, "add mdt");
2970 rc = record_attach(env, llh, log, LUSTRE_MDT_NAME, uuid->uuid);
2973 rc = record_mount_opt(env, llh, log, lovname, NULL);
2976 rc = record_setup(env, llh, log, uuid->uuid, mdt_index, lovname,
2977 failout ? "n" : "f");
2980 rc = record_marker(env, llh, fsdb, CM_END, log, "add mdt");
2984 record_end_log(env, &llh);
2986 name_destroy(&lovname);
2992 /* envelope method for all layers log */
2993 static int mgs_write_log_mdt(const struct lu_env *env,
2994 struct mgs_device *mgs,
2996 struct mgs_target_info *mti)
2998 struct mgs_thread_info *mgi = mgs_env_info(env);
2999 struct llog_handle *llh = NULL;
3004 CDEBUG(D_MGS, "writing new mdt %s\n", mti->mti_svname);
3006 if (mti->mti_uuid[0] == '\0') {
3007 /* Make up our own uuid */
3008 snprintf(mti->mti_uuid, sizeof(mti->mti_uuid),
3009 "%s_UUID", mti->mti_svname);
3013 rc = mgs_write_log_mdt0(env, mgs, fsdb, mti);
3017 /* Append the mdt info to the client log */
3018 rc = name_create(&cliname, mti->mti_fsname, "-client");
3022 if (mgs_log_is_empty(env, mgs, cliname)) {
3023 /* Start client log */
3024 rc = mgs_write_log_lov(env, mgs, fsdb, mti, cliname,
3028 rc = mgs_write_log_lmv(env, mgs, fsdb, mti, cliname,
3032 rc = mgs_write_log_mount_opt(env, mgs, fsdb, cliname);
3038 * #09 L add_uuid nid=uml1@tcp(0x20000c0a80201) 0: 1:uml1_UUID
3039 * #10 L attach 0:MDC_uml1_mdsA_MNT_client 1:mdc 2:1d834_MNT_client_03f
3040 * #11 L setup 0:MDC_uml1_mdsA_MNT_client 1:mdsA_UUID 2:uml1_UUID
3041 * #12 L add_uuid nid=uml2@tcp(0x20000c0a80202) 0: 1:uml2_UUID
3042 * #13 L add_conn 0:MDC_uml1_mdsA_MNT_client 1:uml2_UUID
3045 /* copy client info about lov/lmv */
3046 mgi->mgi_comp.comp_mti = mti;
3047 mgi->mgi_comp.comp_fsdb = fsdb;
3049 rc = mgs_steal_llog_for_mdt_from_client(env, mgs, cliname,
3053 rc = mgs_write_log_mdc_to_lmv(env, mgs, fsdb, mti, cliname,
3058 rc = record_start_log(env, mgs, &llh, cliname);
3062 /* for_all_existing_mdt except current one */
3063 for (i = 0; i < INDEX_MAP_SIZE * 8; i++) {
3064 if (i != mti->mti_stripe_index &&
3065 test_bit(i, fsdb->fsdb_mdt_index_map)) {
3068 rc = name_create_mdt(&logname, fsdb->fsdb_name, i);
3072 /* NB: If the log for the MDT is empty, it means
3073 * the MDT is only added to the index
3074 * map, and not being process yet, i.e. this
3075 * is an unregistered MDT, see mgs_write_log_target().
3076 * so we should skip it. Otherwise
3078 * 1. MGS get register request for MDT1 and MDT2.
3080 * 2. Then both MDT1 and MDT2 are added into
3081 * fsdb_mdt_index_map. (see mgs_set_index()).
3083 * 3. Then MDT1 get the lock of fsdb_mutex, then
3084 * generate the config log, here, it will regard MDT2
3085 * as an existent MDT, and generate "add osp" for
3086 * lustre-MDT0001-osp-MDT0002. Note: at the moment
3087 * MDT0002 config log is still empty, so it will
3088 * add "add osp" even before "lov setup", which
3089 * will definitly cause trouble.
3091 * 4. MDT1 registeration finished, fsdb_mutex is
3092 * released, then MDT2 get in, then in above
3093 * mgs_steal_llog_for_mdt_from_client(), it will
3094 * add another osp log for lustre-MDT0001-osp-MDT0002,
3095 * which will cause another trouble.*/
3096 if (!mgs_log_is_empty(env, mgs, logname))
3097 rc = mgs_write_log_osp_to_mdt(env, mgs, fsdb,
3100 name_destroy(&logname);
3106 record_end_log(env, &llh);
3108 name_destroy(&cliname);
3112 /* Add the ost info to the client/mdt lov */
3113 static int mgs_write_log_osc_to_lov(const struct lu_env *env,
3114 struct mgs_device *mgs, struct fs_db *fsdb,
3115 struct mgs_target_info *mti,
3116 char *logname, char *suffix, char *lovname,
3117 enum lustre_sec_part sec_part, int flags)
3119 char tmp[LNET_NIDSTR_SIZE], *nidstr;
3120 struct llog_handle *llh = NULL;
3121 char *nodeuuid = NULL;
3122 char *oscname = NULL;
3123 char *oscuuid = NULL;
3124 char *lovuuid = NULL;
3125 char *svname = NULL;
3130 CDEBUG(D_INFO, "adding osc for %s to log %s\n",
3131 mti->mti_svname, logname);
3133 if (mgs_log_is_empty(env, mgs, logname)) {
3134 CERROR("log is empty! Logical error\n");
3138 if (!target_supports_large_nid(mti)) {
3139 libcfs_nid2str_r(mti->mti_nids[0], tmp, sizeof(tmp));
3142 nidstr = mti->mti_nidlist[0];
3145 rc = name_create(&nodeuuid, nidstr, "");
3148 rc = name_create(&svname, mti->mti_svname, "-osc");
3152 /* for the system upgraded from old 1.8, keep using the old osc naming
3153 * style for mdt, see name_create_mdt_osc(). LU-1257 */
3154 if (test_bit(FSDB_OSCNAME18, &fsdb->fsdb_flags))
3155 rc = name_create(&oscname, svname, "");
3157 rc = name_create(&oscname, svname, suffix);
3161 rc = name_create(&oscuuid, oscname, "_UUID");
3164 rc = name_create(&lovuuid, lovname, "_UUID");
3169 * #03 L add_uuid nid=uml1@tcp(0x20000c0a80201) 0: 1:uml1_UUID
3171 * #04 L add_uuid nid=1@elan(0x1000000000001) nal=90 0: 1:uml1_UUID
3172 * #04 L attach 0:OSC_uml1_ost1_MNT_client 1:osc 2:89070_lov1_a41dff51a
3173 * #05 L setup 0:OSC_uml1_ost1_MNT_client 1:ost1_UUID 2:uml1_UUID
3175 * #06 L add_uuid nid=uml2@tcp(0x20000c0a80202) 0: 1:uml2_UUID
3176 * #07 L add_conn 0:OSC_uml1_ost1_MNT_client 1:uml2_UUID
3177 * #08 L lov_modify_tgts add 0:lov1 1:ost1_UUID 2(index):0 3(gen):1
3180 rc = record_start_log(env, mgs, &llh, logname);
3184 /* FIXME these should be a single journal transaction */
3185 rc = record_marker(env, llh, fsdb, CM_START | flags, mti->mti_svname,
3190 /* NB: don't change record order, because upon MDT steal OSC config
3191 * from client, it treats all nids before LCFG_SETUP as target nids
3192 * (multiple interfaces), while nids after as failover node nids.
3193 * See mgs_steal_client_llog_handler() LCFG_ADD_UUID.
3195 for (i = 0; i < mti->mti_nid_count; i++) {
3196 struct lnet_nid nid;
3198 if (target_supports_large_nid(mti)) {
3199 rc = libcfs_strnid(&nid, mti->mti_nidlist[i]);
3203 lnet_nid4_to_nid(mti->mti_nids[i], &nid);
3206 CDEBUG(D_MGS, "add nid %s\n", libcfs_nidstr(&nid));
3207 rc = record_add_uuid(env, llh, &nid, nodeuuid);
3212 rc = record_attach(env, llh, oscname, LUSTRE_OSC_NAME, lovuuid);
3215 rc = record_setup(env, llh, oscname, mti->mti_uuid, nodeuuid,
3219 rc = mgs_write_log_failnids(env, mti, llh, oscname);
3223 snprintf(index, sizeof(index), "%d", mti->mti_stripe_index);
3225 rc = record_lov_add(env, llh, lovname, mti->mti_uuid, index, "1");
3228 rc = record_marker(env, llh, fsdb, CM_END | flags, mti->mti_svname,
3233 record_end_log(env, &llh);
3235 name_destroy(&lovuuid);
3236 name_destroy(&oscuuid);
3237 name_destroy(&oscname);
3238 name_destroy(&svname);
3239 name_destroy(&nodeuuid);
3243 static int mgs_write_log_ost(const struct lu_env *env,
3244 struct mgs_device *mgs, struct fs_db *fsdb,
3245 struct mgs_target_info *mti)
3247 struct llog_handle *llh = NULL;
3248 char *logname, *lovname;
3249 char *ptr = mti->mti_params;
3250 int rc, flags = 0, failout = 0, i;
3253 CDEBUG(D_MGS, "writing new ost %s\n", mti->mti_svname);
3255 /* The ost startup log */
3257 /* If the ost log already exists, that means that someone reformatted
3258 * the ost and it called target_add again.
3260 if (!mgs_log_is_empty(env, mgs, mti->mti_svname)) {
3261 LCONSOLE_ERROR_MSG(0x141,
3262 "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",
3268 * attach obdfilter ost1 ost1_UUID
3269 * setup /dev/loop2 ldiskfs f|n errors=remount-ro,user_xattr
3271 if (class_find_param(ptr, PARAM_FAILMODE, &ptr) == 0)
3272 failout = (strncmp(ptr, "failout", 7) == 0);
3273 rc = record_start_log(env, mgs, &llh, mti->mti_svname);
3276 /* FIXME these should be a single journal transaction */
3277 rc = record_marker(env, llh, fsdb, CM_START, mti->mti_svname,"add ost");
3280 if (*mti->mti_uuid == '\0')
3281 snprintf(mti->mti_uuid, sizeof(mti->mti_uuid),
3282 "%s_UUID", mti->mti_svname);
3283 rc = record_attach(env, llh, mti->mti_svname,
3284 "obdfilter"/*LUSTRE_OST_NAME*/, mti->mti_uuid);
3287 rc = record_setup(env, llh, mti->mti_svname,
3288 "dev"/*ignored*/, "type"/*ignored*/,
3289 failout ? "n" : "f", NULL/*options*/);
3292 rc = record_marker(env, llh, fsdb, CM_END, mti->mti_svname, "add ost");
3296 record_end_log(env, &llh);
3299 /* We also have to update the other logs where this osc is part of
3303 if (test_bit(FSDB_OLDLOG14, &fsdb->fsdb_flags)) {
3304 /* If we're upgrading, the old mdt log already has our
3305 * entry. Let's do a fake one for fun.
3307 /* Note that we can't add any new failnids, since we don't
3308 * know the old osc names.
3310 flags = CM_SKIP | CM_UPGRADE146;
3311 } else if ((mti->mti_flags & LDD_F_UPDATE) != LDD_F_UPDATE) {
3312 /* If the update flag isn't set, don't update client/mdt
3316 LCONSOLE_WARN("Client log for %s was not updated; writeconf the MDT first to regenerate it.\n",
3320 /* Add ost to all MDT lov defs */
3321 for (i = 0; i < INDEX_MAP_SIZE * 8; i++) {
3322 if (test_bit(i, fsdb->fsdb_mdt_index_map)) {
3325 rc = name_create_mdt_and_lov(&logname, &lovname, fsdb,
3330 snprintf(mdt_index, sizeof(mdt_index), "-MDT%04x", i);
3331 rc = mgs_write_log_osc_to_lov(env, mgs, fsdb, mti,
3333 lovname, LUSTRE_SP_MDT,
3335 name_destroy(&logname);
3336 name_destroy(&lovname);
3342 /* Append ost info to the client log */
3343 rc = name_create(&logname, mti->mti_fsname, "-client");
3346 if (mgs_log_is_empty(env, mgs, logname)) {
3347 /* Start client log */
3348 rc = mgs_write_log_lov(env, mgs, fsdb, mti, logname,
3352 rc = mgs_write_log_lmv(env, mgs, fsdb, mti, logname,
3356 rc = mgs_write_log_mount_opt(env, mgs, fsdb, logname);
3360 rc = mgs_write_log_osc_to_lov(env, mgs, fsdb, mti, logname, "",
3361 fsdb->fsdb_clilov, LUSTRE_SP_CLI, flags);
3363 name_destroy(&logname);
3367 static __inline__ int mgs_param_empty(char *ptr)
3369 char *tmp = strchr(ptr, '=');
3371 if (tmp && tmp[1] == '\0')
3376 static int mgs_write_log_failnid_internal(const struct lu_env *env,
3377 struct mgs_device *mgs,
3379 struct mgs_target_info *mti,
3380 char *logname, char *cliname)
3383 struct llog_handle *llh = NULL;
3385 if (mgs_param_empty(mti->mti_params)) {
3386 /* Remove _all_ failnids */
3387 rc = mgs_modify(env, mgs, fsdb, mti, logname,
3388 mti->mti_svname, "add failnid", CM_SKIP);
3389 return rc < 0 ? rc : 0;
3392 /* Otherwise failover nids are additive */
3393 rc = record_start_log(env, mgs, &llh, logname);
3396 /* FIXME this should be a single journal transaction */
3397 rc = record_marker(env, llh, fsdb, CM_START, mti->mti_svname,
3401 rc = mgs_write_log_failnids(env, mti, llh, cliname);
3404 rc = record_marker(env, llh, fsdb, CM_END,
3405 mti->mti_svname, "add failnid");
3407 record_end_log(env, &llh);
3411 /* Add additional failnids to an existing log.
3412 The mdc/osc must have been added to logs first */
3413 /* tcp nids must be in dotted-quad ascii -
3414 we can't resolve hostnames from the kernel. */
3415 static int mgs_write_log_add_failnid(const struct lu_env *env,
3416 struct mgs_device *mgs,
3418 struct mgs_target_info *mti)
3420 char *logname, *cliname;
3424 /* FIXME we currently can't erase the failnids
3425 * given when a target first registers, since they aren't part of
3426 * an "add uuid" stanza
3429 /* Verify that we know about this target */
3430 if (mgs_log_is_empty(env, mgs, mti->mti_svname)) {
3431 LCONSOLE_ERROR_MSG(0x142,
3432 "The target %s has not registered yet. It must be started before failnids can be added.\n",
3437 /* Create mdc/osc client name (e.g. lustre-OST0001-osc) */
3438 if (mti->mti_flags & LDD_F_SV_TYPE_MDT)
3439 rc = name_create(&cliname, mti->mti_svname, "-mdc");
3440 else if (mti->mti_flags & LDD_F_SV_TYPE_OST)
3441 rc = name_create(&cliname, mti->mti_svname, "-osc");
3448 /* Add failover nids to the client log */
3449 rc = name_create(&logname, mti->mti_fsname, "-client");
3451 name_destroy(&cliname);
3455 rc = mgs_write_log_failnid_internal(env, mgs, fsdb,mti,logname,cliname);
3456 name_destroy(&logname);
3457 name_destroy(&cliname);
3461 if (mti->mti_flags & LDD_F_SV_TYPE_OST) {
3462 /* Add OST failover nids to the MDT logs as well */
3465 for (i = 0; i < INDEX_MAP_SIZE * 8; i++) {
3466 if (!test_bit(i, fsdb->fsdb_mdt_index_map))
3468 rc = name_create_mdt(&logname, mti->mti_fsname, i);
3471 rc = name_create_mdt_osc(&cliname, mti->mti_svname,
3474 name_destroy(&logname);
3477 rc = mgs_write_log_failnid_internal(env, mgs, fsdb,
3480 name_destroy(&cliname);
3481 name_destroy(&logname);
3490 static int mgs_wlp_lcfg(const struct lu_env *env,
3491 struct mgs_device *mgs, struct fs_db *fsdb,
3492 struct mgs_target_info *mti,
3493 char *logname, struct lustre_cfg_bufs *bufs,
3494 char *tgtname, char *ptr)
3496 char comment[MTI_NAME_MAXLEN];
3498 struct llog_cfg_rec *lcr;
3501 /* Erase any old settings of this same parameter */
3502 strscpy(comment, ptr, sizeof(comment));
3503 /* But don't try to match the value. */
3504 tmp = strchr(comment, '=');
3507 /* FIXME we should skip settings that are the same as old values */
3508 rc = mgs_modify(env, mgs, fsdb, mti, logname, tgtname, comment,CM_SKIP);
3511 del = mgs_param_empty(ptr);
3513 LCONSOLE_INFO("%s parameter %s.%s in log %s\n", del ? "Disabling" : rc ?
3514 "Setting" : "Modifying", tgtname, comment, logname);
3516 /* mgs_modify() will return 1 if nothing had to be done */
3522 lustre_cfg_bufs_reset(bufs, tgtname);
3523 lustre_cfg_bufs_set_string(bufs, 1, ptr);
3524 if (mti->mti_flags & LDD_F_PARAM2)
3525 lustre_cfg_bufs_set_string(bufs, 2, LCTL_UPCALL);
3527 lcr = lustre_cfg_rec_new((mti->mti_flags & LDD_F_PARAM2) ?
3528 LCFG_SET_PARAM : LCFG_PARAM, bufs);
3532 rc = mgs_write_log_direct(env, mgs, fsdb, logname, lcr, tgtname,
3534 lustre_cfg_rec_free(lcr);
3538 /* write global variable settings into log */
3539 static int mgs_write_log_sys(const struct lu_env *env,
3540 struct mgs_device *mgs, struct fs_db *fsdb,
3541 struct mgs_target_info *mti, char *sys, char *ptr)
3543 struct mgs_thread_info *mgi = mgs_env_info(env);
3544 struct lustre_cfg *lcfg;
3545 struct llog_cfg_rec *lcr;
3547 int rc, cmd, convert = 1;
3549 if (class_match_param(ptr, PARAM_TIMEOUT, &tmp) == 0) {
3550 cmd = LCFG_SET_TIMEOUT;
3551 } else if (class_match_param(ptr, PARAM_LDLM_TIMEOUT, &tmp) == 0) {
3552 cmd = LCFG_SET_LDLM_TIMEOUT;
3553 /* Check for known params here so we can return error to lctl */
3554 } else if ((class_match_param(ptr, PARAM_AT_MIN, &tmp) == 0) ||
3555 (class_match_param(ptr, PARAM_AT_MAX, &tmp) == 0) ||
3556 (class_match_param(ptr, PARAM_AT_EXTRA, &tmp) == 0) ||
3557 (class_match_param(ptr, PARAM_AT_EARLY_MARGIN, &tmp) == 0) ||
3558 (class_match_param(ptr, PARAM_AT_HISTORY, &tmp) == 0)) {
3560 } else if (class_match_param(ptr, PARAM_JOBID_VAR, &tmp) == 0) {
3561 convert = 0; /* Don't convert string value to integer */
3567 if (mgs_param_empty(ptr))
3568 CDEBUG(D_MGS, "global '%s' removed\n", sys);
3570 CDEBUG(D_MGS, "global '%s' val=%s\n", sys, tmp);
3572 lustre_cfg_bufs_reset(&mgi->mgi_bufs, NULL);
3573 lustre_cfg_bufs_set_string(&mgi->mgi_bufs, 1, sys);
3574 if (!convert && *tmp != '\0')
3575 lustre_cfg_bufs_set_string(&mgi->mgi_bufs, 2, tmp);
3576 lcr = lustre_cfg_rec_new(cmd, &mgi->mgi_bufs);
3580 lcfg = &lcr->lcr_cfg;
3582 rc = kstrtouint(tmp, 0, &lcfg->lcfg_num);
3584 GOTO(out_rec_free, rc);
3589 /* truncate the comment to the parameter name */
3593 /* modify all servers and clients */
3594 rc = mgs_write_log_direct_all(env, mgs, fsdb, mti,
3595 *tmp == '\0' ? NULL : lcr,
3596 mti->mti_fsname, sys, 0);
3597 if (rc == 0 && *tmp != '\0') {
3599 case LCFG_SET_TIMEOUT:
3600 if (!obd_timeout_set || lcfg->lcfg_num > obd_timeout)
3601 class_process_config(lcfg);
3603 case LCFG_SET_LDLM_TIMEOUT:
3604 if (!ldlm_timeout_set || lcfg->lcfg_num > ldlm_timeout)
3605 class_process_config(lcfg);
3613 lustre_cfg_rec_free(lcr);
3617 /* write quota settings into log */
3618 static int mgs_write_log_quota(const struct lu_env *env, struct mgs_device *mgs,
3619 struct fs_db *fsdb, struct mgs_target_info *mti,
3620 char *quota, char *ptr)
3622 struct mgs_thread_info *mgi = mgs_env_info(env);
3623 struct llog_cfg_rec *lcr;
3626 int rc, cmd = LCFG_PARAM;
3628 /* support only 'meta' and 'data' pools so far */
3629 if (class_match_param(ptr, QUOTA_METAPOOL_NAME, &tmp) != 0 &&
3630 class_match_param(ptr, QUOTA_DATAPOOL_NAME, &tmp) != 0) {
3631 CERROR("parameter quota.%s isn't supported (only quota.mdt "
3632 "& quota.ost are)\n", ptr);
3637 CDEBUG(D_MGS, "global '%s' removed\n", quota);
3639 CDEBUG(D_MGS, "global '%s'\n", quota);
3641 if (strchr(tmp, 'u') == NULL && strchr(tmp, 'g') == NULL &&
3642 strchr(tmp, 'p') == NULL &&
3643 strcmp(tmp, "none") != 0) {
3644 CERROR("enable option(%s) isn't supported\n", tmp);
3649 lustre_cfg_bufs_reset(&mgi->mgi_bufs, mti->mti_fsname);
3650 lustre_cfg_bufs_set_string(&mgi->mgi_bufs, 1, quota);
3651 lcr = lustre_cfg_rec_new(cmd, &mgi->mgi_bufs);
3655 /* truncate the comment to the parameter name */
3660 /* XXX we duplicated quota enable information in all server
3661 * config logs, it should be moved to a separate config
3662 * log once we cleanup the config log for global param. */
3663 /* modify all servers */
3664 rc = mgs_write_log_direct_all(env, mgs, fsdb, mti,
3665 *tmp == '\0' ? NULL : lcr,
3666 mti->mti_fsname, quota, 1);
3668 lustre_cfg_rec_free(lcr);
3669 return rc < 0 ? rc : 0;
3672 static int mgs_srpc_set_param_disk(const struct lu_env *env,
3673 struct mgs_device *mgs,
3675 struct mgs_target_info *mti,
3678 struct mgs_thread_info *mgi = mgs_env_info(env);
3679 struct llog_cfg_rec *lcr;
3680 struct llog_handle *llh = NULL;
3682 char *comment, *ptr;
3688 ptr = strchr(param, '=');
3689 LASSERT(ptr != NULL);
3692 OBD_ALLOC(comment, len + 1);
3693 if (comment == NULL)
3695 strncpy(comment, param, len);
3696 comment[len] = '\0';
3699 lustre_cfg_bufs_reset(&mgi->mgi_bufs, mti->mti_svname);
3700 lustre_cfg_bufs_set_string(&mgi->mgi_bufs, 1, param);
3701 lcr = lustre_cfg_rec_new(LCFG_SPTLRPC_CONF, &mgi->mgi_bufs);
3703 GOTO(out_comment, rc = -ENOMEM);
3705 /* construct log name */
3706 rc = name_create(&logname, mti->mti_fsname, "-sptlrpc");
3710 if (mgs_log_is_empty(env, mgs, logname)) {
3711 rc = record_start_log(env, mgs, &llh, logname);
3714 record_end_log(env, &llh);
3717 /* obsolete old one */
3718 rc = mgs_modify(env, mgs, fsdb, mti, logname, mti->mti_svname,
3722 /* write the new one */
3723 rc = mgs_write_log_direct(env, mgs, fsdb, logname, lcr,
3724 mti->mti_svname, comment);
3726 CERROR("%s: error writing log %s: rc = %d\n",
3727 mgs->mgs_obd->obd_name, logname, rc);
3729 name_destroy(&logname);
3731 lustre_cfg_rec_free(lcr);
3733 OBD_FREE(comment, len + 1);
3737 static int mgs_srpc_set_param_udesc_mem(struct fs_db *fsdb,
3742 /* disable the adjustable udesc parameter for now, i.e. use default
3743 * setting that client always ship udesc to MDT if possible. to enable
3744 * it simply remove the following line
3748 ptr = strchr(param, '=');
3753 if (strcmp(param, PARAM_SRPC_UDESC))
3756 if (strcmp(ptr, "yes") == 0) {
3757 set_bit(FSDB_UDESC, &fsdb->fsdb_flags);
3758 CWARN("Enable user descriptor shipping from client to MDT\n");
3759 } else if (strcmp(ptr, "no") == 0) {
3760 clear_bit(FSDB_UDESC, &fsdb->fsdb_flags);
3761 CWARN("Disable user descriptor shipping from client to MDT\n");
3769 CERROR("Invalid param: %s\n", param);
3773 static int mgs_srpc_set_param_mem(struct fs_db *fsdb,
3777 struct sptlrpc_rule rule;
3778 struct sptlrpc_rule_set *rset;
3782 if (strncmp(param, PARAM_SRPC, sizeof(PARAM_SRPC) - 1) != 0) {
3783 CERROR("Invalid sptlrpc parameter: %s\n", param);
3787 if (strncmp(param, PARAM_SRPC_UDESC,
3788 sizeof(PARAM_SRPC_UDESC) - 1) == 0) {
3789 RETURN(mgs_srpc_set_param_udesc_mem(fsdb, param));
3792 if (strncmp(param, PARAM_SRPC_FLVR, sizeof(PARAM_SRPC_FLVR) - 1) != 0) {
3793 CERROR("Invalid sptlrpc flavor parameter: %s\n", param);
3797 param += sizeof(PARAM_SRPC_FLVR) - 1;
3799 rc = sptlrpc_parse_rule(param, &rule);
3803 /* mgs rules implies must be mgc->mgs */
3804 if (test_bit(FSDB_MGS_SELF, &fsdb->fsdb_flags)) {
3805 if ((rule.sr_from != LUSTRE_SP_MGC &&
3806 rule.sr_from != LUSTRE_SP_ANY) ||
3807 (rule.sr_to != LUSTRE_SP_MGS &&
3808 rule.sr_to != LUSTRE_SP_ANY))
3812 /* prepare room for this coming rule. svcname format should be:
3813 * - fsname: general rule
3814 * - fsname-tgtname: target-specific rule
3816 if (strchr(svname, '-')) {
3817 struct mgs_tgt_srpc_conf *tgtconf;
3820 for (tgtconf = fsdb->fsdb_srpc_tgt; tgtconf != NULL;
3821 tgtconf = tgtconf->mtsc_next) {
3822 if (!strcmp(tgtconf->mtsc_tgt, svname)) {
3831 OBD_ALLOC_PTR(tgtconf);
3832 if (tgtconf == NULL)
3835 name_len = strlen(svname);
3837 OBD_ALLOC(tgtconf->mtsc_tgt, name_len + 1);
3838 if (tgtconf->mtsc_tgt == NULL) {
3839 OBD_FREE_PTR(tgtconf);
3842 memcpy(tgtconf->mtsc_tgt, svname, name_len);
3844 tgtconf->mtsc_next = fsdb->fsdb_srpc_tgt;
3845 fsdb->fsdb_srpc_tgt = tgtconf;
3848 rset = &tgtconf->mtsc_rset;
3849 } else if (strcmp(svname, MGSSELF_NAME) == 0) {
3850 /* put _mgs related srpc rule directly in mgs ruleset */
3851 rset = &fsdb->fsdb_mgs->mgs_lut.lut_sptlrpc_rset;
3853 rset = &fsdb->fsdb_srpc_gen;
3856 rc = sptlrpc_rule_set_merge(rset, &rule);
3861 static int mgs_srpc_set_param(const struct lu_env *env,
3862 struct mgs_device *mgs,
3864 struct mgs_target_info *mti,
3874 /* keep a copy of original param, which could be destroyed
3877 copy_size = strlen(param) + 1;
3878 OBD_ALLOC(copy, copy_size);
3881 memcpy(copy, param, copy_size);
3883 rc = mgs_srpc_set_param_mem(fsdb, mti->mti_svname, param);
3887 /* previous steps guaranteed the syntax is correct */
3888 rc = mgs_srpc_set_param_disk(env, mgs, fsdb, mti, copy);
3892 if (test_bit(FSDB_MGS_SELF, &fsdb->fsdb_flags)) {
3894 * for mgs rules, make them effective immediately.
3896 LASSERT(fsdb->fsdb_srpc_tgt == NULL);
3897 sptlrpc_target_update_exp_flavor(mgs->mgs_obd,
3898 &fsdb->fsdb_srpc_gen);
3902 OBD_FREE(copy, copy_size);
3906 struct mgs_srpc_read_data {
3907 struct fs_db *msrd_fsdb;
3911 static int mgs_srpc_read_handler(const struct lu_env *env,
3912 struct llog_handle *llh,
3913 struct llog_rec_hdr *rec, void *data)
3915 struct mgs_srpc_read_data *msrd = data;
3916 struct cfg_marker *marker;
3917 struct lustre_cfg *lcfg = REC_DATA(rec);
3918 char *svname, *param;
3922 if (rec->lrh_type != OBD_CFG_REC) {
3923 CERROR("unhandled lrh_type: %#x\n", rec->lrh_type);
3927 cfg_len = REC_DATA_LEN(rec);
3929 rc = lustre_cfg_sanity_check(lcfg, cfg_len);
3931 CERROR("Insane cfg\n");
3935 if (lcfg->lcfg_command == LCFG_MARKER) {
3936 marker = lustre_cfg_buf(lcfg, 1);
3938 if (marker->cm_flags & CM_START &&
3939 marker->cm_flags & CM_SKIP)
3940 msrd->msrd_skip = 1;
3941 if (marker->cm_flags & CM_END)
3942 msrd->msrd_skip = 0;
3947 if (msrd->msrd_skip)
3950 if (lcfg->lcfg_command != LCFG_SPTLRPC_CONF) {
3951 CERROR("invalid command (%x)\n", lcfg->lcfg_command);
3955 svname = lustre_cfg_string(lcfg, 0);
3956 if (svname == NULL) {
3957 CERROR("svname is empty\n");
3961 param = lustre_cfg_string(lcfg, 1);
3962 if (param == NULL) {
3963 CERROR("param is empty\n");
3967 rc = mgs_srpc_set_param_mem(msrd->msrd_fsdb, svname, param);
3969 CERROR("read sptlrpc record error (%d): %s\n", rc, param);
3974 int mgs_get_fsdb_srpc_from_llog(const struct lu_env *env,
3975 struct mgs_device *mgs,
3978 struct llog_handle *llh = NULL;
3979 struct llog_ctxt *ctxt;
3981 struct mgs_srpc_read_data msrd;
3985 /* construct log name */
3986 rc = name_create(&logname, fsdb->fsdb_name, "-sptlrpc");
3990 ctxt = llog_get_context(mgs->mgs_obd, LLOG_CONFIG_ORIG_CTXT);
3991 LASSERT(ctxt != NULL);
3993 if (mgs_log_is_empty(env, mgs, logname))
3996 rc = llog_open(env, ctxt, &llh, NULL, logname,
4004 rc = llog_init_handle(env, llh, LLOG_F_IS_PLAIN, NULL);
4006 GOTO(out_close, rc);
4008 if (llog_get_size(llh) <= 1)
4009 GOTO(out_close, rc = 0);
4011 msrd.msrd_fsdb = fsdb;
4014 rc = llog_process(env, llh, mgs_srpc_read_handler, (void *)&msrd,
4018 llog_close(env, llh);
4020 llog_ctxt_put(ctxt);
4021 name_destroy(&logname);
4024 CERROR("failed to read sptlrpc config database: %d\n", rc);
4028 static int mgs_write_log_param2(const struct lu_env *env,
4029 struct mgs_device *mgs,
4031 struct mgs_target_info *mti, char *ptr)
4033 struct lustre_cfg_bufs bufs;
4037 CDEBUG(D_MGS, "next param '%s'\n", ptr);
4039 /* PARAM_MGSNODE and PARAM_NETWORK are set only when formating
4040 * or during the inital mount. It can never change after that.
4042 if (!class_match_param(ptr, PARAM_MGSNODE, NULL) ||
4043 !class_match_param(ptr, PARAM_NETWORK, NULL)) {
4048 /* Processed in mgs_write_log_ost. Another value that can't
4049 * be changed by lctl set_param -P.
4051 if (!class_match_param(ptr, PARAM_FAILMODE, NULL)) {
4052 LCONSOLE_ERROR_MSG(0x169,
4053 "%s can only be changed with tunefs.lustre and --writeconf\n",
4059 /* FIXME !!! Support for sptlrpc is incomplete. Currently the change
4060 * doesn't transmit to the client. See LU-7183.
4062 if (!class_match_param(ptr, PARAM_SRPC, NULL)) {
4063 rc = mgs_srpc_set_param(env, mgs, fsdb, mti, ptr);
4067 /* Can't use class_match_param since ptr doesn't start with
4068 * PARAM_FAILNODE. So we look for PARAM_FAILNODE contained in ptr.
4070 if (strstr(ptr, PARAM_FAILNODE)) {
4071 /* Add a failover nidlist. We already processed failovers
4072 * params for new targets in mgs_write_log_target.
4076 /* can't use wildcards with failover.node */
4077 if (strchr(ptr, '*')) {
4082 param = strstr(ptr, PARAM_FAILNODE);
4083 rc = strscpy(mti->mti_params, param, sizeof(mti->mti_params));
4087 CDEBUG(D_MGS, "Adding failnode with param %s\n",
4089 rc = mgs_write_log_add_failnid(env, mgs, fsdb, mti);
4093 /* root squash parameters must not be set on llite subsystem, this can
4094 * lead to inconsistencies between client and server values
4096 if ((strstr(ptr, PARAM_NOSQUASHNIDS) ||
4097 strstr(ptr, PARAM_ROOTSQUASH)) &&
4098 strncmp(ptr, "llite.", strlen("llite.")) == 0) {
4100 CWARN("%s: cannot add %s param to llite subsystem, use mdt instead: rc=%d\n",
4101 mgs->mgs_obd->obd_name,
4102 strstr(ptr, PARAM_ROOTSQUASH) ?
4103 PARAM_ROOTSQUASH : PARAM_NOSQUASHNIDS,
4108 rc = mgs_wlp_lcfg(env, mgs, fsdb, mti, PARAMS_FILENAME, &bufs,
4109 mti->mti_svname, ptr);
4114 /* Permanent settings of all parameters by writing into the appropriate
4115 * configuration logs.
4116 * A parameter with null value ("<param>='\0'") means to erase it out of
4119 static int mgs_write_log_param(const struct lu_env *env,
4120 struct mgs_device *mgs, struct fs_db *fsdb,
4121 struct mgs_target_info *mti, char *ptr)
4123 struct mgs_thread_info *mgi = mgs_env_info(env);
4129 /* For various parameter settings, we have to figure out which logs
4130 * care about them (e.g. both mdt and client for lov settings)
4132 CDEBUG(D_MGS, "next param '%s'\n", ptr);
4134 /* The params are stored in MOUNT_DATA_FILE and modified via
4135 * tunefs.lustre, or set using lctl conf_param
4138 /* Processed in lustre_start_mgc */
4139 if (class_match_param(ptr, PARAM_MGSNODE, NULL) == 0)
4142 /* Processed in ost/mdt */
4143 if (class_match_param(ptr, PARAM_NETWORK, NULL) == 0)
4146 /* Processed in mgs_write_log_ost */
4147 if (class_match_param(ptr, PARAM_FAILMODE, NULL) == 0) {
4148 if (mti->mti_flags & LDD_F_PARAM) {
4149 LCONSOLE_ERROR_MSG(0x169,
4150 "%s can only be changed with tunefs.lustre and --writeconf\n",
4157 if (class_match_param(ptr, PARAM_SRPC, NULL) == 0) {
4158 rc = mgs_srpc_set_param(env, mgs, fsdb, mti, ptr);
4162 if (class_match_param(ptr, PARAM_FAILNODE, NULL) == 0) {
4163 /* Add a failover nidlist */
4165 /* We already processed failovers params for new
4166 * targets in mgs_write_log_target
4168 if (mti->mti_flags & LDD_F_PARAM) {
4169 CDEBUG(D_MGS, "Adding failnode\n");
4170 rc = mgs_write_log_add_failnid(env, mgs, fsdb, mti);
4175 if (class_match_param(ptr, PARAM_SYS, &tmp) == 0) {
4176 rc = mgs_write_log_sys(env, mgs, fsdb, mti, ptr, tmp);
4180 if (class_match_param(ptr, PARAM_QUOTA, &tmp) == 0) {
4181 rc = mgs_write_log_quota(env, mgs, fsdb, mti, ptr, tmp);
4185 if (class_match_param(ptr, PARAM_OSC PARAM_ACTIVE, &tmp) == 0 ||
4186 class_match_param(ptr, PARAM_MDC PARAM_ACTIVE, &tmp) == 0) {
4187 /* active=0 means off, anything else means on */
4188 int flag = (*tmp == '0') ? CM_EXCLUDE : 0;
4189 bool deactive_osc = memcmp(ptr, PARAM_OSC PARAM_ACTIVE,
4190 strlen(PARAM_OSC PARAM_ACTIVE)) == 0;
4193 if (!deactive_osc) {
4196 rc = server_name2index(mti->mti_svname, &index, NULL);
4201 LCONSOLE_ERROR_MSG(0x144, "%s: MDC0 can not be"
4202 " (de)activated.\n",
4204 GOTO(end, rc = -EPERM);
4208 LCONSOLE_WARN("Permanently %sactivating %s\n",
4209 flag ? "de" : "re", mti->mti_svname);
4211 rc = name_create(&logname, mti->mti_fsname, "-client");
4214 rc = mgs_modify(env, mgs, fsdb, mti, logname,
4216 deactive_osc ? "add osc" : "add mdc", flag);
4217 name_destroy(&logname);
4222 /* Add to all MDT logs for DNE */
4223 for (i = 0; i < INDEX_MAP_SIZE * 8; i++) {
4224 if (!test_bit(i, fsdb->fsdb_mdt_index_map))
4226 rc = name_create_mdt(&logname, mti->mti_fsname, i);
4229 rc = mgs_modify(env, mgs, fsdb, mti, logname,
4231 deactive_osc ? "add osc" : "add osp",
4233 name_destroy(&logname);
4239 LCONSOLE_ERROR_MSG(0x145,
4240 "Couldn't find %s in log (%d). No permanent changes were made to the config log.\n",
4241 mti->mti_svname, rc);
4242 if (test_bit(FSDB_OLDLOG14, &fsdb->fsdb_flags))
4243 LCONSOLE_ERROR_MSG(0x146,
4244 "This may be because the log is in the old 1.4 style. Consider --writeconf to update the logs.\n");
4247 /* Fall through to osc/mdc proc for deactivating live
4248 * OSC/OSP on running MDT / clients.
4251 /* Below here, let obd's XXX_process_config methods handle it */
4253 /* All lov. in proc */
4254 if (class_match_param(ptr, PARAM_LOV, NULL) == 0) {
4257 CDEBUG(D_MGS, "lov param %s\n", ptr);
4258 if (!(mti->mti_flags & LDD_F_SV_TYPE_MDT)) {
4259 LCONSOLE_ERROR_MSG(0x147,
4260 "LOV params must be set on the MDT, not %s. Ignoring.\n",
4266 if (mgs_log_is_empty(env, mgs, mti->mti_svname))
4267 GOTO(end, rc = -ENODEV);
4269 rc = name_create_mdt_and_lov(&logname, &mdtlovname, fsdb,
4270 mti->mti_stripe_index);
4273 rc = mgs_wlp_lcfg(env, mgs, fsdb, mti, mti->mti_svname,
4274 &mgi->mgi_bufs, mdtlovname, ptr);
4275 name_destroy(&logname);
4276 name_destroy(&mdtlovname);
4281 rc = name_create(&logname, mti->mti_fsname, "-client");
4284 rc = mgs_wlp_lcfg(env, mgs, fsdb, mti, logname, &mgi->mgi_bufs,
4285 fsdb->fsdb_clilov, ptr);
4286 name_destroy(&logname);
4290 /* All osc., mdc., llite. params in proc */
4291 if ((class_match_param(ptr, PARAM_OSC, NULL) == 0) ||
4292 (class_match_param(ptr, PARAM_MDC, NULL) == 0) ||
4293 (class_match_param(ptr, PARAM_LLITE, NULL) == 0)) {
4296 if (test_bit(FSDB_OLDLOG14, &fsdb->fsdb_flags)) {
4297 LCONSOLE_ERROR_MSG(0x148, "Upgraded client logs for %s"
4298 " cannot be modified. Consider"
4299 " updating the configuration with"
4302 GOTO(end, rc = -EINVAL);
4304 if (memcmp(ptr, PARAM_LLITE, strlen(PARAM_LLITE)) == 0) {
4305 rc = name_create(&cname, mti->mti_fsname, "-client");
4306 /* Add the client type to match the obdname in
4307 * class_config_llog_handler
4309 } else if (mti->mti_flags & LDD_F_SV_TYPE_MDT) {
4310 rc = name_create(&cname, mti->mti_svname, "-mdc");
4311 } else if (mti->mti_flags & LDD_F_SV_TYPE_OST) {
4312 rc = name_create(&cname, mti->mti_svname, "-osc");
4314 GOTO(end, rc = -EINVAL);
4319 /* Forbid direct update of llite root squash parameters.
4320 * These parameters are indirectly set via the MDT settings.
4322 if ((class_match_param(ptr, PARAM_LLITE, &tmp) == 0) &&
4323 ((memcmp(tmp, "root_squash=", 12) == 0) ||
4324 (memcmp(tmp, "nosquash_nids=", 14) == 0))) {
4325 LCONSOLE_ERROR("%s: root squash parameters can only "
4326 "be updated through MDT component\n",
4328 name_destroy(&cname);
4329 GOTO(end, rc = -EINVAL);
4332 CDEBUG(D_MGS, "%.3s param %s\n", ptr, ptr + 4);
4335 rc = name_create(&logname, mti->mti_fsname, "-client");
4337 name_destroy(&cname);
4340 rc = mgs_wlp_lcfg(env, mgs, fsdb, mti, logname, &mgi->mgi_bufs,
4343 /* osc params affect the MDT as well */
4344 if (!rc && (mti->mti_flags & LDD_F_SV_TYPE_OST)) {
4347 for (i = 0; i < INDEX_MAP_SIZE * 8; i++) {
4348 if (!test_bit(i, fsdb->fsdb_mdt_index_map))
4350 name_destroy(&cname);
4351 rc = name_create_mdt_osc(&cname, mti->mti_svname,
4353 name_destroy(&logname);
4356 rc = name_create_mdt(&logname,
4357 mti->mti_fsname, i);
4360 if (!mgs_log_is_empty(env, mgs, logname)) {
4361 rc = mgs_wlp_lcfg(env, mgs, fsdb,
4371 /* For mdc activate/deactivate, it affects OSP on MDT as well */
4372 if (class_match_param(ptr, PARAM_MDC PARAM_ACTIVE, &tmp) == 0 &&
4375 char *lodname = NULL;
4376 char *param_str = NULL;
4380 /* replace mdc with osp */
4381 memcpy(ptr, PARAM_OSP, strlen(PARAM_OSP));
4382 rc = server_name2index(mti->mti_svname, &index, NULL);
4384 memcpy(ptr, PARAM_MDC, strlen(PARAM_MDC));
4388 for (i = 0; i < INDEX_MAP_SIZE * 8; i++) {
4389 if (!test_bit(i, fsdb->fsdb_mdt_index_map))
4395 name_destroy(&logname);
4396 rc = name_create_mdt(&logname, mti->mti_fsname,
4401 if (mgs_log_is_empty(env, mgs, logname))
4404 snprintf(suffix, sizeof(suffix), "-osp-MDT%04x",
4406 name_destroy(&cname);
4407 rc = name_create(&cname, mti->mti_svname,
4412 rc = mgs_wlp_lcfg(env, mgs, fsdb, mti, logname,
4413 &mgi->mgi_bufs, cname, ptr);
4417 /* Add configuration log for noitfying LOD
4418 * to active/deactive the OSP. */
4419 name_destroy(¶m_str);
4420 rc = name_create(¶m_str, cname,
4421 (*tmp == '0') ? ".active=0" :
4426 name_destroy(&lodname);
4427 rc = name_create(&lodname, logname, "-mdtlov");
4431 rc = mgs_wlp_lcfg(env, mgs, fsdb, mti, logname,
4432 &mgi->mgi_bufs, lodname,
4437 memcpy(ptr, PARAM_MDC, strlen(PARAM_MDC));
4438 name_destroy(&lodname);
4439 name_destroy(¶m_str);
4442 name_destroy(&logname);
4443 name_destroy(&cname);
4447 /* All mdt. params in proc */
4448 if (class_match_param(ptr, PARAM_MDT, &tmp) == 0) {
4452 CDEBUG(D_MGS, "%.3s param %s\n", ptr, ptr + 4);
4453 if (strncmp(mti->mti_svname, mti->mti_fsname,
4454 MTI_NAME_MAXLEN) == 0)
4455 /* device is unspecified completely? */
4456 rc = LDD_F_SV_TYPE_MDT | LDD_F_SV_ALL;
4458 rc = server_name2index(mti->mti_svname, &idx, NULL);
4461 if ((rc & LDD_F_SV_TYPE_MDT) == 0)
4463 if (rc & LDD_F_SV_ALL) {
4464 for (i = 0; i < INDEX_MAP_SIZE * 8; i++) {
4466 fsdb->fsdb_mdt_index_map))
4468 rc = name_create_mdt(&logname,
4469 mti->mti_fsname, i);
4472 rc = mgs_wlp_lcfg(env, mgs, fsdb, mti,
4473 logname, &mgi->mgi_bufs,
4475 name_destroy(&logname);
4480 if ((memcmp(tmp, "root_squash=", 12) == 0) ||
4481 (memcmp(tmp, "nosquash_nids=", 14) == 0)) {
4482 LCONSOLE_ERROR("%s: root squash parameters "
4483 "cannot be applied to a single MDT\n",
4485 GOTO(end, rc = -EINVAL);
4487 rc = mgs_wlp_lcfg(env, mgs, fsdb, mti,
4488 mti->mti_svname, &mgi->mgi_bufs,
4489 mti->mti_svname, ptr);
4494 /* root squash settings are also applied to llite
4495 * config log (see LU-1778) */
4497 ((memcmp(tmp, "root_squash=", 12) == 0) ||
4498 (memcmp(tmp, "nosquash_nids=", 14) == 0))) {
4502 rc = name_create(&cname, mti->mti_fsname, "-client");
4505 rc = name_create(&logname, mti->mti_fsname, "-client");
4507 name_destroy(&cname);
4510 rc = name_create(&ptr2, PARAM_LLITE, tmp);
4512 name_destroy(&cname);
4513 name_destroy(&logname);
4516 rc = mgs_wlp_lcfg(env, mgs, fsdb, mti, logname,
4517 &mgi->mgi_bufs, cname, ptr2);
4518 name_destroy(&ptr2);
4519 name_destroy(&logname);
4520 name_destroy(&cname);
4525 /* All mdd., ost. and osd. params in proc */
4526 if ((class_match_param(ptr, PARAM_MDD, NULL) == 0) ||
4527 (class_match_param(ptr, PARAM_LOD, NULL) == 0) ||
4528 (class_match_param(ptr, PARAM_OST, NULL) == 0) ||
4529 (class_match_param(ptr, PARAM_OSD, NULL) == 0)) {
4530 CDEBUG(D_MGS, "%.3s param %s\n", ptr, ptr + 4);
4531 if (mgs_log_is_empty(env, mgs, mti->mti_svname))
4532 GOTO(end, rc = -ENODEV);
4534 rc = mgs_wlp_lcfg(env, mgs, fsdb, mti, mti->mti_svname,
4535 &mgi->mgi_bufs, mti->mti_svname, ptr);
4539 /* For handling degraded zfs OST */
4540 if (class_match_param(ptr, PARAM_AUTODEGRADE, NULL) == 0)
4543 LCONSOLE_WARN("Ignoring unrecognized param '%s'\n", ptr);
4547 CERROR("err %d on param '%s'\n", rc, ptr);
4552 int mgs_write_log_target(const struct lu_env *env, struct mgs_device *mgs,
4553 struct mgs_target_info *mti, struct fs_db *fsdb)
4560 /* set/check the new target index */
4561 rc = mgs_set_index(env, mgs, mti);
4565 if (rc == EALREADY) {
4566 LCONSOLE_WARN("Found index %d for %s, updating log\n",
4567 mti->mti_stripe_index, mti->mti_svname);
4568 /* We would like to mark old log sections as invalid
4569 and add new log sections in the client and mdt logs.
4570 But if we add new sections, then live clients will
4571 get repeat setup instructions for already running
4572 osc's. So don't update the client/mdt logs. */
4573 mti->mti_flags &= ~LDD_F_UPDATE;
4577 CFS_FAIL_TIMEOUT(OBD_FAIL_MGS_WRITE_TARGET_DELAY, cfs_fail_val > 0 ?
4580 mutex_lock(&fsdb->fsdb_mutex);
4582 if (mti->mti_flags & (LDD_F_VIRGIN | LDD_F_WRITECONF)) {
4583 /* Generate a log from scratch */
4584 if (mti->mti_flags & LDD_F_SV_TYPE_MDT) {
4585 rc = mgs_write_log_mdt(env, mgs, fsdb, mti);
4586 } else if (mti->mti_flags & LDD_F_SV_TYPE_OST) {
4587 rc = mgs_write_log_ost(env, mgs, fsdb, mti);
4589 CERROR("Unknown target type %#x, can't create log for %s\n",
4590 mti->mti_flags, mti->mti_svname);
4593 CERROR("Can't write logs for %s (%d)\n",
4594 mti->mti_svname, rc);
4598 /* Just update the params from tunefs in mgs_write_log_params */
4599 CDEBUG(D_MGS, "Update params for %s\n", mti->mti_svname);
4600 mti->mti_flags |= LDD_F_PARAM;
4603 /* allocate temporary buffer, where class_get_next_param will
4604 * make copy of a current parameter
4606 OBD_ALLOC(buf, strlen(mti->mti_params) + 1);
4608 GOTO(out_up, rc = -ENOMEM);
4609 params = mti->mti_params;
4610 while (params != NULL) {
4611 rc = class_get_next_param(¶ms, buf);
4614 /* there is no next parameter, that is
4620 CDEBUG(D_MGS, "remaining string: '%s', param: '%s'\n",
4622 rc = mgs_write_log_param(env, mgs, fsdb, mti, buf);
4627 OBD_FREE(buf, strlen(mti->mti_params) + 1);
4630 mutex_unlock(&fsdb->fsdb_mutex);
4634 int mgs_erase_log(const struct lu_env *env, struct mgs_device *mgs, char *name)
4636 struct llog_ctxt *ctxt;
4639 ctxt = llog_get_context(mgs->mgs_obd, LLOG_CONFIG_ORIG_CTXT);
4641 CERROR("%s: MGS config context doesn't exist\n",
4642 mgs->mgs_obd->obd_name);
4645 rc = llog_erase(env, ctxt, NULL, name);
4646 /* llog may not exist */
4649 llog_ctxt_put(ctxt);
4653 CERROR("%s: failed to clear log %s: %d\n",
4654 mgs->mgs_obd->obd_name, name, rc);
4659 /* erase all logs for the given fs */
4660 int mgs_erase_logs(const struct lu_env *env, struct mgs_device *mgs,
4663 struct list_head log_list;
4664 struct mgs_direntry *dirent, *n;
4665 char barrier_name[20] = {};
4668 int rc, len = strlen(fsname);
4671 mutex_lock(&mgs->mgs_mutex);
4673 /* Find all the logs in the CONFIGS directory */
4674 rc = class_dentry_readdir(env, mgs, &log_list);
4676 mutex_unlock(&mgs->mgs_mutex);
4680 if (list_empty(&log_list)) {
4681 mutex_unlock(&mgs->mgs_mutex);
4685 snprintf(barrier_name, sizeof(barrier_name) - 1, "%s-%s",
4686 fsname, BARRIER_FILENAME);
4687 /* Delete the barrier fsdb */
4688 mgs_remove_fsdb_by_name(mgs, barrier_name);
4689 /* Delete the fs db */
4690 mgs_remove_fsdb_by_name(mgs, fsname);
4691 mutex_unlock(&mgs->mgs_mutex);
4693 list_for_each_entry_safe(dirent, n, &log_list, mde_list) {
4694 list_del_init(&dirent->mde_list);
4695 suffix = strrchr(dirent->mde_name, '-');
4696 if (suffix != NULL) {
4697 if ((len == suffix - dirent->mde_name) &&
4698 (strncmp(fsname, dirent->mde_name, len) == 0)) {
4699 CDEBUG(D_MGS, "Removing log %s\n",
4701 mgs_erase_log(env, mgs, dirent->mde_name);
4705 mgs_direntry_free(dirent);
4714 /* list all logs for the given fs */
4715 int mgs_list_logs(const struct lu_env *env, struct mgs_device *mgs,
4716 struct obd_ioctl_data *data)
4718 struct list_head log_list;
4719 struct mgs_direntry *dirent, *n;
4720 char *out, *suffix, prefix[] = "config_log: ";
4721 int prefix_len = strlen(prefix);
4722 int len, remains, start = 0, rc;
4726 /* Find all the logs in the CONFIGS directory */
4727 rc = class_dentry_readdir(env, mgs, &log_list);
4731 out = data->ioc_bulk;
4732 remains = data->ioc_inllen1;
4733 /* OBD_FAIL: fetch the config_log records from the specified one */
4734 if (CFS_FAIL_CHECK(OBD_FAIL_CATLIST))
4735 data->ioc_count = cfs_fail_val;
4737 list_for_each_entry_safe(dirent, n, &log_list, mde_list) {
4738 list_del_init(&dirent->mde_list);
4739 suffix = strrchr(dirent->mde_name, '-');
4740 if (suffix != NULL) {
4741 len = prefix_len + dirent->mde_len + 1;
4742 if (remains - len < 0) {
4743 /* No enough space for this record */
4744 mgs_direntry_free(dirent);
4748 if (start < data->ioc_count) {
4749 mgs_direntry_free(dirent);
4752 len = scnprintf(out, remains, "%s%s\n", prefix,
4757 mgs_direntry_free(dirent);
4765 data->ioc_count = start;
4769 struct mgs_lcfg_fork_data {
4770 struct lustre_cfg_bufs mlfd_bufs;
4771 struct mgs_device *mlfd_mgs;
4772 struct llog_handle *mlfd_llh;
4773 const char *mlfd_oldname;
4774 const char *mlfd_newname;
4778 static bool contain_valid_fsname(char *buf, const char *fsname,
4779 int buflen, int namelen)
4781 if (buflen < namelen)
4784 if (memcmp(buf, fsname, namelen) != 0)
4787 if (buf[namelen] != '\0' && buf[namelen] != '-')
4793 static int mgs_lcfg_fork_handler(const struct lu_env *env,
4794 struct llog_handle *o_llh,
4795 struct llog_rec_hdr *o_rec, void *data)
4797 struct mgs_lcfg_fork_data *mlfd = data;
4798 struct lustre_cfg_bufs *n_bufs = &mlfd->mlfd_bufs;
4799 struct lustre_cfg *o_lcfg = (struct lustre_cfg *)(o_rec + 1);
4800 struct llog_cfg_rec *lcr;
4802 char *n_buf = mlfd->mlfd_data;
4804 int o_namelen = strlen(mlfd->mlfd_oldname);
4805 int n_namelen = strlen(mlfd->mlfd_newname);
4806 int diff = n_namelen - o_namelen;
4807 __u32 cmd = o_lcfg->lcfg_command;
4808 __u32 cnt = o_lcfg->lcfg_bufcount;
4814 o_buf = lustre_cfg_buf(o_lcfg, 0);
4815 o_buflen = o_lcfg->lcfg_buflens[0];
4816 if (contain_valid_fsname(o_buf, mlfd->mlfd_oldname, o_buflen,
4818 memcpy(n_buf, mlfd->mlfd_newname, n_namelen);
4819 memcpy(n_buf + n_namelen, o_buf + o_namelen,
4820 o_buflen - o_namelen);
4821 lustre_cfg_bufs_reset(n_bufs, n_buf);
4822 n_buf += round_up(o_buflen + diff, 8);
4824 lustre_cfg_bufs_reset(n_bufs, o_buflen != 0 ? o_buf : NULL);
4829 struct cfg_marker *o_marker;
4830 struct cfg_marker *n_marker;
4834 CDEBUG(D_MGS, "Unknown cfg marker entry with %d "
4839 /* buf[1] is marker */
4840 o_buf = lustre_cfg_buf(o_lcfg, 1);
4841 o_buflen = o_lcfg->lcfg_buflens[1];
4842 o_marker = (struct cfg_marker *)o_buf;
4843 if (!contain_valid_fsname(o_marker->cm_tgtname,
4845 sizeof(o_marker->cm_tgtname),
4847 lustre_cfg_bufs_set(n_bufs, 1, o_marker,
4852 n_marker = (struct cfg_marker *)n_buf;
4853 *n_marker = *o_marker;
4854 memcpy(n_marker->cm_tgtname, mlfd->mlfd_newname, n_namelen);
4855 tgt_namelen = strlen(o_marker->cm_tgtname);
4856 if (tgt_namelen > o_namelen)
4857 memcpy(n_marker->cm_tgtname + n_namelen,
4858 o_marker->cm_tgtname + o_namelen,
4859 tgt_namelen - o_namelen);
4860 n_marker->cm_tgtname[tgt_namelen + diff] = '\0';
4861 lustre_cfg_bufs_set(n_bufs, 1, n_marker, sizeof(*n_marker));
4865 case LCFG_SET_PARAM: {
4866 for (i = 1; i < cnt; i++)
4867 /* buf[i] is the param value, reuse it directly */
4868 lustre_cfg_bufs_set(n_bufs, i,
4869 lustre_cfg_buf(o_lcfg, i),
4870 o_lcfg->lcfg_buflens[i]);
4876 case LCFG_POOL_DEL: {
4877 if (cnt < 3 || cnt > 4) {
4878 CDEBUG(D_MGS, "Unknown cfg pool (%x) entry with %d "
4879 "buffers\n", cmd, cnt);
4883 /* buf[1] is fsname */
4884 o_buf = lustre_cfg_buf(o_lcfg, 1);
4885 o_buflen = o_lcfg->lcfg_buflens[1];
4886 memcpy(n_buf, mlfd->mlfd_newname, n_namelen);
4887 memcpy(n_buf + n_namelen, o_buf + o_namelen,
4888 o_buflen - o_namelen);
4889 lustre_cfg_bufs_set(n_bufs, 1, n_buf, o_buflen + diff);
4890 n_buf += round_up(o_buflen + diff, 8);
4892 /* buf[2] is the pool name, reuse it directly */
4893 lustre_cfg_bufs_set(n_bufs, 2, lustre_cfg_buf(o_lcfg, 2),
4894 o_lcfg->lcfg_buflens[2]);
4899 /* buf[3] is ostname */
4900 o_buf = lustre_cfg_buf(o_lcfg, 3);
4901 o_buflen = o_lcfg->lcfg_buflens[3];
4902 memcpy(n_buf, mlfd->mlfd_newname, n_namelen);
4903 memcpy(n_buf + n_namelen, o_buf + o_namelen,
4904 o_buflen - o_namelen);
4905 lustre_cfg_bufs_set(n_bufs, 3, n_buf, o_buflen + diff);
4910 o_buflen = o_lcfg->lcfg_buflens[1];
4911 if (o_buflen == sizeof(struct lov_desc) ||
4912 o_buflen == sizeof(struct lmv_desc)) {
4918 o_buf = lustre_cfg_buf(o_lcfg, 1);
4919 if (o_buflen == sizeof(struct lov_desc)) {
4920 struct lov_desc *o_desc =
4921 (struct lov_desc *)o_buf;
4922 struct lov_desc *n_desc =
4923 (struct lov_desc *)n_buf;
4926 o_uuid = o_desc->ld_uuid.uuid;
4927 n_uuid = n_desc->ld_uuid.uuid;
4928 uuid_len = sizeof(o_desc->ld_uuid.uuid);
4930 struct lmv_desc *o_desc =
4931 (struct lmv_desc *)o_buf;
4932 struct lmv_desc *n_desc =
4933 (struct lmv_desc *)n_buf;
4936 o_uuid = o_desc->ld_uuid.uuid;
4937 n_uuid = n_desc->ld_uuid.uuid;
4938 uuid_len = sizeof(o_desc->ld_uuid.uuid);
4941 if (unlikely(!contain_valid_fsname(o_uuid,
4942 mlfd->mlfd_oldname, uuid_len,
4944 lustre_cfg_bufs_set(n_bufs, 1, o_buf,
4949 memcpy(n_uuid, mlfd->mlfd_newname, n_namelen);
4950 uuid_len = strlen(o_uuid);
4951 if (uuid_len > o_namelen)
4952 memcpy(n_uuid + n_namelen,
4954 uuid_len - o_namelen);
4955 n_uuid[uuid_len + diff] = '\0';
4956 lustre_cfg_bufs_set(n_bufs, 1, n_buf, o_buflen);
4958 } /* else case fall through */
4959 } /* else case fall through */
4963 for (i = 1; i < cnt; i++) {
4964 o_buflen = o_lcfg->lcfg_buflens[i];
4968 o_buf = lustre_cfg_buf(o_lcfg, i);
4969 if (!contain_valid_fsname(o_buf, mlfd->mlfd_oldname,
4970 o_buflen, o_namelen)) {
4971 lustre_cfg_bufs_set(n_bufs, i, o_buf, o_buflen);
4975 memcpy(n_buf, mlfd->mlfd_newname, n_namelen);
4976 if (o_buflen == o_namelen) {
4977 lustre_cfg_bufs_set(n_bufs, i, n_buf,
4979 n_buf += round_up(n_namelen, 8);
4983 memcpy(n_buf + n_namelen, o_buf + o_namelen,
4984 o_buflen - o_namelen);
4985 lustre_cfg_bufs_set(n_bufs, i, n_buf, o_buflen + diff);
4986 n_buf += round_up(o_buflen + diff, 8);
4992 lcr = lustre_cfg_rec_new(cmd, n_bufs);
4996 lcr->lcr_cfg = *o_lcfg;
4997 rc = llog_write(env, mlfd->mlfd_llh, &lcr->lcr_hdr, LLOG_NEXT_IDX);
4998 lustre_cfg_rec_free(lcr);
5003 static int mgs_lcfg_fork_one(const struct lu_env *env, struct mgs_device *mgs,
5004 struct mgs_direntry *mde, const char *oldname,
5005 const char *newname)
5007 struct llog_handle *old_llh = NULL;
5008 struct llog_handle *new_llh = NULL;
5009 struct llog_ctxt *ctxt = NULL;
5010 struct mgs_lcfg_fork_data *mlfd = NULL;
5011 char *name_buf = NULL;
5013 int old_namelen = strlen(oldname);
5014 int new_namelen = strlen(newname);
5018 name_buflen = mde->mde_len + new_namelen - old_namelen;
5019 OBD_ALLOC(name_buf, name_buflen);
5023 memcpy(name_buf, newname, new_namelen);
5024 memcpy(name_buf + new_namelen, mde->mde_name + old_namelen,
5025 mde->mde_len - old_namelen);
5027 CDEBUG(D_MGS, "Fork the config-log from %s to %s\n",
5028 mde->mde_name, name_buf);
5030 ctxt = llog_get_context(mgs->mgs_obd, LLOG_CONFIG_ORIG_CTXT);
5033 rc = llog_open_create(env, ctxt, &new_llh, NULL, name_buf);
5037 rc = llog_init_handle(env, new_llh, LLOG_F_IS_PLAIN, NULL);
5041 if (unlikely(mgs_log_is_empty(env, mgs, mde->mde_name)))
5044 rc = llog_open(env, ctxt, &old_llh, NULL, mde->mde_name,
5049 rc = llog_init_handle(env, old_llh, LLOG_F_IS_PLAIN, NULL);
5053 new_llh->lgh_hdr->llh_tgtuuid = old_llh->lgh_hdr->llh_tgtuuid;
5055 OBD_ALLOC(mlfd, LLOG_MIN_CHUNK_SIZE);
5057 GOTO(out, rc = -ENOMEM);
5059 mlfd->mlfd_mgs = mgs;
5060 mlfd->mlfd_llh = new_llh;
5061 mlfd->mlfd_oldname = oldname;
5062 mlfd->mlfd_newname = newname;
5064 rc = llog_process(env, old_llh, mgs_lcfg_fork_handler, mlfd, NULL);
5065 OBD_FREE(mlfd, LLOG_MIN_CHUNK_SIZE);
5071 llog_close(env, old_llh);
5073 llog_close(env, new_llh);
5075 OBD_FREE(name_buf, name_buflen);
5077 llog_ctxt_put(ctxt);
5082 int mgs_lcfg_fork(const struct lu_env *env, struct mgs_device *mgs,
5083 const char *oldname, const char *newname)
5085 struct list_head log_list;
5086 struct mgs_direntry *dirent, *n;
5087 int olen = strlen(oldname);
5088 int nlen = strlen(newname);
5093 if (unlikely(!oldname || oldname[0] == '\0' ||
5094 !newname || newname[0] == '\0'))
5097 if (strcmp(oldname, newname) == 0)
5100 /* lock it to prevent fork/erase/register in parallel. */
5101 mutex_lock(&mgs->mgs_mutex);
5103 rc = class_dentry_readdir(env, mgs, &log_list);
5105 mutex_unlock(&mgs->mgs_mutex);
5109 if (list_empty(&log_list)) {
5110 mutex_unlock(&mgs->mgs_mutex);
5114 list_for_each_entry_safe(dirent, n, &log_list, mde_list) {
5117 ptr = strrchr(dirent->mde_name, '-');
5119 int tlen = ptr - dirent->mde_name;
5122 strncmp(newname, dirent->mde_name, tlen) == 0)
5123 GOTO(out, rc = -EEXIST);
5126 strncmp(oldname, dirent->mde_name, tlen) == 0)
5130 list_del_init(&dirent->mde_list);
5131 mgs_direntry_free(dirent);
5134 if (list_empty(&log_list)) {
5135 mutex_unlock(&mgs->mgs_mutex);
5139 list_for_each_entry(dirent, &log_list, mde_list) {
5140 rc = mgs_lcfg_fork_one(env, mgs, dirent, oldname, newname);
5148 mutex_unlock(&mgs->mgs_mutex);
5150 list_for_each_entry_safe(dirent, n, &log_list, mde_list) {
5151 list_del_init(&dirent->mde_list);
5152 mgs_direntry_free(dirent);
5155 if (rc && count > 0)
5156 mgs_erase_logs(env, mgs, newname);
5161 int mgs_lcfg_erase(const struct lu_env *env, struct mgs_device *mgs,
5167 if (unlikely(!fsname || fsname[0] == '\0'))
5170 rc = mgs_erase_logs(env, mgs, fsname);
5175 static int mgs_xattr_del(const struct lu_env *env, struct dt_object *obj)
5177 struct dt_device *dev;
5178 struct thandle *th = NULL;
5183 dev = container_of(obj->do_lu.lo_dev, struct dt_device, dd_lu_dev);
5184 th = dt_trans_create(env, dev);
5186 RETURN(PTR_ERR(th));
5188 rc = dt_declare_xattr_del(env, obj, XATTR_TARGET_RENAME, th);
5192 rc = dt_trans_start_local(env, dev, th);
5196 dt_write_lock(env, obj, 0);
5197 rc = dt_xattr_del(env, obj, XATTR_TARGET_RENAME, th);
5202 dt_write_unlock(env, obj);
5205 dt_trans_stop(env, dev, th);
5210 int mgs_lcfg_rename(const struct lu_env *env, struct mgs_device *mgs)
5212 struct list_head log_list;
5213 struct mgs_direntry *dirent, *n;
5215 struct lu_buf buf = {
5217 .lb_len = sizeof(fsname)
5223 rc = class_dentry_readdir(env, mgs, &log_list);
5227 if (list_empty(&log_list))
5230 list_for_each_entry_safe(dirent, n, &log_list, mde_list) {
5231 struct dt_object *o = NULL;
5236 list_del_init(&dirent->mde_list);
5237 ptr = strrchr(dirent->mde_name, '-');
5241 len = ptr - dirent->mde_name;
5242 if (unlikely(len >= sizeof(oldname))) {
5243 CDEBUG(D_MGS, "Skip invalid configuration file %s\n",
5248 o = local_file_find(env, mgs->mgs_los, mgs->mgs_configs_dir,
5252 CDEBUG(D_MGS, "Fail to locate file %s: rc = %d\n",
5253 dirent->mde_name, rc);
5257 rc = dt_xattr_get(env, o, &buf, XATTR_TARGET_RENAME);
5263 "Fail to get EA for %s: rc = %d\n",
5264 dirent->mde_name, rc);
5268 if (unlikely(rc == len &&
5269 memcmp(fsname, dirent->mde_name, len) == 0)) {
5270 /* The new fsname is the same as the old one. */
5271 rc = mgs_xattr_del(env, o);
5275 memcpy(oldname, dirent->mde_name, len);
5276 oldname[len] = '\0';
5278 rc = mgs_lcfg_fork_one(env, mgs, dirent, oldname, fsname);
5279 if (rc && rc != -EEXIST) {
5280 CDEBUG(D_MGS, "Fail to fork %s: rc = %d\n",
5281 dirent->mde_name, rc);
5285 rc = mgs_erase_log(env, mgs, dirent->mde_name);
5287 CDEBUG(D_MGS, "Fail to erase old %s: rc = %d\n",
5288 dirent->mde_name, rc);
5289 /* keep it there if failed to remove it. */
5294 if (o && !IS_ERR(o))
5295 lu_object_put(env, &o->do_lu);
5297 mgs_direntry_free(dirent);
5302 list_for_each_entry_safe(dirent, n, &log_list, mde_list) {
5303 list_del_init(&dirent->mde_list);
5304 mgs_direntry_free(dirent);
5310 /* Setup _mgs fsdb and log
5312 int mgs__mgs_fsdb_setup(const struct lu_env *env, struct mgs_device *mgs)
5314 struct fs_db *fsdb = NULL;
5318 rc = mgs_find_or_make_fsdb(env, mgs, MGSSELF_NAME, &fsdb);
5320 mgs_put_fsdb(mgs, fsdb);
5325 /* Setup params fsdb and log
5327 int mgs_params_fsdb_setup(const struct lu_env *env, struct mgs_device *mgs)
5329 struct fs_db *fsdb = NULL;
5330 struct llog_handle *params_llh = NULL;
5334 rc = mgs_find_or_make_fsdb(env, mgs, PARAMS_FILENAME, &fsdb);
5336 mutex_lock(&fsdb->fsdb_mutex);
5337 rc = record_start_log(env, mgs, ¶ms_llh, PARAMS_FILENAME);
5339 rc = record_end_log(env, ¶ms_llh);
5340 mutex_unlock(&fsdb->fsdb_mutex);
5341 mgs_put_fsdb(mgs, fsdb);
5347 /* Cleanup params fsdb and log
5349 int mgs_params_fsdb_cleanup(const struct lu_env *env, struct mgs_device *mgs)
5353 rc = mgs_erase_logs(env, mgs, PARAMS_FILENAME);
5354 return rc == -ENOENT ? 0 : rc;
5358 * Fill in the mgs_target_info based on data devname and param provide.
5360 * @env thread context
5362 * @mti mgs target info. We want to set this based other paramters
5363 * passed to this function. Once setup we write it to the config
5365 * @devname optional OBD device name
5366 * @param string that contains both what tunable to set and the value to
5369 * RETURN 0 for success
5370 * negative error number on failure
5372 static int mgs_set_conf_param(const struct lu_env *env, struct mgs_device *mgs,
5373 struct mgs_target_info *mti, const char *devname,
5376 struct fs_db *fsdb = NULL;
5381 /* lustre, lustre-mdtlov, lustre-client, lustre-MDT0000 */
5385 /* We have two possible cases here:
5387 * 1) the device name embedded in the param:
5388 * lustre-OST0000.osc.max_dirty_mb=32
5390 * 2) the file system name is embedded in
5391 * the param: lustre.sys.at.min=0
5393 len = strcspn(param, ".=");
5394 if (!len || param[len] == '=')
5397 if (len >= sizeof(mti->mti_svname))
5400 snprintf(mti->mti_svname, sizeof(mti->mti_svname),
5401 "%.*s", (int)len, param);
5404 rc = strscpy(mti->mti_svname, devname, sizeof(mti->mti_svname));
5409 if (!strlen(mti->mti_svname)) {
5410 LCONSOLE_ERROR_MSG(0x14d, "No target specified: %s\n", param);
5414 dev_type = mgs_parse_devname(mti->mti_svname, mti->mti_fsname,
5415 &mti->mti_stripe_index);
5417 /* For this case we have an invalid obd device name */
5419 CDEBUG(D_MGS, "%s don't contain an index\n", mti->mti_svname);
5420 strscpy(mti->mti_fsname, mti->mti_svname, MTI_NAME_MAXLEN);
5423 /* Not an obd device, assume devname is the fsname.
5424 * User might of only provided fsname and not obd device
5427 CDEBUG(D_MGS, "%s is seen as a file system name\n", mti->mti_svname);
5428 strscpy(mti->mti_fsname, mti->mti_svname, MTI_NAME_MAXLEN);
5433 GOTO(out, rc = dev_type);
5435 /* param related to llite isn't allowed to set by OST or MDT */
5436 if (dev_type & LDD_F_SV_TYPE_OST ||
5437 dev_type & LDD_F_SV_TYPE_MDT) {
5438 /* param related to llite isn't allowed to set by OST
5441 if (!strncmp(param, PARAM_LLITE,
5442 sizeof(PARAM_LLITE) - 1))
5443 GOTO(out, rc = -EINVAL);
5445 /* Strip -osc or -mdc suffix from svname */
5446 if (server_make_name(dev_type, mti->mti_stripe_index,
5447 mti->mti_fsname, mti->mti_svname,
5448 sizeof(mti->mti_svname)))
5449 GOTO(out, rc = -EINVAL);
5453 rc = strscpy(mti->mti_params, param, sizeof(mti->mti_params));
5457 CDEBUG(D_MGS, "set_conf_param fs='%s' device='%s' param='%s'\n",
5458 mti->mti_fsname, mti->mti_svname, mti->mti_params);
5460 rc = mgs_find_or_make_fsdb(env, mgs, mti->mti_fsname, &fsdb);
5464 if (!test_bit(FSDB_MGS_SELF, &fsdb->fsdb_flags) &&
5465 test_bit(FSDB_LOG_EMPTY, &fsdb->fsdb_flags)) {
5466 CERROR("No filesystem targets for %s. cfg_device from lctl "
5467 "is '%s'\n", mti->mti_fsname, mti->mti_svname);
5468 mgs_unlink_fsdb(mgs, fsdb);
5469 GOTO(out, rc = -EINVAL);
5473 * Revoke lock so everyone updates. Should be alright if
5474 * someone was already reading while we were updating the logs,
5475 * so we don't really need to hold the lock while we're
5478 mti->mti_flags = dev_type | LDD_F_PARAM;
5479 mutex_lock(&fsdb->fsdb_mutex);
5480 rc = mgs_write_log_param(env, mgs, fsdb, mti, mti->mti_params);
5481 mutex_unlock(&fsdb->fsdb_mutex);
5482 mgs_revoke_lock(mgs, fsdb, MGS_CFG_T_CONFIG);
5486 mgs_put_fsdb(mgs, fsdb);
5491 static int mgs_set_param2(const struct lu_env *env, struct mgs_device *mgs,
5492 struct mgs_target_info *mti, const char *param)
5494 struct fs_db *fsdb = NULL;
5499 rc = strscpy(mti->mti_params, param, sizeof(mti->mti_params));
5503 len = strcspn(param, ".=");
5504 if (len && param[len] != '=') {
5505 struct list_head *tmp;
5509 ptr = strchr(param, '.');
5511 len = strlen(param);
5514 if (len >= sizeof(mti->mti_svname))
5515 GOTO(out, rc = -E2BIG);
5517 snprintf(mti->mti_svname, sizeof(mti->mti_svname), "%.*s",
5520 mutex_lock(&mgs->mgs_mutex);
5521 if (unlikely(list_empty(&mgs->mgs_fs_db_list))) {
5522 mutex_unlock(&mgs->mgs_mutex);
5523 GOTO(out, rc = -ENODEV);
5526 list_for_each(tmp, &mgs->mgs_fs_db_list) {
5527 fsdb = list_entry(tmp, struct fs_db, fsdb_list);
5528 if (fsdb->fsdb_has_lproc_entry &&
5529 strcmp(fsdb->fsdb_name, "params") != 0 &&
5530 strstr(param, fsdb->fsdb_name)) {
5531 snprintf(mti->mti_svname,
5532 sizeof(mti->mti_svname), "%s",
5540 snprintf(mti->mti_svname, sizeof(mti->mti_svname),
5543 mutex_unlock(&mgs->mgs_mutex);
5545 snprintf(mti->mti_svname, sizeof(mti->mti_svname), "general");
5548 CDEBUG(D_MGS, "set_param2 fs='%s' device='%s' param='%s'\n",
5549 mti->mti_fsname, mti->mti_svname, mti->mti_params);
5551 /* The return value should be the device type i.e LDD_F_SV_TYPE_XXX.
5552 * A returned error tells us we don't have a target obd device.
5554 dev_type = server_name2index(mti->mti_svname, &mti->mti_stripe_index,
5559 /* the return value should be the device type i.e LDD_F_SV_TYPE_XXX.
5560 * Strip -osc or -mdc suffix from svname
5562 if ((dev_type & LDD_F_SV_TYPE_OST || dev_type & LDD_F_SV_TYPE_MDT) &&
5563 server_make_name(dev_type, mti->mti_stripe_index,
5564 mti->mti_fsname, mti->mti_svname,
5565 sizeof(mti->mti_svname)))
5566 GOTO(out, rc = -EINVAL);
5568 rc = mgs_find_or_make_fsdb(env, mgs, PARAMS_FILENAME, &fsdb);
5572 * Revoke lock so everyone updates. Should be alright if
5573 * someone was already reading while we were updating the logs,
5574 * so we don't really need to hold the lock while we're
5577 mti->mti_flags = dev_type | LDD_F_PARAM2;
5578 mutex_lock(&fsdb->fsdb_mutex);
5579 rc = mgs_write_log_param2(env, mgs, fsdb, mti, mti->mti_params);
5580 mutex_unlock(&fsdb->fsdb_mutex);
5581 mgs_revoke_lock(mgs, fsdb, MGS_CFG_T_PARAMS);
5582 mgs_put_fsdb(mgs, fsdb);
5587 /* Set a permanent (config log) param for a target or fs
5589 * @lcfg buf0 may contain the device (testfs-MDT0000) name
5590 * buf1 contains the single parameter
5592 int mgs_set_param(const struct lu_env *env, struct mgs_device *mgs,
5593 struct lustre_cfg *lcfg)
5595 const char *param = lustre_cfg_string(lcfg, 1);
5596 struct mgs_target_info *mti;
5599 /* Create a fake mti to hold everything */
5604 print_lustre_cfg(lcfg);
5606 if (lcfg->lcfg_command == LCFG_PARAM) {
5607 /* For the case of lctl conf_param devname can be
5608 * lustre, lustre-mdtlov, lustre-client, lustre-MDT0000
5610 const char *devname = lustre_cfg_string(lcfg, 0);
5612 rc = mgs_set_conf_param(env, mgs, mti, devname, param);
5614 /* In the case of lctl set_param -P lcfg[0] will always
5615 * be 'general'. At least for now.
5617 rc = mgs_set_param2(env, mgs, mti, param);
5625 static int mgs_write_log_pool(const struct lu_env *env,
5626 struct mgs_device *mgs, char *logname,
5627 struct fs_db *fsdb, char *tgtname,
5628 enum lcfg_command_type cmd,
5629 char *fsname, char *poolname,
5630 char *ostname, char *comment)
5632 struct llog_handle *llh = NULL;
5635 rc = record_start_log(env, mgs, &llh, logname);
5638 rc = record_marker(env, llh, fsdb, CM_START, tgtname, comment);
5641 rc = record_base(env, llh, tgtname, 0, cmd,
5642 fsname, poolname, ostname, NULL);
5645 rc = record_marker(env, llh, fsdb, CM_END, tgtname, comment);
5647 record_end_log(env, &llh);
5651 int mgs_nodemap_cmd(const struct lu_env *env, struct mgs_device *mgs,
5652 enum lcfg_command_type cmd, const char *nodemap_name,
5655 struct lnet_nid nid[2];
5664 case LCFG_NODEMAP_ADD:
5665 rc = nodemap_add(nodemap_name);
5667 case LCFG_NODEMAP_DEL:
5668 rc = nodemap_del(nodemap_name);
5670 case LCFG_NODEMAP_ADD_RANGE:
5671 rc = nodemap_parse_range(param, nid, &netmask);
5674 rc = nodemap_add_range(nodemap_name, nid, netmask);
5676 case LCFG_NODEMAP_DEL_RANGE:
5677 rc = nodemap_parse_range(param, nid, &netmask);
5680 rc = nodemap_del_range(nodemap_name, nid, netmask);
5682 case LCFG_NODEMAP_ADMIN:
5683 rc = kstrtobool(param, &bool_switch);
5686 rc = nodemap_set_allow_root(nodemap_name, bool_switch);
5688 case LCFG_NODEMAP_DENY_UNKNOWN:
5689 rc = kstrtobool(param, &bool_switch);
5692 rc = nodemap_set_deny_unknown(nodemap_name, bool_switch);
5694 case LCFG_NODEMAP_AUDIT_MODE:
5695 rc = kstrtobool(param, &bool_switch);
5697 rc = nodemap_set_audit_mode(nodemap_name, bool_switch);
5699 case LCFG_NODEMAP_FORBID_ENCRYPT:
5700 rc = kstrtobool(param, &bool_switch);
5702 rc = nodemap_set_forbid_encryption(nodemap_name,
5705 case LCFG_NODEMAP_READONLY_MOUNT:
5706 rc = kstrtobool(param, &bool_switch);
5708 rc = nodemap_set_readonly_mount(nodemap_name,
5711 case LCFG_NODEMAP_MAP_MODE:
5716 if ((p = strstr(param, "all")) != NULL) {
5717 if ((p == param || *(p-1) == ',') &&
5718 (*(p+3) == '\0' || *(p+3) == ',')) {
5719 map_mode = NODEMAP_MAP_ALL;
5725 while ((p = strsep(¶m, ",")) != NULL) {
5729 if (strcmp("both", p) == 0)
5730 map_mode |= NODEMAP_MAP_BOTH;
5731 else if (strcmp("uid_only", p) == 0 ||
5732 strcmp("uid", p) == 0)
5733 map_mode |= NODEMAP_MAP_UID;
5734 else if (strcmp("gid_only", p) == 0 ||
5735 strcmp("gid", p) == 0)
5736 map_mode |= NODEMAP_MAP_GID;
5737 else if (strcmp("projid_only", p) == 0 ||
5738 strcmp("projid", p) == 0)
5739 map_mode |= NODEMAP_MAP_PROJID;
5749 rc = nodemap_set_mapping_mode(nodemap_name, map_mode);
5752 case LCFG_NODEMAP_RBAC:
5754 enum nodemap_rbac_roles rbac;
5757 if (strcmp(param, "all") == 0) {
5758 rbac = NODEMAP_RBAC_ALL;
5759 } else if (strcmp(param, "none") == 0) {
5760 rbac = NODEMAP_RBAC_NONE;
5762 rbac = NODEMAP_RBAC_NONE;
5763 while ((p = strsep(¶m, ",")) != NULL) {
5769 for (i = 0; i < ARRAY_SIZE(nodemap_rbac_names);
5772 nodemap_rbac_names[i].nrn_name)
5775 nodemap_rbac_names[i].nrn_mode;
5779 if (i == ARRAY_SIZE(nodemap_rbac_names))
5788 rc = nodemap_set_rbac(nodemap_name, rbac);
5791 case LCFG_NODEMAP_TRUSTED:
5792 rc = kstrtobool(param, &bool_switch);
5795 rc = nodemap_set_trust_client_ids(nodemap_name, bool_switch);
5797 case LCFG_NODEMAP_SQUASH_UID:
5798 rc = kstrtouint(param, 10, &int_id);
5801 rc = nodemap_set_squash_uid(nodemap_name, int_id);
5803 case LCFG_NODEMAP_SQUASH_GID:
5804 rc = kstrtouint(param, 10, &int_id);
5807 rc = nodemap_set_squash_gid(nodemap_name, int_id);
5809 case LCFG_NODEMAP_SQUASH_PROJID:
5810 rc = kstrtouint(param, 10, &int_id);
5813 rc = nodemap_set_squash_projid(nodemap_name, int_id);
5815 case LCFG_NODEMAP_ADD_UIDMAP:
5816 case LCFG_NODEMAP_ADD_GIDMAP:
5817 case LCFG_NODEMAP_ADD_PROJIDMAP:
5818 rc = nodemap_parse_idmap(param, idmap);
5821 if (cmd == LCFG_NODEMAP_ADD_UIDMAP)
5822 rc = nodemap_add_idmap(nodemap_name, NODEMAP_UID,
5824 else if (cmd == LCFG_NODEMAP_ADD_GIDMAP)
5825 rc = nodemap_add_idmap(nodemap_name, NODEMAP_GID,
5827 else if (cmd == LCFG_NODEMAP_ADD_PROJIDMAP)
5828 rc = nodemap_add_idmap(nodemap_name, NODEMAP_PROJID,
5833 case LCFG_NODEMAP_DEL_UIDMAP:
5834 case LCFG_NODEMAP_DEL_GIDMAP:
5835 case LCFG_NODEMAP_DEL_PROJIDMAP:
5836 rc = nodemap_parse_idmap(param, idmap);
5839 if (cmd == LCFG_NODEMAP_DEL_UIDMAP)
5840 rc = nodemap_del_idmap(nodemap_name, NODEMAP_UID,
5842 else if (cmd == LCFG_NODEMAP_DEL_GIDMAP)
5843 rc = nodemap_del_idmap(nodemap_name, NODEMAP_GID,
5845 else if (cmd == LCFG_NODEMAP_DEL_PROJIDMAP)
5846 rc = nodemap_del_idmap(nodemap_name, NODEMAP_PROJID,
5851 case LCFG_NODEMAP_SET_FILESET:
5852 rc = nodemap_set_fileset(nodemap_name, param);
5854 case LCFG_NODEMAP_SET_SEPOL:
5855 rc = nodemap_set_sepol(nodemap_name, param);
5865 int mgs_pool_check_ostname(struct fs_db *fsdb, char *fsname, char *ostname)
5870 /* check if ostname match fsname */
5871 ptr = strrchr(ostname, '-');
5872 if (!ptr || (strncmp(fsname, ostname, ptr - ostname) != 0))
5876 if (sscanf(ptr, "OST%04x_UUID", &index) != 1)
5878 if (index > INDEX_MAP_MAX_VALUE)
5880 if (!test_bit(index, fsdb->fsdb_ost_index_map))
5887 int mgs_pool_sanity(const struct lu_env *env, struct mgs_device *mgs,
5888 struct fs_db *fsdb, struct mgs_target_info *mti,
5889 char *logname, char *devname, enum lcfg_command_type cmd,
5890 char *fsname, char *poolname, char *ostname)
5892 char *lov = fsdb->fsdb_clilov;
5896 status = mgs_search_pool(env, mgs, fsdb, mti, logname, lov,
5897 fsname, poolname, ostname);
5903 if (status >= POOL_STATUS_EXIST)
5907 if (status == POOL_STATUS_NONE)
5909 else if (status == POOL_STATUS_OST_EXIST)
5913 if (status == POOL_STATUS_NONE)
5915 if (status != POOL_STATUS_OST_EXIST)
5919 if (status == POOL_STATUS_NONE)
5921 if (status == POOL_STATUS_OST_EXIST)
5933 int mgs_pool_cmd(const struct lu_env *env, struct mgs_device *mgs,
5934 enum lcfg_command_type cmd, char *fsname,
5935 char *poolname, char *ostname)
5941 char *canceled_label = NULL;
5943 struct mgs_target_info *mti = NULL;
5947 if ((cmd == LCFG_POOL_REM || cmd == LCFG_POOL_ADD) && !ostname)
5949 if ((cmd == LCFG_POOL_DEL || cmd == LCFG_POOL_NEW) && ostname)
5952 rc = mgs_find_or_make_fsdb(env, mgs, fsname, &fsdb);
5954 CERROR("Can't get db for %s\n", fsname);
5957 if (test_bit(FSDB_LOG_EMPTY, &fsdb->fsdb_flags)) {
5958 CERROR("%s is not defined\n", fsname);
5959 mgs_unlink_fsdb(mgs, fsdb);
5960 GOTO(out_fsdb, rc = -EINVAL);
5963 label_sz = 10 + strlen(fsname) + strlen(poolname);
5965 rc = mgs_pool_check_ostname(fsdb, fsname, ostname);
5968 label_sz += strlen(ostname);
5971 OBD_ALLOC(label, label_sz);
5973 GOTO(out_fsdb, rc = -ENOMEM);
5977 sprintf(label, "new %s.%s", fsname, poolname);
5980 sprintf(label, "add %s.%s.%s", fsname, poolname, ostname);
5983 OBD_ALLOC(canceled_label, label_sz);
5984 if (canceled_label == NULL)
5985 GOTO(out_label, rc = -ENOMEM);
5986 sprintf(label, "rem %s.%s.%s", fsname, poolname, ostname);
5987 sprintf(canceled_label, "add %s.%s.%s",
5988 fsname, poolname, ostname);
5991 OBD_ALLOC(canceled_label, label_sz);
5992 if (canceled_label == NULL)
5993 GOTO(out_label, rc = -ENOMEM);
5995 sprintf(label, "del %s.%s", fsname, poolname);
5996 sprintf(canceled_label, "new %s.%s", fsname, poolname);
6004 GOTO(out_cancel, rc = -ENOMEM);
6005 strscpy(mti->mti_svname, "lov pool", sizeof(mti->mti_svname));
6007 mutex_lock(&fsdb->fsdb_mutex);
6009 rc = name_create(&logname, fsname, "-client");
6011 GOTO(out_unlock, rc);
6013 rc = mgs_pool_sanity(env, mgs, fsdb, mti, logname, fsdb->fsdb_clilov,
6014 cmd, fsname, poolname, ostname);
6016 GOTO(out_logname, rc);
6019 rc = mgs_modify(env, mgs, fsdb, mti, logname,
6020 fsdb->fsdb_clilov, canceled_label, CM_SKIP);
6023 GOTO(out_logname, rc);
6025 rc = mgs_write_log_pool(env, mgs, logname, fsdb, fsdb->fsdb_clilov,
6026 cmd, fsname, poolname, ostname, label);
6028 GOTO(out_logname, rc);
6030 name_destroy(&logname);
6032 /* write pool def to all MDT logs */
6033 for_each_set_bit(i, fsdb->fsdb_mdt_index_map, INDEX_MAP_SIZE) {
6034 rc = name_create_mdt_and_lov(&logname, &lovname, fsdb, i);
6036 GOTO(out_unlock, rc);
6039 rc = mgs_modify(env, mgs, fsdb, mti, logname, lovname,
6040 canceled_label, CM_SKIP);
6043 GOTO(out_names, rc);
6045 rc = mgs_write_log_pool(env, mgs, logname, fsdb, lovname, cmd,
6046 fsname, poolname, ostname, label);
6048 GOTO(out_names, rc);
6050 name_destroy(&logname);
6051 name_destroy(&lovname);
6053 mutex_unlock(&fsdb->fsdb_mutex);
6055 /* request for update */
6056 mgs_revoke_lock(mgs, fsdb, MGS_CFG_T_CONFIG);
6061 name_destroy(&lovname);
6063 name_destroy(&logname);
6065 mutex_unlock(&fsdb->fsdb_mutex);
6070 OBD_FREE(canceled_label, label_sz);
6072 OBD_FREE(label, label_sz);
6074 mgs_put_fsdb(mgs, fsdb);