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 if (strlcpy(mml->mml_marker.cm_comment, comment,
999 sizeof(mml->mml_marker.cm_comment)) >=
1000 sizeof(mml->mml_marker.cm_comment))
1001 GOTO(out_free, rc = -E2BIG);
1002 if (strlcpy(mml->mml_marker.cm_tgtname, devname,
1003 sizeof(mml->mml_marker.cm_tgtname)) >=
1004 sizeof(mml->mml_marker.cm_tgtname))
1005 GOTO(out_free, rc = -E2BIG);
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 strlcpy(mrd->target.mti_svname, devname,
1483 sizeof(mrd->target.mti_svname));
1484 /* data is parsed in llog callback */
1486 strlcpy(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 = strlcpy(mgi->mgi_marker.cm_tgtname, tgtname,
1975 sizeof(mgi->mgi_marker.cm_tgtname));
1976 if (cplen >= sizeof(mgi->mgi_marker.cm_tgtname))
1978 cplen = strlcpy(mgi->mgi_marker.cm_comment, comment,
1979 sizeof(mgi->mgi_marker.cm_comment));
1980 if (cplen >= 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 = strlcpy(tmti->mti_svname, marker->cm_tgtname,
2215 sizeof(tmti->mti_svname));
2216 if (cplen >= 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 strlcpy(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 if (strlcpy(mti->mti_params, param, sizeof(mti->mti_params)) >=
4084 sizeof(mti->mti_params)) {
4089 CDEBUG(D_MGS, "Adding failnode with param %s\n",
4091 rc = mgs_write_log_add_failnid(env, mgs, fsdb, mti);
4095 /* root squash parameters must not be set on llite subsystem, this can
4096 * lead to inconsistencies between client and server values
4098 if ((strstr(ptr, PARAM_NOSQUASHNIDS) ||
4099 strstr(ptr, PARAM_ROOTSQUASH)) &&
4100 strncmp(ptr, "llite.", strlen("llite.")) == 0) {
4102 CWARN("%s: cannot add %s param to llite subsystem, use mdt instead: rc=%d\n",
4103 mgs->mgs_obd->obd_name,
4104 strstr(ptr, PARAM_ROOTSQUASH) ?
4105 PARAM_ROOTSQUASH : PARAM_NOSQUASHNIDS,
4110 rc = mgs_wlp_lcfg(env, mgs, fsdb, mti, PARAMS_FILENAME, &bufs,
4111 mti->mti_svname, ptr);
4116 /* Permanent settings of all parameters by writing into the appropriate
4117 * configuration logs.
4118 * A parameter with null value ("<param>='\0'") means to erase it out of
4121 static int mgs_write_log_param(const struct lu_env *env,
4122 struct mgs_device *mgs, struct fs_db *fsdb,
4123 struct mgs_target_info *mti, char *ptr)
4125 struct mgs_thread_info *mgi = mgs_env_info(env);
4131 /* For various parameter settings, we have to figure out which logs
4132 * care about them (e.g. both mdt and client for lov settings)
4134 CDEBUG(D_MGS, "next param '%s'\n", ptr);
4136 /* The params are stored in MOUNT_DATA_FILE and modified via
4137 * tunefs.lustre, or set using lctl conf_param
4140 /* Processed in lustre_start_mgc */
4141 if (class_match_param(ptr, PARAM_MGSNODE, NULL) == 0)
4144 /* Processed in ost/mdt */
4145 if (class_match_param(ptr, PARAM_NETWORK, NULL) == 0)
4148 /* Processed in mgs_write_log_ost */
4149 if (class_match_param(ptr, PARAM_FAILMODE, NULL) == 0) {
4150 if (mti->mti_flags & LDD_F_PARAM) {
4151 LCONSOLE_ERROR_MSG(0x169,
4152 "%s can only be changed with tunefs.lustre and --writeconf\n",
4159 if (class_match_param(ptr, PARAM_SRPC, NULL) == 0) {
4160 rc = mgs_srpc_set_param(env, mgs, fsdb, mti, ptr);
4164 if (class_match_param(ptr, PARAM_FAILNODE, NULL) == 0) {
4165 /* Add a failover nidlist */
4167 /* We already processed failovers params for new
4168 * targets in mgs_write_log_target
4170 if (mti->mti_flags & LDD_F_PARAM) {
4171 CDEBUG(D_MGS, "Adding failnode\n");
4172 rc = mgs_write_log_add_failnid(env, mgs, fsdb, mti);
4177 if (class_match_param(ptr, PARAM_SYS, &tmp) == 0) {
4178 rc = mgs_write_log_sys(env, mgs, fsdb, mti, ptr, tmp);
4182 if (class_match_param(ptr, PARAM_QUOTA, &tmp) == 0) {
4183 rc = mgs_write_log_quota(env, mgs, fsdb, mti, ptr, tmp);
4187 if (class_match_param(ptr, PARAM_OSC PARAM_ACTIVE, &tmp) == 0 ||
4188 class_match_param(ptr, PARAM_MDC PARAM_ACTIVE, &tmp) == 0) {
4189 /* active=0 means off, anything else means on */
4190 int flag = (*tmp == '0') ? CM_EXCLUDE : 0;
4191 bool deactive_osc = memcmp(ptr, PARAM_OSC PARAM_ACTIVE,
4192 strlen(PARAM_OSC PARAM_ACTIVE)) == 0;
4195 if (!deactive_osc) {
4198 rc = server_name2index(mti->mti_svname, &index, NULL);
4203 LCONSOLE_ERROR_MSG(0x144, "%s: MDC0 can not be"
4204 " (de)activated.\n",
4206 GOTO(end, rc = -EPERM);
4210 LCONSOLE_WARN("Permanently %sactivating %s\n",
4211 flag ? "de" : "re", mti->mti_svname);
4213 rc = name_create(&logname, mti->mti_fsname, "-client");
4216 rc = mgs_modify(env, mgs, fsdb, mti, logname,
4218 deactive_osc ? "add osc" : "add mdc", flag);
4219 name_destroy(&logname);
4224 /* Add to all MDT logs for DNE */
4225 for (i = 0; i < INDEX_MAP_SIZE * 8; i++) {
4226 if (!test_bit(i, fsdb->fsdb_mdt_index_map))
4228 rc = name_create_mdt(&logname, mti->mti_fsname, i);
4231 rc = mgs_modify(env, mgs, fsdb, mti, logname,
4233 deactive_osc ? "add osc" : "add osp",
4235 name_destroy(&logname);
4241 LCONSOLE_ERROR_MSG(0x145,
4242 "Couldn't find %s in log (%d). No permanent changes were made to the config log.\n",
4243 mti->mti_svname, rc);
4244 if (test_bit(FSDB_OLDLOG14, &fsdb->fsdb_flags))
4245 LCONSOLE_ERROR_MSG(0x146,
4246 "This may be because the log is in the old 1.4 style. Consider --writeconf to update the logs.\n");
4249 /* Fall through to osc/mdc proc for deactivating live
4250 * OSC/OSP on running MDT / clients.
4253 /* Below here, let obd's XXX_process_config methods handle it */
4255 /* All lov. in proc */
4256 if (class_match_param(ptr, PARAM_LOV, NULL) == 0) {
4259 CDEBUG(D_MGS, "lov param %s\n", ptr);
4260 if (!(mti->mti_flags & LDD_F_SV_TYPE_MDT)) {
4261 LCONSOLE_ERROR_MSG(0x147,
4262 "LOV params must be set on the MDT, not %s. Ignoring.\n",
4268 if (mgs_log_is_empty(env, mgs, mti->mti_svname))
4269 GOTO(end, rc = -ENODEV);
4271 rc = name_create_mdt_and_lov(&logname, &mdtlovname, fsdb,
4272 mti->mti_stripe_index);
4275 rc = mgs_wlp_lcfg(env, mgs, fsdb, mti, mti->mti_svname,
4276 &mgi->mgi_bufs, mdtlovname, ptr);
4277 name_destroy(&logname);
4278 name_destroy(&mdtlovname);
4283 rc = name_create(&logname, mti->mti_fsname, "-client");
4286 rc = mgs_wlp_lcfg(env, mgs, fsdb, mti, logname, &mgi->mgi_bufs,
4287 fsdb->fsdb_clilov, ptr);
4288 name_destroy(&logname);
4292 /* All osc., mdc., llite. params in proc */
4293 if ((class_match_param(ptr, PARAM_OSC, NULL) == 0) ||
4294 (class_match_param(ptr, PARAM_MDC, NULL) == 0) ||
4295 (class_match_param(ptr, PARAM_LLITE, NULL) == 0)) {
4298 if (test_bit(FSDB_OLDLOG14, &fsdb->fsdb_flags)) {
4299 LCONSOLE_ERROR_MSG(0x148, "Upgraded client logs for %s"
4300 " cannot be modified. Consider"
4301 " updating the configuration with"
4304 GOTO(end, rc = -EINVAL);
4306 if (memcmp(ptr, PARAM_LLITE, strlen(PARAM_LLITE)) == 0) {
4307 rc = name_create(&cname, mti->mti_fsname, "-client");
4308 /* Add the client type to match the obdname in
4309 * class_config_llog_handler
4311 } else if (mti->mti_flags & LDD_F_SV_TYPE_MDT) {
4312 rc = name_create(&cname, mti->mti_svname, "-mdc");
4313 } else if (mti->mti_flags & LDD_F_SV_TYPE_OST) {
4314 rc = name_create(&cname, mti->mti_svname, "-osc");
4316 GOTO(end, rc = -EINVAL);
4321 /* Forbid direct update of llite root squash parameters.
4322 * These parameters are indirectly set via the MDT settings.
4324 if ((class_match_param(ptr, PARAM_LLITE, &tmp) == 0) &&
4325 ((memcmp(tmp, "root_squash=", 12) == 0) ||
4326 (memcmp(tmp, "nosquash_nids=", 14) == 0))) {
4327 LCONSOLE_ERROR("%s: root squash parameters can only "
4328 "be updated through MDT component\n",
4330 name_destroy(&cname);
4331 GOTO(end, rc = -EINVAL);
4334 CDEBUG(D_MGS, "%.3s param %s\n", ptr, ptr + 4);
4337 rc = name_create(&logname, mti->mti_fsname, "-client");
4339 name_destroy(&cname);
4342 rc = mgs_wlp_lcfg(env, mgs, fsdb, mti, logname, &mgi->mgi_bufs,
4345 /* osc params affect the MDT as well */
4346 if (!rc && (mti->mti_flags & LDD_F_SV_TYPE_OST)) {
4349 for (i = 0; i < INDEX_MAP_SIZE * 8; i++) {
4350 if (!test_bit(i, fsdb->fsdb_mdt_index_map))
4352 name_destroy(&cname);
4353 rc = name_create_mdt_osc(&cname, mti->mti_svname,
4355 name_destroy(&logname);
4358 rc = name_create_mdt(&logname,
4359 mti->mti_fsname, i);
4362 if (!mgs_log_is_empty(env, mgs, logname)) {
4363 rc = mgs_wlp_lcfg(env, mgs, fsdb,
4373 /* For mdc activate/deactivate, it affects OSP on MDT as well */
4374 if (class_match_param(ptr, PARAM_MDC PARAM_ACTIVE, &tmp) == 0 &&
4377 char *lodname = NULL;
4378 char *param_str = NULL;
4382 /* replace mdc with osp */
4383 memcpy(ptr, PARAM_OSP, strlen(PARAM_OSP));
4384 rc = server_name2index(mti->mti_svname, &index, NULL);
4386 memcpy(ptr, PARAM_MDC, strlen(PARAM_MDC));
4390 for (i = 0; i < INDEX_MAP_SIZE * 8; i++) {
4391 if (!test_bit(i, fsdb->fsdb_mdt_index_map))
4397 name_destroy(&logname);
4398 rc = name_create_mdt(&logname, mti->mti_fsname,
4403 if (mgs_log_is_empty(env, mgs, logname))
4406 snprintf(suffix, sizeof(suffix), "-osp-MDT%04x",
4408 name_destroy(&cname);
4409 rc = name_create(&cname, mti->mti_svname,
4414 rc = mgs_wlp_lcfg(env, mgs, fsdb, mti, logname,
4415 &mgi->mgi_bufs, cname, ptr);
4419 /* Add configuration log for noitfying LOD
4420 * to active/deactive the OSP. */
4421 name_destroy(¶m_str);
4422 rc = name_create(¶m_str, cname,
4423 (*tmp == '0') ? ".active=0" :
4428 name_destroy(&lodname);
4429 rc = name_create(&lodname, logname, "-mdtlov");
4433 rc = mgs_wlp_lcfg(env, mgs, fsdb, mti, logname,
4434 &mgi->mgi_bufs, lodname,
4439 memcpy(ptr, PARAM_MDC, strlen(PARAM_MDC));
4440 name_destroy(&lodname);
4441 name_destroy(¶m_str);
4444 name_destroy(&logname);
4445 name_destroy(&cname);
4449 /* All mdt. params in proc */
4450 if (class_match_param(ptr, PARAM_MDT, &tmp) == 0) {
4454 CDEBUG(D_MGS, "%.3s param %s\n", ptr, ptr + 4);
4455 if (strncmp(mti->mti_svname, mti->mti_fsname,
4456 MTI_NAME_MAXLEN) == 0)
4457 /* device is unspecified completely? */
4458 rc = LDD_F_SV_TYPE_MDT | LDD_F_SV_ALL;
4460 rc = server_name2index(mti->mti_svname, &idx, NULL);
4463 if ((rc & LDD_F_SV_TYPE_MDT) == 0)
4465 if (rc & LDD_F_SV_ALL) {
4466 for (i = 0; i < INDEX_MAP_SIZE * 8; i++) {
4468 fsdb->fsdb_mdt_index_map))
4470 rc = name_create_mdt(&logname,
4471 mti->mti_fsname, i);
4474 rc = mgs_wlp_lcfg(env, mgs, fsdb, mti,
4475 logname, &mgi->mgi_bufs,
4477 name_destroy(&logname);
4482 if ((memcmp(tmp, "root_squash=", 12) == 0) ||
4483 (memcmp(tmp, "nosquash_nids=", 14) == 0)) {
4484 LCONSOLE_ERROR("%s: root squash parameters "
4485 "cannot be applied to a single MDT\n",
4487 GOTO(end, rc = -EINVAL);
4489 rc = mgs_wlp_lcfg(env, mgs, fsdb, mti,
4490 mti->mti_svname, &mgi->mgi_bufs,
4491 mti->mti_svname, ptr);
4496 /* root squash settings are also applied to llite
4497 * config log (see LU-1778) */
4499 ((memcmp(tmp, "root_squash=", 12) == 0) ||
4500 (memcmp(tmp, "nosquash_nids=", 14) == 0))) {
4504 rc = name_create(&cname, mti->mti_fsname, "-client");
4507 rc = name_create(&logname, mti->mti_fsname, "-client");
4509 name_destroy(&cname);
4512 rc = name_create(&ptr2, PARAM_LLITE, tmp);
4514 name_destroy(&cname);
4515 name_destroy(&logname);
4518 rc = mgs_wlp_lcfg(env, mgs, fsdb, mti, logname,
4519 &mgi->mgi_bufs, cname, ptr2);
4520 name_destroy(&ptr2);
4521 name_destroy(&logname);
4522 name_destroy(&cname);
4527 /* All mdd., ost. and osd. params in proc */
4528 if ((class_match_param(ptr, PARAM_MDD, NULL) == 0) ||
4529 (class_match_param(ptr, PARAM_LOD, NULL) == 0) ||
4530 (class_match_param(ptr, PARAM_OST, NULL) == 0) ||
4531 (class_match_param(ptr, PARAM_OSD, NULL) == 0)) {
4532 CDEBUG(D_MGS, "%.3s param %s\n", ptr, ptr + 4);
4533 if (mgs_log_is_empty(env, mgs, mti->mti_svname))
4534 GOTO(end, rc = -ENODEV);
4536 rc = mgs_wlp_lcfg(env, mgs, fsdb, mti, mti->mti_svname,
4537 &mgi->mgi_bufs, mti->mti_svname, ptr);
4541 /* For handling degraded zfs OST */
4542 if (class_match_param(ptr, PARAM_AUTODEGRADE, NULL) == 0)
4545 LCONSOLE_WARN("Ignoring unrecognized param '%s'\n", ptr);
4549 CERROR("err %d on param '%s'\n", rc, ptr);
4554 int mgs_write_log_target(const struct lu_env *env, struct mgs_device *mgs,
4555 struct mgs_target_info *mti, struct fs_db *fsdb)
4562 /* set/check the new target index */
4563 rc = mgs_set_index(env, mgs, mti);
4567 if (rc == EALREADY) {
4568 LCONSOLE_WARN("Found index %d for %s, updating log\n",
4569 mti->mti_stripe_index, mti->mti_svname);
4570 /* We would like to mark old log sections as invalid
4571 and add new log sections in the client and mdt logs.
4572 But if we add new sections, then live clients will
4573 get repeat setup instructions for already running
4574 osc's. So don't update the client/mdt logs. */
4575 mti->mti_flags &= ~LDD_F_UPDATE;
4579 CFS_FAIL_TIMEOUT(OBD_FAIL_MGS_WRITE_TARGET_DELAY, cfs_fail_val > 0 ?
4582 mutex_lock(&fsdb->fsdb_mutex);
4584 if (mti->mti_flags & (LDD_F_VIRGIN | LDD_F_WRITECONF)) {
4585 /* Generate a log from scratch */
4586 if (mti->mti_flags & LDD_F_SV_TYPE_MDT) {
4587 rc = mgs_write_log_mdt(env, mgs, fsdb, mti);
4588 } else if (mti->mti_flags & LDD_F_SV_TYPE_OST) {
4589 rc = mgs_write_log_ost(env, mgs, fsdb, mti);
4591 CERROR("Unknown target type %#x, can't create log for %s\n",
4592 mti->mti_flags, mti->mti_svname);
4595 CERROR("Can't write logs for %s (%d)\n",
4596 mti->mti_svname, rc);
4600 /* Just update the params from tunefs in mgs_write_log_params */
4601 CDEBUG(D_MGS, "Update params for %s\n", mti->mti_svname);
4602 mti->mti_flags |= LDD_F_PARAM;
4605 /* allocate temporary buffer, where class_get_next_param will
4606 * make copy of a current parameter
4608 OBD_ALLOC(buf, strlen(mti->mti_params) + 1);
4610 GOTO(out_up, rc = -ENOMEM);
4611 params = mti->mti_params;
4612 while (params != NULL) {
4613 rc = class_get_next_param(¶ms, buf);
4616 /* there is no next parameter, that is
4622 CDEBUG(D_MGS, "remaining string: '%s', param: '%s'\n",
4624 rc = mgs_write_log_param(env, mgs, fsdb, mti, buf);
4629 OBD_FREE(buf, strlen(mti->mti_params) + 1);
4632 mutex_unlock(&fsdb->fsdb_mutex);
4636 int mgs_erase_log(const struct lu_env *env, struct mgs_device *mgs, char *name)
4638 struct llog_ctxt *ctxt;
4641 ctxt = llog_get_context(mgs->mgs_obd, LLOG_CONFIG_ORIG_CTXT);
4643 CERROR("%s: MGS config context doesn't exist\n",
4644 mgs->mgs_obd->obd_name);
4647 rc = llog_erase(env, ctxt, NULL, name);
4648 /* llog may not exist */
4651 llog_ctxt_put(ctxt);
4655 CERROR("%s: failed to clear log %s: %d\n",
4656 mgs->mgs_obd->obd_name, name, rc);
4661 /* erase all logs for the given fs */
4662 int mgs_erase_logs(const struct lu_env *env, struct mgs_device *mgs,
4665 struct list_head log_list;
4666 struct mgs_direntry *dirent, *n;
4667 char barrier_name[20] = {};
4670 int rc, len = strlen(fsname);
4673 mutex_lock(&mgs->mgs_mutex);
4675 /* Find all the logs in the CONFIGS directory */
4676 rc = class_dentry_readdir(env, mgs, &log_list);
4678 mutex_unlock(&mgs->mgs_mutex);
4682 if (list_empty(&log_list)) {
4683 mutex_unlock(&mgs->mgs_mutex);
4687 snprintf(barrier_name, sizeof(barrier_name) - 1, "%s-%s",
4688 fsname, BARRIER_FILENAME);
4689 /* Delete the barrier fsdb */
4690 mgs_remove_fsdb_by_name(mgs, barrier_name);
4691 /* Delete the fs db */
4692 mgs_remove_fsdb_by_name(mgs, fsname);
4693 mutex_unlock(&mgs->mgs_mutex);
4695 list_for_each_entry_safe(dirent, n, &log_list, mde_list) {
4696 list_del_init(&dirent->mde_list);
4697 suffix = strrchr(dirent->mde_name, '-');
4698 if (suffix != NULL) {
4699 if ((len == suffix - dirent->mde_name) &&
4700 (strncmp(fsname, dirent->mde_name, len) == 0)) {
4701 CDEBUG(D_MGS, "Removing log %s\n",
4703 mgs_erase_log(env, mgs, dirent->mde_name);
4707 mgs_direntry_free(dirent);
4716 /* list all logs for the given fs */
4717 int mgs_list_logs(const struct lu_env *env, struct mgs_device *mgs,
4718 struct obd_ioctl_data *data)
4720 struct list_head log_list;
4721 struct mgs_direntry *dirent, *n;
4722 char *out, *suffix, prefix[] = "config_log: ";
4723 int prefix_len = strlen(prefix);
4724 int len, remains, start = 0, rc;
4728 /* Find all the logs in the CONFIGS directory */
4729 rc = class_dentry_readdir(env, mgs, &log_list);
4733 out = data->ioc_bulk;
4734 remains = data->ioc_inllen1;
4735 /* OBD_FAIL: fetch the config_log records from the specified one */
4736 if (CFS_FAIL_CHECK(OBD_FAIL_CATLIST))
4737 data->ioc_count = cfs_fail_val;
4739 list_for_each_entry_safe(dirent, n, &log_list, mde_list) {
4740 list_del_init(&dirent->mde_list);
4741 suffix = strrchr(dirent->mde_name, '-');
4742 if (suffix != NULL) {
4743 len = prefix_len + dirent->mde_len + 1;
4744 if (remains - len < 0) {
4745 /* No enough space for this record */
4746 mgs_direntry_free(dirent);
4750 if (start < data->ioc_count) {
4751 mgs_direntry_free(dirent);
4754 len = scnprintf(out, remains, "%s%s\n", prefix,
4759 mgs_direntry_free(dirent);
4767 data->ioc_count = start;
4771 struct mgs_lcfg_fork_data {
4772 struct lustre_cfg_bufs mlfd_bufs;
4773 struct mgs_device *mlfd_mgs;
4774 struct llog_handle *mlfd_llh;
4775 const char *mlfd_oldname;
4776 const char *mlfd_newname;
4780 static bool contain_valid_fsname(char *buf, const char *fsname,
4781 int buflen, int namelen)
4783 if (buflen < namelen)
4786 if (memcmp(buf, fsname, namelen) != 0)
4789 if (buf[namelen] != '\0' && buf[namelen] != '-')
4795 static int mgs_lcfg_fork_handler(const struct lu_env *env,
4796 struct llog_handle *o_llh,
4797 struct llog_rec_hdr *o_rec, void *data)
4799 struct mgs_lcfg_fork_data *mlfd = data;
4800 struct lustre_cfg_bufs *n_bufs = &mlfd->mlfd_bufs;
4801 struct lustre_cfg *o_lcfg = (struct lustre_cfg *)(o_rec + 1);
4802 struct llog_cfg_rec *lcr;
4804 char *n_buf = mlfd->mlfd_data;
4806 int o_namelen = strlen(mlfd->mlfd_oldname);
4807 int n_namelen = strlen(mlfd->mlfd_newname);
4808 int diff = n_namelen - o_namelen;
4809 __u32 cmd = o_lcfg->lcfg_command;
4810 __u32 cnt = o_lcfg->lcfg_bufcount;
4816 o_buf = lustre_cfg_buf(o_lcfg, 0);
4817 o_buflen = o_lcfg->lcfg_buflens[0];
4818 if (contain_valid_fsname(o_buf, mlfd->mlfd_oldname, o_buflen,
4820 memcpy(n_buf, mlfd->mlfd_newname, n_namelen);
4821 memcpy(n_buf + n_namelen, o_buf + o_namelen,
4822 o_buflen - o_namelen);
4823 lustre_cfg_bufs_reset(n_bufs, n_buf);
4824 n_buf += round_up(o_buflen + diff, 8);
4826 lustre_cfg_bufs_reset(n_bufs, o_buflen != 0 ? o_buf : NULL);
4831 struct cfg_marker *o_marker;
4832 struct cfg_marker *n_marker;
4836 CDEBUG(D_MGS, "Unknown cfg marker entry with %d "
4841 /* buf[1] is marker */
4842 o_buf = lustre_cfg_buf(o_lcfg, 1);
4843 o_buflen = o_lcfg->lcfg_buflens[1];
4844 o_marker = (struct cfg_marker *)o_buf;
4845 if (!contain_valid_fsname(o_marker->cm_tgtname,
4847 sizeof(o_marker->cm_tgtname),
4849 lustre_cfg_bufs_set(n_bufs, 1, o_marker,
4854 n_marker = (struct cfg_marker *)n_buf;
4855 *n_marker = *o_marker;
4856 memcpy(n_marker->cm_tgtname, mlfd->mlfd_newname, n_namelen);
4857 tgt_namelen = strlen(o_marker->cm_tgtname);
4858 if (tgt_namelen > o_namelen)
4859 memcpy(n_marker->cm_tgtname + n_namelen,
4860 o_marker->cm_tgtname + o_namelen,
4861 tgt_namelen - o_namelen);
4862 n_marker->cm_tgtname[tgt_namelen + diff] = '\0';
4863 lustre_cfg_bufs_set(n_bufs, 1, n_marker, sizeof(*n_marker));
4867 case LCFG_SET_PARAM: {
4868 for (i = 1; i < cnt; i++)
4869 /* buf[i] is the param value, reuse it directly */
4870 lustre_cfg_bufs_set(n_bufs, i,
4871 lustre_cfg_buf(o_lcfg, i),
4872 o_lcfg->lcfg_buflens[i]);
4878 case LCFG_POOL_DEL: {
4879 if (cnt < 3 || cnt > 4) {
4880 CDEBUG(D_MGS, "Unknown cfg pool (%x) entry with %d "
4881 "buffers\n", cmd, cnt);
4885 /* buf[1] is fsname */
4886 o_buf = lustre_cfg_buf(o_lcfg, 1);
4887 o_buflen = o_lcfg->lcfg_buflens[1];
4888 memcpy(n_buf, mlfd->mlfd_newname, n_namelen);
4889 memcpy(n_buf + n_namelen, o_buf + o_namelen,
4890 o_buflen - o_namelen);
4891 lustre_cfg_bufs_set(n_bufs, 1, n_buf, o_buflen + diff);
4892 n_buf += round_up(o_buflen + diff, 8);
4894 /* buf[2] is the pool name, reuse it directly */
4895 lustre_cfg_bufs_set(n_bufs, 2, lustre_cfg_buf(o_lcfg, 2),
4896 o_lcfg->lcfg_buflens[2]);
4901 /* buf[3] is ostname */
4902 o_buf = lustre_cfg_buf(o_lcfg, 3);
4903 o_buflen = o_lcfg->lcfg_buflens[3];
4904 memcpy(n_buf, mlfd->mlfd_newname, n_namelen);
4905 memcpy(n_buf + n_namelen, o_buf + o_namelen,
4906 o_buflen - o_namelen);
4907 lustre_cfg_bufs_set(n_bufs, 3, n_buf, o_buflen + diff);
4912 o_buflen = o_lcfg->lcfg_buflens[1];
4913 if (o_buflen == sizeof(struct lov_desc) ||
4914 o_buflen == sizeof(struct lmv_desc)) {
4920 o_buf = lustre_cfg_buf(o_lcfg, 1);
4921 if (o_buflen == sizeof(struct lov_desc)) {
4922 struct lov_desc *o_desc =
4923 (struct lov_desc *)o_buf;
4924 struct lov_desc *n_desc =
4925 (struct lov_desc *)n_buf;
4928 o_uuid = o_desc->ld_uuid.uuid;
4929 n_uuid = n_desc->ld_uuid.uuid;
4930 uuid_len = sizeof(o_desc->ld_uuid.uuid);
4932 struct lmv_desc *o_desc =
4933 (struct lmv_desc *)o_buf;
4934 struct lmv_desc *n_desc =
4935 (struct lmv_desc *)n_buf;
4938 o_uuid = o_desc->ld_uuid.uuid;
4939 n_uuid = n_desc->ld_uuid.uuid;
4940 uuid_len = sizeof(o_desc->ld_uuid.uuid);
4943 if (unlikely(!contain_valid_fsname(o_uuid,
4944 mlfd->mlfd_oldname, uuid_len,
4946 lustre_cfg_bufs_set(n_bufs, 1, o_buf,
4951 memcpy(n_uuid, mlfd->mlfd_newname, n_namelen);
4952 uuid_len = strlen(o_uuid);
4953 if (uuid_len > o_namelen)
4954 memcpy(n_uuid + n_namelen,
4956 uuid_len - o_namelen);
4957 n_uuid[uuid_len + diff] = '\0';
4958 lustre_cfg_bufs_set(n_bufs, 1, n_buf, o_buflen);
4960 } /* else case fall through */
4961 } /* else case fall through */
4965 for (i = 1; i < cnt; i++) {
4966 o_buflen = o_lcfg->lcfg_buflens[i];
4970 o_buf = lustre_cfg_buf(o_lcfg, i);
4971 if (!contain_valid_fsname(o_buf, mlfd->mlfd_oldname,
4972 o_buflen, o_namelen)) {
4973 lustre_cfg_bufs_set(n_bufs, i, o_buf, o_buflen);
4977 memcpy(n_buf, mlfd->mlfd_newname, n_namelen);
4978 if (o_buflen == o_namelen) {
4979 lustre_cfg_bufs_set(n_bufs, i, n_buf,
4981 n_buf += round_up(n_namelen, 8);
4985 memcpy(n_buf + n_namelen, o_buf + o_namelen,
4986 o_buflen - o_namelen);
4987 lustre_cfg_bufs_set(n_bufs, i, n_buf, o_buflen + diff);
4988 n_buf += round_up(o_buflen + diff, 8);
4994 lcr = lustre_cfg_rec_new(cmd, n_bufs);
4998 lcr->lcr_cfg = *o_lcfg;
4999 rc = llog_write(env, mlfd->mlfd_llh, &lcr->lcr_hdr, LLOG_NEXT_IDX);
5000 lustre_cfg_rec_free(lcr);
5005 static int mgs_lcfg_fork_one(const struct lu_env *env, struct mgs_device *mgs,
5006 struct mgs_direntry *mde, const char *oldname,
5007 const char *newname)
5009 struct llog_handle *old_llh = NULL;
5010 struct llog_handle *new_llh = NULL;
5011 struct llog_ctxt *ctxt = NULL;
5012 struct mgs_lcfg_fork_data *mlfd = NULL;
5013 char *name_buf = NULL;
5015 int old_namelen = strlen(oldname);
5016 int new_namelen = strlen(newname);
5020 name_buflen = mde->mde_len + new_namelen - old_namelen;
5021 OBD_ALLOC(name_buf, name_buflen);
5025 memcpy(name_buf, newname, new_namelen);
5026 memcpy(name_buf + new_namelen, mde->mde_name + old_namelen,
5027 mde->mde_len - old_namelen);
5029 CDEBUG(D_MGS, "Fork the config-log from %s to %s\n",
5030 mde->mde_name, name_buf);
5032 ctxt = llog_get_context(mgs->mgs_obd, LLOG_CONFIG_ORIG_CTXT);
5035 rc = llog_open_create(env, ctxt, &new_llh, NULL, name_buf);
5039 rc = llog_init_handle(env, new_llh, LLOG_F_IS_PLAIN, NULL);
5043 if (unlikely(mgs_log_is_empty(env, mgs, mde->mde_name)))
5046 rc = llog_open(env, ctxt, &old_llh, NULL, mde->mde_name,
5051 rc = llog_init_handle(env, old_llh, LLOG_F_IS_PLAIN, NULL);
5055 new_llh->lgh_hdr->llh_tgtuuid = old_llh->lgh_hdr->llh_tgtuuid;
5057 OBD_ALLOC(mlfd, LLOG_MIN_CHUNK_SIZE);
5059 GOTO(out, rc = -ENOMEM);
5061 mlfd->mlfd_mgs = mgs;
5062 mlfd->mlfd_llh = new_llh;
5063 mlfd->mlfd_oldname = oldname;
5064 mlfd->mlfd_newname = newname;
5066 rc = llog_process(env, old_llh, mgs_lcfg_fork_handler, mlfd, NULL);
5067 OBD_FREE(mlfd, LLOG_MIN_CHUNK_SIZE);
5073 llog_close(env, old_llh);
5075 llog_close(env, new_llh);
5077 OBD_FREE(name_buf, name_buflen);
5079 llog_ctxt_put(ctxt);
5084 int mgs_lcfg_fork(const struct lu_env *env, struct mgs_device *mgs,
5085 const char *oldname, const char *newname)
5087 struct list_head log_list;
5088 struct mgs_direntry *dirent, *n;
5089 int olen = strlen(oldname);
5090 int nlen = strlen(newname);
5095 if (unlikely(!oldname || oldname[0] == '\0' ||
5096 !newname || newname[0] == '\0'))
5099 if (strcmp(oldname, newname) == 0)
5102 /* lock it to prevent fork/erase/register in parallel. */
5103 mutex_lock(&mgs->mgs_mutex);
5105 rc = class_dentry_readdir(env, mgs, &log_list);
5107 mutex_unlock(&mgs->mgs_mutex);
5111 if (list_empty(&log_list)) {
5112 mutex_unlock(&mgs->mgs_mutex);
5116 list_for_each_entry_safe(dirent, n, &log_list, mde_list) {
5119 ptr = strrchr(dirent->mde_name, '-');
5121 int tlen = ptr - dirent->mde_name;
5124 strncmp(newname, dirent->mde_name, tlen) == 0)
5125 GOTO(out, rc = -EEXIST);
5128 strncmp(oldname, dirent->mde_name, tlen) == 0)
5132 list_del_init(&dirent->mde_list);
5133 mgs_direntry_free(dirent);
5136 if (list_empty(&log_list)) {
5137 mutex_unlock(&mgs->mgs_mutex);
5141 list_for_each_entry(dirent, &log_list, mde_list) {
5142 rc = mgs_lcfg_fork_one(env, mgs, dirent, oldname, newname);
5150 mutex_unlock(&mgs->mgs_mutex);
5152 list_for_each_entry_safe(dirent, n, &log_list, mde_list) {
5153 list_del_init(&dirent->mde_list);
5154 mgs_direntry_free(dirent);
5157 if (rc && count > 0)
5158 mgs_erase_logs(env, mgs, newname);
5163 int mgs_lcfg_erase(const struct lu_env *env, struct mgs_device *mgs,
5169 if (unlikely(!fsname || fsname[0] == '\0'))
5172 rc = mgs_erase_logs(env, mgs, fsname);
5177 static int mgs_xattr_del(const struct lu_env *env, struct dt_object *obj)
5179 struct dt_device *dev;
5180 struct thandle *th = NULL;
5185 dev = container_of(obj->do_lu.lo_dev, struct dt_device, dd_lu_dev);
5186 th = dt_trans_create(env, dev);
5188 RETURN(PTR_ERR(th));
5190 rc = dt_declare_xattr_del(env, obj, XATTR_TARGET_RENAME, th);
5194 rc = dt_trans_start_local(env, dev, th);
5198 dt_write_lock(env, obj, 0);
5199 rc = dt_xattr_del(env, obj, XATTR_TARGET_RENAME, th);
5204 dt_write_unlock(env, obj);
5207 dt_trans_stop(env, dev, th);
5212 int mgs_lcfg_rename(const struct lu_env *env, struct mgs_device *mgs)
5214 struct list_head log_list;
5215 struct mgs_direntry *dirent, *n;
5217 struct lu_buf buf = {
5219 .lb_len = sizeof(fsname)
5225 rc = class_dentry_readdir(env, mgs, &log_list);
5229 if (list_empty(&log_list))
5232 list_for_each_entry_safe(dirent, n, &log_list, mde_list) {
5233 struct dt_object *o = NULL;
5238 list_del_init(&dirent->mde_list);
5239 ptr = strrchr(dirent->mde_name, '-');
5243 len = ptr - dirent->mde_name;
5244 if (unlikely(len >= sizeof(oldname))) {
5245 CDEBUG(D_MGS, "Skip invalid configuration file %s\n",
5250 o = local_file_find(env, mgs->mgs_los, mgs->mgs_configs_dir,
5254 CDEBUG(D_MGS, "Fail to locate file %s: rc = %d\n",
5255 dirent->mde_name, rc);
5259 rc = dt_xattr_get(env, o, &buf, XATTR_TARGET_RENAME);
5265 "Fail to get EA for %s: rc = %d\n",
5266 dirent->mde_name, rc);
5270 if (unlikely(rc == len &&
5271 memcmp(fsname, dirent->mde_name, len) == 0)) {
5272 /* The new fsname is the same as the old one. */
5273 rc = mgs_xattr_del(env, o);
5277 memcpy(oldname, dirent->mde_name, len);
5278 oldname[len] = '\0';
5280 rc = mgs_lcfg_fork_one(env, mgs, dirent, oldname, fsname);
5281 if (rc && rc != -EEXIST) {
5282 CDEBUG(D_MGS, "Fail to fork %s: rc = %d\n",
5283 dirent->mde_name, rc);
5287 rc = mgs_erase_log(env, mgs, dirent->mde_name);
5289 CDEBUG(D_MGS, "Fail to erase old %s: rc = %d\n",
5290 dirent->mde_name, rc);
5291 /* keep it there if failed to remove it. */
5296 if (o && !IS_ERR(o))
5297 lu_object_put(env, &o->do_lu);
5299 mgs_direntry_free(dirent);
5304 list_for_each_entry_safe(dirent, n, &log_list, mde_list) {
5305 list_del_init(&dirent->mde_list);
5306 mgs_direntry_free(dirent);
5312 /* Setup _mgs fsdb and log
5314 int mgs__mgs_fsdb_setup(const struct lu_env *env, struct mgs_device *mgs)
5316 struct fs_db *fsdb = NULL;
5320 rc = mgs_find_or_make_fsdb(env, mgs, MGSSELF_NAME, &fsdb);
5322 mgs_put_fsdb(mgs, fsdb);
5327 /* Setup params fsdb and log
5329 int mgs_params_fsdb_setup(const struct lu_env *env, struct mgs_device *mgs)
5331 struct fs_db *fsdb = NULL;
5332 struct llog_handle *params_llh = NULL;
5336 rc = mgs_find_or_make_fsdb(env, mgs, PARAMS_FILENAME, &fsdb);
5338 mutex_lock(&fsdb->fsdb_mutex);
5339 rc = record_start_log(env, mgs, ¶ms_llh, PARAMS_FILENAME);
5341 rc = record_end_log(env, ¶ms_llh);
5342 mutex_unlock(&fsdb->fsdb_mutex);
5343 mgs_put_fsdb(mgs, fsdb);
5349 /* Cleanup params fsdb and log
5351 int mgs_params_fsdb_cleanup(const struct lu_env *env, struct mgs_device *mgs)
5355 rc = mgs_erase_logs(env, mgs, PARAMS_FILENAME);
5356 return rc == -ENOENT ? 0 : rc;
5360 * Fill in the mgs_target_info based on data devname and param provide.
5362 * @env thread context
5364 * @mti mgs target info. We want to set this based other paramters
5365 * passed to this function. Once setup we write it to the config
5367 * @devname optional OBD device name
5368 * @param string that contains both what tunable to set and the value to
5371 * RETURN 0 for success
5372 * negative error number on failure
5374 static int mgs_set_conf_param(const struct lu_env *env, struct mgs_device *mgs,
5375 struct mgs_target_info *mti, const char *devname,
5378 struct fs_db *fsdb = NULL;
5383 /* lustre, lustre-mdtlov, lustre-client, lustre-MDT0000 */
5387 /* We have two possible cases here:
5389 * 1) the device name embedded in the param:
5390 * lustre-OST0000.osc.max_dirty_mb=32
5392 * 2) the file system name is embedded in
5393 * the param: lustre.sys.at.min=0
5395 len = strcspn(param, ".=");
5396 if (!len || param[len] == '=')
5399 if (len >= sizeof(mti->mti_svname))
5402 snprintf(mti->mti_svname, sizeof(mti->mti_svname),
5403 "%.*s", (int)len, param);
5406 if (strlcpy(mti->mti_svname, devname, sizeof(mti->mti_svname)) >=
5407 sizeof(mti->mti_svname))
5411 if (!strlen(mti->mti_svname)) {
5412 LCONSOLE_ERROR_MSG(0x14d, "No target specified: %s\n", param);
5416 dev_type = mgs_parse_devname(mti->mti_svname, mti->mti_fsname,
5417 &mti->mti_stripe_index);
5419 /* For this case we have an invalid obd device name */
5421 CDEBUG(D_MGS, "%s don't contain an index\n", mti->mti_svname);
5422 strlcpy(mti->mti_fsname, mti->mti_svname, MTI_NAME_MAXLEN);
5425 /* Not an obd device, assume devname is the fsname.
5426 * User might of only provided fsname and not obd device
5429 CDEBUG(D_MGS, "%s is seen as a file system name\n", mti->mti_svname);
5430 strlcpy(mti->mti_fsname, mti->mti_svname, MTI_NAME_MAXLEN);
5435 GOTO(out, rc = dev_type);
5437 /* param related to llite isn't allowed to set by OST or MDT */
5438 if (dev_type & LDD_F_SV_TYPE_OST ||
5439 dev_type & LDD_F_SV_TYPE_MDT) {
5440 /* param related to llite isn't allowed to set by OST
5443 if (!strncmp(param, PARAM_LLITE,
5444 sizeof(PARAM_LLITE) - 1))
5445 GOTO(out, rc = -EINVAL);
5447 /* Strip -osc or -mdc suffix from svname */
5448 if (server_make_name(dev_type, mti->mti_stripe_index,
5449 mti->mti_fsname, mti->mti_svname,
5450 sizeof(mti->mti_svname)))
5451 GOTO(out, rc = -EINVAL);
5456 if (strlcpy(mti->mti_params, param, sizeof(mti->mti_params)) >=
5457 sizeof(mti->mti_params))
5458 GOTO(out, rc = -E2BIG);
5460 CDEBUG(D_MGS, "set_conf_param fs='%s' device='%s' param='%s'\n",
5461 mti->mti_fsname, mti->mti_svname, mti->mti_params);
5463 rc = mgs_find_or_make_fsdb(env, mgs, mti->mti_fsname, &fsdb);
5467 if (!test_bit(FSDB_MGS_SELF, &fsdb->fsdb_flags) &&
5468 test_bit(FSDB_LOG_EMPTY, &fsdb->fsdb_flags)) {
5469 CERROR("No filesystem targets for %s. cfg_device from lctl "
5470 "is '%s'\n", mti->mti_fsname, mti->mti_svname);
5471 mgs_unlink_fsdb(mgs, fsdb);
5472 GOTO(out, rc = -EINVAL);
5476 * Revoke lock so everyone updates. Should be alright if
5477 * someone was already reading while we were updating the logs,
5478 * so we don't really need to hold the lock while we're
5481 mti->mti_flags = dev_type | LDD_F_PARAM;
5482 mutex_lock(&fsdb->fsdb_mutex);
5483 rc = mgs_write_log_param(env, mgs, fsdb, mti, mti->mti_params);
5484 mutex_unlock(&fsdb->fsdb_mutex);
5485 mgs_revoke_lock(mgs, fsdb, MGS_CFG_T_CONFIG);
5489 mgs_put_fsdb(mgs, fsdb);
5494 static int mgs_set_param2(const struct lu_env *env, struct mgs_device *mgs,
5495 struct mgs_target_info *mti, const char *param)
5497 struct fs_db *fsdb = NULL;
5502 if (strlcpy(mti->mti_params, param, sizeof(mti->mti_params)) >=
5503 sizeof(mti->mti_params))
5504 GOTO(out, rc = -E2BIG);
5506 len = strcspn(param, ".=");
5507 if (len && param[len] != '=') {
5508 struct list_head *tmp;
5512 ptr = strchr(param, '.');
5514 len = strlen(param);
5517 if (len >= sizeof(mti->mti_svname))
5518 GOTO(out, rc = -E2BIG);
5520 snprintf(mti->mti_svname, sizeof(mti->mti_svname), "%.*s",
5523 mutex_lock(&mgs->mgs_mutex);
5524 if (unlikely(list_empty(&mgs->mgs_fs_db_list))) {
5525 mutex_unlock(&mgs->mgs_mutex);
5526 GOTO(out, rc = -ENODEV);
5529 list_for_each(tmp, &mgs->mgs_fs_db_list) {
5530 fsdb = list_entry(tmp, struct fs_db, fsdb_list);
5531 if (fsdb->fsdb_has_lproc_entry &&
5532 strcmp(fsdb->fsdb_name, "params") != 0 &&
5533 strstr(param, fsdb->fsdb_name)) {
5534 snprintf(mti->mti_svname,
5535 sizeof(mti->mti_svname), "%s",
5543 snprintf(mti->mti_svname, sizeof(mti->mti_svname),
5546 mutex_unlock(&mgs->mgs_mutex);
5548 snprintf(mti->mti_svname, sizeof(mti->mti_svname), "general");
5551 CDEBUG(D_MGS, "set_param2 fs='%s' device='%s' param='%s'\n",
5552 mti->mti_fsname, mti->mti_svname, mti->mti_params);
5554 /* The return value should be the device type i.e LDD_F_SV_TYPE_XXX.
5555 * A returned error tells us we don't have a target obd device.
5557 dev_type = server_name2index(mti->mti_svname, &mti->mti_stripe_index,
5562 /* the return value should be the device type i.e LDD_F_SV_TYPE_XXX.
5563 * Strip -osc or -mdc suffix from svname
5565 if ((dev_type & LDD_F_SV_TYPE_OST || dev_type & LDD_F_SV_TYPE_MDT) &&
5566 server_make_name(dev_type, mti->mti_stripe_index,
5567 mti->mti_fsname, mti->mti_svname,
5568 sizeof(mti->mti_svname)))
5569 GOTO(out, rc = -EINVAL);
5571 rc = mgs_find_or_make_fsdb(env, mgs, PARAMS_FILENAME, &fsdb);
5575 * Revoke lock so everyone updates. Should be alright if
5576 * someone was already reading while we were updating the logs,
5577 * so we don't really need to hold the lock while we're
5580 mti->mti_flags = dev_type | LDD_F_PARAM2;
5581 mutex_lock(&fsdb->fsdb_mutex);
5582 rc = mgs_write_log_param2(env, mgs, fsdb, mti, mti->mti_params);
5583 mutex_unlock(&fsdb->fsdb_mutex);
5584 mgs_revoke_lock(mgs, fsdb, MGS_CFG_T_PARAMS);
5585 mgs_put_fsdb(mgs, fsdb);
5590 /* Set a permanent (config log) param for a target or fs
5592 * @lcfg buf0 may contain the device (testfs-MDT0000) name
5593 * buf1 contains the single parameter
5595 int mgs_set_param(const struct lu_env *env, struct mgs_device *mgs,
5596 struct lustre_cfg *lcfg)
5598 const char *param = lustre_cfg_string(lcfg, 1);
5599 struct mgs_target_info *mti;
5602 /* Create a fake mti to hold everything */
5607 print_lustre_cfg(lcfg);
5609 if (lcfg->lcfg_command == LCFG_PARAM) {
5610 /* For the case of lctl conf_param devname can be
5611 * lustre, lustre-mdtlov, lustre-client, lustre-MDT0000
5613 const char *devname = lustre_cfg_string(lcfg, 0);
5615 rc = mgs_set_conf_param(env, mgs, mti, devname, param);
5617 /* In the case of lctl set_param -P lcfg[0] will always
5618 * be 'general'. At least for now.
5620 rc = mgs_set_param2(env, mgs, mti, param);
5628 static int mgs_write_log_pool(const struct lu_env *env,
5629 struct mgs_device *mgs, char *logname,
5630 struct fs_db *fsdb, char *tgtname,
5631 enum lcfg_command_type cmd,
5632 char *fsname, char *poolname,
5633 char *ostname, char *comment)
5635 struct llog_handle *llh = NULL;
5638 rc = record_start_log(env, mgs, &llh, logname);
5641 rc = record_marker(env, llh, fsdb, CM_START, tgtname, comment);
5644 rc = record_base(env, llh, tgtname, 0, cmd,
5645 fsname, poolname, ostname, NULL);
5648 rc = record_marker(env, llh, fsdb, CM_END, tgtname, comment);
5650 record_end_log(env, &llh);
5654 int mgs_nodemap_cmd(const struct lu_env *env, struct mgs_device *mgs,
5655 enum lcfg_command_type cmd, const char *nodemap_name,
5658 struct lnet_nid nid[2];
5667 case LCFG_NODEMAP_ADD:
5668 rc = nodemap_add(nodemap_name);
5670 case LCFG_NODEMAP_DEL:
5671 rc = nodemap_del(nodemap_name);
5673 case LCFG_NODEMAP_ADD_RANGE:
5674 rc = nodemap_parse_range(param, nid, &netmask);
5677 rc = nodemap_add_range(nodemap_name, nid, netmask);
5679 case LCFG_NODEMAP_DEL_RANGE:
5680 rc = nodemap_parse_range(param, nid, &netmask);
5683 rc = nodemap_del_range(nodemap_name, nid, netmask);
5685 case LCFG_NODEMAP_ADMIN:
5686 rc = kstrtobool(param, &bool_switch);
5689 rc = nodemap_set_allow_root(nodemap_name, bool_switch);
5691 case LCFG_NODEMAP_DENY_UNKNOWN:
5692 rc = kstrtobool(param, &bool_switch);
5695 rc = nodemap_set_deny_unknown(nodemap_name, bool_switch);
5697 case LCFG_NODEMAP_AUDIT_MODE:
5698 rc = kstrtobool(param, &bool_switch);
5700 rc = nodemap_set_audit_mode(nodemap_name, bool_switch);
5702 case LCFG_NODEMAP_FORBID_ENCRYPT:
5703 rc = kstrtobool(param, &bool_switch);
5705 rc = nodemap_set_forbid_encryption(nodemap_name,
5708 case LCFG_NODEMAP_READONLY_MOUNT:
5709 rc = kstrtobool(param, &bool_switch);
5711 rc = nodemap_set_readonly_mount(nodemap_name,
5714 case LCFG_NODEMAP_MAP_MODE:
5719 if ((p = strstr(param, "all")) != NULL) {
5720 if ((p == param || *(p-1) == ',') &&
5721 (*(p+3) == '\0' || *(p+3) == ',')) {
5722 map_mode = NODEMAP_MAP_ALL;
5728 while ((p = strsep(¶m, ",")) != NULL) {
5732 if (strcmp("both", p) == 0)
5733 map_mode |= NODEMAP_MAP_BOTH;
5734 else if (strcmp("uid_only", p) == 0 ||
5735 strcmp("uid", p) == 0)
5736 map_mode |= NODEMAP_MAP_UID;
5737 else if (strcmp("gid_only", p) == 0 ||
5738 strcmp("gid", p) == 0)
5739 map_mode |= NODEMAP_MAP_GID;
5740 else if (strcmp("projid_only", p) == 0 ||
5741 strcmp("projid", p) == 0)
5742 map_mode |= NODEMAP_MAP_PROJID;
5752 rc = nodemap_set_mapping_mode(nodemap_name, map_mode);
5755 case LCFG_NODEMAP_RBAC:
5757 enum nodemap_rbac_roles rbac;
5760 if (strcmp(param, "all") == 0) {
5761 rbac = NODEMAP_RBAC_ALL;
5762 } else if (strcmp(param, "none") == 0) {
5763 rbac = NODEMAP_RBAC_NONE;
5765 rbac = NODEMAP_RBAC_NONE;
5766 while ((p = strsep(¶m, ",")) != NULL) {
5772 for (i = 0; i < ARRAY_SIZE(nodemap_rbac_names);
5775 nodemap_rbac_names[i].nrn_name)
5778 nodemap_rbac_names[i].nrn_mode;
5782 if (i == ARRAY_SIZE(nodemap_rbac_names))
5791 rc = nodemap_set_rbac(nodemap_name, rbac);
5794 case LCFG_NODEMAP_TRUSTED:
5795 rc = kstrtobool(param, &bool_switch);
5798 rc = nodemap_set_trust_client_ids(nodemap_name, bool_switch);
5800 case LCFG_NODEMAP_SQUASH_UID:
5801 rc = kstrtouint(param, 10, &int_id);
5804 rc = nodemap_set_squash_uid(nodemap_name, int_id);
5806 case LCFG_NODEMAP_SQUASH_GID:
5807 rc = kstrtouint(param, 10, &int_id);
5810 rc = nodemap_set_squash_gid(nodemap_name, int_id);
5812 case LCFG_NODEMAP_SQUASH_PROJID:
5813 rc = kstrtouint(param, 10, &int_id);
5816 rc = nodemap_set_squash_projid(nodemap_name, int_id);
5818 case LCFG_NODEMAP_ADD_UIDMAP:
5819 case LCFG_NODEMAP_ADD_GIDMAP:
5820 case LCFG_NODEMAP_ADD_PROJIDMAP:
5821 rc = nodemap_parse_idmap(param, idmap);
5824 if (cmd == LCFG_NODEMAP_ADD_UIDMAP)
5825 rc = nodemap_add_idmap(nodemap_name, NODEMAP_UID,
5827 else if (cmd == LCFG_NODEMAP_ADD_GIDMAP)
5828 rc = nodemap_add_idmap(nodemap_name, NODEMAP_GID,
5830 else if (cmd == LCFG_NODEMAP_ADD_PROJIDMAP)
5831 rc = nodemap_add_idmap(nodemap_name, NODEMAP_PROJID,
5836 case LCFG_NODEMAP_DEL_UIDMAP:
5837 case LCFG_NODEMAP_DEL_GIDMAP:
5838 case LCFG_NODEMAP_DEL_PROJIDMAP:
5839 rc = nodemap_parse_idmap(param, idmap);
5842 if (cmd == LCFG_NODEMAP_DEL_UIDMAP)
5843 rc = nodemap_del_idmap(nodemap_name, NODEMAP_UID,
5845 else if (cmd == LCFG_NODEMAP_DEL_GIDMAP)
5846 rc = nodemap_del_idmap(nodemap_name, NODEMAP_GID,
5848 else if (cmd == LCFG_NODEMAP_DEL_PROJIDMAP)
5849 rc = nodemap_del_idmap(nodemap_name, NODEMAP_PROJID,
5854 case LCFG_NODEMAP_SET_FILESET:
5855 rc = nodemap_set_fileset(nodemap_name, param);
5857 case LCFG_NODEMAP_SET_SEPOL:
5858 rc = nodemap_set_sepol(nodemap_name, param);
5868 int mgs_pool_check_ostname(struct fs_db *fsdb, char *fsname, char *ostname)
5873 /* check if ostname match fsname */
5874 ptr = strrchr(ostname, '-');
5875 if (!ptr || (strncmp(fsname, ostname, ptr - ostname) != 0))
5879 if (sscanf(ptr, "OST%04x_UUID", &index) != 1)
5881 if (index > INDEX_MAP_MAX_VALUE)
5883 if (!test_bit(index, fsdb->fsdb_ost_index_map))
5890 int mgs_pool_sanity(const struct lu_env *env, struct mgs_device *mgs,
5891 struct fs_db *fsdb, struct mgs_target_info *mti,
5892 char *logname, char *devname, enum lcfg_command_type cmd,
5893 char *fsname, char *poolname, char *ostname)
5895 char *lov = fsdb->fsdb_clilov;
5899 status = mgs_search_pool(env, mgs, fsdb, mti, logname, lov,
5900 fsname, poolname, ostname);
5906 if (status >= POOL_STATUS_EXIST)
5910 if (status == POOL_STATUS_NONE)
5912 else if (status == POOL_STATUS_OST_EXIST)
5916 if (status == POOL_STATUS_NONE)
5918 if (status != POOL_STATUS_OST_EXIST)
5922 if (status == POOL_STATUS_NONE)
5924 if (status == POOL_STATUS_OST_EXIST)
5936 int mgs_pool_cmd(const struct lu_env *env, struct mgs_device *mgs,
5937 enum lcfg_command_type cmd, char *fsname,
5938 char *poolname, char *ostname)
5944 char *canceled_label = NULL;
5946 struct mgs_target_info *mti = NULL;
5950 if ((cmd == LCFG_POOL_REM || cmd == LCFG_POOL_ADD) && !ostname)
5952 if ((cmd == LCFG_POOL_DEL || cmd == LCFG_POOL_NEW) && ostname)
5955 rc = mgs_find_or_make_fsdb(env, mgs, fsname, &fsdb);
5957 CERROR("Can't get db for %s\n", fsname);
5960 if (test_bit(FSDB_LOG_EMPTY, &fsdb->fsdb_flags)) {
5961 CERROR("%s is not defined\n", fsname);
5962 mgs_unlink_fsdb(mgs, fsdb);
5963 GOTO(out_fsdb, rc = -EINVAL);
5966 label_sz = 10 + strlen(fsname) + strlen(poolname);
5968 rc = mgs_pool_check_ostname(fsdb, fsname, ostname);
5971 label_sz += strlen(ostname);
5974 OBD_ALLOC(label, label_sz);
5976 GOTO(out_fsdb, rc = -ENOMEM);
5980 sprintf(label, "new %s.%s", fsname, poolname);
5983 sprintf(label, "add %s.%s.%s", fsname, poolname, ostname);
5986 OBD_ALLOC(canceled_label, label_sz);
5987 if (canceled_label == NULL)
5988 GOTO(out_label, rc = -ENOMEM);
5989 sprintf(label, "rem %s.%s.%s", fsname, poolname, ostname);
5990 sprintf(canceled_label, "add %s.%s.%s",
5991 fsname, poolname, ostname);
5994 OBD_ALLOC(canceled_label, label_sz);
5995 if (canceled_label == NULL)
5996 GOTO(out_label, rc = -ENOMEM);
5998 sprintf(label, "del %s.%s", fsname, poolname);
5999 sprintf(canceled_label, "new %s.%s", fsname, poolname);
6007 GOTO(out_cancel, rc = -ENOMEM);
6008 strscpy(mti->mti_svname, "lov pool", sizeof(mti->mti_svname));
6010 mutex_lock(&fsdb->fsdb_mutex);
6012 rc = name_create(&logname, fsname, "-client");
6014 GOTO(out_unlock, rc);
6016 rc = mgs_pool_sanity(env, mgs, fsdb, mti, logname, fsdb->fsdb_clilov,
6017 cmd, fsname, poolname, ostname);
6019 GOTO(out_logname, rc);
6022 rc = mgs_modify(env, mgs, fsdb, mti, logname,
6023 fsdb->fsdb_clilov, canceled_label, CM_SKIP);
6026 GOTO(out_logname, rc);
6028 rc = mgs_write_log_pool(env, mgs, logname, fsdb, fsdb->fsdb_clilov,
6029 cmd, fsname, poolname, ostname, label);
6031 GOTO(out_logname, rc);
6033 name_destroy(&logname);
6035 /* write pool def to all MDT logs */
6036 for_each_set_bit(i, fsdb->fsdb_mdt_index_map, INDEX_MAP_SIZE) {
6037 rc = name_create_mdt_and_lov(&logname, &lovname, fsdb, i);
6039 GOTO(out_unlock, rc);
6042 rc = mgs_modify(env, mgs, fsdb, mti, logname, lovname,
6043 canceled_label, CM_SKIP);
6046 GOTO(out_names, rc);
6048 rc = mgs_write_log_pool(env, mgs, logname, fsdb, lovname, cmd,
6049 fsname, poolname, ostname, label);
6051 GOTO(out_names, rc);
6053 name_destroy(&logname);
6054 name_destroy(&lovname);
6056 mutex_unlock(&fsdb->fsdb_mutex);
6058 /* request for update */
6059 mgs_revoke_lock(mgs, fsdb, MGS_CFG_T_CONFIG);
6064 name_destroy(&lovname);
6066 name_destroy(&logname);
6068 mutex_unlock(&fsdb->fsdb_mutex);
6073 OBD_FREE(canceled_label, label_sz);
6075 OBD_FREE(label, label_sz);
6077 mgs_put_fsdb(mgs, fsdb);