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/
30 * Lustre is a trademark of Sun Microsystems, Inc.
32 * lustre/mgs/mgs_llog.c
34 * Lustre Management Server (mgs) config llog creation
36 * Author: Nathan Rutman <nathan@clusterfs.com>
37 * Author: Alex Zhuravlev <bzzz@whamcloud.com>
38 * Author: Mikhail Pershin <tappro@whamcloud.com>
41 #define DEBUG_SUBSYSTEM S_MGS
42 #define D_MGS D_CONFIG
45 #include <uapi/linux/lustre/lustre_ioctl.h>
46 #include <uapi/linux/lustre/lustre_param.h>
47 #include <lustre_sec.h>
48 #include <lustre_quota.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 ".bak" files */
109 /* sizeof(".bak") - 1 == 3 */
111 !memcmp(".bak", key + key_sz - 3, 3)) {
112 CDEBUG(D_MGS, "Skipping backup file %.*s\n",
117 de = mgs_direntry_alloc(key_sz + 1);
123 memcpy(de->mde_name, key, key_sz);
124 de->mde_name[key_sz] = 0;
126 list_add(&de->mde_list, log_list);
129 rc = iops->next(env, it);
139 struct mgs_direntry *n;
141 CERROR("%s: key failed when listing %s: rc = %d\n",
142 mgs->mgs_obd->obd_name, MOUNT_CONFIGS_DIR, rc);
144 list_for_each_entry_safe(de, n, log_list, mde_list) {
145 list_del_init(&de->mde_list);
146 mgs_direntry_free(de);
153 /******************** DB functions *********************/
155 static inline int name_create(char **newname, char *prefix, char *suffix)
158 OBD_ALLOC(*newname, strlen(prefix) + strlen(suffix) + 1);
161 sprintf(*newname, "%s%s", prefix, suffix);
165 static inline void name_destroy(char **name)
168 OBD_FREE(*name, strlen(*name) + 1);
172 struct mgs_fsdb_handler_data
178 /* from the (client) config log, figure out:
179 1. which ost's/mdt's are configured (by index)
180 2. what the last config step is
181 3. COMPAT_18 osc name
183 /* It might be better to have a separate db file, instead of parsing the info
184 out of the client log. This is slow and potentially error-prone. */
185 static int mgs_fsdb_handler(const struct lu_env *env, struct llog_handle *llh,
186 struct llog_rec_hdr *rec, void *data)
188 struct mgs_fsdb_handler_data *d = data;
189 struct fs_db *fsdb = d->fsdb;
190 int cfg_len = rec->lrh_len;
191 char *cfg_buf = (char*) (rec + 1);
192 struct lustre_cfg *lcfg;
197 if (rec->lrh_type != OBD_CFG_REC) {
198 CERROR("unhandled lrh_type: %#x\n", rec->lrh_type);
202 rc = lustre_cfg_sanity_check(cfg_buf, cfg_len);
204 CERROR("Insane cfg\n");
208 lcfg = (struct lustre_cfg *)cfg_buf;
210 CDEBUG(D_INFO, "cmd %x %s %s\n", lcfg->lcfg_command,
211 lustre_cfg_string(lcfg, 0), lustre_cfg_string(lcfg, 1));
213 /* Figure out ost indicies */
214 /* lov_modify_tgts add 0:lov1 1:ost1_UUID 2(index):0 3(gen):1 */
215 if (lcfg->lcfg_command == LCFG_LOV_ADD_OBD ||
216 lcfg->lcfg_command == LCFG_LOV_DEL_OBD) {
217 index = simple_strtoul(lustre_cfg_string(lcfg, 2),
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;
268 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 int mgs_find_or_make_fsdb(const struct lu_env *env, struct mgs_device *mgs,
545 char *name, struct fs_db **dbh)
551 mutex_lock(&mgs->mgs_mutex);
552 fsdb = mgs_find_fsdb(mgs, name);
554 fsdb = mgs_new_fsdb(env, mgs, name);
558 CDEBUG(D_MGS, "Created new db: rc = %d\n", rc);
560 mutex_unlock(&mgs->mgs_mutex);
570 -1= empty client log */
571 int mgs_check_index(const struct lu_env *env,
572 struct mgs_device *mgs,
573 struct mgs_target_info *mti)
580 LASSERT(!(mti->mti_flags & LDD_F_NEED_INDEX));
582 rc = mgs_find_or_make_fsdb(env, mgs, mti->mti_fsname, &fsdb);
584 CERROR("Can't get db for %s\n", mti->mti_fsname);
588 if (test_bit(FSDB_LOG_EMPTY, &fsdb->fsdb_flags))
591 if (mti->mti_flags & LDD_F_SV_TYPE_OST)
592 imap = fsdb->fsdb_ost_index_map;
593 else if (mti->mti_flags & LDD_F_SV_TYPE_MDT)
594 imap = fsdb->fsdb_mdt_index_map;
596 GOTO(out, rc = -EINVAL);
598 if (test_bit(mti->mti_stripe_index, imap))
604 mgs_put_fsdb(mgs, fsdb);
608 static __inline__ int next_index(void *index_map, int map_len)
611 for (i = 0; i < map_len * 8; i++)
612 if (!test_bit(i, index_map)) {
615 CERROR("max index %d exceeded.\n", i);
619 /* Make the mdt/ost server obd name based on the filesystem name */
620 static bool server_make_name(u32 flags, u16 index, const char *fs,
621 char *name_buf, size_t name_buf_size)
623 bool invalid_flag = false;
625 if (flags & (LDD_F_SV_TYPE_MDT | LDD_F_SV_TYPE_OST)) {
626 if (!(flags & LDD_F_SV_ALL))
627 snprintf(name_buf, name_buf_size, "%.8s%c%s%04x", fs,
628 (flags & LDD_F_VIRGIN) ? ':' :
629 ((flags & LDD_F_WRITECONF) ? '=' : '-'),
630 (flags & LDD_F_SV_TYPE_MDT) ? "MDT" : "OST",
632 } else if (flags & LDD_F_SV_TYPE_MGS) {
633 snprintf(name_buf, name_buf_size, "MGS");
635 CERROR("unknown server type %#x\n", flags);
642 0 newly marked as in use
644 +EALREADY for update of an old index */
645 static int mgs_set_index(const struct lu_env *env,
646 struct mgs_device *mgs,
647 struct mgs_target_info *mti)
654 rc = mgs_find_or_make_fsdb(env, mgs, mti->mti_fsname, &fsdb);
656 CERROR("Can't get db for %s\n", mti->mti_fsname);
660 mutex_lock(&fsdb->fsdb_mutex);
661 if (mti->mti_flags & LDD_F_SV_TYPE_OST) {
662 imap = fsdb->fsdb_ost_index_map;
663 } else if (mti->mti_flags & LDD_F_SV_TYPE_MDT) {
664 imap = fsdb->fsdb_mdt_index_map;
666 GOTO(out_up, rc = -EINVAL);
669 if (mti->mti_flags & LDD_F_NEED_INDEX) {
670 rc = next_index(imap, INDEX_MAP_SIZE);
672 GOTO(out_up, rc = -ERANGE);
673 mti->mti_stripe_index = rc;
676 /* the last index(0xffff) is reserved for default value. */
677 if (mti->mti_stripe_index >= INDEX_MAP_SIZE * 8 - 1) {
678 LCONSOLE_ERROR_MSG(0x13f, "Server %s requested index %u, "
679 "but index must be less than %u.\n",
680 mti->mti_svname, mti->mti_stripe_index,
681 INDEX_MAP_SIZE * 8 - 1);
682 GOTO(out_up, rc = -ERANGE);
685 if (test_bit(mti->mti_stripe_index, imap)) {
686 if ((mti->mti_flags & LDD_F_VIRGIN) &&
687 !(mti->mti_flags & LDD_F_WRITECONF)) {
688 LCONSOLE_ERROR_MSG(0x140, "Server %s requested index "
689 "%d, but that index is already in "
690 "use. Use --writeconf to force\n",
692 mti->mti_stripe_index);
693 GOTO(out_up, rc = -EADDRINUSE);
695 CDEBUG(D_MGS, "Server %s updating index %d\n",
696 mti->mti_svname, mti->mti_stripe_index);
697 GOTO(out_up, rc = EALREADY);
700 set_bit(mti->mti_stripe_index, imap);
701 if (mti->mti_flags & LDD_F_SV_TYPE_MDT)
702 fsdb->fsdb_mdt_count++;
705 set_bit(mti->mti_stripe_index, imap);
706 clear_bit(FSDB_LOG_EMPTY, &fsdb->fsdb_flags);
707 if (server_make_name(mti->mti_flags & ~(LDD_F_VIRGIN | LDD_F_WRITECONF),
708 mti->mti_stripe_index, mti->mti_fsname,
709 mti->mti_svname, sizeof(mti->mti_svname))) {
710 CERROR("unknown server type %#x\n", mti->mti_flags);
711 GOTO(out_up, rc = -EINVAL);
714 CDEBUG(D_MGS, "Set index for %s to %d\n", mti->mti_svname,
715 mti->mti_stripe_index);
717 GOTO(out_up, rc = 0);
720 mutex_unlock(&fsdb->fsdb_mutex);
721 mgs_put_fsdb(mgs, fsdb);
725 struct mgs_modify_lookup {
726 struct cfg_marker mml_marker;
730 static int mgs_check_record_match(const struct lu_env *env,
731 struct llog_handle *llh,
732 struct llog_rec_hdr *rec, void *data)
734 struct cfg_marker *mc_marker = data;
735 struct cfg_marker *marker;
736 struct lustre_cfg *lcfg = REC_DATA(rec);
737 int cfg_len = REC_DATA_LEN(rec);
742 if (rec->lrh_type != OBD_CFG_REC) {
743 CDEBUG(D_ERROR, "Unhandled lrh_type: %#x\n", rec->lrh_type);
747 rc = lustre_cfg_sanity_check(lcfg, cfg_len);
749 CDEBUG(D_ERROR, "Insane cfg\n");
753 /* We only care about markers */
754 if (lcfg->lcfg_command != LCFG_MARKER)
757 marker = lustre_cfg_buf(lcfg, 1);
759 if (marker->cm_flags & CM_SKIP)
762 if ((strcmp(mc_marker->cm_comment, marker->cm_comment) == 0) &&
763 (strcmp(mc_marker->cm_tgtname, marker->cm_tgtname) == 0)) {
764 /* Found a non-skipped marker match */
765 CDEBUG(D_MGS, "Matched rec %u marker %d flag %x %s %s\n",
766 rec->lrh_index, marker->cm_step,
767 marker->cm_flags, marker->cm_tgtname,
769 rc = LLOG_PROC_BREAK;
776 * Check an existing config log record with matching comment and device
778 * 0 - checked successfully,
779 * LLOG_PROC_BREAK - record matches
782 static int mgs_check_marker(const struct lu_env *env, struct mgs_device *mgs,
783 struct fs_db *fsdb, struct mgs_target_info *mti,
784 char *logname, char *devname, char *comment)
786 struct llog_handle *loghandle;
787 struct llog_ctxt *ctxt;
788 struct cfg_marker *mc_marker;
793 LASSERT(mutex_is_locked(&fsdb->fsdb_mutex));
794 CDEBUG(D_MGS, "mgs check %s/%s/%s\n", logname, devname, comment);
796 ctxt = llog_get_context(mgs->mgs_obd, LLOG_CONFIG_ORIG_CTXT);
797 LASSERT(ctxt != NULL);
798 rc = llog_open(env, ctxt, &loghandle, NULL, logname, LLOG_OPEN_EXISTS);
805 rc = llog_init_handle(env, loghandle, LLOG_F_IS_PLAIN, NULL);
809 if (llog_get_size(loghandle) <= 1)
810 GOTO(out_close, rc = 0);
812 OBD_ALLOC_PTR(mc_marker);
814 GOTO(out_close, rc = -ENOMEM);
815 if (strlcpy(mc_marker->cm_comment, comment,
816 sizeof(mc_marker->cm_comment)) >=
817 sizeof(mc_marker->cm_comment))
818 GOTO(out_free, rc = -E2BIG);
819 if (strlcpy(mc_marker->cm_tgtname, devname,
820 sizeof(mc_marker->cm_tgtname)) >=
821 sizeof(mc_marker->cm_tgtname))
822 GOTO(out_free, rc = -E2BIG);
824 rc = llog_process(env, loghandle, mgs_check_record_match,
825 (void *)mc_marker, NULL);
828 OBD_FREE_PTR(mc_marker);
831 llog_close(env, loghandle);
833 if (rc && rc != LLOG_PROC_BREAK)
834 CDEBUG(D_ERROR, "%s: mgs check %s/%s failed: rc = %d\n",
835 mgs->mgs_obd->obd_name, mti->mti_svname, comment, rc);
840 static int mgs_modify_handler(const struct lu_env *env,
841 struct llog_handle *llh,
842 struct llog_rec_hdr *rec, void *data)
844 struct mgs_modify_lookup *mml = data;
845 struct cfg_marker *marker;
846 struct lustre_cfg *lcfg = REC_DATA(rec);
847 int cfg_len = REC_DATA_LEN(rec);
851 if (rec->lrh_type != OBD_CFG_REC) {
852 CERROR("unhandled lrh_type: %#x\n", rec->lrh_type);
856 rc = lustre_cfg_sanity_check(lcfg, cfg_len);
858 CERROR("Insane cfg\n");
862 /* We only care about markers */
863 if (lcfg->lcfg_command != LCFG_MARKER)
866 marker = lustre_cfg_buf(lcfg, 1);
867 if ((strcmp(mml->mml_marker.cm_comment, marker->cm_comment) == 0) &&
868 (strcmp(mml->mml_marker.cm_tgtname, marker->cm_tgtname) == 0) &&
869 !(marker->cm_flags & CM_SKIP)) {
870 /* Found a non-skipped marker match */
871 CDEBUG(D_MGS, "Changing rec %u marker %d %x->%x: %s %s\n",
872 rec->lrh_index, marker->cm_step,
873 marker->cm_flags, mml->mml_marker.cm_flags,
874 marker->cm_tgtname, marker->cm_comment);
875 /* Overwrite the old marker llog entry */
876 marker->cm_flags &= ~CM_EXCLUDE; /* in case we're unexcluding */
877 marker->cm_flags |= mml->mml_marker.cm_flags;
878 marker->cm_canceltime = mml->mml_marker.cm_canceltime;
879 rc = llog_write(env, llh, rec, rec->lrh_index);
888 * Modify an existing config log record (for CM_SKIP or CM_EXCLUDE)
890 * 0 - modified successfully,
891 * 1 - no modification was done
894 static int mgs_modify(const struct lu_env *env, struct mgs_device *mgs,
895 struct fs_db *fsdb, struct mgs_target_info *mti,
896 char *logname, char *devname, char *comment, int flags)
898 struct llog_handle *loghandle;
899 struct llog_ctxt *ctxt;
900 struct mgs_modify_lookup *mml;
905 LASSERT(mutex_is_locked(&fsdb->fsdb_mutex));
906 CDEBUG(D_MGS, "modify %s/%s/%s fl=%x\n", logname, devname, comment,
909 ctxt = llog_get_context(mgs->mgs_obd, LLOG_CONFIG_ORIG_CTXT);
910 LASSERT(ctxt != NULL);
911 rc = llog_open(env, ctxt, &loghandle, NULL, logname, LLOG_OPEN_EXISTS);
918 rc = llog_init_handle(env, loghandle, LLOG_F_IS_PLAIN, NULL);
922 if (llog_get_size(loghandle) <= 1)
923 GOTO(out_close, rc = 0);
927 GOTO(out_close, rc = -ENOMEM);
928 if (strlcpy(mml->mml_marker.cm_comment, comment,
929 sizeof(mml->mml_marker.cm_comment)) >=
930 sizeof(mml->mml_marker.cm_comment))
931 GOTO(out_free, rc = -E2BIG);
932 if (strlcpy(mml->mml_marker.cm_tgtname, devname,
933 sizeof(mml->mml_marker.cm_tgtname)) >=
934 sizeof(mml->mml_marker.cm_tgtname))
935 GOTO(out_free, rc = -E2BIG);
936 /* Modify mostly means cancel */
937 mml->mml_marker.cm_flags = flags;
938 mml->mml_marker.cm_canceltime = flags ? ktime_get_real_seconds() : 0;
939 mml->mml_modified = 0;
940 rc = llog_process(env, loghandle, mgs_modify_handler, (void *)mml,
942 if (!rc && !mml->mml_modified)
949 llog_close(env, loghandle);
952 CERROR("%s: modify %s/%s failed: rc = %d\n",
953 mgs->mgs_obd->obd_name, mti->mti_svname, comment, rc);
958 /** This structure is passed to mgs_replace_handler */
959 struct mgs_replace_uuid_lookup {
960 /* Nids are replaced for this target device */
961 struct mgs_target_info target;
962 /* Temporary modified llog */
963 struct llog_handle *temp_llh;
964 /* Flag is set if in target block*/
965 int in_target_device;
966 /* Nids already added. Just skip (multiple nids) */
967 int device_nids_added;
968 /* Flag is set if this block should not be copied */
973 * Check: a) if block should be skipped
974 * b) is it target block
979 * \retval 0 should not to be skipped
980 * \retval 1 should to be skipped
982 static int check_markers(struct lustre_cfg *lcfg,
983 struct mgs_replace_uuid_lookup *mrul)
985 struct cfg_marker *marker;
987 /* Track markers. Find given device */
988 if (lcfg->lcfg_command == LCFG_MARKER) {
989 marker = lustre_cfg_buf(lcfg, 1);
990 /* Clean llog from records marked as CM_EXCLUDE.
991 CM_SKIP records are used for "active" command
992 and can be restored if needed */
993 if ((marker->cm_flags & (CM_EXCLUDE | CM_START)) ==
994 (CM_EXCLUDE | CM_START)) {
999 if ((marker->cm_flags & (CM_EXCLUDE | CM_END)) ==
1000 (CM_EXCLUDE | CM_END)) {
1005 if (strcmp(mrul->target.mti_svname, marker->cm_tgtname) == 0) {
1006 LASSERT(!(marker->cm_flags & CM_START) ||
1007 !(marker->cm_flags & CM_END));
1008 if (marker->cm_flags & CM_START) {
1009 mrul->in_target_device = 1;
1010 mrul->device_nids_added = 0;
1011 } else if (marker->cm_flags & CM_END)
1012 mrul->in_target_device = 0;
1019 static int record_base(const struct lu_env *env, struct llog_handle *llh,
1020 char *cfgname, lnet_nid_t nid, int cmd,
1021 char *s1, char *s2, char *s3, char *s4)
1023 struct mgs_thread_info *mgi = mgs_env_info(env);
1024 struct llog_cfg_rec *lcr;
1027 CDEBUG(D_MGS, "lcfg %s %#x %s %s %s %s\n", cfgname,
1028 cmd, s1, s2, s3, s4);
1030 lustre_cfg_bufs_reset(&mgi->mgi_bufs, cfgname);
1032 lustre_cfg_bufs_set_string(&mgi->mgi_bufs, 1, s1);
1034 lustre_cfg_bufs_set_string(&mgi->mgi_bufs, 2, s2);
1036 lustre_cfg_bufs_set_string(&mgi->mgi_bufs, 3, s3);
1038 lustre_cfg_bufs_set_string(&mgi->mgi_bufs, 4, s4);
1040 lcr = lustre_cfg_rec_new(cmd, &mgi->mgi_bufs);
1044 lcr->lcr_cfg.lcfg_nid = nid;
1045 rc = llog_write(env, llh, &lcr->lcr_hdr, LLOG_NEXT_IDX);
1047 lustre_cfg_rec_free(lcr);
1051 "failed to write lcfg %s %#x %s %s %s %s: rc = %d\n",
1052 cfgname, cmd, s1, s2, s3, s4, rc);
1056 static inline int record_add_uuid(const struct lu_env *env,
1057 struct llog_handle *llh,
1058 uint64_t nid, char *uuid)
1060 return record_base(env, llh, NULL, nid, LCFG_ADD_UUID, uuid,
1064 static inline int record_add_conn(const struct lu_env *env,
1065 struct llog_handle *llh,
1066 char *devname, char *uuid)
1068 return record_base(env, llh, devname, 0, LCFG_ADD_CONN, uuid,
1072 static inline int record_attach(const struct lu_env *env,
1073 struct llog_handle *llh, char *devname,
1074 char *type, char *uuid)
1076 return record_base(env, llh, devname, 0, LCFG_ATTACH, type, uuid,
1080 static inline int record_setup(const struct lu_env *env,
1081 struct llog_handle *llh, char *devname,
1082 char *s1, char *s2, char *s3, char *s4)
1084 return record_base(env, llh, devname, 0, LCFG_SETUP, s1, s2, s3, s4);
1088 * \retval <0 record processing error
1089 * \retval n record is processed. No need copy original one.
1090 * \retval 0 record is not processed.
1092 static int process_command(const struct lu_env *env, struct lustre_cfg *lcfg,
1093 struct mgs_replace_uuid_lookup *mrul)
1100 if (lcfg->lcfg_command == LCFG_ADD_UUID) {
1101 /* LCFG_ADD_UUID command found. Let's skip original command
1102 and add passed nids */
1103 ptr = mrul->target.mti_params;
1104 while (class_parse_nid(ptr, &nid, &ptr) == 0) {
1105 CDEBUG(D_MGS, "add nid %s with uuid %s, "
1106 "device %s\n", libcfs_nid2str(nid),
1107 mrul->target.mti_params,
1108 mrul->target.mti_svname);
1109 rc = record_add_uuid(env,
1110 mrul->temp_llh, nid,
1111 mrul->target.mti_params);
1116 if (nids_added == 0) {
1117 CERROR("No new nids were added, nid %s with uuid %s, "
1118 "device %s\n", libcfs_nid2str(nid),
1119 mrul->target.mti_params,
1120 mrul->target.mti_svname);
1123 mrul->device_nids_added = 1;
1129 if (mrul->device_nids_added && lcfg->lcfg_command == LCFG_SETUP) {
1130 /* LCFG_SETUP command found. UUID should be changed */
1131 rc = record_setup(env,
1133 /* devname the same */
1134 lustre_cfg_string(lcfg, 0),
1135 /* s1 is not changed */
1136 lustre_cfg_string(lcfg, 1),
1137 /* new uuid should be
1139 mrul->target.mti_params,
1140 /* s3 is not changed */
1141 lustre_cfg_string(lcfg, 3),
1142 /* s4 is not changed */
1143 lustre_cfg_string(lcfg, 4));
1147 /* Another commands in target device block */
1152 * Handler that called for every record in llog.
1153 * Records are processed in order they placed in llog.
1155 * \param[in] llh log to be processed
1156 * \param[in] rec current record
1157 * \param[in] data mgs_replace_uuid_lookup structure
1161 static int mgs_replace_handler(const struct lu_env *env,
1162 struct llog_handle *llh,
1163 struct llog_rec_hdr *rec,
1166 struct mgs_replace_uuid_lookup *mrul;
1167 struct lustre_cfg *lcfg = REC_DATA(rec);
1168 int cfg_len = REC_DATA_LEN(rec);
1172 mrul = (struct mgs_replace_uuid_lookup *)data;
1174 if (rec->lrh_type != OBD_CFG_REC) {
1175 CERROR("unhandled lrh_type: %#x, cmd %x %s %s\n",
1176 rec->lrh_type, lcfg->lcfg_command,
1177 lustre_cfg_string(lcfg, 0),
1178 lustre_cfg_string(lcfg, 1));
1182 rc = lustre_cfg_sanity_check(lcfg, cfg_len);
1184 /* Do not copy any invalidated records */
1185 GOTO(skip_out, rc = 0);
1188 rc = check_markers(lcfg, mrul);
1189 if (rc || mrul->skip_it)
1190 GOTO(skip_out, rc = 0);
1192 /* Write to new log all commands outside target device block */
1193 if (!mrul->in_target_device)
1194 GOTO(copy_out, rc = 0);
1196 /* Skip all other LCFG_ADD_UUID and LCFG_ADD_CONN records
1197 (failover nids) for this target, assuming that if then
1198 primary is changing then so is the failover */
1199 if (mrul->device_nids_added &&
1200 (lcfg->lcfg_command == LCFG_ADD_UUID ||
1201 lcfg->lcfg_command == LCFG_ADD_CONN))
1202 GOTO(skip_out, rc = 0);
1204 rc = process_command(env, lcfg, mrul);
1211 /* Record is placed in temporary llog as is */
1212 rc = llog_write(env, mrul->temp_llh, rec, LLOG_NEXT_IDX);
1214 CDEBUG(D_MGS, "Copied idx=%d, rc=%d, len=%d, cmd %x %s %s\n",
1215 rec->lrh_index, rc, rec->lrh_len, lcfg->lcfg_command,
1216 lustre_cfg_string(lcfg, 0), lustre_cfg_string(lcfg, 1));
1220 CDEBUG(D_MGS, "Skipped idx=%d, rc=%d, len=%d, cmd %x %s %s\n",
1221 rec->lrh_index, rc, rec->lrh_len, lcfg->lcfg_command,
1222 lustre_cfg_string(lcfg, 0), lustre_cfg_string(lcfg, 1));
1226 static int mgs_log_is_empty(const struct lu_env *env,
1227 struct mgs_device *mgs, char *name)
1229 struct llog_ctxt *ctxt;
1232 ctxt = llog_get_context(mgs->mgs_obd, LLOG_CONFIG_ORIG_CTXT);
1233 LASSERT(ctxt != NULL);
1235 rc = llog_is_empty(env, ctxt, name);
1236 llog_ctxt_put(ctxt);
1240 static int mgs_replace_nids_log(const struct lu_env *env,
1241 struct obd_device *mgs, struct fs_db *fsdb,
1242 char *logname, char *devname, char *nids)
1244 struct llog_handle *orig_llh, *backup_llh;
1245 struct llog_ctxt *ctxt;
1246 struct mgs_replace_uuid_lookup *mrul;
1247 struct mgs_device *mgs_dev = lu2mgs_dev(mgs->obd_lu_dev);
1248 static struct obd_uuid cfg_uuid = { .uuid = "config_uuid" };
1253 CDEBUG(D_MGS, "Replace nids for %s in %s\n", devname, logname);
1255 ctxt = llog_get_context(mgs, LLOG_CONFIG_ORIG_CTXT);
1256 LASSERT(ctxt != NULL);
1258 if (mgs_log_is_empty(env, mgs_dev, logname)) {
1259 /* Log is empty. Nothing to replace */
1260 GOTO(out_put, rc = 0);
1263 OBD_ALLOC(backup, strlen(logname) + strlen(".bak") + 1);
1265 GOTO(out_put, rc = -ENOMEM);
1267 sprintf(backup, "%s.bak", logname);
1269 rc = llog_backup(env, mgs, ctxt, ctxt, logname, backup);
1271 /* Now erase original log file. Connections are not allowed.
1272 Backup is already saved */
1273 rc = llog_erase(env, ctxt, NULL, logname);
1276 } else if (rc != -ENOENT) {
1277 CERROR("%s: can't make backup for %s: rc = %d\n",
1278 mgs->obd_name, logname, rc);
1282 /* open local log */
1283 rc = llog_open_create(env, ctxt, &orig_llh, NULL, logname);
1285 GOTO(out_restore, rc);
1287 rc = llog_init_handle(env, orig_llh, LLOG_F_IS_PLAIN, &cfg_uuid);
1289 GOTO(out_closel, rc);
1291 /* open backup llog */
1292 rc = llog_open(env, ctxt, &backup_llh, NULL, backup,
1295 GOTO(out_closel, rc);
1297 rc = llog_init_handle(env, backup_llh, LLOG_F_IS_PLAIN, NULL);
1299 GOTO(out_close, rc);
1301 if (llog_get_size(backup_llh) <= 1)
1302 GOTO(out_close, rc = 0);
1304 OBD_ALLOC_PTR(mrul);
1306 GOTO(out_close, rc = -ENOMEM);
1307 /* devname is only needed information to replace UUID records */
1308 strlcpy(mrul->target.mti_svname, devname,
1309 sizeof(mrul->target.mti_svname));
1310 /* parse nids later */
1311 strlcpy(mrul->target.mti_params, nids, sizeof(mrul->target.mti_params));
1312 /* Copy records to this temporary llog */
1313 mrul->temp_llh = orig_llh;
1315 rc = llog_process(env, backup_llh, mgs_replace_handler,
1316 (void *)mrul, NULL);
1319 rc2 = llog_close(NULL, backup_llh);
1323 rc2 = llog_close(NULL, orig_llh);
1329 CERROR("%s: llog should be restored: rc = %d\n",
1331 rc2 = llog_backup(env, mgs, ctxt, ctxt, backup,
1334 CERROR("%s: can't restore backup %s: rc = %d\n",
1335 mgs->obd_name, logname, rc2);
1339 OBD_FREE(backup, strlen(backup) + 1);
1342 llog_ctxt_put(ctxt);
1345 CERROR("%s: failed to replace nids in log %s: rc = %d\n",
1346 mgs->obd_name, logname, rc);
1352 * Parse device name and get file system name and/or device index
1354 * @devname device name (ex. lustre-MDT0000)
1355 * @fsname file system name extracted from @devname and returned
1356 * to the caller (optional)
1357 * @index device index extracted from @devname and returned to
1358 * the caller (optional)
1360 * RETURN 0 success if we are only interested in
1361 * extracting fsname from devname.
1364 * LDD_F_SV_TYPE_* Besides extracting the fsname the
1365 * user also wants the index. Report to
1366 * the user the type of obd device the
1367 * returned index belongs too.
1369 * -EINVAL The obd device name is improper so
1370 * fsname could not be extracted.
1372 * -ENXIO Failed to extract the index out of
1373 * the obd device name. Most likely an
1374 * invalid obd device name
1376 static int mgs_parse_devname(char *devname, char *fsname, u32 *index)
1381 /* Extract fsname */
1383 rc = server_name2fsname(devname, fsname, NULL);
1385 CDEBUG(D_MGS, "Device name %s without fsname\n",
1392 rc = server_name2index(devname, index, NULL);
1394 CDEBUG(D_MGS, "Device name %s with wrong index\n",
1400 /* server_name2index can return LDD_F_SV_TYPE_* so always return rc */
1404 /* This is only called during replace_nids */
1405 static int only_mgs_is_running(struct obd_device *mgs_obd)
1407 /* TDB: Is global variable with devices count exists? */
1408 int num_devices = get_devices_count();
1409 int num_exports = 0;
1410 struct obd_export *exp;
1412 spin_lock(&mgs_obd->obd_dev_lock);
1413 list_for_each_entry(exp, &mgs_obd->obd_exports, exp_obd_chain) {
1414 /* skip self export */
1415 if (exp == mgs_obd->obd_self_export)
1417 if (exp_connect_flags(exp) & OBD_CONNECT_MDS_MDS)
1422 CERROR("%s: node %s still connected during replace_nids "
1423 "connect_flags:%llx\n",
1425 libcfs_nid2str(exp->exp_nid_stats->nid),
1426 exp_connect_flags(exp));
1429 spin_unlock(&mgs_obd->obd_dev_lock);
1431 /* osd, MGS and MGC + self_export
1432 (wc -l /proc/fs/lustre/devices <= 2) && (non self exports == 0) */
1433 return (num_devices <= 3) && (num_exports == 0);
1436 static int name_create_mdt(char **logname, char *fsname, int i)
1440 sprintf(mdt_index, "-MDT%04x", i);
1441 return name_create(logname, fsname, mdt_index);
1445 * Replace nids for \a device to \a nids values
1447 * \param obd MGS obd device
1448 * \param devname nids need to be replaced for this device
1449 * (ex. lustre-OST0000)
1450 * \param nids nids list (ex. nid1,nid2,nid3)
1454 int mgs_replace_nids(const struct lu_env *env,
1455 struct mgs_device *mgs,
1456 char *devname, char *nids)
1458 /* Assume fsname is part of device name */
1459 char fsname[MTI_NAME_MAXLEN];
1463 struct fs_db *fsdb = NULL;
1466 struct obd_device *mgs_obd = mgs->mgs_obd;
1469 /* We can only change NIDs if no other nodes are connected */
1470 spin_lock(&mgs_obd->obd_dev_lock);
1471 conn_state = mgs_obd->obd_no_conn;
1472 mgs_obd->obd_no_conn = 1;
1473 spin_unlock(&mgs_obd->obd_dev_lock);
1475 /* We can not change nids if not only MGS is started */
1476 if (!only_mgs_is_running(mgs_obd)) {
1477 CERROR("Only MGS is allowed to be started\n");
1478 GOTO(out, rc = -EINPROGRESS);
1481 /* Get fsname and index */
1482 rc = mgs_parse_devname(devname, fsname, &index);
1486 rc = mgs_find_or_make_fsdb(env, mgs, fsname, &fsdb);
1488 CERROR("%s: can't find fsdb: rc = %d\n", fsname, rc);
1492 /* Process client llogs */
1493 name_create(&logname, fsname, "-client");
1494 rc = mgs_replace_nids_log(env, mgs_obd, fsdb, logname, devname, nids);
1495 name_destroy(&logname);
1497 CERROR("%s: error while replacing NIDs for %s: rc = %d\n",
1498 fsname, devname, rc);
1502 /* Process MDT llogs */
1503 for (i = 0; i < INDEX_MAP_SIZE * 8; i++) {
1504 if (!test_bit(i, fsdb->fsdb_mdt_index_map))
1506 name_create_mdt(&logname, fsname, i);
1507 rc = mgs_replace_nids_log(env, mgs_obd, fsdb, logname, devname, nids);
1508 name_destroy(&logname);
1514 spin_lock(&mgs_obd->obd_dev_lock);
1515 mgs_obd->obd_no_conn = conn_state;
1516 spin_unlock(&mgs_obd->obd_dev_lock);
1519 mgs_put_fsdb(mgs, fsdb);
1524 static int record_lov_setup(const struct lu_env *env, struct llog_handle *llh,
1525 char *devname, struct lov_desc *desc)
1527 struct mgs_thread_info *mgi = mgs_env_info(env);
1528 struct llog_cfg_rec *lcr;
1531 lustre_cfg_bufs_reset(&mgi->mgi_bufs, devname);
1532 lustre_cfg_bufs_set(&mgi->mgi_bufs, 1, desc, sizeof(*desc));
1533 lcr = lustre_cfg_rec_new(LCFG_SETUP, &mgi->mgi_bufs);
1537 rc = llog_write(env, llh, &lcr->lcr_hdr, LLOG_NEXT_IDX);
1538 lustre_cfg_rec_free(lcr);
1542 static int record_lmv_setup(const struct lu_env *env, struct llog_handle *llh,
1543 char *devname, struct lmv_desc *desc)
1545 struct mgs_thread_info *mgi = mgs_env_info(env);
1546 struct llog_cfg_rec *lcr;
1549 lustre_cfg_bufs_reset(&mgi->mgi_bufs, devname);
1550 lustre_cfg_bufs_set(&mgi->mgi_bufs, 1, desc, sizeof(*desc));
1551 lcr = lustre_cfg_rec_new(LCFG_SETUP, &mgi->mgi_bufs);
1555 rc = llog_write(env, llh, &lcr->lcr_hdr, LLOG_NEXT_IDX);
1556 lustre_cfg_rec_free(lcr);
1560 static inline int record_mdc_add(const struct lu_env *env,
1561 struct llog_handle *llh,
1562 char *logname, char *mdcuuid,
1563 char *mdtuuid, char *index,
1566 return record_base(env,llh,logname,0,LCFG_ADD_MDC,
1567 mdtuuid,index,gen,mdcuuid);
1570 static inline int record_lov_add(const struct lu_env *env,
1571 struct llog_handle *llh,
1572 char *lov_name, char *ost_uuid,
1573 char *index, char *gen)
1575 return record_base(env, llh, lov_name, 0, LCFG_LOV_ADD_OBD,
1576 ost_uuid, index, gen, NULL);
1579 static inline int record_mount_opt(const struct lu_env *env,
1580 struct llog_handle *llh,
1581 char *profile, char *lov_name,
1584 return record_base(env, llh, NULL, 0, LCFG_MOUNTOPT,
1585 profile, lov_name, mdc_name, NULL);
1588 static int record_marker(const struct lu_env *env,
1589 struct llog_handle *llh,
1590 struct fs_db *fsdb, __u32 flags,
1591 char *tgtname, char *comment)
1593 struct mgs_thread_info *mgi = mgs_env_info(env);
1594 struct llog_cfg_rec *lcr;
1598 if (flags & CM_START)
1600 mgi->mgi_marker.cm_step = fsdb->fsdb_gen;
1601 mgi->mgi_marker.cm_flags = flags;
1602 mgi->mgi_marker.cm_vers = LUSTRE_VERSION_CODE;
1603 cplen = strlcpy(mgi->mgi_marker.cm_tgtname, tgtname,
1604 sizeof(mgi->mgi_marker.cm_tgtname));
1605 if (cplen >= sizeof(mgi->mgi_marker.cm_tgtname))
1607 cplen = strlcpy(mgi->mgi_marker.cm_comment, comment,
1608 sizeof(mgi->mgi_marker.cm_comment));
1609 if (cplen >= sizeof(mgi->mgi_marker.cm_comment))
1611 mgi->mgi_marker.cm_createtime = ktime_get_real_seconds();
1612 mgi->mgi_marker.cm_canceltime = 0;
1613 lustre_cfg_bufs_reset(&mgi->mgi_bufs, NULL);
1614 lustre_cfg_bufs_set(&mgi->mgi_bufs, 1, &mgi->mgi_marker,
1615 sizeof(mgi->mgi_marker));
1616 lcr = lustre_cfg_rec_new(LCFG_MARKER, &mgi->mgi_bufs);
1620 rc = llog_write(env, llh, &lcr->lcr_hdr, LLOG_NEXT_IDX);
1621 lustre_cfg_rec_free(lcr);
1625 static int record_start_log(const struct lu_env *env, struct mgs_device *mgs,
1626 struct llog_handle **llh, char *name)
1628 static struct obd_uuid cfg_uuid = { .uuid = "config_uuid" };
1629 struct llog_ctxt *ctxt;
1634 GOTO(out, rc = -EBUSY);
1636 ctxt = llog_get_context(mgs->mgs_obd, LLOG_CONFIG_ORIG_CTXT);
1638 GOTO(out, rc = -ENODEV);
1639 LASSERT(ctxt->loc_obd == mgs->mgs_obd);
1641 rc = llog_open_create(env, ctxt, llh, NULL, name);
1644 rc = llog_init_handle(env, *llh, LLOG_F_IS_PLAIN, &cfg_uuid);
1646 llog_close(env, *llh);
1648 llog_ctxt_put(ctxt);
1651 CERROR("%s: can't start log %s: rc = %d\n",
1652 mgs->mgs_obd->obd_name, name, rc);
1658 static int record_end_log(const struct lu_env *env, struct llog_handle **llh)
1662 rc = llog_close(env, *llh);
1668 /******************** config "macros" *********************/
1670 /* write an lcfg directly into a log (with markers) */
1671 static int mgs_write_log_direct(const struct lu_env *env,
1672 struct mgs_device *mgs, struct fs_db *fsdb,
1673 char *logname, struct llog_cfg_rec *lcr,
1674 char *devname, char *comment)
1676 struct llog_handle *llh = NULL;
1681 rc = record_start_log(env, mgs, &llh, logname);
1685 /* FIXME These should be a single journal transaction */
1686 rc = record_marker(env, llh, fsdb, CM_START, devname, comment);
1689 rc = llog_write(env, llh, &lcr->lcr_hdr, LLOG_NEXT_IDX);
1692 rc = record_marker(env, llh, fsdb, CM_END, devname, comment);
1696 record_end_log(env, &llh);
1700 /* write the lcfg in all logs for the given fs */
1701 static int mgs_write_log_direct_all(const struct lu_env *env,
1702 struct mgs_device *mgs,
1704 struct mgs_target_info *mti,
1705 struct llog_cfg_rec *lcr, char *devname,
1706 char *comment, int server_only)
1708 struct list_head log_list;
1709 struct mgs_direntry *dirent, *n;
1710 char *fsname = mti->mti_fsname;
1711 int rc = 0, len = strlen(fsname);
1714 /* Find all the logs in the CONFIGS directory */
1715 rc = class_dentry_readdir(env, mgs, &log_list);
1719 /* Could use fsdb index maps instead of directory listing */
1720 list_for_each_entry_safe(dirent, n, &log_list, mde_list) {
1721 list_del_init(&dirent->mde_list);
1722 /* don't write to sptlrpc rule log */
1723 if (strstr(dirent->mde_name, "-sptlrpc") != NULL)
1726 /* caller wants write server logs only */
1727 if (server_only && strstr(dirent->mde_name, "-client") != NULL)
1730 if (strlen(dirent->mde_name) <= len ||
1731 strncmp(fsname, dirent->mde_name, len) != 0 ||
1732 dirent->mde_name[len] != '-')
1735 CDEBUG(D_MGS, "Changing log %s\n", dirent->mde_name);
1736 /* Erase any old settings of this same parameter */
1737 rc = mgs_modify(env, mgs, fsdb, mti, dirent->mde_name,
1738 devname, comment, CM_SKIP);
1740 CERROR("%s: Can't modify llog %s: rc = %d\n",
1741 mgs->mgs_obd->obd_name, dirent->mde_name, rc);
1744 /* Write the new one */
1745 rc = mgs_write_log_direct(env, mgs, fsdb, dirent->mde_name,
1746 lcr, devname, comment);
1748 CERROR("%s: writing log %s: rc = %d\n",
1749 mgs->mgs_obd->obd_name, dirent->mde_name, rc);
1751 mgs_direntry_free(dirent);
1757 static int mgs_write_log_osp_to_mdt(const struct lu_env *env,
1758 struct mgs_device *mgs,
1760 struct mgs_target_info *mti,
1761 int index, char *logname);
1762 static int mgs_write_log_osc_to_lov(const struct lu_env *env,
1763 struct mgs_device *mgs,
1765 struct mgs_target_info *mti,
1766 char *logname, char *suffix, char *lovname,
1767 enum lustre_sec_part sec_part, int flags);
1768 static int name_create_mdt_and_lov(char **logname, char **lovname,
1769 struct fs_db *fsdb, int i);
1771 static int add_param(char *params, char *key, char *val)
1773 char *start = params + strlen(params);
1774 char *end = params + sizeof(((struct mgs_target_info *)0)->mti_params);
1778 keylen = strlen(key);
1779 if (start + 1 + keylen + strlen(val) >= end) {
1780 CERROR("params are too long: %s %s%s\n",
1781 params, key != NULL ? key : "", val);
1785 sprintf(start, " %s%s", key != NULL ? key : "", val);
1790 * Walk through client config log record and convert the related records
1793 static int mgs_steal_client_llog_handler(const struct lu_env *env,
1794 struct llog_handle *llh,
1795 struct llog_rec_hdr *rec, void *data)
1797 struct mgs_device *mgs;
1798 struct obd_device *obd;
1799 struct mgs_target_info *mti, *tmti;
1801 int cfg_len = rec->lrh_len;
1802 char *cfg_buf = (char*) (rec + 1);
1803 struct lustre_cfg *lcfg;
1805 struct llog_handle *mdt_llh = NULL;
1806 static int got_an_osc_or_mdc = 0;
1807 /* 0: not found any osc/mdc;
1811 static int last_step = -1;
1816 mti = ((struct temp_comp*)data)->comp_mti;
1817 tmti = ((struct temp_comp*)data)->comp_tmti;
1818 fsdb = ((struct temp_comp*)data)->comp_fsdb;
1819 obd = ((struct temp_comp *)data)->comp_obd;
1820 mgs = lu2mgs_dev(obd->obd_lu_dev);
1823 if (rec->lrh_type != OBD_CFG_REC) {
1824 CERROR("unhandled lrh_type: %#x\n", rec->lrh_type);
1828 rc = lustre_cfg_sanity_check(cfg_buf, cfg_len);
1830 CERROR("Insane cfg\n");
1834 lcfg = (struct lustre_cfg *)cfg_buf;
1836 if (lcfg->lcfg_command == LCFG_MARKER) {
1837 struct cfg_marker *marker;
1838 marker = lustre_cfg_buf(lcfg, 1);
1839 if (!strncmp(marker->cm_comment, "add osc", 7) &&
1840 (marker->cm_flags & CM_START) &&
1841 !(marker->cm_flags & CM_SKIP)) {
1842 got_an_osc_or_mdc = 1;
1843 cplen = strlcpy(tmti->mti_svname, marker->cm_tgtname,
1844 sizeof(tmti->mti_svname));
1845 if (cplen >= sizeof(tmti->mti_svname))
1847 rc = record_start_log(env, mgs, &mdt_llh,
1851 rc = record_marker(env, mdt_llh, fsdb, CM_START,
1852 mti->mti_svname, "add osc(copied)");
1853 record_end_log(env, &mdt_llh);
1854 last_step = marker->cm_step;
1857 if (!strncmp(marker->cm_comment, "add osc", 7) &&
1858 (marker->cm_flags & CM_END) &&
1859 !(marker->cm_flags & CM_SKIP)) {
1860 LASSERT(last_step == marker->cm_step);
1862 got_an_osc_or_mdc = 0;
1863 memset(tmti, 0, sizeof(*tmti));
1864 rc = record_start_log(env, mgs, &mdt_llh,
1868 rc = record_marker(env, mdt_llh, fsdb, CM_END,
1869 mti->mti_svname, "add osc(copied)");
1870 record_end_log(env, &mdt_llh);
1873 if (!strncmp(marker->cm_comment, "add mdc", 7) &&
1874 (marker->cm_flags & CM_START) &&
1875 !(marker->cm_flags & CM_SKIP)) {
1876 got_an_osc_or_mdc = 2;
1877 last_step = marker->cm_step;
1878 memcpy(tmti->mti_svname, marker->cm_tgtname,
1879 strlen(marker->cm_tgtname));
1883 if (!strncmp(marker->cm_comment, "add mdc", 7) &&
1884 (marker->cm_flags & CM_END) &&
1885 !(marker->cm_flags & CM_SKIP)) {
1886 LASSERT(last_step == marker->cm_step);
1888 got_an_osc_or_mdc = 0;
1889 memset(tmti, 0, sizeof(*tmti));
1894 if (got_an_osc_or_mdc == 0 || last_step < 0)
1897 if (lcfg->lcfg_command == LCFG_ADD_UUID) {
1898 __u64 nodenid = lcfg->lcfg_nid;
1900 if (strlen(tmti->mti_uuid) == 0) {
1901 /* target uuid not set, this config record is before
1902 * LCFG_SETUP, this nid is one of target node nid.
1904 tmti->mti_nids[tmti->mti_nid_count] = nodenid;
1905 tmti->mti_nid_count++;
1907 char nidstr[LNET_NIDSTR_SIZE];
1909 /* failover node nid */
1910 libcfs_nid2str_r(nodenid, nidstr, sizeof(nidstr));
1911 rc = add_param(tmti->mti_params, PARAM_FAILNODE,
1918 if (lcfg->lcfg_command == LCFG_SETUP) {
1921 target = lustre_cfg_string(lcfg, 1);
1922 memcpy(tmti->mti_uuid, target, strlen(target));
1926 /* ignore client side sptlrpc_conf_log */
1927 if (lcfg->lcfg_command == LCFG_SPTLRPC_CONF)
1930 if (lcfg->lcfg_command == LCFG_ADD_MDC &&
1931 strstr(lustre_cfg_string(lcfg, 0), "-clilmv") != NULL) {
1934 if (sscanf(lustre_cfg_buf(lcfg, 2), "%d", &index) != 1)
1937 memcpy(tmti->mti_fsname, mti->mti_fsname,
1938 strlen(mti->mti_fsname));
1939 tmti->mti_stripe_index = index;
1941 rc = mgs_write_log_osp_to_mdt(env, mgs, fsdb, tmti,
1942 mti->mti_stripe_index,
1944 memset(tmti, 0, sizeof(*tmti));
1948 if (lcfg->lcfg_command == LCFG_LOV_ADD_OBD) {
1951 char *logname, *lovname;
1953 rc = name_create_mdt_and_lov(&logname, &lovname, fsdb,
1954 mti->mti_stripe_index);
1957 sprintf(mdt_index, "-MDT%04x", mti->mti_stripe_index);
1959 if (sscanf(lustre_cfg_buf(lcfg, 2), "%d", &index) != 1) {
1960 name_destroy(&logname);
1961 name_destroy(&lovname);
1965 tmti->mti_stripe_index = index;
1966 rc = mgs_write_log_osc_to_lov(env, mgs, fsdb, tmti, logname,
1969 name_destroy(&logname);
1970 name_destroy(&lovname);
1976 /* fsdb->fsdb_mutex is already held in mgs_write_log_target*/
1977 /* stealed from mgs_get_fsdb_from_llog*/
1978 static int mgs_steal_llog_for_mdt_from_client(const struct lu_env *env,
1979 struct mgs_device *mgs,
1981 struct temp_comp* comp)
1983 struct llog_handle *loghandle;
1984 struct mgs_target_info *tmti;
1985 struct llog_ctxt *ctxt;
1990 ctxt = llog_get_context(mgs->mgs_obd, LLOG_CONFIG_ORIG_CTXT);
1991 LASSERT(ctxt != NULL);
1993 OBD_ALLOC_PTR(tmti);
1995 GOTO(out_ctxt, rc = -ENOMEM);
1997 comp->comp_tmti = tmti;
1998 comp->comp_obd = mgs->mgs_obd;
2000 rc = llog_open(env, ctxt, &loghandle, NULL, client_name,
2008 rc = llog_init_handle(env, loghandle, LLOG_F_IS_PLAIN, NULL);
2010 GOTO(out_close, rc);
2012 rc = llog_process_or_fork(env, loghandle, mgs_steal_client_llog_handler,
2013 (void *)comp, NULL, false);
2014 CDEBUG(D_MGS, "steal llog re = %d\n", rc);
2016 llog_close(env, loghandle);
2020 llog_ctxt_put(ctxt);
2024 /* lmv is the second thing for client logs */
2025 /* copied from mgs_write_log_lov. Please refer to that. */
2026 static int mgs_write_log_lmv(const struct lu_env *env,
2027 struct mgs_device *mgs,
2029 struct mgs_target_info *mti,
2030 char *logname, char *lmvname)
2032 struct llog_handle *llh = NULL;
2033 struct lmv_desc *lmvdesc;
2038 CDEBUG(D_MGS, "Writing lmv(%s) log for %s\n", lmvname,logname);
2040 OBD_ALLOC_PTR(lmvdesc);
2041 if (lmvdesc == NULL)
2043 lmvdesc->ld_active_tgt_count = 0;
2044 lmvdesc->ld_tgt_count = 0;
2045 sprintf((char*)lmvdesc->ld_uuid.uuid, "%s_UUID", lmvname);
2046 uuid = (char *)lmvdesc->ld_uuid.uuid;
2048 rc = record_start_log(env, mgs, &llh, logname);
2051 rc = record_marker(env, llh, fsdb, CM_START, lmvname, "lmv setup");
2054 rc = record_attach(env, llh, lmvname, "lmv", uuid);
2057 rc = record_lmv_setup(env, llh, lmvname, lmvdesc);
2060 rc = record_marker(env, llh, fsdb, CM_END, lmvname, "lmv setup");
2064 record_end_log(env, &llh);
2066 OBD_FREE_PTR(lmvdesc);
2070 /* lov is the first thing in the mdt and client logs */
2071 static int mgs_write_log_lov(const struct lu_env *env, struct mgs_device *mgs,
2072 struct fs_db *fsdb, struct mgs_target_info *mti,
2073 char *logname, char *lovname)
2075 struct llog_handle *llh = NULL;
2076 struct lov_desc *lovdesc;
2081 CDEBUG(D_MGS, "Writing lov(%s) log for %s\n", lovname, logname);
2084 #01 L attach 0:lov_mdsA 1:lov 2:71ccb_lov_mdsA_19f961a9e1
2085 #02 L lov_setup 0:lov_mdsA 1:(struct lov_desc)
2086 uuid=lov1_UUID, stripe count=1, size=1048576, offset=0, pattern=0
2089 /* FIXME just make lov_setup accept empty desc (put uuid in buf 2) */
2090 OBD_ALLOC_PTR(lovdesc);
2091 if (lovdesc == NULL)
2093 lovdesc->ld_magic = LOV_DESC_MAGIC;
2094 lovdesc->ld_tgt_count = 0;
2095 /* Defaults. Can be changed later by lcfg config_param */
2096 lovdesc->ld_default_stripe_count = 1;
2097 lovdesc->ld_pattern = LOV_PATTERN_RAID0;
2098 lovdesc->ld_default_stripe_size = LOV_DESC_STRIPE_SIZE_DEFAULT;
2099 lovdesc->ld_default_stripe_offset = -1;
2100 lovdesc->ld_qos_maxage = LOV_DESC_QOS_MAXAGE_DEFAULT;
2101 sprintf((char*)lovdesc->ld_uuid.uuid, "%s_UUID", lovname);
2102 /* can these be the same? */
2103 uuid = (char *)lovdesc->ld_uuid.uuid;
2105 /* This should always be the first entry in a log.
2106 rc = mgs_clear_log(obd, logname); */
2107 rc = record_start_log(env, mgs, &llh, logname);
2110 /* FIXME these should be a single journal transaction */
2111 rc = record_marker(env, llh, fsdb, CM_START, lovname, "lov setup");
2114 rc = record_attach(env, llh, lovname, "lov", uuid);
2117 rc = record_lov_setup(env, llh, lovname, lovdesc);
2120 rc = record_marker(env, llh, fsdb, CM_END, lovname, "lov setup");
2125 record_end_log(env, &llh);
2127 OBD_FREE_PTR(lovdesc);
2131 /* add failnids to open log */
2132 static int mgs_write_log_failnids(const struct lu_env *env,
2133 struct mgs_target_info *mti,
2134 struct llog_handle *llh,
2137 char *failnodeuuid = NULL;
2138 char *ptr = mti->mti_params;
2143 #03 L add_uuid nid=uml1@tcp(0x20000c0a80201) nal=90 0: 1:uml1_UUID
2144 #04 L add_uuid nid=1@elan(0x1000000000001) nal=90 0: 1:uml1_UUID
2145 #05 L setup 0:OSC_uml1_ost1_mdsA 1:ost1_UUID 2:uml1_UUID
2146 #06 L add_uuid nid=uml2@tcp(0x20000c0a80202) nal=90 0: 1:uml2_UUID
2147 #0x L add_uuid nid=2@elan(0x1000000000002) nal=90 0: 1:uml2_UUID
2148 #07 L add_conn 0:OSC_uml1_ost1_mdsA 1:uml2_UUID
2152 * Pull failnid info out of params string, which may contain something
2153 * like "<nid1>,<nid2>:<nid3>,<nid4>". class_parse_nid() does not
2154 * complain about abnormal inputs like ",:<nid1>", "<nid1>:,<nid2>",
2155 * etc. However, convert_hostnames() should have caught those.
2157 while (class_find_param(ptr, PARAM_FAILNODE, &ptr) == 0) {
2158 while (class_parse_nid(ptr, &nid, &ptr) == 0) {
2159 char nidstr[LNET_NIDSTR_SIZE];
2161 if (failnodeuuid == NULL) {
2162 /* We don't know the failover node name,
2163 * so just use the first nid as the uuid */
2164 libcfs_nid2str_r(nid, nidstr, sizeof(nidstr));
2165 rc = name_create(&failnodeuuid, nidstr, "");
2169 CDEBUG(D_MGS, "add nid %s for failover uuid %s, "
2171 libcfs_nid2str_r(nid, nidstr, sizeof(nidstr)),
2172 failnodeuuid, cliname);
2173 rc = record_add_uuid(env, llh, nid, failnodeuuid);
2175 * If *ptr is ':', we have added all NIDs for
2179 rc = record_add_conn(env, llh, cliname,
2181 name_destroy(&failnodeuuid);
2182 failnodeuuid = NULL;
2186 rc = record_add_conn(env, llh, cliname, failnodeuuid);
2187 name_destroy(&failnodeuuid);
2188 failnodeuuid = NULL;
2195 static int mgs_write_log_mdc_to_lmv(const struct lu_env *env,
2196 struct mgs_device *mgs,
2198 struct mgs_target_info *mti,
2199 char *logname, char *lmvname)
2201 struct llog_handle *llh = NULL;
2202 char *mdcname = NULL;
2203 char *nodeuuid = NULL;
2204 char *mdcuuid = NULL;
2205 char *lmvuuid = NULL;
2207 char nidstr[LNET_NIDSTR_SIZE];
2211 if (mgs_log_is_empty(env, mgs, logname)) {
2212 CERROR("log is empty! Logical error\n");
2216 CDEBUG(D_MGS, "adding mdc for %s to log %s:lmv(%s)\n",
2217 mti->mti_svname, logname, lmvname);
2219 libcfs_nid2str_r(mti->mti_nids[0], nidstr, sizeof(nidstr));
2220 rc = name_create(&nodeuuid, nidstr, "");
2223 rc = name_create(&mdcname, mti->mti_svname, "-mdc");
2226 rc = name_create(&mdcuuid, mdcname, "_UUID");
2229 rc = name_create(&lmvuuid, lmvname, "_UUID");
2233 rc = record_start_log(env, mgs, &llh, logname);
2236 rc = record_marker(env, llh, fsdb, CM_START, mti->mti_svname,
2240 for (i = 0; i < mti->mti_nid_count; i++) {
2241 CDEBUG(D_MGS, "add nid %s for mdt\n",
2242 libcfs_nid2str_r(mti->mti_nids[i],
2243 nidstr, sizeof(nidstr)));
2245 rc = record_add_uuid(env, llh, mti->mti_nids[i], nodeuuid);
2250 rc = record_attach(env, llh, mdcname, LUSTRE_MDC_NAME, lmvuuid);
2253 rc = record_setup(env, llh, mdcname, mti->mti_uuid, nodeuuid,
2257 rc = mgs_write_log_failnids(env, mti, llh, mdcname);
2260 snprintf(index, sizeof(index), "%d", mti->mti_stripe_index);
2261 rc = record_mdc_add(env, llh, lmvname, mdcuuid, mti->mti_uuid,
2265 rc = record_marker(env, llh, fsdb, CM_END, mti->mti_svname,
2270 record_end_log(env, &llh);
2272 name_destroy(&lmvuuid);
2273 name_destroy(&mdcuuid);
2274 name_destroy(&mdcname);
2275 name_destroy(&nodeuuid);
2279 static inline int name_create_lov(char **lovname, char *mdtname,
2280 struct fs_db *fsdb, int index)
2283 if (index == 0 && test_bit(FSDB_OSCNAME18, &fsdb->fsdb_flags))
2284 return name_create(lovname, fsdb->fsdb_name, "-mdtlov");
2286 return name_create(lovname, mdtname, "-mdtlov");
2289 static int name_create_mdt_and_lov(char **logname, char **lovname,
2290 struct fs_db *fsdb, int i)
2294 rc = name_create_mdt(logname, fsdb->fsdb_name, i);
2298 if (i == 0 && test_bit(FSDB_OSCNAME18, &fsdb->fsdb_flags))
2299 rc = name_create(lovname, fsdb->fsdb_name, "-mdtlov");
2301 rc = name_create(lovname, *logname, "-mdtlov");
2303 name_destroy(logname);
2309 static inline int name_create_mdt_osc(char **oscname, char *ostname,
2310 struct fs_db *fsdb, int i)
2314 if (i == 0 && test_bit(FSDB_OSCNAME18, &fsdb->fsdb_flags))
2315 sprintf(suffix, "-osc");
2317 sprintf(suffix, "-osc-MDT%04x", i);
2318 return name_create(oscname, ostname, suffix);
2321 /* add new mdc to already existent MDS */
2322 static int mgs_write_log_osp_to_mdt(const struct lu_env *env,
2323 struct mgs_device *mgs,
2325 struct mgs_target_info *mti,
2326 int mdt_index, char *logname)
2328 struct llog_handle *llh = NULL;
2329 char *nodeuuid = NULL;
2330 char *ospname = NULL;
2331 char *lovuuid = NULL;
2332 char *mdtuuid = NULL;
2333 char *svname = NULL;
2334 char *mdtname = NULL;
2335 char *lovname = NULL;
2337 char nidstr[LNET_NIDSTR_SIZE];
2341 if (mgs_log_is_empty(env, mgs, mti->mti_svname)) {
2342 CERROR("log is empty! Logical error\n");
2346 CDEBUG(D_MGS, "adding osp index %d to %s\n", mti->mti_stripe_index,
2349 rc = name_create_mdt(&mdtname, fsdb->fsdb_name, mti->mti_stripe_index);
2353 libcfs_nid2str_r(mti->mti_nids[0], nidstr, sizeof(nidstr));
2354 rc = name_create(&nodeuuid, nidstr, "");
2356 GOTO(out_destory, rc);
2358 rc = name_create(&svname, mdtname, "-osp");
2360 GOTO(out_destory, rc);
2362 sprintf(index_str, "-MDT%04x", mdt_index);
2363 rc = name_create(&ospname, svname, index_str);
2365 GOTO(out_destory, rc);
2367 rc = name_create_lov(&lovname, logname, fsdb, mdt_index);
2369 GOTO(out_destory, rc);
2371 rc = name_create(&lovuuid, lovname, "_UUID");
2373 GOTO(out_destory, rc);
2375 rc = name_create(&mdtuuid, mdtname, "_UUID");
2377 GOTO(out_destory, rc);
2379 rc = record_start_log(env, mgs, &llh, logname);
2381 GOTO(out_destory, rc);
2383 rc = record_marker(env, llh, fsdb, CM_START, mti->mti_svname,
2386 GOTO(out_destory, rc);
2388 for (i = 0; i < mti->mti_nid_count; i++) {
2389 CDEBUG(D_MGS, "add nid %s for mdt\n",
2390 libcfs_nid2str_r(mti->mti_nids[i],
2391 nidstr, sizeof(nidstr)));
2392 rc = record_add_uuid(env, llh, mti->mti_nids[i], nodeuuid);
2397 rc = record_attach(env, llh, ospname, LUSTRE_OSP_NAME, lovuuid);
2401 rc = record_setup(env, llh, ospname, mti->mti_uuid, nodeuuid,
2406 rc = mgs_write_log_failnids(env, mti, llh, ospname);
2410 /* Add mdc(osp) to lod */
2411 snprintf(index_str, sizeof(index_str), "%d", mti->mti_stripe_index);
2412 rc = record_base(env, llh, lovname, 0, LCFG_ADD_MDC, mti->mti_uuid,
2413 index_str, "1", NULL);
2417 rc = record_marker(env, llh, fsdb, CM_END, mti->mti_svname, "add osp");
2422 record_end_log(env, &llh);
2425 name_destroy(&mdtuuid);
2426 name_destroy(&lovuuid);
2427 name_destroy(&lovname);
2428 name_destroy(&ospname);
2429 name_destroy(&svname);
2430 name_destroy(&nodeuuid);
2431 name_destroy(&mdtname);
2435 static int mgs_write_log_mdt0(const struct lu_env *env,
2436 struct mgs_device *mgs,
2438 struct mgs_target_info *mti)
2440 char *log = mti->mti_svname;
2441 struct llog_handle *llh = NULL;
2442 char *uuid, *lovname;
2444 char *ptr = mti->mti_params;
2445 int rc = 0, failout = 0;
2448 OBD_ALLOC(uuid, sizeof(struct obd_uuid));
2452 if (class_find_param(ptr, PARAM_FAILMODE, &ptr) == 0)
2453 failout = (strncmp(ptr, "failout", 7) == 0);
2455 rc = name_create(&lovname, log, "-mdtlov");
2458 if (mgs_log_is_empty(env, mgs, log)) {
2459 rc = mgs_write_log_lov(env, mgs, fsdb, mti, log, lovname);
2464 sprintf(mdt_index, "%d", mti->mti_stripe_index);
2466 rc = record_start_log(env, mgs, &llh, log);
2470 /* add MDT itself */
2472 /* FIXME this whole fn should be a single journal transaction */
2473 sprintf(uuid, "%s_UUID", log);
2474 rc = record_marker(env, llh, fsdb, CM_START, log, "add mdt");
2477 rc = record_attach(env, llh, log, LUSTRE_MDT_NAME, uuid);
2480 rc = record_mount_opt(env, llh, log, lovname, NULL);
2483 rc = record_setup(env, llh, log, uuid, mdt_index, lovname,
2484 failout ? "n" : "f");
2487 rc = record_marker(env, llh, fsdb, CM_END, log, "add mdt");
2491 record_end_log(env, &llh);
2493 name_destroy(&lovname);
2495 OBD_FREE(uuid, sizeof(struct obd_uuid));
2499 /* envelope method for all layers log */
2500 static int mgs_write_log_mdt(const struct lu_env *env,
2501 struct mgs_device *mgs,
2503 struct mgs_target_info *mti)
2505 struct mgs_thread_info *mgi = mgs_env_info(env);
2506 struct llog_handle *llh = NULL;
2511 CDEBUG(D_MGS, "writing new mdt %s\n", mti->mti_svname);
2513 if (mti->mti_uuid[0] == '\0') {
2514 /* Make up our own uuid */
2515 snprintf(mti->mti_uuid, sizeof(mti->mti_uuid),
2516 "%s_UUID", mti->mti_svname);
2520 rc = mgs_write_log_mdt0(env, mgs, fsdb, mti);
2523 /* Append the mdt info to the client log */
2524 rc = name_create(&cliname, mti->mti_fsname, "-client");
2528 if (mgs_log_is_empty(env, mgs, cliname)) {
2529 /* Start client log */
2530 rc = mgs_write_log_lov(env, mgs, fsdb, mti, cliname,
2534 rc = mgs_write_log_lmv(env, mgs, fsdb, mti, cliname,
2541 #09 L add_uuid nid=uml1@tcp(0x20000c0a80201) 0: 1:uml1_UUID
2542 #10 L attach 0:MDC_uml1_mdsA_MNT_client 1:mdc 2:1d834_MNT_client_03f
2543 #11 L setup 0:MDC_uml1_mdsA_MNT_client 1:mdsA_UUID 2:uml1_UUID
2544 #12 L add_uuid nid=uml2@tcp(0x20000c0a80202) 0: 1:uml2_UUID
2545 #13 L add_conn 0:MDC_uml1_mdsA_MNT_client 1:uml2_UUID
2546 #14 L mount_option 0: 1:client 2:lov1 3:MDC_uml1_mdsA_MNT_client
2549 /* copy client info about lov/lmv */
2550 mgi->mgi_comp.comp_mti = mti;
2551 mgi->mgi_comp.comp_fsdb = fsdb;
2553 rc = mgs_steal_llog_for_mdt_from_client(env, mgs, cliname,
2557 rc = mgs_write_log_mdc_to_lmv(env, mgs, fsdb, mti, cliname,
2563 rc = record_start_log(env, mgs, &llh, cliname);
2567 rc = record_marker(env, llh, fsdb, CM_START, cliname, "mount opts");
2570 rc = record_mount_opt(env, llh, cliname, fsdb->fsdb_clilov,
2574 rc = record_marker(env, llh, fsdb, CM_END, cliname, "mount opts");
2578 /* for_all_existing_mdt except current one */
2579 for (i = 0; i < INDEX_MAP_SIZE * 8; i++) {
2580 if (i != mti->mti_stripe_index &&
2581 test_bit(i, fsdb->fsdb_mdt_index_map)) {
2584 rc = name_create_mdt(&logname, fsdb->fsdb_name, i);
2588 /* NB: If the log for the MDT is empty, it means
2589 * the MDT is only added to the index
2590 * map, and not being process yet, i.e. this
2591 * is an unregistered MDT, see mgs_write_log_target().
2592 * so we should skip it. Otherwise
2594 * 1. MGS get register request for MDT1 and MDT2.
2596 * 2. Then both MDT1 and MDT2 are added into
2597 * fsdb_mdt_index_map. (see mgs_set_index()).
2599 * 3. Then MDT1 get the lock of fsdb_mutex, then
2600 * generate the config log, here, it will regard MDT2
2601 * as an existent MDT, and generate "add osp" for
2602 * lustre-MDT0001-osp-MDT0002. Note: at the moment
2603 * MDT0002 config log is still empty, so it will
2604 * add "add osp" even before "lov setup", which
2605 * will definitly cause trouble.
2607 * 4. MDT1 registeration finished, fsdb_mutex is
2608 * released, then MDT2 get in, then in above
2609 * mgs_steal_llog_for_mdt_from_client(), it will
2610 * add another osp log for lustre-MDT0001-osp-MDT0002,
2611 * which will cause another trouble.*/
2612 if (!mgs_log_is_empty(env, mgs, logname))
2613 rc = mgs_write_log_osp_to_mdt(env, mgs, fsdb,
2616 name_destroy(&logname);
2622 record_end_log(env, &llh);
2624 name_destroy(&cliname);
2628 /* Add the ost info to the client/mdt lov */
2629 static int mgs_write_log_osc_to_lov(const struct lu_env *env,
2630 struct mgs_device *mgs, struct fs_db *fsdb,
2631 struct mgs_target_info *mti,
2632 char *logname, char *suffix, char *lovname,
2633 enum lustre_sec_part sec_part, int flags)
2635 struct llog_handle *llh = NULL;
2636 char *nodeuuid = NULL;
2637 char *oscname = NULL;
2638 char *oscuuid = NULL;
2639 char *lovuuid = NULL;
2640 char *svname = NULL;
2642 char nidstr[LNET_NIDSTR_SIZE];
2646 CDEBUG(D_INFO, "adding osc for %s to log %s\n",
2647 mti->mti_svname, logname);
2649 if (mgs_log_is_empty(env, mgs, logname)) {
2650 CERROR("log is empty! Logical error\n");
2654 libcfs_nid2str_r(mti->mti_nids[0], nidstr, sizeof(nidstr));
2655 rc = name_create(&nodeuuid, nidstr, "");
2658 rc = name_create(&svname, mti->mti_svname, "-osc");
2662 /* for the system upgraded from old 1.8, keep using the old osc naming
2663 * style for mdt, see name_create_mdt_osc(). LU-1257 */
2664 if (test_bit(FSDB_OSCNAME18, &fsdb->fsdb_flags))
2665 rc = name_create(&oscname, svname, "");
2667 rc = name_create(&oscname, svname, suffix);
2671 rc = name_create(&oscuuid, oscname, "_UUID");
2674 rc = name_create(&lovuuid, lovname, "_UUID");
2680 #03 L add_uuid nid=uml1@tcp(0x20000c0a80201) 0: 1:uml1_UUID
2682 #04 L add_uuid nid=1@elan(0x1000000000001) nal=90 0: 1:uml1_UUID
2683 #04 L attach 0:OSC_uml1_ost1_MNT_client 1:osc 2:89070_lov1_a41dff51a
2684 #05 L setup 0:OSC_uml1_ost1_MNT_client 1:ost1_UUID 2:uml1_UUID
2686 #06 L add_uuid nid=uml2@tcp(0x20000c0a80202) 0: 1:uml2_UUID
2687 #07 L add_conn 0:OSC_uml1_ost1_MNT_client 1:uml2_UUID
2688 #08 L lov_modify_tgts add 0:lov1 1:ost1_UUID 2(index):0 3(gen):1
2691 rc = record_start_log(env, mgs, &llh, logname);
2695 /* FIXME these should be a single journal transaction */
2696 rc = record_marker(env, llh, fsdb, CM_START | flags, mti->mti_svname,
2701 /* NB: don't change record order, because upon MDT steal OSC config
2702 * from client, it treats all nids before LCFG_SETUP as target nids
2703 * (multiple interfaces), while nids after as failover node nids.
2704 * See mgs_steal_client_llog_handler() LCFG_ADD_UUID.
2706 for (i = 0; i < mti->mti_nid_count; i++) {
2707 CDEBUG(D_MGS, "add nid %s\n",
2708 libcfs_nid2str_r(mti->mti_nids[i],
2709 nidstr, sizeof(nidstr)));
2710 rc = record_add_uuid(env, llh, mti->mti_nids[i], nodeuuid);
2714 rc = record_attach(env, llh, oscname, LUSTRE_OSC_NAME, lovuuid);
2717 rc = record_setup(env, llh, oscname, mti->mti_uuid, nodeuuid,
2721 rc = mgs_write_log_failnids(env, mti, llh, oscname);
2725 snprintf(index, sizeof(index), "%d", mti->mti_stripe_index);
2727 rc = record_lov_add(env, llh, lovname, mti->mti_uuid, index, "1");
2730 rc = record_marker(env, llh, fsdb, CM_END | flags, mti->mti_svname,
2735 record_end_log(env, &llh);
2737 name_destroy(&lovuuid);
2738 name_destroy(&oscuuid);
2739 name_destroy(&oscname);
2740 name_destroy(&svname);
2741 name_destroy(&nodeuuid);
2745 static int mgs_write_log_ost(const struct lu_env *env,
2746 struct mgs_device *mgs, struct fs_db *fsdb,
2747 struct mgs_target_info *mti)
2749 struct llog_handle *llh = NULL;
2750 char *logname, *lovname;
2751 char *ptr = mti->mti_params;
2752 int rc, flags = 0, failout = 0, i;
2755 CDEBUG(D_MGS, "writing new ost %s\n", mti->mti_svname);
2757 /* The ost startup log */
2759 /* If the ost log already exists, that means that someone reformatted
2760 the ost and it called target_add again. */
2761 if (!mgs_log_is_empty(env, mgs, mti->mti_svname)) {
2762 LCONSOLE_ERROR_MSG(0x141, "The config log for %s already "
2763 "exists, yet the server claims it never "
2764 "registered. It may have been reformatted, "
2765 "or the index changed. writeconf the MDT to "
2766 "regenerate all logs.\n", mti->mti_svname);
2771 attach obdfilter ost1 ost1_UUID
2772 setup /dev/loop2 ldiskfs f|n errors=remount-ro,user_xattr
2774 if (class_find_param(ptr, PARAM_FAILMODE, &ptr) == 0)
2775 failout = (strncmp(ptr, "failout", 7) == 0);
2776 rc = record_start_log(env, mgs, &llh, mti->mti_svname);
2779 /* FIXME these should be a single journal transaction */
2780 rc = record_marker(env, llh, fsdb, CM_START, mti->mti_svname,"add ost");
2783 if (*mti->mti_uuid == '\0')
2784 snprintf(mti->mti_uuid, sizeof(mti->mti_uuid),
2785 "%s_UUID", mti->mti_svname);
2786 rc = record_attach(env, llh, mti->mti_svname,
2787 "obdfilter"/*LUSTRE_OST_NAME*/, mti->mti_uuid);
2790 rc = record_setup(env, llh, mti->mti_svname,
2791 "dev"/*ignored*/, "type"/*ignored*/,
2792 failout ? "n" : "f", NULL/*options*/);
2795 rc = record_marker(env, llh, fsdb, CM_END, mti->mti_svname, "add ost");
2799 record_end_log(env, &llh);
2802 /* We also have to update the other logs where this osc is part of
2805 if (test_bit(FSDB_OLDLOG14, &fsdb->fsdb_flags)) {
2806 /* If we're upgrading, the old mdt log already has our
2807 entry. Let's do a fake one for fun. */
2808 /* Note that we can't add any new failnids, since we don't
2809 know the old osc names. */
2810 flags = CM_SKIP | CM_UPGRADE146;
2812 } else if ((mti->mti_flags & LDD_F_UPDATE) != LDD_F_UPDATE) {
2813 /* If the update flag isn't set, don't update client/mdt
2816 LCONSOLE_WARN("Client log for %s was not updated; writeconf "
2817 "the MDT first to regenerate it.\n",
2821 /* Add ost to all MDT lov defs */
2822 for (i = 0; i < INDEX_MAP_SIZE * 8; i++){
2823 if (test_bit(i, fsdb->fsdb_mdt_index_map)) {
2826 rc = name_create_mdt_and_lov(&logname, &lovname, fsdb,
2830 sprintf(mdt_index, "-MDT%04x", i);
2831 rc = mgs_write_log_osc_to_lov(env, mgs, fsdb, mti,
2833 lovname, LUSTRE_SP_MDT,
2835 name_destroy(&logname);
2836 name_destroy(&lovname);
2842 /* Append ost info to the client log */
2843 rc = name_create(&logname, mti->mti_fsname, "-client");
2846 if (mgs_log_is_empty(env, mgs, logname)) {
2847 /* Start client log */
2848 rc = mgs_write_log_lov(env, mgs, fsdb, mti, logname,
2852 rc = mgs_write_log_lmv(env, mgs, fsdb, mti, logname,
2857 rc = mgs_write_log_osc_to_lov(env, mgs, fsdb, mti, logname, "",
2858 fsdb->fsdb_clilov, LUSTRE_SP_CLI, flags);
2860 name_destroy(&logname);
2864 static __inline__ int mgs_param_empty(char *ptr)
2868 if ((tmp = strchr(ptr, '=')) && (*(++tmp) == '\0'))
2873 static int mgs_write_log_failnid_internal(const struct lu_env *env,
2874 struct mgs_device *mgs,
2876 struct mgs_target_info *mti,
2877 char *logname, char *cliname)
2880 struct llog_handle *llh = NULL;
2882 if (mgs_param_empty(mti->mti_params)) {
2883 /* Remove _all_ failnids */
2884 rc = mgs_modify(env, mgs, fsdb, mti, logname,
2885 mti->mti_svname, "add failnid", CM_SKIP);
2886 return rc < 0 ? rc : 0;
2889 /* Otherwise failover nids are additive */
2890 rc = record_start_log(env, mgs, &llh, logname);
2893 /* FIXME this should be a single journal transaction */
2894 rc = record_marker(env, llh, fsdb, CM_START, mti->mti_svname,
2898 rc = mgs_write_log_failnids(env, mti, llh, cliname);
2901 rc = record_marker(env, llh, fsdb, CM_END,
2902 mti->mti_svname, "add failnid");
2904 record_end_log(env, &llh);
2909 /* Add additional failnids to an existing log.
2910 The mdc/osc must have been added to logs first */
2911 /* tcp nids must be in dotted-quad ascii -
2912 we can't resolve hostnames from the kernel. */
2913 static int mgs_write_log_add_failnid(const struct lu_env *env,
2914 struct mgs_device *mgs,
2916 struct mgs_target_info *mti)
2918 char *logname, *cliname;
2922 /* FIXME we currently can't erase the failnids
2923 * given when a target first registers, since they aren't part of
2924 * an "add uuid" stanza
2927 /* Verify that we know about this target */
2928 if (mgs_log_is_empty(env, mgs, mti->mti_svname)) {
2929 LCONSOLE_ERROR_MSG(0x142, "The target %s has not registered "
2930 "yet. It must be started before failnids "
2931 "can be added.\n", mti->mti_svname);
2935 /* Create mdc/osc client name (e.g. lustre-OST0001-osc) */
2936 if (mti->mti_flags & LDD_F_SV_TYPE_MDT) {
2937 rc = name_create(&cliname, mti->mti_svname, "-mdc");
2938 } else if (mti->mti_flags & LDD_F_SV_TYPE_OST) {
2939 rc = name_create(&cliname, mti->mti_svname, "-osc");
2946 /* Add failover nids to the client log */
2947 rc = name_create(&logname, mti->mti_fsname, "-client");
2949 name_destroy(&cliname);
2953 rc = mgs_write_log_failnid_internal(env, mgs, fsdb,mti,logname,cliname);
2954 name_destroy(&logname);
2955 name_destroy(&cliname);
2959 if (mti->mti_flags & LDD_F_SV_TYPE_OST) {
2960 /* Add OST failover nids to the MDT logs as well */
2963 for (i = 0; i < INDEX_MAP_SIZE * 8; i++) {
2964 if (!test_bit(i, fsdb->fsdb_mdt_index_map))
2966 rc = name_create_mdt(&logname, mti->mti_fsname, i);
2969 rc = name_create_mdt_osc(&cliname, mti->mti_svname,
2972 name_destroy(&logname);
2975 rc = mgs_write_log_failnid_internal(env, mgs, fsdb,
2978 name_destroy(&cliname);
2979 name_destroy(&logname);
2988 static int mgs_wlp_lcfg(const struct lu_env *env,
2989 struct mgs_device *mgs, struct fs_db *fsdb,
2990 struct mgs_target_info *mti,
2991 char *logname, struct lustre_cfg_bufs *bufs,
2992 char *tgtname, char *ptr)
2994 char comment[MTI_NAME_MAXLEN];
2996 struct llog_cfg_rec *lcr;
2999 /* Erase any old settings of this same parameter */
3000 memcpy(comment, ptr, MTI_NAME_MAXLEN);
3001 comment[MTI_NAME_MAXLEN - 1] = 0;
3002 /* But don't try to match the value. */
3003 tmp = strchr(comment, '=');
3006 /* FIXME we should skip settings that are the same as old values */
3007 rc = mgs_modify(env, mgs, fsdb, mti, logname, tgtname, comment,CM_SKIP);
3010 del = mgs_param_empty(ptr);
3012 LCONSOLE_INFO("%s parameter %s.%s in log %s\n", del ? "Disabling" : rc ?
3013 "Setting" : "Modifying", tgtname, comment, logname);
3015 /* mgs_modify() will return 1 if nothing had to be done */
3021 lustre_cfg_bufs_reset(bufs, tgtname);
3022 lustre_cfg_bufs_set_string(bufs, 1, ptr);
3023 if (mti->mti_flags & LDD_F_PARAM2)
3024 lustre_cfg_bufs_set_string(bufs, 2, LCTL_UPCALL);
3026 lcr = lustre_cfg_rec_new((mti->mti_flags & LDD_F_PARAM2) ?
3027 LCFG_SET_PARAM : LCFG_PARAM, bufs);
3031 rc = mgs_write_log_direct(env, mgs, fsdb, logname, lcr, tgtname,
3033 lustre_cfg_rec_free(lcr);
3037 /* write global variable settings into log */
3038 static int mgs_write_log_sys(const struct lu_env *env,
3039 struct mgs_device *mgs, struct fs_db *fsdb,
3040 struct mgs_target_info *mti, char *sys, char *ptr)
3042 struct mgs_thread_info *mgi = mgs_env_info(env);
3043 struct lustre_cfg *lcfg;
3044 struct llog_cfg_rec *lcr;
3046 int rc, cmd, convert = 1;
3048 if (class_match_param(ptr, PARAM_TIMEOUT, &tmp) == 0) {
3049 cmd = LCFG_SET_TIMEOUT;
3050 } else if (class_match_param(ptr, PARAM_LDLM_TIMEOUT, &tmp) == 0) {
3051 cmd = LCFG_SET_LDLM_TIMEOUT;
3052 /* Check for known params here so we can return error to lctl */
3053 } else if ((class_match_param(ptr, PARAM_AT_MIN, &tmp) == 0) ||
3054 (class_match_param(ptr, PARAM_AT_MAX, &tmp) == 0) ||
3055 (class_match_param(ptr, PARAM_AT_EXTRA, &tmp) == 0) ||
3056 (class_match_param(ptr, PARAM_AT_EARLY_MARGIN, &tmp) == 0) ||
3057 (class_match_param(ptr, PARAM_AT_HISTORY, &tmp) == 0)) {
3059 } else if (class_match_param(ptr, PARAM_JOBID_VAR, &tmp) == 0) {
3060 convert = 0; /* Don't convert string value to integer */
3066 if (mgs_param_empty(ptr))
3067 CDEBUG(D_MGS, "global '%s' removed\n", sys);
3069 CDEBUG(D_MGS, "global '%s' val=%s\n", sys, tmp);
3071 lustre_cfg_bufs_reset(&mgi->mgi_bufs, NULL);
3072 lustre_cfg_bufs_set_string(&mgi->mgi_bufs, 1, sys);
3073 if (!convert && *tmp != '\0')
3074 lustre_cfg_bufs_set_string(&mgi->mgi_bufs, 2, tmp);
3075 lcr = lustre_cfg_rec_new(cmd, &mgi->mgi_bufs);
3079 lcfg = &lcr->lcr_cfg;
3080 lcfg->lcfg_num = convert ? simple_strtoul(tmp, NULL, 0) : 0;
3081 /* truncate the comment to the parameter name */
3085 /* modify all servers and clients */
3086 rc = mgs_write_log_direct_all(env, mgs, fsdb, mti,
3087 *tmp == '\0' ? NULL : lcr,
3088 mti->mti_fsname, sys, 0);
3089 if (rc == 0 && *tmp != '\0') {
3091 case LCFG_SET_TIMEOUT:
3092 if (!obd_timeout_set || lcfg->lcfg_num > obd_timeout)
3093 class_process_config(lcfg);
3095 case LCFG_SET_LDLM_TIMEOUT:
3096 if (!ldlm_timeout_set || lcfg->lcfg_num > ldlm_timeout)
3097 class_process_config(lcfg);
3104 lustre_cfg_rec_free(lcr);
3108 /* write quota settings into log */
3109 static int mgs_write_log_quota(const struct lu_env *env, struct mgs_device *mgs,
3110 struct fs_db *fsdb, struct mgs_target_info *mti,
3111 char *quota, char *ptr)
3113 struct mgs_thread_info *mgi = mgs_env_info(env);
3114 struct llog_cfg_rec *lcr;
3117 int rc, cmd = LCFG_PARAM;
3119 /* support only 'meta' and 'data' pools so far */
3120 if (class_match_param(ptr, QUOTA_METAPOOL_NAME, &tmp) != 0 &&
3121 class_match_param(ptr, QUOTA_DATAPOOL_NAME, &tmp) != 0) {
3122 CERROR("parameter quota.%s isn't supported (only quota.mdt "
3123 "& quota.ost are)\n", ptr);
3128 CDEBUG(D_MGS, "global '%s' removed\n", quota);
3130 CDEBUG(D_MGS, "global '%s'\n", quota);
3132 if (strchr(tmp, 'u') == NULL && strchr(tmp, 'g') == NULL &&
3133 strchr(tmp, 'p') == NULL &&
3134 strcmp(tmp, "none") != 0) {
3135 CERROR("enable option(%s) isn't supported\n", tmp);
3140 lustre_cfg_bufs_reset(&mgi->mgi_bufs, mti->mti_fsname);
3141 lustre_cfg_bufs_set_string(&mgi->mgi_bufs, 1, quota);
3142 lcr = lustre_cfg_rec_new(cmd, &mgi->mgi_bufs);
3146 /* truncate the comment to the parameter name */
3151 /* XXX we duplicated quota enable information in all server
3152 * config logs, it should be moved to a separate config
3153 * log once we cleanup the config log for global param. */
3154 /* modify all servers */
3155 rc = mgs_write_log_direct_all(env, mgs, fsdb, mti,
3156 *tmp == '\0' ? NULL : lcr,
3157 mti->mti_fsname, quota, 1);
3159 lustre_cfg_rec_free(lcr);
3160 return rc < 0 ? rc : 0;
3163 static int mgs_srpc_set_param_disk(const struct lu_env *env,
3164 struct mgs_device *mgs,
3166 struct mgs_target_info *mti,
3169 struct mgs_thread_info *mgi = mgs_env_info(env);
3170 struct llog_cfg_rec *lcr;
3171 struct llog_handle *llh = NULL;
3173 char *comment, *ptr;
3179 ptr = strchr(param, '=');
3180 LASSERT(ptr != NULL);
3183 OBD_ALLOC(comment, len + 1);
3184 if (comment == NULL)
3186 strncpy(comment, param, len);
3187 comment[len] = '\0';
3190 lustre_cfg_bufs_reset(&mgi->mgi_bufs, mti->mti_svname);
3191 lustre_cfg_bufs_set_string(&mgi->mgi_bufs, 1, param);
3192 lcr = lustre_cfg_rec_new(LCFG_SPTLRPC_CONF, &mgi->mgi_bufs);
3194 GOTO(out_comment, rc = -ENOMEM);
3196 /* construct log name */
3197 rc = name_create(&logname, mti->mti_fsname, "-sptlrpc");
3201 if (mgs_log_is_empty(env, mgs, logname)) {
3202 rc = record_start_log(env, mgs, &llh, logname);
3205 record_end_log(env, &llh);
3208 /* obsolete old one */
3209 rc = mgs_modify(env, mgs, fsdb, mti, logname, mti->mti_svname,
3213 /* write the new one */
3214 rc = mgs_write_log_direct(env, mgs, fsdb, logname, lcr,
3215 mti->mti_svname, comment);
3217 CERROR("%s: error writing log %s: rc = %d\n",
3218 mgs->mgs_obd->obd_name, logname, rc);
3220 name_destroy(&logname);
3222 lustre_cfg_rec_free(lcr);
3224 OBD_FREE(comment, len + 1);
3228 static int mgs_srpc_set_param_udesc_mem(struct fs_db *fsdb,
3233 /* disable the adjustable udesc parameter for now, i.e. use default
3234 * setting that client always ship udesc to MDT if possible. to enable
3235 * it simply remove the following line */
3238 ptr = strchr(param, '=');
3243 if (strcmp(param, PARAM_SRPC_UDESC))
3246 if (strcmp(ptr, "yes") == 0) {
3247 set_bit(FSDB_UDESC, &fsdb->fsdb_flags);
3248 CWARN("Enable user descriptor shipping from client to MDT\n");
3249 } else if (strcmp(ptr, "no") == 0) {
3250 clear_bit(FSDB_UDESC, &fsdb->fsdb_flags);
3251 CWARN("Disable user descriptor shipping from client to MDT\n");
3259 CERROR("Invalid param: %s\n", param);
3263 static int mgs_srpc_set_param_mem(struct fs_db *fsdb,
3267 struct sptlrpc_rule rule;
3268 struct sptlrpc_rule_set *rset;
3272 if (strncmp(param, PARAM_SRPC, sizeof(PARAM_SRPC) - 1) != 0) {
3273 CERROR("Invalid sptlrpc parameter: %s\n", param);
3277 if (strncmp(param, PARAM_SRPC_UDESC,
3278 sizeof(PARAM_SRPC_UDESC) - 1) == 0) {
3279 RETURN(mgs_srpc_set_param_udesc_mem(fsdb, param));
3282 if (strncmp(param, PARAM_SRPC_FLVR, sizeof(PARAM_SRPC_FLVR) - 1) != 0) {
3283 CERROR("Invalid sptlrpc flavor parameter: %s\n", param);
3287 param += sizeof(PARAM_SRPC_FLVR) - 1;
3289 rc = sptlrpc_parse_rule(param, &rule);
3293 /* mgs rules implies must be mgc->mgs */
3294 if (test_bit(FSDB_MGS_SELF, &fsdb->fsdb_flags)) {
3295 if ((rule.sr_from != LUSTRE_SP_MGC &&
3296 rule.sr_from != LUSTRE_SP_ANY) ||
3297 (rule.sr_to != LUSTRE_SP_MGS &&
3298 rule.sr_to != LUSTRE_SP_ANY))
3302 /* preapre room for this coming rule. svcname format should be:
3303 * - fsname: general rule
3304 * - fsname-tgtname: target-specific rule
3306 if (strchr(svname, '-')) {
3307 struct mgs_tgt_srpc_conf *tgtconf;
3310 for (tgtconf = fsdb->fsdb_srpc_tgt; tgtconf != NULL;
3311 tgtconf = tgtconf->mtsc_next) {
3312 if (!strcmp(tgtconf->mtsc_tgt, svname)) {
3321 OBD_ALLOC_PTR(tgtconf);
3322 if (tgtconf == NULL)
3325 name_len = strlen(svname);
3327 OBD_ALLOC(tgtconf->mtsc_tgt, name_len + 1);
3328 if (tgtconf->mtsc_tgt == NULL) {
3329 OBD_FREE_PTR(tgtconf);
3332 memcpy(tgtconf->mtsc_tgt, svname, name_len);
3334 tgtconf->mtsc_next = fsdb->fsdb_srpc_tgt;
3335 fsdb->fsdb_srpc_tgt = tgtconf;
3338 rset = &tgtconf->mtsc_rset;
3339 } else if (strcmp(svname, MGSSELF_NAME) == 0) {
3340 /* put _mgs related srpc rule directly in mgs ruleset */
3341 rset = &fsdb->fsdb_mgs->mgs_lut.lut_sptlrpc_rset;
3343 rset = &fsdb->fsdb_srpc_gen;
3346 rc = sptlrpc_rule_set_merge(rset, &rule);
3351 static int mgs_srpc_set_param(const struct lu_env *env,
3352 struct mgs_device *mgs,
3354 struct mgs_target_info *mti,
3364 /* keep a copy of original param, which could be destroied
3366 copy_size = strlen(param) + 1;
3367 OBD_ALLOC(copy, copy_size);
3370 memcpy(copy, param, copy_size);
3372 rc = mgs_srpc_set_param_mem(fsdb, mti->mti_svname, param);
3376 /* previous steps guaranteed the syntax is correct */
3377 rc = mgs_srpc_set_param_disk(env, mgs, fsdb, mti, copy);
3381 if (test_bit(FSDB_MGS_SELF, &fsdb->fsdb_flags)) {
3383 * for mgs rules, make them effective immediately.
3385 LASSERT(fsdb->fsdb_srpc_tgt == NULL);
3386 sptlrpc_target_update_exp_flavor(mgs->mgs_obd,
3387 &fsdb->fsdb_srpc_gen);
3391 OBD_FREE(copy, copy_size);
3395 struct mgs_srpc_read_data {
3396 struct fs_db *msrd_fsdb;
3400 static int mgs_srpc_read_handler(const struct lu_env *env,
3401 struct llog_handle *llh,
3402 struct llog_rec_hdr *rec, void *data)
3404 struct mgs_srpc_read_data *msrd = data;
3405 struct cfg_marker *marker;
3406 struct lustre_cfg *lcfg = REC_DATA(rec);
3407 char *svname, *param;
3411 if (rec->lrh_type != OBD_CFG_REC) {
3412 CERROR("unhandled lrh_type: %#x\n", rec->lrh_type);
3416 cfg_len = REC_DATA_LEN(rec);
3418 rc = lustre_cfg_sanity_check(lcfg, cfg_len);
3420 CERROR("Insane cfg\n");
3424 if (lcfg->lcfg_command == LCFG_MARKER) {
3425 marker = lustre_cfg_buf(lcfg, 1);
3427 if (marker->cm_flags & CM_START &&
3428 marker->cm_flags & CM_SKIP)
3429 msrd->msrd_skip = 1;
3430 if (marker->cm_flags & CM_END)
3431 msrd->msrd_skip = 0;
3436 if (msrd->msrd_skip)
3439 if (lcfg->lcfg_command != LCFG_SPTLRPC_CONF) {
3440 CERROR("invalid command (%x)\n", lcfg->lcfg_command);
3444 svname = lustre_cfg_string(lcfg, 0);
3445 if (svname == NULL) {
3446 CERROR("svname is empty\n");
3450 param = lustre_cfg_string(lcfg, 1);
3451 if (param == NULL) {
3452 CERROR("param is empty\n");
3456 rc = mgs_srpc_set_param_mem(msrd->msrd_fsdb, svname, param);
3458 CERROR("read sptlrpc record error (%d): %s\n", rc, param);
3463 int mgs_get_fsdb_srpc_from_llog(const struct lu_env *env,
3464 struct mgs_device *mgs,
3467 struct llog_handle *llh = NULL;
3468 struct llog_ctxt *ctxt;
3470 struct mgs_srpc_read_data msrd;
3474 /* construct log name */
3475 rc = name_create(&logname, fsdb->fsdb_name, "-sptlrpc");
3479 ctxt = llog_get_context(mgs->mgs_obd, LLOG_CONFIG_ORIG_CTXT);
3480 LASSERT(ctxt != NULL);
3482 if (mgs_log_is_empty(env, mgs, logname))
3485 rc = llog_open(env, ctxt, &llh, NULL, logname,
3493 rc = llog_init_handle(env, llh, LLOG_F_IS_PLAIN, NULL);
3495 GOTO(out_close, rc);
3497 if (llog_get_size(llh) <= 1)
3498 GOTO(out_close, rc = 0);
3500 msrd.msrd_fsdb = fsdb;
3503 rc = llog_process(env, llh, mgs_srpc_read_handler, (void *)&msrd,
3507 llog_close(env, llh);
3509 llog_ctxt_put(ctxt);
3510 name_destroy(&logname);
3513 CERROR("failed to read sptlrpc config database: %d\n", rc);
3517 static int mgs_write_log_param2(const struct lu_env *env,
3518 struct mgs_device *mgs,
3520 struct mgs_target_info *mti, char *ptr)
3522 struct lustre_cfg_bufs bufs;
3526 CDEBUG(D_MGS, "next param '%s'\n", ptr);
3528 /* PARAM_MGSNODE and PARAM_NETWORK are set only when formating
3529 * or during the inital mount. It can never change after that.
3531 if (!class_match_param(ptr, PARAM_MGSNODE, NULL) ||
3532 !class_match_param(ptr, PARAM_NETWORK, NULL)) {
3537 /* Processed in mgs_write_log_ost. Another value that can't
3538 * be changed by lctl set_param -P.
3540 if (!class_match_param(ptr, PARAM_FAILMODE, NULL)) {
3541 LCONSOLE_ERROR_MSG(0x169,
3542 "%s can only be changed with tunefs.lustre and --writeconf\n",
3548 /* FIXME !!! Support for sptlrpc is incomplete. Currently the change
3549 * doesn't transmit to the client. See LU-7183.
3551 if (!class_match_param(ptr, PARAM_SRPC, NULL)) {
3552 rc = mgs_srpc_set_param(env, mgs, fsdb, mti, ptr);
3556 /* Can't use class_match_param since ptr doesn't start with
3557 * PARAM_FAILNODE. So we look for PARAM_FAILNODE contained in ptr.
3559 if (strstr(ptr, PARAM_FAILNODE)) {
3560 /* Add a failover nidlist. We already processed failovers
3561 * params for new targets in mgs_write_log_target.
3565 /* can't use wildcards with failover.node */
3566 if (strchr(ptr, '*')) {
3571 param = strstr(ptr, PARAM_FAILNODE);
3572 if (strlcpy(mti->mti_params, param, sizeof(mti->mti_params)) >=
3573 sizeof(mti->mti_params)) {
3578 CDEBUG(D_MGS, "Adding failnode with param %s\n",
3580 rc = mgs_write_log_add_failnid(env, mgs, fsdb, mti);
3584 rc = mgs_wlp_lcfg(env, mgs, fsdb, mti, PARAMS_FILENAME, &bufs,
3585 mti->mti_svname, ptr);
3590 /* Permanent settings of all parameters by writing into the appropriate
3591 * configuration logs.
3592 * A parameter with null value ("<param>='\0'") means to erase it out of
3595 static int mgs_write_log_param(const struct lu_env *env,
3596 struct mgs_device *mgs, struct fs_db *fsdb,
3597 struct mgs_target_info *mti, char *ptr)
3599 struct mgs_thread_info *mgi = mgs_env_info(env);
3605 /* For various parameter settings, we have to figure out which logs
3606 care about them (e.g. both mdt and client for lov settings) */
3607 CDEBUG(D_MGS, "next param '%s'\n", ptr);
3609 /* The params are stored in MOUNT_DATA_FILE and modified via
3610 tunefs.lustre, or set using lctl conf_param */
3612 /* Processed in lustre_start_mgc */
3613 if (class_match_param(ptr, PARAM_MGSNODE, NULL) == 0)
3616 /* Processed in ost/mdt */
3617 if (class_match_param(ptr, PARAM_NETWORK, NULL) == 0)
3620 /* Processed in mgs_write_log_ost */
3621 if (class_match_param(ptr, PARAM_FAILMODE, NULL) == 0) {
3622 if (mti->mti_flags & LDD_F_PARAM) {
3623 LCONSOLE_ERROR_MSG(0x169, "%s can only be "
3624 "changed with tunefs.lustre"
3625 "and --writeconf\n", ptr);
3631 if (class_match_param(ptr, PARAM_SRPC, NULL) == 0) {
3632 rc = mgs_srpc_set_param(env, mgs, fsdb, mti, ptr);
3636 if (class_match_param(ptr, PARAM_FAILNODE, NULL) == 0) {
3637 /* Add a failover nidlist */
3639 /* We already processed failovers params for new
3640 targets in mgs_write_log_target */
3641 if (mti->mti_flags & LDD_F_PARAM) {
3642 CDEBUG(D_MGS, "Adding failnode\n");
3643 rc = mgs_write_log_add_failnid(env, mgs, fsdb, mti);
3648 if (class_match_param(ptr, PARAM_SYS, &tmp) == 0) {
3649 rc = mgs_write_log_sys(env, mgs, fsdb, mti, ptr, tmp);
3653 if (class_match_param(ptr, PARAM_QUOTA, &tmp) == 0) {
3654 rc = mgs_write_log_quota(env, mgs, fsdb, mti, ptr, tmp);
3658 if (class_match_param(ptr, PARAM_OSC PARAM_ACTIVE, &tmp) == 0 ||
3659 class_match_param(ptr, PARAM_MDC PARAM_ACTIVE, &tmp) == 0) {
3660 /* active=0 means off, anything else means on */
3661 int flag = (*tmp == '0') ? CM_EXCLUDE : 0;
3662 bool deactive_osc = memcmp(ptr, PARAM_OSC PARAM_ACTIVE,
3663 strlen(PARAM_OSC PARAM_ACTIVE)) == 0;
3666 if (!deactive_osc) {
3669 rc = server_name2index(mti->mti_svname, &index, NULL);
3674 LCONSOLE_ERROR_MSG(0x144, "%s: MDC0 can not be"
3675 " (de)activated.\n",
3677 GOTO(end, rc = -EPERM);
3681 LCONSOLE_WARN("Permanently %sactivating %s\n",
3682 flag ? "de" : "re", mti->mti_svname);
3684 rc = name_create(&logname, mti->mti_fsname, "-client");
3687 rc = mgs_modify(env, mgs, fsdb, mti, logname,
3689 deactive_osc ? "add osc" : "add mdc", flag);
3690 name_destroy(&logname);
3695 /* Add to all MDT logs for DNE */
3696 for (i = 0; i < INDEX_MAP_SIZE * 8; i++) {
3697 if (!test_bit(i, fsdb->fsdb_mdt_index_map))
3699 rc = name_create_mdt(&logname, mti->mti_fsname, i);
3702 rc = mgs_modify(env, mgs, fsdb, mti, logname,
3704 deactive_osc ? "add osc" : "add osp",
3706 name_destroy(&logname);
3712 LCONSOLE_ERROR_MSG(0x145, "Couldn't find %s in"
3713 "log (%d). No permanent "
3714 "changes were made to the "
3716 mti->mti_svname, rc);
3717 if (test_bit(FSDB_OLDLOG14, &fsdb->fsdb_flags))
3718 LCONSOLE_ERROR_MSG(0x146, "This may be"
3723 "update the logs.\n");
3726 /* Fall through to osc/mdc proc for deactivating live
3727 OSC/OSP on running MDT / clients. */
3729 /* Below here, let obd's XXX_process_config methods handle it */
3731 /* All lov. in proc */
3732 if (class_match_param(ptr, PARAM_LOV, NULL) == 0) {
3735 CDEBUG(D_MGS, "lov param %s\n", ptr);
3736 if (!(mti->mti_flags & LDD_F_SV_TYPE_MDT)) {
3737 LCONSOLE_ERROR_MSG(0x147, "LOV params must be "
3738 "set on the MDT, not %s. "
3745 if (mgs_log_is_empty(env, mgs, mti->mti_svname))
3746 GOTO(end, rc = -ENODEV);
3748 rc = name_create_mdt_and_lov(&logname, &mdtlovname, fsdb,
3749 mti->mti_stripe_index);
3752 rc = mgs_wlp_lcfg(env, mgs, fsdb, mti, mti->mti_svname,
3753 &mgi->mgi_bufs, mdtlovname, ptr);
3754 name_destroy(&logname);
3755 name_destroy(&mdtlovname);
3760 rc = name_create(&logname, mti->mti_fsname, "-client");
3763 rc = mgs_wlp_lcfg(env, mgs, fsdb, mti, logname, &mgi->mgi_bufs,
3764 fsdb->fsdb_clilov, ptr);
3765 name_destroy(&logname);
3769 /* All osc., mdc., llite. params in proc */
3770 if ((class_match_param(ptr, PARAM_OSC, NULL) == 0) ||
3771 (class_match_param(ptr, PARAM_MDC, NULL) == 0) ||
3772 (class_match_param(ptr, PARAM_LLITE, NULL) == 0)) {
3775 if (test_bit(FSDB_OLDLOG14, &fsdb->fsdb_flags)) {
3776 LCONSOLE_ERROR_MSG(0x148, "Upgraded client logs for %s"
3777 " cannot be modified. Consider"
3778 " updating the configuration with"
3781 GOTO(end, rc = -EINVAL);
3783 if (memcmp(ptr, PARAM_LLITE, strlen(PARAM_LLITE)) == 0) {
3784 rc = name_create(&cname, mti->mti_fsname, "-client");
3785 /* Add the client type to match the obdname in
3786 class_config_llog_handler */
3787 } else if (mti->mti_flags & LDD_F_SV_TYPE_MDT) {
3788 rc = name_create(&cname, mti->mti_svname, "-mdc");
3789 } else if (mti->mti_flags & LDD_F_SV_TYPE_OST) {
3790 rc = name_create(&cname, mti->mti_svname, "-osc");
3792 GOTO(end, rc = -EINVAL);
3797 /* Forbid direct update of llite root squash parameters.
3798 * These parameters are indirectly set via the MDT settings.
3800 if ((class_match_param(ptr, PARAM_LLITE, &tmp) == 0) &&
3801 ((memcmp(tmp, "root_squash=", 12) == 0) ||
3802 (memcmp(tmp, "nosquash_nids=", 14) == 0))) {
3803 LCONSOLE_ERROR("%s: root squash parameters can only "
3804 "be updated through MDT component\n",
3806 name_destroy(&cname);
3807 GOTO(end, rc = -EINVAL);
3810 CDEBUG(D_MGS, "%.3s param %s\n", ptr, ptr + 4);
3813 rc = name_create(&logname, mti->mti_fsname, "-client");
3815 name_destroy(&cname);
3818 rc = mgs_wlp_lcfg(env, mgs, fsdb, mti, logname, &mgi->mgi_bufs,
3821 /* osc params affect the MDT as well */
3822 if (!rc && (mti->mti_flags & LDD_F_SV_TYPE_OST)) {
3825 for (i = 0; i < INDEX_MAP_SIZE * 8; i++){
3826 if (!test_bit(i, fsdb->fsdb_mdt_index_map))
3828 name_destroy(&cname);
3829 rc = name_create_mdt_osc(&cname, mti->mti_svname,
3831 name_destroy(&logname);
3834 rc = name_create_mdt(&logname,
3835 mti->mti_fsname, i);
3838 if (!mgs_log_is_empty(env, mgs, logname)) {
3839 rc = mgs_wlp_lcfg(env, mgs, fsdb,
3849 /* For mdc activate/deactivate, it affects OSP on MDT as well */
3850 if (class_match_param(ptr, PARAM_MDC PARAM_ACTIVE, &tmp) == 0 &&
3853 char *lodname = NULL;
3854 char *param_str = NULL;
3858 /* replace mdc with osp */
3859 memcpy(ptr, PARAM_OSP, strlen(PARAM_OSP));
3860 rc = server_name2index(mti->mti_svname, &index, NULL);
3862 memcpy(ptr, PARAM_MDC, strlen(PARAM_MDC));
3866 for (i = 0; i < INDEX_MAP_SIZE * 8; i++) {
3867 if (!test_bit(i, fsdb->fsdb_mdt_index_map))
3873 name_destroy(&logname);
3874 rc = name_create_mdt(&logname, mti->mti_fsname,
3879 if (mgs_log_is_empty(env, mgs, logname))
3882 snprintf(suffix, sizeof(suffix), "-osp-MDT%04x",
3884 name_destroy(&cname);
3885 rc = name_create(&cname, mti->mti_svname,
3890 rc = mgs_wlp_lcfg(env, mgs, fsdb, mti, logname,
3891 &mgi->mgi_bufs, cname, ptr);
3895 /* Add configuration log for noitfying LOD
3896 * to active/deactive the OSP. */
3897 name_destroy(¶m_str);
3898 rc = name_create(¶m_str, cname,
3899 (*tmp == '0') ? ".active=0" :
3904 name_destroy(&lodname);
3905 rc = name_create(&lodname, logname, "-mdtlov");
3909 rc = mgs_wlp_lcfg(env, mgs, fsdb, mti, logname,
3910 &mgi->mgi_bufs, lodname,
3915 memcpy(ptr, PARAM_MDC, strlen(PARAM_MDC));
3916 name_destroy(&lodname);
3917 name_destroy(¶m_str);
3920 name_destroy(&logname);
3921 name_destroy(&cname);
3925 /* All mdt. params in proc */
3926 if (class_match_param(ptr, PARAM_MDT, &tmp) == 0) {
3930 CDEBUG(D_MGS, "%.3s param %s\n", ptr, ptr + 4);
3931 if (strncmp(mti->mti_svname, mti->mti_fsname,
3932 MTI_NAME_MAXLEN) == 0)
3933 /* device is unspecified completely? */
3934 rc = LDD_F_SV_TYPE_MDT | LDD_F_SV_ALL;
3936 rc = server_name2index(mti->mti_svname, &idx, NULL);
3939 if ((rc & LDD_F_SV_TYPE_MDT) == 0)
3941 if (rc & LDD_F_SV_ALL) {
3942 for (i = 0; i < INDEX_MAP_SIZE * 8; i++) {
3944 fsdb->fsdb_mdt_index_map))
3946 rc = name_create_mdt(&logname,
3947 mti->mti_fsname, i);
3950 rc = mgs_wlp_lcfg(env, mgs, fsdb, mti,
3951 logname, &mgi->mgi_bufs,
3953 name_destroy(&logname);
3958 if ((memcmp(tmp, "root_squash=", 12) == 0) ||
3959 (memcmp(tmp, "nosquash_nids=", 14) == 0)) {
3960 LCONSOLE_ERROR("%s: root squash parameters "
3961 "cannot be applied to a single MDT\n",
3963 GOTO(end, rc = -EINVAL);
3965 rc = mgs_wlp_lcfg(env, mgs, fsdb, mti,
3966 mti->mti_svname, &mgi->mgi_bufs,
3967 mti->mti_svname, ptr);
3972 /* root squash settings are also applied to llite
3973 * config log (see LU-1778) */
3975 ((memcmp(tmp, "root_squash=", 12) == 0) ||
3976 (memcmp(tmp, "nosquash_nids=", 14) == 0))) {
3980 rc = name_create(&cname, mti->mti_fsname, "-client");
3983 rc = name_create(&logname, mti->mti_fsname, "-client");
3985 name_destroy(&cname);
3988 rc = name_create(&ptr2, PARAM_LLITE, tmp);
3990 name_destroy(&cname);
3991 name_destroy(&logname);
3994 rc = mgs_wlp_lcfg(env, mgs, fsdb, mti, logname,
3995 &mgi->mgi_bufs, cname, ptr2);
3996 name_destroy(&ptr2);
3997 name_destroy(&logname);
3998 name_destroy(&cname);
4003 /* All mdd., ost. and osd. params in proc */
4004 if ((class_match_param(ptr, PARAM_MDD, NULL) == 0) ||
4005 (class_match_param(ptr, PARAM_LOD, NULL) == 0) ||
4006 (class_match_param(ptr, PARAM_OST, NULL) == 0) ||
4007 (class_match_param(ptr, PARAM_OSD, NULL) == 0)) {
4008 CDEBUG(D_MGS, "%.3s param %s\n", ptr, ptr + 4);
4009 if (mgs_log_is_empty(env, mgs, mti->mti_svname))
4010 GOTO(end, rc = -ENODEV);
4012 rc = mgs_wlp_lcfg(env, mgs, fsdb, mti, mti->mti_svname,
4013 &mgi->mgi_bufs, mti->mti_svname, ptr);
4017 LCONSOLE_WARN("Ignoring unrecognized param '%s'\n", ptr);
4021 CERROR("err %d on param '%s'\n", rc, ptr);
4026 int mgs_write_log_target(const struct lu_env *env, struct mgs_device *mgs,
4027 struct mgs_target_info *mti, struct fs_db *fsdb)
4034 /* set/check the new target index */
4035 rc = mgs_set_index(env, mgs, mti);
4039 if (rc == EALREADY) {
4040 LCONSOLE_WARN("Found index %d for %s, updating log\n",
4041 mti->mti_stripe_index, mti->mti_svname);
4042 /* We would like to mark old log sections as invalid
4043 and add new log sections in the client and mdt logs.
4044 But if we add new sections, then live clients will
4045 get repeat setup instructions for already running
4046 osc's. So don't update the client/mdt logs. */
4047 mti->mti_flags &= ~LDD_F_UPDATE;
4051 OBD_FAIL_TIMEOUT(OBD_FAIL_MGS_WRITE_TARGET_DELAY, cfs_fail_val > 0 ?
4054 mutex_lock(&fsdb->fsdb_mutex);
4056 if (mti->mti_flags &
4057 (LDD_F_VIRGIN | LDD_F_UPGRADE14 | LDD_F_WRITECONF)) {
4058 /* Generate a log from scratch */
4059 if (mti->mti_flags & LDD_F_SV_TYPE_MDT) {
4060 rc = mgs_write_log_mdt(env, mgs, fsdb, mti);
4061 } else if (mti->mti_flags & LDD_F_SV_TYPE_OST) {
4062 rc = mgs_write_log_ost(env, mgs, fsdb, mti);
4064 CERROR("Unknown target type %#x, can't create log for "
4065 "%s\n", mti->mti_flags, mti->mti_svname);
4068 CERROR("Can't write logs for %s (%d)\n",
4069 mti->mti_svname, rc);
4073 /* Just update the params from tunefs in mgs_write_log_params */
4074 CDEBUG(D_MGS, "Update params for %s\n", mti->mti_svname);
4075 mti->mti_flags |= LDD_F_PARAM;
4078 /* allocate temporary buffer, where class_get_next_param will
4079 make copy of a current parameter */
4080 OBD_ALLOC(buf, strlen(mti->mti_params) + 1);
4082 GOTO(out_up, rc = -ENOMEM);
4083 params = mti->mti_params;
4084 while (params != NULL) {
4085 rc = class_get_next_param(¶ms, buf);
4088 /* there is no next parameter, that is
4093 CDEBUG(D_MGS, "remaining string: '%s', param: '%s'\n",
4095 rc = mgs_write_log_param(env, mgs, fsdb, mti, buf);
4100 OBD_FREE(buf, strlen(mti->mti_params) + 1);
4103 mutex_unlock(&fsdb->fsdb_mutex);
4107 int mgs_erase_log(const struct lu_env *env, struct mgs_device *mgs, char *name)
4109 struct llog_ctxt *ctxt;
4112 ctxt = llog_get_context(mgs->mgs_obd, LLOG_CONFIG_ORIG_CTXT);
4114 CERROR("%s: MGS config context doesn't exist\n",
4115 mgs->mgs_obd->obd_name);
4118 rc = llog_erase(env, ctxt, NULL, name);
4119 /* llog may not exist */
4122 llog_ctxt_put(ctxt);
4126 CERROR("%s: failed to clear log %s: %d\n",
4127 mgs->mgs_obd->obd_name, name, rc);
4132 /* erase all logs for the given fs */
4133 int mgs_erase_logs(const struct lu_env *env, struct mgs_device *mgs,
4136 struct list_head log_list;
4137 struct mgs_direntry *dirent, *n;
4138 char barrier_name[20] = {};
4141 int rc, len = strlen(fsname);
4144 mutex_lock(&mgs->mgs_mutex);
4146 /* Find all the logs in the CONFIGS directory */
4147 rc = class_dentry_readdir(env, mgs, &log_list);
4149 mutex_unlock(&mgs->mgs_mutex);
4153 if (list_empty(&log_list)) {
4154 mutex_unlock(&mgs->mgs_mutex);
4158 snprintf(barrier_name, sizeof(barrier_name) - 1, "%s-%s",
4159 fsname, BARRIER_FILENAME);
4160 /* Delete the barrier fsdb */
4161 mgs_remove_fsdb_by_name(mgs, barrier_name);
4162 /* Delete the fs db */
4163 mgs_remove_fsdb_by_name(mgs, fsname);
4164 mutex_unlock(&mgs->mgs_mutex);
4166 list_for_each_entry_safe(dirent, n, &log_list, mde_list) {
4167 list_del_init(&dirent->mde_list);
4168 suffix = strrchr(dirent->mde_name, '-');
4169 if (suffix != NULL) {
4170 if ((len == suffix - dirent->mde_name) &&
4171 (strncmp(fsname, dirent->mde_name, len) == 0)) {
4172 CDEBUG(D_MGS, "Removing log %s\n",
4174 mgs_erase_log(env, mgs, dirent->mde_name);
4178 mgs_direntry_free(dirent);
4187 /* list all logs for the given fs */
4188 int mgs_list_logs(const struct lu_env *env, struct mgs_device *mgs,
4189 struct obd_ioctl_data *data)
4191 struct list_head log_list;
4192 struct mgs_direntry *dirent, *n;
4198 /* Find all the logs in the CONFIGS directory */
4199 rc = class_dentry_readdir(env, mgs, &log_list);
4203 out = data->ioc_bulk;
4204 remains = data->ioc_inllen1;
4205 list_for_each_entry_safe(dirent, n, &log_list, mde_list) {
4206 list_del_init(&dirent->mde_list);
4207 suffix = strrchr(dirent->mde_name, '-');
4208 if (suffix != NULL) {
4209 l = snprintf(out, remains, "config_log: %s\n",
4214 mgs_direntry_free(dirent);
4221 struct mgs_lcfg_fork_data {
4222 struct lustre_cfg_bufs mlfd_bufs;
4223 struct mgs_device *mlfd_mgs;
4224 struct llog_handle *mlfd_llh;
4225 const char *mlfd_oldname;
4226 const char *mlfd_newname;
4230 static bool contain_valid_fsname(char *buf, const char *fsname,
4231 int buflen, int namelen)
4233 if (buflen < namelen)
4236 if (memcmp(buf, fsname, namelen) != 0)
4239 if (buf[namelen] != '\0' && buf[namelen] != '-')
4245 static int mgs_lcfg_fork_handler(const struct lu_env *env,
4246 struct llog_handle *o_llh,
4247 struct llog_rec_hdr *o_rec, void *data)
4249 struct mgs_lcfg_fork_data *mlfd = data;
4250 struct lustre_cfg_bufs *n_bufs = &mlfd->mlfd_bufs;
4251 struct lustre_cfg *o_lcfg = (struct lustre_cfg *)(o_rec + 1);
4252 struct llog_cfg_rec *lcr;
4254 char *n_buf = mlfd->mlfd_data;
4256 int o_namelen = strlen(mlfd->mlfd_oldname);
4257 int n_namelen = strlen(mlfd->mlfd_newname);
4258 int diff = n_namelen - o_namelen;
4259 __u32 cmd = o_lcfg->lcfg_command;
4260 __u32 cnt = o_lcfg->lcfg_bufcount;
4266 o_buf = lustre_cfg_buf(o_lcfg, 0);
4267 o_buflen = o_lcfg->lcfg_buflens[0];
4268 if (contain_valid_fsname(o_buf, mlfd->mlfd_oldname, o_buflen,
4270 memcpy(n_buf, mlfd->mlfd_newname, n_namelen);
4271 memcpy(n_buf + n_namelen, o_buf + o_namelen,
4272 o_buflen - o_namelen);
4273 lustre_cfg_bufs_reset(n_bufs, n_buf);
4274 n_buf += cfs_size_round(o_buflen + diff);
4276 lustre_cfg_bufs_reset(n_bufs, o_buflen != 0 ? o_buf : NULL);
4281 struct cfg_marker *o_marker;
4282 struct cfg_marker *n_marker;
4286 CDEBUG(D_MGS, "Unknown cfg marker entry with %d "
4291 /* buf[1] is marker */
4292 o_buf = lustre_cfg_buf(o_lcfg, 1);
4293 o_buflen = o_lcfg->lcfg_buflens[1];
4294 o_marker = (struct cfg_marker *)o_buf;
4295 if (!contain_valid_fsname(o_marker->cm_tgtname,
4297 sizeof(o_marker->cm_tgtname),
4299 lustre_cfg_bufs_set(n_bufs, 1, o_marker,
4304 n_marker = (struct cfg_marker *)n_buf;
4305 *n_marker = *o_marker;
4306 memcpy(n_marker->cm_tgtname, mlfd->mlfd_newname, n_namelen);
4307 tgt_namelen = strlen(o_marker->cm_tgtname);
4308 if (tgt_namelen > o_namelen)
4309 memcpy(n_marker->cm_tgtname + n_namelen,
4310 o_marker->cm_tgtname + o_namelen,
4311 tgt_namelen - o_namelen);
4312 n_marker->cm_tgtname[tgt_namelen + diff] = '\0';
4313 lustre_cfg_bufs_set(n_bufs, 1, n_marker, sizeof(*n_marker));
4317 case LCFG_SET_PARAM: {
4318 for (i = 1; i < cnt; i++)
4319 /* buf[i] is the param value, reuse it directly */
4320 lustre_cfg_bufs_set(n_bufs, i,
4321 lustre_cfg_buf(o_lcfg, i),
4322 o_lcfg->lcfg_buflens[i]);
4328 case LCFG_POOL_DEL: {
4329 if (cnt < 3 || cnt > 4) {
4330 CDEBUG(D_MGS, "Unknown cfg pool (%x) entry with %d "
4331 "buffers\n", cmd, cnt);
4335 /* buf[1] is fsname */
4336 o_buf = lustre_cfg_buf(o_lcfg, 1);
4337 o_buflen = o_lcfg->lcfg_buflens[1];
4338 memcpy(n_buf, mlfd->mlfd_newname, n_namelen);
4339 memcpy(n_buf + n_namelen, o_buf + o_namelen,
4340 o_buflen - o_namelen);
4341 lustre_cfg_bufs_set(n_bufs, 1, n_buf, o_buflen + diff);
4342 n_buf += cfs_size_round(o_buflen + diff);
4344 /* buf[2] is the pool name, reuse it directly */
4345 lustre_cfg_bufs_set(n_bufs, 2, lustre_cfg_buf(o_lcfg, 2),
4346 o_lcfg->lcfg_buflens[2]);
4351 /* buf[3] is ostname */
4352 o_buf = lustre_cfg_buf(o_lcfg, 3);
4353 o_buflen = o_lcfg->lcfg_buflens[3];
4354 memcpy(n_buf, mlfd->mlfd_newname, n_namelen);
4355 memcpy(n_buf + n_namelen, o_buf + o_namelen,
4356 o_buflen - o_namelen);
4357 lustre_cfg_bufs_set(n_bufs, 3, n_buf, o_buflen + diff);
4362 o_buflen = o_lcfg->lcfg_buflens[1];
4363 if (o_buflen == sizeof(struct lov_desc) ||
4364 o_buflen == sizeof(struct lmv_desc)) {
4370 o_buf = lustre_cfg_buf(o_lcfg, 1);
4371 if (o_buflen == sizeof(struct lov_desc)) {
4372 struct lov_desc *o_desc =
4373 (struct lov_desc *)o_buf;
4374 struct lov_desc *n_desc =
4375 (struct lov_desc *)n_buf;
4378 o_uuid = o_desc->ld_uuid.uuid;
4379 n_uuid = n_desc->ld_uuid.uuid;
4380 uuid_len = sizeof(o_desc->ld_uuid.uuid);
4382 struct lmv_desc *o_desc =
4383 (struct lmv_desc *)o_buf;
4384 struct lmv_desc *n_desc =
4385 (struct lmv_desc *)n_buf;
4388 o_uuid = o_desc->ld_uuid.uuid;
4389 n_uuid = n_desc->ld_uuid.uuid;
4390 uuid_len = sizeof(o_desc->ld_uuid.uuid);
4393 if (unlikely(!contain_valid_fsname(o_uuid,
4394 mlfd->mlfd_oldname, uuid_len,
4396 lustre_cfg_bufs_set(n_bufs, 1, o_buf,
4401 memcpy(n_uuid, mlfd->mlfd_newname, n_namelen);
4402 uuid_len = strlen(o_uuid);
4403 if (uuid_len > o_namelen)
4404 memcpy(n_uuid + n_namelen,
4406 uuid_len - o_namelen);
4407 n_uuid[uuid_len + diff] = '\0';
4408 lustre_cfg_bufs_set(n_bufs, 1, n_buf, o_buflen);
4410 } /* else case fall through */
4411 } /* else case fall through */
4414 for (i = 1; i < cnt; i++) {
4415 o_buflen = o_lcfg->lcfg_buflens[i];
4419 o_buf = lustre_cfg_buf(o_lcfg, i);
4420 if (!contain_valid_fsname(o_buf, mlfd->mlfd_oldname,
4421 o_buflen, o_namelen)) {
4422 lustre_cfg_bufs_set(n_bufs, i, o_buf, o_buflen);
4426 memcpy(n_buf, mlfd->mlfd_newname, n_namelen);
4427 if (o_buflen == o_namelen) {
4428 lustre_cfg_bufs_set(n_bufs, i, n_buf,
4430 n_buf += cfs_size_round(n_namelen);
4434 memcpy(n_buf + n_namelen, o_buf + o_namelen,
4435 o_buflen - o_namelen);
4436 lustre_cfg_bufs_set(n_bufs, i, n_buf, o_buflen + diff);
4437 n_buf += cfs_size_round(o_buflen + diff);
4443 lcr = lustre_cfg_rec_new(cmd, n_bufs);
4447 lcr->lcr_cfg = *o_lcfg;
4448 rc = llog_write(env, mlfd->mlfd_llh, &lcr->lcr_hdr, LLOG_NEXT_IDX);
4449 lustre_cfg_rec_free(lcr);
4454 static int mgs_lcfg_fork_one(const struct lu_env *env, struct mgs_device *mgs,
4455 struct mgs_direntry *mde, const char *oldname,
4456 const char *newname)
4458 struct llog_handle *old_llh = NULL;
4459 struct llog_handle *new_llh = NULL;
4460 struct llog_ctxt *ctxt = NULL;
4461 struct mgs_lcfg_fork_data *mlfd = NULL;
4462 char *name_buf = NULL;
4464 int old_namelen = strlen(oldname);
4465 int new_namelen = strlen(newname);
4469 name_buflen = mde->mde_len + new_namelen - old_namelen;
4470 OBD_ALLOC(name_buf, name_buflen);
4474 memcpy(name_buf, newname, new_namelen);
4475 memcpy(name_buf + new_namelen, mde->mde_name + old_namelen,
4476 mde->mde_len - old_namelen);
4478 CDEBUG(D_MGS, "Fork the config-log from %s to %s\n",
4479 mde->mde_name, name_buf);
4481 ctxt = llog_get_context(mgs->mgs_obd, LLOG_CONFIG_ORIG_CTXT);
4484 rc = llog_open_create(env, ctxt, &new_llh, NULL, name_buf);
4488 rc = llog_init_handle(env, new_llh, LLOG_F_IS_PLAIN, NULL);
4492 if (unlikely(mgs_log_is_empty(env, mgs, mde->mde_name)))
4495 rc = llog_open(env, ctxt, &old_llh, NULL, mde->mde_name,
4500 rc = llog_init_handle(env, old_llh, LLOG_F_IS_PLAIN, NULL);
4504 new_llh->lgh_hdr->llh_tgtuuid = old_llh->lgh_hdr->llh_tgtuuid;
4506 OBD_ALLOC(mlfd, LLOG_MIN_CHUNK_SIZE);
4508 GOTO(out, rc = -ENOMEM);
4510 mlfd->mlfd_mgs = mgs;
4511 mlfd->mlfd_llh = new_llh;
4512 mlfd->mlfd_oldname = oldname;
4513 mlfd->mlfd_newname = newname;
4515 rc = llog_process(env, old_llh, mgs_lcfg_fork_handler, mlfd, NULL);
4516 OBD_FREE(mlfd, LLOG_MIN_CHUNK_SIZE);
4522 llog_close(env, old_llh);
4524 llog_close(env, new_llh);
4526 OBD_FREE(name_buf, name_buflen);
4528 llog_ctxt_put(ctxt);
4533 int mgs_lcfg_fork(const struct lu_env *env, struct mgs_device *mgs,
4534 const char *oldname, const char *newname)
4536 struct list_head log_list;
4537 struct mgs_direntry *dirent, *n;
4538 int olen = strlen(oldname);
4539 int nlen = strlen(newname);
4544 if (unlikely(!oldname || oldname[0] == '\0' ||
4545 !newname || newname[0] == '\0'))
4548 if (strcmp(oldname, newname) == 0)
4551 /* lock it to prevent fork/erase/register in parallel. */
4552 mutex_lock(&mgs->mgs_mutex);
4554 rc = class_dentry_readdir(env, mgs, &log_list);
4556 mutex_unlock(&mgs->mgs_mutex);
4560 if (list_empty(&log_list)) {
4561 mutex_unlock(&mgs->mgs_mutex);
4565 list_for_each_entry_safe(dirent, n, &log_list, mde_list) {
4568 ptr = strrchr(dirent->mde_name, '-');
4570 int tlen = ptr - dirent->mde_name;
4573 strncmp(newname, dirent->mde_name, tlen) == 0)
4574 GOTO(out, rc = -EEXIST);
4577 strncmp(oldname, dirent->mde_name, tlen) == 0)
4581 list_del_init(&dirent->mde_list);
4582 mgs_direntry_free(dirent);
4585 if (list_empty(&log_list)) {
4586 mutex_unlock(&mgs->mgs_mutex);
4590 list_for_each_entry(dirent, &log_list, mde_list) {
4591 rc = mgs_lcfg_fork_one(env, mgs, dirent, oldname, newname);
4599 mutex_unlock(&mgs->mgs_mutex);
4601 list_for_each_entry_safe(dirent, n, &log_list, mde_list) {
4602 list_del_init(&dirent->mde_list);
4603 mgs_direntry_free(dirent);
4606 if (rc && count > 0)
4607 mgs_erase_logs(env, mgs, newname);
4612 int mgs_lcfg_erase(const struct lu_env *env, struct mgs_device *mgs,
4618 if (unlikely(!fsname || fsname[0] == '\0'))
4621 rc = mgs_erase_logs(env, mgs, fsname);
4626 static int mgs_xattr_del(const struct lu_env *env, struct dt_object *obj)
4628 struct dt_device *dev;
4629 struct thandle *th = NULL;
4634 dev = container_of0(obj->do_lu.lo_dev, struct dt_device, dd_lu_dev);
4635 th = dt_trans_create(env, dev);
4637 RETURN(PTR_ERR(th));
4639 rc = dt_declare_xattr_del(env, obj, XATTR_TARGET_RENAME, th);
4643 rc = dt_trans_start_local(env, dev, th);
4647 dt_write_lock(env, obj, 0);
4648 rc = dt_xattr_del(env, obj, XATTR_TARGET_RENAME, th);
4653 dt_write_unlock(env, obj);
4656 dt_trans_stop(env, dev, th);
4661 int mgs_lcfg_rename(const struct lu_env *env, struct mgs_device *mgs)
4663 struct list_head log_list;
4664 struct mgs_direntry *dirent, *n;
4666 struct lu_buf buf = {
4668 .lb_len = sizeof(fsname)
4674 rc = class_dentry_readdir(env, mgs, &log_list);
4678 if (list_empty(&log_list))
4681 list_for_each_entry_safe(dirent, n, &log_list, mde_list) {
4682 struct dt_object *o = NULL;
4687 list_del_init(&dirent->mde_list);
4688 ptr = strrchr(dirent->mde_name, '-');
4692 len = ptr - dirent->mde_name;
4693 if (unlikely(len >= sizeof(oldname))) {
4694 CDEBUG(D_MGS, "Skip invalid configuration file %s\n",
4699 o = local_file_find(env, mgs->mgs_los, mgs->mgs_configs_dir,
4703 CDEBUG(D_MGS, "Fail to locate file %s: rc = %d\n",
4704 dirent->mde_name, rc);
4708 rc = dt_xattr_get(env, o, &buf, XATTR_TARGET_RENAME);
4714 "Fail to get EA for %s: rc = %d\n",
4715 dirent->mde_name, rc);
4719 if (unlikely(rc == len &&
4720 memcmp(fsname, dirent->mde_name, len) == 0)) {
4721 /* The new fsname is the same as the old one. */
4722 rc = mgs_xattr_del(env, o);
4726 memcpy(oldname, dirent->mde_name, len);
4727 oldname[len] = '\0';
4729 rc = mgs_lcfg_fork_one(env, mgs, dirent, oldname, fsname);
4730 if (rc && rc != -EEXIST) {
4731 CDEBUG(D_MGS, "Fail to fork %s: rc = %d\n",
4732 dirent->mde_name, rc);
4736 rc = mgs_erase_log(env, mgs, dirent->mde_name);
4738 CDEBUG(D_MGS, "Fail to erase old %s: rc = %d\n",
4739 dirent->mde_name, rc);
4740 /* keep it there if failed to remove it. */
4745 if (o && !IS_ERR(o))
4746 lu_object_put(env, &o->do_lu);
4748 mgs_direntry_free(dirent);
4753 list_for_each_entry_safe(dirent, n, &log_list, mde_list) {
4754 list_del_init(&dirent->mde_list);
4755 mgs_direntry_free(dirent);
4761 /* Setup _mgs fsdb and log
4763 int mgs__mgs_fsdb_setup(const struct lu_env *env, struct mgs_device *mgs)
4765 struct fs_db *fsdb = NULL;
4769 rc = mgs_find_or_make_fsdb(env, mgs, MGSSELF_NAME, &fsdb);
4771 mgs_put_fsdb(mgs, fsdb);
4776 /* Setup params fsdb and log
4778 int mgs_params_fsdb_setup(const struct lu_env *env, struct mgs_device *mgs)
4780 struct fs_db *fsdb = NULL;
4781 struct llog_handle *params_llh = NULL;
4785 rc = mgs_find_or_make_fsdb(env, mgs, PARAMS_FILENAME, &fsdb);
4787 mutex_lock(&fsdb->fsdb_mutex);
4788 rc = record_start_log(env, mgs, ¶ms_llh, PARAMS_FILENAME);
4790 rc = record_end_log(env, ¶ms_llh);
4791 mutex_unlock(&fsdb->fsdb_mutex);
4792 mgs_put_fsdb(mgs, fsdb);
4798 /* Cleanup params fsdb and log
4800 int mgs_params_fsdb_cleanup(const struct lu_env *env, struct mgs_device *mgs)
4804 rc = mgs_erase_logs(env, mgs, PARAMS_FILENAME);
4805 return rc == -ENOENT ? 0 : rc;
4809 * Fill in the mgs_target_info based on data devname and param provide.
4811 * @env thread context
4813 * @mti mgs target info. We want to set this based other paramters
4814 * passed to this function. Once setup we write it to the config
4816 * @devname optional OBD device name
4817 * @param string that contains both what tunable to set and the value to
4820 * RETURN 0 for success
4821 * negative error number on failure
4823 static int mgs_set_conf_param(const struct lu_env *env, struct mgs_device *mgs,
4824 struct mgs_target_info *mti, const char *devname,
4827 struct fs_db *fsdb = NULL;
4832 /* lustre, lustre-mdtlov, lustre-client, lustre-MDT0000 */
4836 /* We have two possible cases here:
4838 * 1) the device name embedded in the param:
4839 * lustre-OST0000.osc.max_dirty_mb=32
4841 * 2) the file system name is embedded in
4842 * the param: lustre.sys.at.min=0
4844 len = strcspn(param, ".=");
4845 if (!len || param[len] == '=')
4848 if (len >= sizeof(mti->mti_svname))
4851 snprintf(mti->mti_svname, sizeof(mti->mti_svname),
4852 "%.*s", (int)len, param);
4855 if (strlcpy(mti->mti_svname, devname, sizeof(mti->mti_svname)) >=
4856 sizeof(mti->mti_svname))
4860 if (!strlen(mti->mti_svname)) {
4861 LCONSOLE_ERROR_MSG(0x14d, "No target specified: %s\n", param);
4865 dev_type = mgs_parse_devname(mti->mti_svname, mti->mti_fsname,
4866 &mti->mti_stripe_index);
4868 /* For this case we have an invalid obd device name */
4870 CDEBUG(D_MGS, "%s don't contain an index\n", mti->mti_svname);
4871 strlcpy(mti->mti_fsname, mti->mti_svname, MTI_NAME_MAXLEN);
4874 /* Not an obd device, assume devname is the fsname.
4875 * User might of only provided fsname and not obd device
4878 CDEBUG(D_MGS, "%s is seen as a file system name\n", mti->mti_svname);
4879 strlcpy(mti->mti_fsname, mti->mti_svname, MTI_NAME_MAXLEN);
4884 GOTO(out, rc = dev_type);
4886 /* param related to llite isn't allowed to set by OST or MDT */
4887 if (dev_type & LDD_F_SV_TYPE_OST ||
4888 dev_type & LDD_F_SV_TYPE_MDT) {
4889 /* param related to llite isn't allowed to set by OST
4892 if (!strncmp(param, PARAM_LLITE,
4893 sizeof(PARAM_LLITE) - 1))
4894 GOTO(out, rc = -EINVAL);
4896 /* Strip -osc or -mdc suffix from svname */
4897 if (server_make_name(dev_type, mti->mti_stripe_index,
4898 mti->mti_fsname, mti->mti_svname,
4899 sizeof(mti->mti_svname)))
4900 GOTO(out, rc = -EINVAL);
4905 if (strlcpy(mti->mti_params, param, sizeof(mti->mti_params)) >=
4906 sizeof(mti->mti_params))
4907 GOTO(out, rc = -E2BIG);
4909 CDEBUG(D_MGS, "set_conf_param fs='%s' device='%s' param='%s'\n",
4910 mti->mti_fsname, mti->mti_svname, mti->mti_params);
4912 rc = mgs_find_or_make_fsdb(env, mgs, mti->mti_fsname, &fsdb);
4916 if (!test_bit(FSDB_MGS_SELF, &fsdb->fsdb_flags) &&
4917 test_bit(FSDB_LOG_EMPTY, &fsdb->fsdb_flags)) {
4918 CERROR("No filesystem targets for %s. cfg_device from lctl "
4919 "is '%s'\n", mti->mti_fsname, mti->mti_svname);
4920 mgs_unlink_fsdb(mgs, fsdb);
4921 GOTO(out, rc = -EINVAL);
4925 * Revoke lock so everyone updates. Should be alright if
4926 * someone was already reading while we were updating the logs,
4927 * so we don't really need to hold the lock while we're
4930 mti->mti_flags = dev_type | LDD_F_PARAM;
4931 mutex_lock(&fsdb->fsdb_mutex);
4932 rc = mgs_write_log_param(env, mgs, fsdb, mti, mti->mti_params);
4933 mutex_unlock(&fsdb->fsdb_mutex);
4934 mgs_revoke_lock(mgs, fsdb, CONFIG_T_CONFIG);
4938 mgs_put_fsdb(mgs, fsdb);
4943 static int mgs_set_param2(const struct lu_env *env, struct mgs_device *mgs,
4944 struct mgs_target_info *mti, const char *param)
4946 struct fs_db *fsdb = NULL;
4951 if (strlcpy(mti->mti_params, param, sizeof(mti->mti_params)) >=
4952 sizeof(mti->mti_params))
4953 GOTO(out, rc = -E2BIG);
4955 /* obdname2fsname reports devname as an obd device */
4956 len = strcspn(param, ".=");
4957 if (len && param[len] != '=') {
4961 ptr = strchr(param, '.');
4963 len = strlen(param);
4966 if (len >= sizeof(mti->mti_svname))
4967 GOTO(out, rc = -E2BIG);
4969 snprintf(mti->mti_svname, sizeof(mti->mti_svname), "%.*s",
4972 obdname2fsname(mti->mti_svname, mti->mti_fsname,
4973 sizeof(mti->mti_fsname));
4975 snprintf(mti->mti_svname, sizeof(mti->mti_svname), "general");
4978 CDEBUG(D_MGS, "set_param2 fs='%s' device='%s' param='%s'\n",
4979 mti->mti_fsname, mti->mti_svname, mti->mti_params);
4981 /* The return value should be the device type i.e LDD_F_SV_TYPE_XXX.
4982 * A returned error tells us we don't have a target obd device.
4984 dev_type = server_name2index(mti->mti_svname, &mti->mti_stripe_index,
4989 /* the return value should be the device type i.e LDD_F_SV_TYPE_XXX.
4990 * Strip -osc or -mdc suffix from svname
4992 if ((dev_type & LDD_F_SV_TYPE_OST || dev_type & LDD_F_SV_TYPE_MDT) &&
4993 server_make_name(dev_type, mti->mti_stripe_index,
4994 mti->mti_fsname, mti->mti_svname,
4995 sizeof(mti->mti_svname)))
4996 GOTO(out, rc = -EINVAL);
4998 rc = mgs_find_or_make_fsdb(env, mgs, PARAMS_FILENAME, &fsdb);
5002 * Revoke lock so everyone updates. Should be alright if
5003 * someone was already reading while we were updating the logs,
5004 * so we don't really need to hold the lock while we're
5007 mti->mti_flags = dev_type | LDD_F_PARAM2;
5008 mutex_lock(&fsdb->fsdb_mutex);
5009 rc = mgs_write_log_param2(env, mgs, fsdb, mti, mti->mti_params);
5010 mutex_unlock(&fsdb->fsdb_mutex);
5011 mgs_revoke_lock(mgs, fsdb, CONFIG_T_PARAMS);
5012 mgs_put_fsdb(mgs, fsdb);
5017 /* Set a permanent (config log) param for a target or fs
5019 * @lcfg buf0 may contain the device (testfs-MDT0000) name
5020 * buf1 contains the single parameter
5022 int mgs_set_param(const struct lu_env *env, struct mgs_device *mgs,
5023 struct lustre_cfg *lcfg)
5025 const char *param = lustre_cfg_string(lcfg, 1);
5026 struct mgs_target_info *mti;
5029 /* Create a fake mti to hold everything */
5034 print_lustre_cfg(lcfg);
5036 if (lcfg->lcfg_command == LCFG_PARAM) {
5037 /* For the case of lctl conf_param devname can be
5038 * lustre, lustre-mdtlov, lustre-client, lustre-MDT0000
5040 const char *devname = lustre_cfg_string(lcfg, 0);
5042 rc = mgs_set_conf_param(env, mgs, mti, devname, param);
5044 /* In the case of lctl set_param -P lcfg[0] will always
5045 * be 'general'. At least for now.
5047 rc = mgs_set_param2(env, mgs, mti, param);
5055 static int mgs_write_log_pool(const struct lu_env *env,
5056 struct mgs_device *mgs, char *logname,
5057 struct fs_db *fsdb, char *tgtname,
5058 enum lcfg_command_type cmd,
5059 char *fsname, char *poolname,
5060 char *ostname, char *comment)
5062 struct llog_handle *llh = NULL;
5065 rc = record_start_log(env, mgs, &llh, logname);
5068 rc = record_marker(env, llh, fsdb, CM_START, tgtname, comment);
5071 rc = record_base(env, llh, tgtname, 0, cmd,
5072 fsname, poolname, ostname, NULL);
5075 rc = record_marker(env, llh, fsdb, CM_END, tgtname, comment);
5077 record_end_log(env, &llh);
5081 int mgs_nodemap_cmd(const struct lu_env *env, struct mgs_device *mgs,
5082 enum lcfg_command_type cmd, const char *nodemap_name,
5093 case LCFG_NODEMAP_ADD:
5094 rc = nodemap_add(nodemap_name);
5096 case LCFG_NODEMAP_DEL:
5097 rc = nodemap_del(nodemap_name);
5099 case LCFG_NODEMAP_ADD_RANGE:
5100 rc = nodemap_parse_range(param, nid);
5103 rc = nodemap_add_range(nodemap_name, nid);
5105 case LCFG_NODEMAP_DEL_RANGE:
5106 rc = nodemap_parse_range(param, nid);
5109 rc = nodemap_del_range(nodemap_name, nid);
5111 case LCFG_NODEMAP_ADMIN:
5112 bool_switch = simple_strtoul(param, NULL, 10);
5113 rc = nodemap_set_allow_root(nodemap_name, bool_switch);
5115 case LCFG_NODEMAP_DENY_UNKNOWN:
5116 bool_switch = simple_strtoul(param, NULL, 10);
5117 rc = nodemap_set_deny_unknown(nodemap_name, bool_switch);
5119 case LCFG_NODEMAP_MAP_MODE:
5120 if (strcmp("both", param) == 0)
5121 rc = nodemap_set_mapping_mode(nodemap_name,
5123 else if (strcmp("uid_only", param) == 0)
5124 rc = nodemap_set_mapping_mode(nodemap_name,
5125 NODEMAP_MAP_UID_ONLY);
5126 else if (strcmp("gid_only", param) == 0)
5127 rc = nodemap_set_mapping_mode(nodemap_name,
5128 NODEMAP_MAP_GID_ONLY);
5132 case LCFG_NODEMAP_TRUSTED:
5133 bool_switch = simple_strtoul(param, NULL, 10);
5134 rc = nodemap_set_trust_client_ids(nodemap_name, bool_switch);
5136 case LCFG_NODEMAP_SQUASH_UID:
5137 int_id = simple_strtoul(param, NULL, 10);
5138 rc = nodemap_set_squash_uid(nodemap_name, int_id);
5140 case LCFG_NODEMAP_SQUASH_GID:
5141 int_id = simple_strtoul(param, NULL, 10);
5142 rc = nodemap_set_squash_gid(nodemap_name, int_id);
5144 case LCFG_NODEMAP_ADD_UIDMAP:
5145 case LCFG_NODEMAP_ADD_GIDMAP:
5146 rc = nodemap_parse_idmap(param, idmap);
5149 if (cmd == LCFG_NODEMAP_ADD_UIDMAP)
5150 rc = nodemap_add_idmap(nodemap_name, NODEMAP_UID,
5153 rc = nodemap_add_idmap(nodemap_name, NODEMAP_GID,
5156 case LCFG_NODEMAP_DEL_UIDMAP:
5157 case LCFG_NODEMAP_DEL_GIDMAP:
5158 rc = nodemap_parse_idmap(param, idmap);
5161 if (cmd == LCFG_NODEMAP_DEL_UIDMAP)
5162 rc = nodemap_del_idmap(nodemap_name, NODEMAP_UID,
5165 rc = nodemap_del_idmap(nodemap_name, NODEMAP_GID,
5168 case LCFG_NODEMAP_SET_FILESET:
5169 rc = nodemap_set_fileset(nodemap_name, param);
5178 int mgs_pool_cmd(const struct lu_env *env, struct mgs_device *mgs,
5179 enum lcfg_command_type cmd, char *fsname,
5180 char *poolname, char *ostname)
5185 char *label = NULL, *canceled_label = NULL;
5187 struct mgs_target_info *mti = NULL;
5188 bool checked = false;
5189 bool locked = false;
5194 rc = mgs_find_or_make_fsdb(env, mgs, fsname, &fsdb);
5196 CERROR("Can't get db for %s\n", fsname);
5199 if (test_bit(FSDB_LOG_EMPTY, &fsdb->fsdb_flags)) {
5200 CERROR("%s is not defined\n", fsname);
5202 GOTO(out_fsdb, rc = -EINVAL);
5205 label_sz = 10 + strlen(fsname) + strlen(poolname);
5207 /* check if ostname match fsname */
5208 if (ostname != NULL) {
5211 ptr = strrchr(ostname, '-');
5212 if ((ptr == NULL) ||
5213 (strncmp(fsname, ostname, ptr-ostname) != 0))
5215 label_sz += strlen(ostname);
5218 OBD_ALLOC(label, label_sz);
5220 GOTO(out_fsdb, rc = -ENOMEM);
5225 "new %s.%s", fsname, poolname);
5229 "add %s.%s.%s", fsname, poolname, ostname);
5232 OBD_ALLOC(canceled_label, label_sz);
5233 if (canceled_label == NULL)
5234 GOTO(out_label, rc = -ENOMEM);
5236 "rem %s.%s.%s", fsname, poolname, ostname);
5237 sprintf(canceled_label,
5238 "add %s.%s.%s", fsname, poolname, ostname);
5241 OBD_ALLOC(canceled_label, label_sz);
5242 if (canceled_label == NULL)
5243 GOTO(out_label, rc = -ENOMEM);
5245 "del %s.%s", fsname, poolname);
5246 sprintf(canceled_label,
5247 "new %s.%s", fsname, poolname);
5255 GOTO(out_cancel, rc = -ENOMEM);
5256 strncpy(mti->mti_svname, "lov pool", sizeof(mti->mti_svname));
5258 mutex_lock(&fsdb->fsdb_mutex);
5260 /* write pool def to all MDT logs */
5261 for (i = 0; i < INDEX_MAP_SIZE * 8; i++) {
5262 if (test_bit(i, fsdb->fsdb_mdt_index_map)) {
5263 rc = name_create_mdt_and_lov(&logname, &lovname,
5268 if (!checked && (canceled_label == NULL)) {
5269 rc = mgs_check_marker(env, mgs, fsdb, mti,
5270 logname, lovname, label);
5272 name_destroy(&logname);
5273 name_destroy(&lovname);
5275 rc = (rc == LLOG_PROC_BREAK ?
5280 if (canceled_label != NULL)
5281 rc = mgs_modify(env, mgs, fsdb, mti, logname,
5282 lovname, canceled_label,
5286 rc = mgs_write_log_pool(env, mgs, logname,
5290 name_destroy(&logname);
5291 name_destroy(&lovname);
5297 rc = name_create(&logname, fsname, "-client");
5301 if (!checked && (canceled_label == NULL)) {
5302 rc = mgs_check_marker(env, mgs, fsdb, mti, logname,
5303 fsdb->fsdb_clilov, label);
5305 name_destroy(&logname);
5306 GOTO(out_mti, rc = (rc == LLOG_PROC_BREAK ?
5310 if (canceled_label != NULL) {
5311 rc = mgs_modify(env, mgs, fsdb, mti, logname,
5312 fsdb->fsdb_clilov, canceled_label, CM_SKIP);
5314 name_destroy(&logname);
5319 rc = mgs_write_log_pool(env, mgs, logname, fsdb, fsdb->fsdb_clilov,
5320 cmd, fsname, poolname, ostname, label);
5321 mutex_unlock(&fsdb->fsdb_mutex);
5323 name_destroy(&logname);
5324 /* request for update */
5325 mgs_revoke_lock(mgs, fsdb, CONFIG_T_CONFIG);
5331 mutex_unlock(&fsdb->fsdb_mutex);
5335 if (canceled_label != NULL)
5336 OBD_FREE(canceled_label, label_sz);
5338 OBD_FREE(label, label_sz);
5341 mgs_unlink_fsdb(mgs, fsdb);
5342 mgs_put_fsdb(mgs, fsdb);