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, 2016, 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 * \param[in] devname device name (ex. lustre-MDT0000)
1355 * \param[out] fsname file system name(optional)
1356 * \param[out] index device index(optional)
1360 static int mgs_parse_devname(char *devname, char *fsname, __u32 *index)
1365 /* Extract fsname */
1367 rc = server_name2fsname(devname, fsname, NULL);
1369 CDEBUG(D_MGS, "Device name %s without fsname\n",
1376 rc = server_name2index(devname, index, NULL);
1378 CDEBUG(D_MGS, "Device name %s with wrong index\n",
1387 /* This is only called during replace_nids */
1388 static int only_mgs_is_running(struct obd_device *mgs_obd)
1390 /* TDB: Is global variable with devices count exists? */
1391 int num_devices = get_devices_count();
1392 int num_exports = 0;
1393 struct obd_export *exp;
1395 spin_lock(&mgs_obd->obd_dev_lock);
1396 list_for_each_entry(exp, &mgs_obd->obd_exports, exp_obd_chain) {
1397 /* skip self export */
1398 if (exp == mgs_obd->obd_self_export)
1400 if (exp_connect_flags(exp) & OBD_CONNECT_MDS_MDS)
1405 CERROR("%s: node %s still connected during replace_nids "
1406 "connect_flags:%llx\n",
1408 libcfs_nid2str(exp->exp_nid_stats->nid),
1409 exp_connect_flags(exp));
1412 spin_unlock(&mgs_obd->obd_dev_lock);
1414 /* osd, MGS and MGC + self_export
1415 (wc -l /proc/fs/lustre/devices <= 2) && (non self exports == 0) */
1416 return (num_devices <= 3) && (num_exports == 0);
1419 static int name_create_mdt(char **logname, char *fsname, int i)
1423 sprintf(mdt_index, "-MDT%04x", i);
1424 return name_create(logname, fsname, mdt_index);
1428 * Replace nids for \a device to \a nids values
1430 * \param obd MGS obd device
1431 * \param devname nids need to be replaced for this device
1432 * (ex. lustre-OST0000)
1433 * \param nids nids list (ex. nid1,nid2,nid3)
1437 int mgs_replace_nids(const struct lu_env *env,
1438 struct mgs_device *mgs,
1439 char *devname, char *nids)
1441 /* Assume fsname is part of device name */
1442 char fsname[MTI_NAME_MAXLEN];
1446 struct fs_db *fsdb = NULL;
1449 struct obd_device *mgs_obd = mgs->mgs_obd;
1452 /* We can only change NIDs if no other nodes are connected */
1453 spin_lock(&mgs_obd->obd_dev_lock);
1454 conn_state = mgs_obd->obd_no_conn;
1455 mgs_obd->obd_no_conn = 1;
1456 spin_unlock(&mgs_obd->obd_dev_lock);
1458 /* We can not change nids if not only MGS is started */
1459 if (!only_mgs_is_running(mgs_obd)) {
1460 CERROR("Only MGS is allowed to be started\n");
1461 GOTO(out, rc = -EINPROGRESS);
1464 /* Get fsname and index*/
1465 rc = mgs_parse_devname(devname, fsname, &index);
1469 rc = mgs_find_or_make_fsdb(env, mgs, fsname, &fsdb);
1471 CERROR("%s: can't find fsdb: rc = %d\n", fsname, rc);
1475 /* Process client llogs */
1476 name_create(&logname, fsname, "-client");
1477 rc = mgs_replace_nids_log(env, mgs_obd, fsdb, logname, devname, nids);
1478 name_destroy(&logname);
1480 CERROR("%s: error while replacing NIDs for %s: rc = %d\n",
1481 fsname, devname, rc);
1485 /* Process MDT llogs */
1486 for (i = 0; i < INDEX_MAP_SIZE * 8; i++) {
1487 if (!test_bit(i, fsdb->fsdb_mdt_index_map))
1489 name_create_mdt(&logname, fsname, i);
1490 rc = mgs_replace_nids_log(env, mgs_obd, fsdb, logname, devname, nids);
1491 name_destroy(&logname);
1497 spin_lock(&mgs_obd->obd_dev_lock);
1498 mgs_obd->obd_no_conn = conn_state;
1499 spin_unlock(&mgs_obd->obd_dev_lock);
1502 mgs_put_fsdb(mgs, fsdb);
1507 static int record_lov_setup(const struct lu_env *env, struct llog_handle *llh,
1508 char *devname, struct lov_desc *desc)
1510 struct mgs_thread_info *mgi = mgs_env_info(env);
1511 struct llog_cfg_rec *lcr;
1514 lustre_cfg_bufs_reset(&mgi->mgi_bufs, devname);
1515 lustre_cfg_bufs_set(&mgi->mgi_bufs, 1, desc, sizeof(*desc));
1516 lcr = lustre_cfg_rec_new(LCFG_SETUP, &mgi->mgi_bufs);
1520 rc = llog_write(env, llh, &lcr->lcr_hdr, LLOG_NEXT_IDX);
1521 lustre_cfg_rec_free(lcr);
1525 static int record_lmv_setup(const struct lu_env *env, struct llog_handle *llh,
1526 char *devname, struct lmv_desc *desc)
1528 struct mgs_thread_info *mgi = mgs_env_info(env);
1529 struct llog_cfg_rec *lcr;
1532 lustre_cfg_bufs_reset(&mgi->mgi_bufs, devname);
1533 lustre_cfg_bufs_set(&mgi->mgi_bufs, 1, desc, sizeof(*desc));
1534 lcr = lustre_cfg_rec_new(LCFG_SETUP, &mgi->mgi_bufs);
1538 rc = llog_write(env, llh, &lcr->lcr_hdr, LLOG_NEXT_IDX);
1539 lustre_cfg_rec_free(lcr);
1543 static inline int record_mdc_add(const struct lu_env *env,
1544 struct llog_handle *llh,
1545 char *logname, char *mdcuuid,
1546 char *mdtuuid, char *index,
1549 return record_base(env,llh,logname,0,LCFG_ADD_MDC,
1550 mdtuuid,index,gen,mdcuuid);
1553 static inline int record_lov_add(const struct lu_env *env,
1554 struct llog_handle *llh,
1555 char *lov_name, char *ost_uuid,
1556 char *index, char *gen)
1558 return record_base(env, llh, lov_name, 0, LCFG_LOV_ADD_OBD,
1559 ost_uuid, index, gen, NULL);
1562 static inline int record_mount_opt(const struct lu_env *env,
1563 struct llog_handle *llh,
1564 char *profile, char *lov_name,
1567 return record_base(env, llh, NULL, 0, LCFG_MOUNTOPT,
1568 profile, lov_name, mdc_name, NULL);
1571 static int record_marker(const struct lu_env *env,
1572 struct llog_handle *llh,
1573 struct fs_db *fsdb, __u32 flags,
1574 char *tgtname, char *comment)
1576 struct mgs_thread_info *mgi = mgs_env_info(env);
1577 struct llog_cfg_rec *lcr;
1581 if (flags & CM_START)
1583 mgi->mgi_marker.cm_step = fsdb->fsdb_gen;
1584 mgi->mgi_marker.cm_flags = flags;
1585 mgi->mgi_marker.cm_vers = LUSTRE_VERSION_CODE;
1586 cplen = strlcpy(mgi->mgi_marker.cm_tgtname, tgtname,
1587 sizeof(mgi->mgi_marker.cm_tgtname));
1588 if (cplen >= sizeof(mgi->mgi_marker.cm_tgtname))
1590 cplen = strlcpy(mgi->mgi_marker.cm_comment, comment,
1591 sizeof(mgi->mgi_marker.cm_comment));
1592 if (cplen >= sizeof(mgi->mgi_marker.cm_comment))
1594 mgi->mgi_marker.cm_createtime = ktime_get_real_seconds();
1595 mgi->mgi_marker.cm_canceltime = 0;
1596 lustre_cfg_bufs_reset(&mgi->mgi_bufs, NULL);
1597 lustre_cfg_bufs_set(&mgi->mgi_bufs, 1, &mgi->mgi_marker,
1598 sizeof(mgi->mgi_marker));
1599 lcr = lustre_cfg_rec_new(LCFG_MARKER, &mgi->mgi_bufs);
1603 rc = llog_write(env, llh, &lcr->lcr_hdr, LLOG_NEXT_IDX);
1604 lustre_cfg_rec_free(lcr);
1608 static int record_start_log(const struct lu_env *env, struct mgs_device *mgs,
1609 struct llog_handle **llh, char *name)
1611 static struct obd_uuid cfg_uuid = { .uuid = "config_uuid" };
1612 struct llog_ctxt *ctxt;
1617 GOTO(out, rc = -EBUSY);
1619 ctxt = llog_get_context(mgs->mgs_obd, LLOG_CONFIG_ORIG_CTXT);
1621 GOTO(out, rc = -ENODEV);
1622 LASSERT(ctxt->loc_obd == mgs->mgs_obd);
1624 rc = llog_open_create(env, ctxt, llh, NULL, name);
1627 rc = llog_init_handle(env, *llh, LLOG_F_IS_PLAIN, &cfg_uuid);
1629 llog_close(env, *llh);
1631 llog_ctxt_put(ctxt);
1634 CERROR("%s: can't start log %s: rc = %d\n",
1635 mgs->mgs_obd->obd_name, name, rc);
1641 static int record_end_log(const struct lu_env *env, struct llog_handle **llh)
1645 rc = llog_close(env, *llh);
1651 /******************** config "macros" *********************/
1653 /* write an lcfg directly into a log (with markers) */
1654 static int mgs_write_log_direct(const struct lu_env *env,
1655 struct mgs_device *mgs, struct fs_db *fsdb,
1656 char *logname, struct llog_cfg_rec *lcr,
1657 char *devname, char *comment)
1659 struct llog_handle *llh = NULL;
1664 rc = record_start_log(env, mgs, &llh, logname);
1668 /* FIXME These should be a single journal transaction */
1669 rc = record_marker(env, llh, fsdb, CM_START, devname, comment);
1672 rc = llog_write(env, llh, &lcr->lcr_hdr, LLOG_NEXT_IDX);
1675 rc = record_marker(env, llh, fsdb, CM_END, devname, comment);
1679 record_end_log(env, &llh);
1683 /* write the lcfg in all logs for the given fs */
1684 static int mgs_write_log_direct_all(const struct lu_env *env,
1685 struct mgs_device *mgs,
1687 struct mgs_target_info *mti,
1688 struct llog_cfg_rec *lcr, char *devname,
1689 char *comment, int server_only)
1691 struct list_head log_list;
1692 struct mgs_direntry *dirent, *n;
1693 char *fsname = mti->mti_fsname;
1694 int rc = 0, len = strlen(fsname);
1697 /* Find all the logs in the CONFIGS directory */
1698 rc = class_dentry_readdir(env, mgs, &log_list);
1702 /* Could use fsdb index maps instead of directory listing */
1703 list_for_each_entry_safe(dirent, n, &log_list, mde_list) {
1704 list_del_init(&dirent->mde_list);
1705 /* don't write to sptlrpc rule log */
1706 if (strstr(dirent->mde_name, "-sptlrpc") != NULL)
1709 /* caller wants write server logs only */
1710 if (server_only && strstr(dirent->mde_name, "-client") != NULL)
1713 if (strlen(dirent->mde_name) <= len ||
1714 strncmp(fsname, dirent->mde_name, len) != 0 ||
1715 dirent->mde_name[len] != '-')
1718 CDEBUG(D_MGS, "Changing log %s\n", dirent->mde_name);
1719 /* Erase any old settings of this same parameter */
1720 rc = mgs_modify(env, mgs, fsdb, mti, dirent->mde_name,
1721 devname, comment, CM_SKIP);
1723 CERROR("%s: Can't modify llog %s: rc = %d\n",
1724 mgs->mgs_obd->obd_name, dirent->mde_name, rc);
1727 /* Write the new one */
1728 rc = mgs_write_log_direct(env, mgs, fsdb, dirent->mde_name,
1729 lcr, devname, comment);
1731 CERROR("%s: writing log %s: rc = %d\n",
1732 mgs->mgs_obd->obd_name, dirent->mde_name, rc);
1734 mgs_direntry_free(dirent);
1740 static int mgs_write_log_osp_to_mdt(const struct lu_env *env,
1741 struct mgs_device *mgs,
1743 struct mgs_target_info *mti,
1744 int index, char *logname);
1745 static int mgs_write_log_osc_to_lov(const struct lu_env *env,
1746 struct mgs_device *mgs,
1748 struct mgs_target_info *mti,
1749 char *logname, char *suffix, char *lovname,
1750 enum lustre_sec_part sec_part, int flags);
1751 static int name_create_mdt_and_lov(char **logname, char **lovname,
1752 struct fs_db *fsdb, int i);
1754 static int add_param(char *params, char *key, char *val)
1756 char *start = params + strlen(params);
1757 char *end = params + sizeof(((struct mgs_target_info *)0)->mti_params);
1761 keylen = strlen(key);
1762 if (start + 1 + keylen + strlen(val) >= end) {
1763 CERROR("params are too long: %s %s%s\n",
1764 params, key != NULL ? key : "", val);
1768 sprintf(start, " %s%s", key != NULL ? key : "", val);
1773 * Walk through client config log record and convert the related records
1776 static int mgs_steal_client_llog_handler(const struct lu_env *env,
1777 struct llog_handle *llh,
1778 struct llog_rec_hdr *rec, void *data)
1780 struct mgs_device *mgs;
1781 struct obd_device *obd;
1782 struct mgs_target_info *mti, *tmti;
1784 int cfg_len = rec->lrh_len;
1785 char *cfg_buf = (char*) (rec + 1);
1786 struct lustre_cfg *lcfg;
1788 struct llog_handle *mdt_llh = NULL;
1789 static int got_an_osc_or_mdc = 0;
1790 /* 0: not found any osc/mdc;
1794 static int last_step = -1;
1799 mti = ((struct temp_comp*)data)->comp_mti;
1800 tmti = ((struct temp_comp*)data)->comp_tmti;
1801 fsdb = ((struct temp_comp*)data)->comp_fsdb;
1802 obd = ((struct temp_comp *)data)->comp_obd;
1803 mgs = lu2mgs_dev(obd->obd_lu_dev);
1806 if (rec->lrh_type != OBD_CFG_REC) {
1807 CERROR("unhandled lrh_type: %#x\n", rec->lrh_type);
1811 rc = lustre_cfg_sanity_check(cfg_buf, cfg_len);
1813 CERROR("Insane cfg\n");
1817 lcfg = (struct lustre_cfg *)cfg_buf;
1819 if (lcfg->lcfg_command == LCFG_MARKER) {
1820 struct cfg_marker *marker;
1821 marker = lustre_cfg_buf(lcfg, 1);
1822 if (!strncmp(marker->cm_comment, "add osc", 7) &&
1823 (marker->cm_flags & CM_START) &&
1824 !(marker->cm_flags & CM_SKIP)) {
1825 got_an_osc_or_mdc = 1;
1826 cplen = strlcpy(tmti->mti_svname, marker->cm_tgtname,
1827 sizeof(tmti->mti_svname));
1828 if (cplen >= sizeof(tmti->mti_svname))
1830 rc = record_start_log(env, mgs, &mdt_llh,
1834 rc = record_marker(env, mdt_llh, fsdb, CM_START,
1835 mti->mti_svname, "add osc(copied)");
1836 record_end_log(env, &mdt_llh);
1837 last_step = marker->cm_step;
1840 if (!strncmp(marker->cm_comment, "add osc", 7) &&
1841 (marker->cm_flags & CM_END) &&
1842 !(marker->cm_flags & CM_SKIP)) {
1843 LASSERT(last_step == marker->cm_step);
1845 got_an_osc_or_mdc = 0;
1846 memset(tmti, 0, sizeof(*tmti));
1847 rc = record_start_log(env, mgs, &mdt_llh,
1851 rc = record_marker(env, mdt_llh, fsdb, CM_END,
1852 mti->mti_svname, "add osc(copied)");
1853 record_end_log(env, &mdt_llh);
1856 if (!strncmp(marker->cm_comment, "add mdc", 7) &&
1857 (marker->cm_flags & CM_START) &&
1858 !(marker->cm_flags & CM_SKIP)) {
1859 got_an_osc_or_mdc = 2;
1860 last_step = marker->cm_step;
1861 memcpy(tmti->mti_svname, marker->cm_tgtname,
1862 strlen(marker->cm_tgtname));
1866 if (!strncmp(marker->cm_comment, "add mdc", 7) &&
1867 (marker->cm_flags & CM_END) &&
1868 !(marker->cm_flags & CM_SKIP)) {
1869 LASSERT(last_step == marker->cm_step);
1871 got_an_osc_or_mdc = 0;
1872 memset(tmti, 0, sizeof(*tmti));
1877 if (got_an_osc_or_mdc == 0 || last_step < 0)
1880 if (lcfg->lcfg_command == LCFG_ADD_UUID) {
1881 __u64 nodenid = lcfg->lcfg_nid;
1883 if (strlen(tmti->mti_uuid) == 0) {
1884 /* target uuid not set, this config record is before
1885 * LCFG_SETUP, this nid is one of target node nid.
1887 tmti->mti_nids[tmti->mti_nid_count] = nodenid;
1888 tmti->mti_nid_count++;
1890 char nidstr[LNET_NIDSTR_SIZE];
1892 /* failover node nid */
1893 libcfs_nid2str_r(nodenid, nidstr, sizeof(nidstr));
1894 rc = add_param(tmti->mti_params, PARAM_FAILNODE,
1901 if (lcfg->lcfg_command == LCFG_SETUP) {
1904 target = lustre_cfg_string(lcfg, 1);
1905 memcpy(tmti->mti_uuid, target, strlen(target));
1909 /* ignore client side sptlrpc_conf_log */
1910 if (lcfg->lcfg_command == LCFG_SPTLRPC_CONF)
1913 if (lcfg->lcfg_command == LCFG_ADD_MDC &&
1914 strstr(lustre_cfg_string(lcfg, 0), "-clilmv") != NULL) {
1917 if (sscanf(lustre_cfg_buf(lcfg, 2), "%d", &index) != 1)
1920 memcpy(tmti->mti_fsname, mti->mti_fsname,
1921 strlen(mti->mti_fsname));
1922 tmti->mti_stripe_index = index;
1924 rc = mgs_write_log_osp_to_mdt(env, mgs, fsdb, tmti,
1925 mti->mti_stripe_index,
1927 memset(tmti, 0, sizeof(*tmti));
1931 if (lcfg->lcfg_command == LCFG_LOV_ADD_OBD) {
1934 char *logname, *lovname;
1936 rc = name_create_mdt_and_lov(&logname, &lovname, fsdb,
1937 mti->mti_stripe_index);
1940 sprintf(mdt_index, "-MDT%04x", mti->mti_stripe_index);
1942 if (sscanf(lustre_cfg_buf(lcfg, 2), "%d", &index) != 1) {
1943 name_destroy(&logname);
1944 name_destroy(&lovname);
1948 tmti->mti_stripe_index = index;
1949 rc = mgs_write_log_osc_to_lov(env, mgs, fsdb, tmti, logname,
1952 name_destroy(&logname);
1953 name_destroy(&lovname);
1959 /* fsdb->fsdb_mutex is already held in mgs_write_log_target*/
1960 /* stealed from mgs_get_fsdb_from_llog*/
1961 static int mgs_steal_llog_for_mdt_from_client(const struct lu_env *env,
1962 struct mgs_device *mgs,
1964 struct temp_comp* comp)
1966 struct llog_handle *loghandle;
1967 struct mgs_target_info *tmti;
1968 struct llog_ctxt *ctxt;
1973 ctxt = llog_get_context(mgs->mgs_obd, LLOG_CONFIG_ORIG_CTXT);
1974 LASSERT(ctxt != NULL);
1976 OBD_ALLOC_PTR(tmti);
1978 GOTO(out_ctxt, rc = -ENOMEM);
1980 comp->comp_tmti = tmti;
1981 comp->comp_obd = mgs->mgs_obd;
1983 rc = llog_open(env, ctxt, &loghandle, NULL, client_name,
1991 rc = llog_init_handle(env, loghandle, LLOG_F_IS_PLAIN, NULL);
1993 GOTO(out_close, rc);
1995 rc = llog_process_or_fork(env, loghandle, mgs_steal_client_llog_handler,
1996 (void *)comp, NULL, false);
1997 CDEBUG(D_MGS, "steal llog re = %d\n", rc);
1999 llog_close(env, loghandle);
2003 llog_ctxt_put(ctxt);
2007 /* lmv is the second thing for client logs */
2008 /* copied from mgs_write_log_lov. Please refer to that. */
2009 static int mgs_write_log_lmv(const struct lu_env *env,
2010 struct mgs_device *mgs,
2012 struct mgs_target_info *mti,
2013 char *logname, char *lmvname)
2015 struct llog_handle *llh = NULL;
2016 struct lmv_desc *lmvdesc;
2021 CDEBUG(D_MGS, "Writing lmv(%s) log for %s\n", lmvname,logname);
2023 OBD_ALLOC_PTR(lmvdesc);
2024 if (lmvdesc == NULL)
2026 lmvdesc->ld_active_tgt_count = 0;
2027 lmvdesc->ld_tgt_count = 0;
2028 sprintf((char*)lmvdesc->ld_uuid.uuid, "%s_UUID", lmvname);
2029 uuid = (char *)lmvdesc->ld_uuid.uuid;
2031 rc = record_start_log(env, mgs, &llh, logname);
2034 rc = record_marker(env, llh, fsdb, CM_START, lmvname, "lmv setup");
2037 rc = record_attach(env, llh, lmvname, "lmv", uuid);
2040 rc = record_lmv_setup(env, llh, lmvname, lmvdesc);
2043 rc = record_marker(env, llh, fsdb, CM_END, lmvname, "lmv setup");
2047 record_end_log(env, &llh);
2049 OBD_FREE_PTR(lmvdesc);
2053 /* lov is the first thing in the mdt and client logs */
2054 static int mgs_write_log_lov(const struct lu_env *env, struct mgs_device *mgs,
2055 struct fs_db *fsdb, struct mgs_target_info *mti,
2056 char *logname, char *lovname)
2058 struct llog_handle *llh = NULL;
2059 struct lov_desc *lovdesc;
2064 CDEBUG(D_MGS, "Writing lov(%s) log for %s\n", lovname, logname);
2067 #01 L attach 0:lov_mdsA 1:lov 2:71ccb_lov_mdsA_19f961a9e1
2068 #02 L lov_setup 0:lov_mdsA 1:(struct lov_desc)
2069 uuid=lov1_UUID, stripe count=1, size=1048576, offset=0, pattern=0
2072 /* FIXME just make lov_setup accept empty desc (put uuid in buf 2) */
2073 OBD_ALLOC_PTR(lovdesc);
2074 if (lovdesc == NULL)
2076 lovdesc->ld_magic = LOV_DESC_MAGIC;
2077 lovdesc->ld_tgt_count = 0;
2078 /* Defaults. Can be changed later by lcfg config_param */
2079 lovdesc->ld_default_stripe_count = 1;
2080 lovdesc->ld_pattern = LOV_PATTERN_RAID0;
2081 lovdesc->ld_default_stripe_size = LOV_DESC_STRIPE_SIZE_DEFAULT;
2082 lovdesc->ld_default_stripe_offset = -1;
2083 lovdesc->ld_qos_maxage = LOV_DESC_QOS_MAXAGE_DEFAULT;
2084 sprintf((char*)lovdesc->ld_uuid.uuid, "%s_UUID", lovname);
2085 /* can these be the same? */
2086 uuid = (char *)lovdesc->ld_uuid.uuid;
2088 /* This should always be the first entry in a log.
2089 rc = mgs_clear_log(obd, logname); */
2090 rc = record_start_log(env, mgs, &llh, logname);
2093 /* FIXME these should be a single journal transaction */
2094 rc = record_marker(env, llh, fsdb, CM_START, lovname, "lov setup");
2097 rc = record_attach(env, llh, lovname, "lov", uuid);
2100 rc = record_lov_setup(env, llh, lovname, lovdesc);
2103 rc = record_marker(env, llh, fsdb, CM_END, lovname, "lov setup");
2108 record_end_log(env, &llh);
2110 OBD_FREE_PTR(lovdesc);
2114 /* add failnids to open log */
2115 static int mgs_write_log_failnids(const struct lu_env *env,
2116 struct mgs_target_info *mti,
2117 struct llog_handle *llh,
2120 char *failnodeuuid = NULL;
2121 char *ptr = mti->mti_params;
2126 #03 L add_uuid nid=uml1@tcp(0x20000c0a80201) nal=90 0: 1:uml1_UUID
2127 #04 L add_uuid nid=1@elan(0x1000000000001) nal=90 0: 1:uml1_UUID
2128 #05 L setup 0:OSC_uml1_ost1_mdsA 1:ost1_UUID 2:uml1_UUID
2129 #06 L add_uuid nid=uml2@tcp(0x20000c0a80202) nal=90 0: 1:uml2_UUID
2130 #0x L add_uuid nid=2@elan(0x1000000000002) nal=90 0: 1:uml2_UUID
2131 #07 L add_conn 0:OSC_uml1_ost1_mdsA 1:uml2_UUID
2135 * Pull failnid info out of params string, which may contain something
2136 * like "<nid1>,<nid2>:<nid3>,<nid4>". class_parse_nid() does not
2137 * complain about abnormal inputs like ",:<nid1>", "<nid1>:,<nid2>",
2138 * etc. However, convert_hostnames() should have caught those.
2140 while (class_find_param(ptr, PARAM_FAILNODE, &ptr) == 0) {
2141 while (class_parse_nid(ptr, &nid, &ptr) == 0) {
2142 char nidstr[LNET_NIDSTR_SIZE];
2144 if (failnodeuuid == NULL) {
2145 /* We don't know the failover node name,
2146 * so just use the first nid as the uuid */
2147 libcfs_nid2str_r(nid, nidstr, sizeof(nidstr));
2148 rc = name_create(&failnodeuuid, nidstr, "");
2152 CDEBUG(D_MGS, "add nid %s for failover uuid %s, "
2154 libcfs_nid2str_r(nid, nidstr, sizeof(nidstr)),
2155 failnodeuuid, cliname);
2156 rc = record_add_uuid(env, llh, nid, failnodeuuid);
2158 * If *ptr is ':', we have added all NIDs for
2162 rc = record_add_conn(env, llh, cliname,
2164 name_destroy(&failnodeuuid);
2165 failnodeuuid = NULL;
2169 rc = record_add_conn(env, llh, cliname, failnodeuuid);
2170 name_destroy(&failnodeuuid);
2171 failnodeuuid = NULL;
2178 static int mgs_write_log_mdc_to_lmv(const struct lu_env *env,
2179 struct mgs_device *mgs,
2181 struct mgs_target_info *mti,
2182 char *logname, char *lmvname)
2184 struct llog_handle *llh = NULL;
2185 char *mdcname = NULL;
2186 char *nodeuuid = NULL;
2187 char *mdcuuid = NULL;
2188 char *lmvuuid = NULL;
2190 char nidstr[LNET_NIDSTR_SIZE];
2194 if (mgs_log_is_empty(env, mgs, logname)) {
2195 CERROR("log is empty! Logical error\n");
2199 CDEBUG(D_MGS, "adding mdc for %s to log %s:lmv(%s)\n",
2200 mti->mti_svname, logname, lmvname);
2202 libcfs_nid2str_r(mti->mti_nids[0], nidstr, sizeof(nidstr));
2203 rc = name_create(&nodeuuid, nidstr, "");
2206 rc = name_create(&mdcname, mti->mti_svname, "-mdc");
2209 rc = name_create(&mdcuuid, mdcname, "_UUID");
2212 rc = name_create(&lmvuuid, lmvname, "_UUID");
2216 rc = record_start_log(env, mgs, &llh, logname);
2219 rc = record_marker(env, llh, fsdb, CM_START, mti->mti_svname,
2223 for (i = 0; i < mti->mti_nid_count; i++) {
2224 CDEBUG(D_MGS, "add nid %s for mdt\n",
2225 libcfs_nid2str_r(mti->mti_nids[i],
2226 nidstr, sizeof(nidstr)));
2228 rc = record_add_uuid(env, llh, mti->mti_nids[i], nodeuuid);
2233 rc = record_attach(env, llh, mdcname, LUSTRE_MDC_NAME, lmvuuid);
2236 rc = record_setup(env, llh, mdcname, mti->mti_uuid, nodeuuid,
2240 rc = mgs_write_log_failnids(env, mti, llh, mdcname);
2243 snprintf(index, sizeof(index), "%d", mti->mti_stripe_index);
2244 rc = record_mdc_add(env, llh, lmvname, mdcuuid, mti->mti_uuid,
2248 rc = record_marker(env, llh, fsdb, CM_END, mti->mti_svname,
2253 record_end_log(env, &llh);
2255 name_destroy(&lmvuuid);
2256 name_destroy(&mdcuuid);
2257 name_destroy(&mdcname);
2258 name_destroy(&nodeuuid);
2262 static inline int name_create_lov(char **lovname, char *mdtname,
2263 struct fs_db *fsdb, int index)
2266 if (index == 0 && test_bit(FSDB_OSCNAME18, &fsdb->fsdb_flags))
2267 return name_create(lovname, fsdb->fsdb_name, "-mdtlov");
2269 return name_create(lovname, mdtname, "-mdtlov");
2272 static int name_create_mdt_and_lov(char **logname, char **lovname,
2273 struct fs_db *fsdb, int i)
2277 rc = name_create_mdt(logname, fsdb->fsdb_name, i);
2281 if (i == 0 && test_bit(FSDB_OSCNAME18, &fsdb->fsdb_flags))
2282 rc = name_create(lovname, fsdb->fsdb_name, "-mdtlov");
2284 rc = name_create(lovname, *logname, "-mdtlov");
2286 name_destroy(logname);
2292 static inline int name_create_mdt_osc(char **oscname, char *ostname,
2293 struct fs_db *fsdb, int i)
2297 if (i == 0 && test_bit(FSDB_OSCNAME18, &fsdb->fsdb_flags))
2298 sprintf(suffix, "-osc");
2300 sprintf(suffix, "-osc-MDT%04x", i);
2301 return name_create(oscname, ostname, suffix);
2304 /* add new mdc to already existent MDS */
2305 static int mgs_write_log_osp_to_mdt(const struct lu_env *env,
2306 struct mgs_device *mgs,
2308 struct mgs_target_info *mti,
2309 int mdt_index, char *logname)
2311 struct llog_handle *llh = NULL;
2312 char *nodeuuid = NULL;
2313 char *ospname = NULL;
2314 char *lovuuid = NULL;
2315 char *mdtuuid = NULL;
2316 char *svname = NULL;
2317 char *mdtname = NULL;
2318 char *lovname = NULL;
2320 char nidstr[LNET_NIDSTR_SIZE];
2324 if (mgs_log_is_empty(env, mgs, mti->mti_svname)) {
2325 CERROR("log is empty! Logical error\n");
2329 CDEBUG(D_MGS, "adding osp index %d to %s\n", mti->mti_stripe_index,
2332 rc = name_create_mdt(&mdtname, fsdb->fsdb_name, mti->mti_stripe_index);
2336 libcfs_nid2str_r(mti->mti_nids[0], nidstr, sizeof(nidstr));
2337 rc = name_create(&nodeuuid, nidstr, "");
2339 GOTO(out_destory, rc);
2341 rc = name_create(&svname, mdtname, "-osp");
2343 GOTO(out_destory, rc);
2345 sprintf(index_str, "-MDT%04x", mdt_index);
2346 rc = name_create(&ospname, svname, index_str);
2348 GOTO(out_destory, rc);
2350 rc = name_create_lov(&lovname, logname, fsdb, mdt_index);
2352 GOTO(out_destory, rc);
2354 rc = name_create(&lovuuid, lovname, "_UUID");
2356 GOTO(out_destory, rc);
2358 rc = name_create(&mdtuuid, mdtname, "_UUID");
2360 GOTO(out_destory, rc);
2362 rc = record_start_log(env, mgs, &llh, logname);
2364 GOTO(out_destory, rc);
2366 rc = record_marker(env, llh, fsdb, CM_START, mti->mti_svname,
2369 GOTO(out_destory, rc);
2371 for (i = 0; i < mti->mti_nid_count; i++) {
2372 CDEBUG(D_MGS, "add nid %s for mdt\n",
2373 libcfs_nid2str_r(mti->mti_nids[i],
2374 nidstr, sizeof(nidstr)));
2375 rc = record_add_uuid(env, llh, mti->mti_nids[i], nodeuuid);
2380 rc = record_attach(env, llh, ospname, LUSTRE_OSP_NAME, lovuuid);
2384 rc = record_setup(env, llh, ospname, mti->mti_uuid, nodeuuid,
2389 rc = mgs_write_log_failnids(env, mti, llh, ospname);
2393 /* Add mdc(osp) to lod */
2394 snprintf(index_str, sizeof(index_str), "%d", mti->mti_stripe_index);
2395 rc = record_base(env, llh, lovname, 0, LCFG_ADD_MDC, mti->mti_uuid,
2396 index_str, "1", NULL);
2400 rc = record_marker(env, llh, fsdb, CM_END, mti->mti_svname, "add osp");
2405 record_end_log(env, &llh);
2408 name_destroy(&mdtuuid);
2409 name_destroy(&lovuuid);
2410 name_destroy(&lovname);
2411 name_destroy(&ospname);
2412 name_destroy(&svname);
2413 name_destroy(&nodeuuid);
2414 name_destroy(&mdtname);
2418 static int mgs_write_log_mdt0(const struct lu_env *env,
2419 struct mgs_device *mgs,
2421 struct mgs_target_info *mti)
2423 char *log = mti->mti_svname;
2424 struct llog_handle *llh = NULL;
2425 char *uuid, *lovname;
2427 char *ptr = mti->mti_params;
2428 int rc = 0, failout = 0;
2431 OBD_ALLOC(uuid, sizeof(struct obd_uuid));
2435 if (class_find_param(ptr, PARAM_FAILMODE, &ptr) == 0)
2436 failout = (strncmp(ptr, "failout", 7) == 0);
2438 rc = name_create(&lovname, log, "-mdtlov");
2441 if (mgs_log_is_empty(env, mgs, log)) {
2442 rc = mgs_write_log_lov(env, mgs, fsdb, mti, log, lovname);
2447 sprintf(mdt_index, "%d", mti->mti_stripe_index);
2449 rc = record_start_log(env, mgs, &llh, log);
2453 /* add MDT itself */
2455 /* FIXME this whole fn should be a single journal transaction */
2456 sprintf(uuid, "%s_UUID", log);
2457 rc = record_marker(env, llh, fsdb, CM_START, log, "add mdt");
2460 rc = record_attach(env, llh, log, LUSTRE_MDT_NAME, uuid);
2463 rc = record_mount_opt(env, llh, log, lovname, NULL);
2466 rc = record_setup(env, llh, log, uuid, mdt_index, lovname,
2467 failout ? "n" : "f");
2470 rc = record_marker(env, llh, fsdb, CM_END, log, "add mdt");
2474 record_end_log(env, &llh);
2476 name_destroy(&lovname);
2478 OBD_FREE(uuid, sizeof(struct obd_uuid));
2482 /* envelope method for all layers log */
2483 static int mgs_write_log_mdt(const struct lu_env *env,
2484 struct mgs_device *mgs,
2486 struct mgs_target_info *mti)
2488 struct mgs_thread_info *mgi = mgs_env_info(env);
2489 struct llog_handle *llh = NULL;
2494 CDEBUG(D_MGS, "writing new mdt %s\n", mti->mti_svname);
2496 if (mti->mti_uuid[0] == '\0') {
2497 /* Make up our own uuid */
2498 snprintf(mti->mti_uuid, sizeof(mti->mti_uuid),
2499 "%s_UUID", mti->mti_svname);
2503 rc = mgs_write_log_mdt0(env, mgs, fsdb, mti);
2506 /* Append the mdt info to the client log */
2507 rc = name_create(&cliname, mti->mti_fsname, "-client");
2511 if (mgs_log_is_empty(env, mgs, cliname)) {
2512 /* Start client log */
2513 rc = mgs_write_log_lov(env, mgs, fsdb, mti, cliname,
2517 rc = mgs_write_log_lmv(env, mgs, fsdb, mti, cliname,
2524 #09 L add_uuid nid=uml1@tcp(0x20000c0a80201) 0: 1:uml1_UUID
2525 #10 L attach 0:MDC_uml1_mdsA_MNT_client 1:mdc 2:1d834_MNT_client_03f
2526 #11 L setup 0:MDC_uml1_mdsA_MNT_client 1:mdsA_UUID 2:uml1_UUID
2527 #12 L add_uuid nid=uml2@tcp(0x20000c0a80202) 0: 1:uml2_UUID
2528 #13 L add_conn 0:MDC_uml1_mdsA_MNT_client 1:uml2_UUID
2529 #14 L mount_option 0: 1:client 2:lov1 3:MDC_uml1_mdsA_MNT_client
2532 /* copy client info about lov/lmv */
2533 mgi->mgi_comp.comp_mti = mti;
2534 mgi->mgi_comp.comp_fsdb = fsdb;
2536 rc = mgs_steal_llog_for_mdt_from_client(env, mgs, cliname,
2540 rc = mgs_write_log_mdc_to_lmv(env, mgs, fsdb, mti, cliname,
2546 rc = record_start_log(env, mgs, &llh, cliname);
2550 rc = record_marker(env, llh, fsdb, CM_START, cliname, "mount opts");
2553 rc = record_mount_opt(env, llh, cliname, fsdb->fsdb_clilov,
2557 rc = record_marker(env, llh, fsdb, CM_END, cliname, "mount opts");
2561 /* for_all_existing_mdt except current one */
2562 for (i = 0; i < INDEX_MAP_SIZE * 8; i++) {
2563 if (i != mti->mti_stripe_index &&
2564 test_bit(i, fsdb->fsdb_mdt_index_map)) {
2567 rc = name_create_mdt(&logname, fsdb->fsdb_name, i);
2571 /* NB: If the log for the MDT is empty, it means
2572 * the MDT is only added to the index
2573 * map, and not being process yet, i.e. this
2574 * is an unregistered MDT, see mgs_write_log_target().
2575 * so we should skip it. Otherwise
2577 * 1. MGS get register request for MDT1 and MDT2.
2579 * 2. Then both MDT1 and MDT2 are added into
2580 * fsdb_mdt_index_map. (see mgs_set_index()).
2582 * 3. Then MDT1 get the lock of fsdb_mutex, then
2583 * generate the config log, here, it will regard MDT2
2584 * as an existent MDT, and generate "add osp" for
2585 * lustre-MDT0001-osp-MDT0002. Note: at the moment
2586 * MDT0002 config log is still empty, so it will
2587 * add "add osp" even before "lov setup", which
2588 * will definitly cause trouble.
2590 * 4. MDT1 registeration finished, fsdb_mutex is
2591 * released, then MDT2 get in, then in above
2592 * mgs_steal_llog_for_mdt_from_client(), it will
2593 * add another osp log for lustre-MDT0001-osp-MDT0002,
2594 * which will cause another trouble.*/
2595 if (!mgs_log_is_empty(env, mgs, logname))
2596 rc = mgs_write_log_osp_to_mdt(env, mgs, fsdb,
2599 name_destroy(&logname);
2605 record_end_log(env, &llh);
2607 name_destroy(&cliname);
2611 /* Add the ost info to the client/mdt lov */
2612 static int mgs_write_log_osc_to_lov(const struct lu_env *env,
2613 struct mgs_device *mgs, struct fs_db *fsdb,
2614 struct mgs_target_info *mti,
2615 char *logname, char *suffix, char *lovname,
2616 enum lustre_sec_part sec_part, int flags)
2618 struct llog_handle *llh = NULL;
2619 char *nodeuuid = NULL;
2620 char *oscname = NULL;
2621 char *oscuuid = NULL;
2622 char *lovuuid = NULL;
2623 char *svname = NULL;
2625 char nidstr[LNET_NIDSTR_SIZE];
2629 CDEBUG(D_INFO, "adding osc for %s to log %s\n",
2630 mti->mti_svname, logname);
2632 if (mgs_log_is_empty(env, mgs, logname)) {
2633 CERROR("log is empty! Logical error\n");
2637 libcfs_nid2str_r(mti->mti_nids[0], nidstr, sizeof(nidstr));
2638 rc = name_create(&nodeuuid, nidstr, "");
2641 rc = name_create(&svname, mti->mti_svname, "-osc");
2645 /* for the system upgraded from old 1.8, keep using the old osc naming
2646 * style for mdt, see name_create_mdt_osc(). LU-1257 */
2647 if (test_bit(FSDB_OSCNAME18, &fsdb->fsdb_flags))
2648 rc = name_create(&oscname, svname, "");
2650 rc = name_create(&oscname, svname, suffix);
2654 rc = name_create(&oscuuid, oscname, "_UUID");
2657 rc = name_create(&lovuuid, lovname, "_UUID");
2663 #03 L add_uuid nid=uml1@tcp(0x20000c0a80201) 0: 1:uml1_UUID
2665 #04 L add_uuid nid=1@elan(0x1000000000001) nal=90 0: 1:uml1_UUID
2666 #04 L attach 0:OSC_uml1_ost1_MNT_client 1:osc 2:89070_lov1_a41dff51a
2667 #05 L setup 0:OSC_uml1_ost1_MNT_client 1:ost1_UUID 2:uml1_UUID
2669 #06 L add_uuid nid=uml2@tcp(0x20000c0a80202) 0: 1:uml2_UUID
2670 #07 L add_conn 0:OSC_uml1_ost1_MNT_client 1:uml2_UUID
2671 #08 L lov_modify_tgts add 0:lov1 1:ost1_UUID 2(index):0 3(gen):1
2674 rc = record_start_log(env, mgs, &llh, logname);
2678 /* FIXME these should be a single journal transaction */
2679 rc = record_marker(env, llh, fsdb, CM_START | flags, mti->mti_svname,
2684 /* NB: don't change record order, because upon MDT steal OSC config
2685 * from client, it treats all nids before LCFG_SETUP as target nids
2686 * (multiple interfaces), while nids after as failover node nids.
2687 * See mgs_steal_client_llog_handler() LCFG_ADD_UUID.
2689 for (i = 0; i < mti->mti_nid_count; i++) {
2690 CDEBUG(D_MGS, "add nid %s\n",
2691 libcfs_nid2str_r(mti->mti_nids[i],
2692 nidstr, sizeof(nidstr)));
2693 rc = record_add_uuid(env, llh, mti->mti_nids[i], nodeuuid);
2697 rc = record_attach(env, llh, oscname, LUSTRE_OSC_NAME, lovuuid);
2700 rc = record_setup(env, llh, oscname, mti->mti_uuid, nodeuuid,
2704 rc = mgs_write_log_failnids(env, mti, llh, oscname);
2708 snprintf(index, sizeof(index), "%d", mti->mti_stripe_index);
2710 rc = record_lov_add(env, llh, lovname, mti->mti_uuid, index, "1");
2713 rc = record_marker(env, llh, fsdb, CM_END | flags, mti->mti_svname,
2718 record_end_log(env, &llh);
2720 name_destroy(&lovuuid);
2721 name_destroy(&oscuuid);
2722 name_destroy(&oscname);
2723 name_destroy(&svname);
2724 name_destroy(&nodeuuid);
2728 static int mgs_write_log_ost(const struct lu_env *env,
2729 struct mgs_device *mgs, struct fs_db *fsdb,
2730 struct mgs_target_info *mti)
2732 struct llog_handle *llh = NULL;
2733 char *logname, *lovname;
2734 char *ptr = mti->mti_params;
2735 int rc, flags = 0, failout = 0, i;
2738 CDEBUG(D_MGS, "writing new ost %s\n", mti->mti_svname);
2740 /* The ost startup log */
2742 /* If the ost log already exists, that means that someone reformatted
2743 the ost and it called target_add again. */
2744 if (!mgs_log_is_empty(env, mgs, mti->mti_svname)) {
2745 LCONSOLE_ERROR_MSG(0x141, "The config log for %s already "
2746 "exists, yet the server claims it never "
2747 "registered. It may have been reformatted, "
2748 "or the index changed. writeconf the MDT to "
2749 "regenerate all logs.\n", mti->mti_svname);
2754 attach obdfilter ost1 ost1_UUID
2755 setup /dev/loop2 ldiskfs f|n errors=remount-ro,user_xattr
2757 if (class_find_param(ptr, PARAM_FAILMODE, &ptr) == 0)
2758 failout = (strncmp(ptr, "failout", 7) == 0);
2759 rc = record_start_log(env, mgs, &llh, mti->mti_svname);
2762 /* FIXME these should be a single journal transaction */
2763 rc = record_marker(env, llh, fsdb, CM_START, mti->mti_svname,"add ost");
2766 if (*mti->mti_uuid == '\0')
2767 snprintf(mti->mti_uuid, sizeof(mti->mti_uuid),
2768 "%s_UUID", mti->mti_svname);
2769 rc = record_attach(env, llh, mti->mti_svname,
2770 "obdfilter"/*LUSTRE_OST_NAME*/, mti->mti_uuid);
2773 rc = record_setup(env, llh, mti->mti_svname,
2774 "dev"/*ignored*/, "type"/*ignored*/,
2775 failout ? "n" : "f", NULL/*options*/);
2778 rc = record_marker(env, llh, fsdb, CM_END, mti->mti_svname, "add ost");
2782 record_end_log(env, &llh);
2785 /* We also have to update the other logs where this osc is part of
2788 if (test_bit(FSDB_OLDLOG14, &fsdb->fsdb_flags)) {
2789 /* If we're upgrading, the old mdt log already has our
2790 entry. Let's do a fake one for fun. */
2791 /* Note that we can't add any new failnids, since we don't
2792 know the old osc names. */
2793 flags = CM_SKIP | CM_UPGRADE146;
2795 } else if ((mti->mti_flags & LDD_F_UPDATE) != LDD_F_UPDATE) {
2796 /* If the update flag isn't set, don't update client/mdt
2799 LCONSOLE_WARN("Client log for %s was not updated; writeconf "
2800 "the MDT first to regenerate it.\n",
2804 /* Add ost to all MDT lov defs */
2805 for (i = 0; i < INDEX_MAP_SIZE * 8; i++){
2806 if (test_bit(i, fsdb->fsdb_mdt_index_map)) {
2809 rc = name_create_mdt_and_lov(&logname, &lovname, fsdb,
2813 sprintf(mdt_index, "-MDT%04x", i);
2814 rc = mgs_write_log_osc_to_lov(env, mgs, fsdb, mti,
2816 lovname, LUSTRE_SP_MDT,
2818 name_destroy(&logname);
2819 name_destroy(&lovname);
2825 /* Append ost info to the client log */
2826 rc = name_create(&logname, mti->mti_fsname, "-client");
2829 if (mgs_log_is_empty(env, mgs, logname)) {
2830 /* Start client log */
2831 rc = mgs_write_log_lov(env, mgs, fsdb, mti, logname,
2835 rc = mgs_write_log_lmv(env, mgs, fsdb, mti, logname,
2840 rc = mgs_write_log_osc_to_lov(env, mgs, fsdb, mti, logname, "",
2841 fsdb->fsdb_clilov, LUSTRE_SP_CLI, flags);
2843 name_destroy(&logname);
2847 static __inline__ int mgs_param_empty(char *ptr)
2851 if ((tmp = strchr(ptr, '=')) && (*(++tmp) == '\0'))
2856 static int mgs_write_log_failnid_internal(const struct lu_env *env,
2857 struct mgs_device *mgs,
2859 struct mgs_target_info *mti,
2860 char *logname, char *cliname)
2863 struct llog_handle *llh = NULL;
2865 if (mgs_param_empty(mti->mti_params)) {
2866 /* Remove _all_ failnids */
2867 rc = mgs_modify(env, mgs, fsdb, mti, logname,
2868 mti->mti_svname, "add failnid", CM_SKIP);
2869 return rc < 0 ? rc : 0;
2872 /* Otherwise failover nids are additive */
2873 rc = record_start_log(env, mgs, &llh, logname);
2876 /* FIXME this should be a single journal transaction */
2877 rc = record_marker(env, llh, fsdb, CM_START, mti->mti_svname,
2881 rc = mgs_write_log_failnids(env, mti, llh, cliname);
2884 rc = record_marker(env, llh, fsdb, CM_END,
2885 mti->mti_svname, "add failnid");
2887 record_end_log(env, &llh);
2892 /* Add additional failnids to an existing log.
2893 The mdc/osc must have been added to logs first */
2894 /* tcp nids must be in dotted-quad ascii -
2895 we can't resolve hostnames from the kernel. */
2896 static int mgs_write_log_add_failnid(const struct lu_env *env,
2897 struct mgs_device *mgs,
2899 struct mgs_target_info *mti)
2901 char *logname, *cliname;
2905 /* FIXME we currently can't erase the failnids
2906 * given when a target first registers, since they aren't part of
2907 * an "add uuid" stanza */
2909 /* Verify that we know about this target */
2910 if (mgs_log_is_empty(env, mgs, mti->mti_svname)) {
2911 LCONSOLE_ERROR_MSG(0x142, "The target %s has not registered "
2912 "yet. It must be started before failnids "
2913 "can be added.\n", mti->mti_svname);
2917 /* Create mdc/osc client name (e.g. lustre-OST0001-osc) */
2918 if (mti->mti_flags & LDD_F_SV_TYPE_MDT) {
2919 rc = name_create(&cliname, mti->mti_svname, "-mdc");
2920 } else if (mti->mti_flags & LDD_F_SV_TYPE_OST) {
2921 rc = name_create(&cliname, mti->mti_svname, "-osc");
2927 /* Add failover nids to the client log */
2928 rc = name_create(&logname, mti->mti_fsname, "-client");
2930 name_destroy(&cliname);
2933 rc = mgs_write_log_failnid_internal(env, mgs, fsdb,mti,logname,cliname);
2934 name_destroy(&logname);
2935 name_destroy(&cliname);
2939 if (mti->mti_flags & LDD_F_SV_TYPE_OST) {
2940 /* Add OST failover nids to the MDT logs as well */
2943 for (i = 0; i < INDEX_MAP_SIZE * 8; i++) {
2944 if (!test_bit(i, fsdb->fsdb_mdt_index_map))
2946 rc = name_create_mdt(&logname, mti->mti_fsname, i);
2949 rc = name_create_mdt_osc(&cliname, mti->mti_svname,
2952 name_destroy(&logname);
2955 rc = mgs_write_log_failnid_internal(env, mgs, fsdb,
2958 name_destroy(&cliname);
2959 name_destroy(&logname);
2968 static int mgs_wlp_lcfg(const struct lu_env *env,
2969 struct mgs_device *mgs, struct fs_db *fsdb,
2970 struct mgs_target_info *mti,
2971 char *logname, struct lustre_cfg_bufs *bufs,
2972 char *tgtname, char *ptr)
2974 char comment[MTI_NAME_MAXLEN];
2976 struct llog_cfg_rec *lcr;
2979 /* Erase any old settings of this same parameter */
2980 memcpy(comment, ptr, MTI_NAME_MAXLEN);
2981 comment[MTI_NAME_MAXLEN - 1] = 0;
2982 /* But don't try to match the value. */
2983 tmp = strchr(comment, '=');
2986 /* FIXME we should skip settings that are the same as old values */
2987 rc = mgs_modify(env, mgs, fsdb, mti, logname, tgtname, comment,CM_SKIP);
2990 del = mgs_param_empty(ptr);
2992 LCONSOLE_INFO("%s parameter %s.%s in log %s\n", del ? "Disabling" : rc ?
2993 "Setting" : "Modifying", tgtname, comment, logname);
2995 /* mgs_modify() will return 1 if nothing had to be done */
3001 lustre_cfg_bufs_reset(bufs, tgtname);
3002 lustre_cfg_bufs_set_string(bufs, 1, ptr);
3003 if (mti->mti_flags & LDD_F_PARAM2)
3004 lustre_cfg_bufs_set_string(bufs, 2, LCTL_UPCALL);
3006 lcr = lustre_cfg_rec_new((mti->mti_flags & LDD_F_PARAM2) ?
3007 LCFG_SET_PARAM : LCFG_PARAM, bufs);
3011 rc = mgs_write_log_direct(env, mgs, fsdb, logname, lcr, tgtname,
3013 lustre_cfg_rec_free(lcr);
3017 static int mgs_write_log_param2(const struct lu_env *env,
3018 struct mgs_device *mgs,
3020 struct mgs_target_info *mti, char *ptr)
3022 struct lustre_cfg_bufs bufs;
3026 CDEBUG(D_MGS, "next param '%s'\n", ptr);
3027 rc = mgs_wlp_lcfg(env, mgs, fsdb, mti, PARAMS_FILENAME, &bufs,
3028 mti->mti_svname, ptr);
3033 /* write global variable settings into log */
3034 static int mgs_write_log_sys(const struct lu_env *env,
3035 struct mgs_device *mgs, struct fs_db *fsdb,
3036 struct mgs_target_info *mti, char *sys, char *ptr)
3038 struct mgs_thread_info *mgi = mgs_env_info(env);
3039 struct lustre_cfg *lcfg;
3040 struct llog_cfg_rec *lcr;
3042 int rc, cmd, convert = 1;
3044 if (class_match_param(ptr, PARAM_TIMEOUT, &tmp) == 0) {
3045 cmd = LCFG_SET_TIMEOUT;
3046 } else if (class_match_param(ptr, PARAM_LDLM_TIMEOUT, &tmp) == 0) {
3047 cmd = LCFG_SET_LDLM_TIMEOUT;
3048 /* Check for known params here so we can return error to lctl */
3049 } else if ((class_match_param(ptr, PARAM_AT_MIN, &tmp) == 0) ||
3050 (class_match_param(ptr, PARAM_AT_MAX, &tmp) == 0) ||
3051 (class_match_param(ptr, PARAM_AT_EXTRA, &tmp) == 0) ||
3052 (class_match_param(ptr, PARAM_AT_EARLY_MARGIN, &tmp) == 0) ||
3053 (class_match_param(ptr, PARAM_AT_HISTORY, &tmp) == 0)) {
3055 } else if (class_match_param(ptr, PARAM_JOBID_VAR, &tmp) == 0) {
3056 convert = 0; /* Don't convert string value to integer */
3062 if (mgs_param_empty(ptr))
3063 CDEBUG(D_MGS, "global '%s' removed\n", sys);
3065 CDEBUG(D_MGS, "global '%s' val=%s\n", sys, tmp);
3067 lustre_cfg_bufs_reset(&mgi->mgi_bufs, NULL);
3068 lustre_cfg_bufs_set_string(&mgi->mgi_bufs, 1, sys);
3069 if (!convert && *tmp != '\0')
3070 lustre_cfg_bufs_set_string(&mgi->mgi_bufs, 2, tmp);
3071 lcr = lustre_cfg_rec_new(cmd, &mgi->mgi_bufs);
3075 lcfg = &lcr->lcr_cfg;
3076 lcfg->lcfg_num = convert ? simple_strtoul(tmp, NULL, 0) : 0;
3077 /* truncate the comment to the parameter name */
3081 /* modify all servers and clients */
3082 rc = mgs_write_log_direct_all(env, mgs, fsdb, mti,
3083 *tmp == '\0' ? NULL : lcr,
3084 mti->mti_fsname, sys, 0);
3085 if (rc == 0 && *tmp != '\0') {
3087 case LCFG_SET_TIMEOUT:
3088 if (!obd_timeout_set || lcfg->lcfg_num > obd_timeout)
3089 class_process_config(lcfg);
3091 case LCFG_SET_LDLM_TIMEOUT:
3092 if (!ldlm_timeout_set || lcfg->lcfg_num > ldlm_timeout)
3093 class_process_config(lcfg);
3100 lustre_cfg_rec_free(lcr);
3104 /* write quota settings into log */
3105 static int mgs_write_log_quota(const struct lu_env *env, struct mgs_device *mgs,
3106 struct fs_db *fsdb, struct mgs_target_info *mti,
3107 char *quota, char *ptr)
3109 struct mgs_thread_info *mgi = mgs_env_info(env);
3110 struct llog_cfg_rec *lcr;
3113 int rc, cmd = LCFG_PARAM;
3115 /* support only 'meta' and 'data' pools so far */
3116 if (class_match_param(ptr, QUOTA_METAPOOL_NAME, &tmp) != 0 &&
3117 class_match_param(ptr, QUOTA_DATAPOOL_NAME, &tmp) != 0) {
3118 CERROR("parameter quota.%s isn't supported (only quota.mdt "
3119 "& quota.ost are)\n", ptr);
3124 CDEBUG(D_MGS, "global '%s' removed\n", quota);
3126 CDEBUG(D_MGS, "global '%s'\n", quota);
3128 if (strchr(tmp, 'u') == NULL && strchr(tmp, 'g') == NULL &&
3129 strchr(tmp, 'p') == NULL &&
3130 strcmp(tmp, "none") != 0) {
3131 CERROR("enable option(%s) isn't supported\n", tmp);
3136 lustre_cfg_bufs_reset(&mgi->mgi_bufs, mti->mti_fsname);
3137 lustre_cfg_bufs_set_string(&mgi->mgi_bufs, 1, quota);
3138 lcr = lustre_cfg_rec_new(cmd, &mgi->mgi_bufs);
3142 /* truncate the comment to the parameter name */
3147 /* XXX we duplicated quota enable information in all server
3148 * config logs, it should be moved to a separate config
3149 * log once we cleanup the config log for global param. */
3150 /* modify all servers */
3151 rc = mgs_write_log_direct_all(env, mgs, fsdb, mti,
3152 *tmp == '\0' ? NULL : lcr,
3153 mti->mti_fsname, quota, 1);
3155 lustre_cfg_rec_free(lcr);
3156 return rc < 0 ? rc : 0;
3159 static int mgs_srpc_set_param_disk(const struct lu_env *env,
3160 struct mgs_device *mgs,
3162 struct mgs_target_info *mti,
3165 struct mgs_thread_info *mgi = mgs_env_info(env);
3166 struct llog_cfg_rec *lcr;
3167 struct llog_handle *llh = NULL;
3169 char *comment, *ptr;
3175 ptr = strchr(param, '=');
3176 LASSERT(ptr != NULL);
3179 OBD_ALLOC(comment, len + 1);
3180 if (comment == NULL)
3182 strncpy(comment, param, len);
3183 comment[len] = '\0';
3186 lustre_cfg_bufs_reset(&mgi->mgi_bufs, mti->mti_svname);
3187 lustre_cfg_bufs_set_string(&mgi->mgi_bufs, 1, param);
3188 lcr = lustre_cfg_rec_new(LCFG_SPTLRPC_CONF, &mgi->mgi_bufs);
3190 GOTO(out_comment, rc = -ENOMEM);
3192 /* construct log name */
3193 rc = name_create(&logname, mti->mti_fsname, "-sptlrpc");
3197 if (mgs_log_is_empty(env, mgs, logname)) {
3198 rc = record_start_log(env, mgs, &llh, logname);
3201 record_end_log(env, &llh);
3204 /* obsolete old one */
3205 rc = mgs_modify(env, mgs, fsdb, mti, logname, mti->mti_svname,
3209 /* write the new one */
3210 rc = mgs_write_log_direct(env, mgs, fsdb, logname, lcr,
3211 mti->mti_svname, comment);
3213 CERROR("%s: error writing log %s: rc = %d\n",
3214 mgs->mgs_obd->obd_name, logname, rc);
3216 name_destroy(&logname);
3218 lustre_cfg_rec_free(lcr);
3220 OBD_FREE(comment, len + 1);
3224 static int mgs_srpc_set_param_udesc_mem(struct fs_db *fsdb,
3229 /* disable the adjustable udesc parameter for now, i.e. use default
3230 * setting that client always ship udesc to MDT if possible. to enable
3231 * it simply remove the following line */
3234 ptr = strchr(param, '=');
3239 if (strcmp(param, PARAM_SRPC_UDESC))
3242 if (strcmp(ptr, "yes") == 0) {
3243 set_bit(FSDB_UDESC, &fsdb->fsdb_flags);
3244 CWARN("Enable user descriptor shipping from client to MDT\n");
3245 } else if (strcmp(ptr, "no") == 0) {
3246 clear_bit(FSDB_UDESC, &fsdb->fsdb_flags);
3247 CWARN("Disable user descriptor shipping from client to MDT\n");
3255 CERROR("Invalid param: %s\n", param);
3259 static int mgs_srpc_set_param_mem(struct fs_db *fsdb,
3263 struct sptlrpc_rule rule;
3264 struct sptlrpc_rule_set *rset;
3268 if (strncmp(param, PARAM_SRPC, sizeof(PARAM_SRPC) - 1) != 0) {
3269 CERROR("Invalid sptlrpc parameter: %s\n", param);
3273 if (strncmp(param, PARAM_SRPC_UDESC,
3274 sizeof(PARAM_SRPC_UDESC) - 1) == 0) {
3275 RETURN(mgs_srpc_set_param_udesc_mem(fsdb, param));
3278 if (strncmp(param, PARAM_SRPC_FLVR, sizeof(PARAM_SRPC_FLVR) - 1) != 0) {
3279 CERROR("Invalid sptlrpc flavor parameter: %s\n", param);
3283 param += sizeof(PARAM_SRPC_FLVR) - 1;
3285 rc = sptlrpc_parse_rule(param, &rule);
3289 /* mgs rules implies must be mgc->mgs */
3290 if (test_bit(FSDB_MGS_SELF, &fsdb->fsdb_flags)) {
3291 if ((rule.sr_from != LUSTRE_SP_MGC &&
3292 rule.sr_from != LUSTRE_SP_ANY) ||
3293 (rule.sr_to != LUSTRE_SP_MGS &&
3294 rule.sr_to != LUSTRE_SP_ANY))
3298 /* preapre room for this coming rule. svcname format should be:
3299 * - fsname: general rule
3300 * - fsname-tgtname: target-specific rule
3302 if (strchr(svname, '-')) {
3303 struct mgs_tgt_srpc_conf *tgtconf;
3306 for (tgtconf = fsdb->fsdb_srpc_tgt; tgtconf != NULL;
3307 tgtconf = tgtconf->mtsc_next) {
3308 if (!strcmp(tgtconf->mtsc_tgt, svname)) {
3317 OBD_ALLOC_PTR(tgtconf);
3318 if (tgtconf == NULL)
3321 name_len = strlen(svname);
3323 OBD_ALLOC(tgtconf->mtsc_tgt, name_len + 1);
3324 if (tgtconf->mtsc_tgt == NULL) {
3325 OBD_FREE_PTR(tgtconf);
3328 memcpy(tgtconf->mtsc_tgt, svname, name_len);
3330 tgtconf->mtsc_next = fsdb->fsdb_srpc_tgt;
3331 fsdb->fsdb_srpc_tgt = tgtconf;
3334 rset = &tgtconf->mtsc_rset;
3335 } else if (strcmp(svname, MGSSELF_NAME) == 0) {
3336 /* put _mgs related srpc rule directly in mgs ruleset */
3337 rset = &fsdb->fsdb_mgs->mgs_lut.lut_sptlrpc_rset;
3339 rset = &fsdb->fsdb_srpc_gen;
3342 rc = sptlrpc_rule_set_merge(rset, &rule);
3347 static int mgs_srpc_set_param(const struct lu_env *env,
3348 struct mgs_device *mgs,
3350 struct mgs_target_info *mti,
3360 /* keep a copy of original param, which could be destroied
3362 copy_size = strlen(param) + 1;
3363 OBD_ALLOC(copy, copy_size);
3366 memcpy(copy, param, copy_size);
3368 rc = mgs_srpc_set_param_mem(fsdb, mti->mti_svname, param);
3372 /* previous steps guaranteed the syntax is correct */
3373 rc = mgs_srpc_set_param_disk(env, mgs, fsdb, mti, copy);
3377 if (test_bit(FSDB_MGS_SELF, &fsdb->fsdb_flags)) {
3379 * for mgs rules, make them effective immediately.
3381 LASSERT(fsdb->fsdb_srpc_tgt == NULL);
3382 sptlrpc_target_update_exp_flavor(mgs->mgs_obd,
3383 &fsdb->fsdb_srpc_gen);
3387 OBD_FREE(copy, copy_size);
3391 struct mgs_srpc_read_data {
3392 struct fs_db *msrd_fsdb;
3396 static int mgs_srpc_read_handler(const struct lu_env *env,
3397 struct llog_handle *llh,
3398 struct llog_rec_hdr *rec, void *data)
3400 struct mgs_srpc_read_data *msrd = data;
3401 struct cfg_marker *marker;
3402 struct lustre_cfg *lcfg = REC_DATA(rec);
3403 char *svname, *param;
3407 if (rec->lrh_type != OBD_CFG_REC) {
3408 CERROR("unhandled lrh_type: %#x\n", rec->lrh_type);
3412 cfg_len = REC_DATA_LEN(rec);
3414 rc = lustre_cfg_sanity_check(lcfg, cfg_len);
3416 CERROR("Insane cfg\n");
3420 if (lcfg->lcfg_command == LCFG_MARKER) {
3421 marker = lustre_cfg_buf(lcfg, 1);
3423 if (marker->cm_flags & CM_START &&
3424 marker->cm_flags & CM_SKIP)
3425 msrd->msrd_skip = 1;
3426 if (marker->cm_flags & CM_END)
3427 msrd->msrd_skip = 0;
3432 if (msrd->msrd_skip)
3435 if (lcfg->lcfg_command != LCFG_SPTLRPC_CONF) {
3436 CERROR("invalid command (%x)\n", lcfg->lcfg_command);
3440 svname = lustre_cfg_string(lcfg, 0);
3441 if (svname == NULL) {
3442 CERROR("svname is empty\n");
3446 param = lustre_cfg_string(lcfg, 1);
3447 if (param == NULL) {
3448 CERROR("param is empty\n");
3452 rc = mgs_srpc_set_param_mem(msrd->msrd_fsdb, svname, param);
3454 CERROR("read sptlrpc record error (%d): %s\n", rc, param);
3459 int mgs_get_fsdb_srpc_from_llog(const struct lu_env *env,
3460 struct mgs_device *mgs,
3463 struct llog_handle *llh = NULL;
3464 struct llog_ctxt *ctxt;
3466 struct mgs_srpc_read_data msrd;
3470 /* construct log name */
3471 rc = name_create(&logname, fsdb->fsdb_name, "-sptlrpc");
3475 ctxt = llog_get_context(mgs->mgs_obd, LLOG_CONFIG_ORIG_CTXT);
3476 LASSERT(ctxt != NULL);
3478 if (mgs_log_is_empty(env, mgs, logname))
3481 rc = llog_open(env, ctxt, &llh, NULL, logname,
3489 rc = llog_init_handle(env, llh, LLOG_F_IS_PLAIN, NULL);
3491 GOTO(out_close, rc);
3493 if (llog_get_size(llh) <= 1)
3494 GOTO(out_close, rc = 0);
3496 msrd.msrd_fsdb = fsdb;
3499 rc = llog_process(env, llh, mgs_srpc_read_handler, (void *)&msrd,
3503 llog_close(env, llh);
3505 llog_ctxt_put(ctxt);
3506 name_destroy(&logname);
3509 CERROR("failed to read sptlrpc config database: %d\n", rc);
3513 /* Permanent settings of all parameters by writing into the appropriate
3514 * configuration logs.
3515 * A parameter with null value ("<param>='\0'") means to erase it out of
3518 static int mgs_write_log_param(const struct lu_env *env,
3519 struct mgs_device *mgs, struct fs_db *fsdb,
3520 struct mgs_target_info *mti, char *ptr)
3522 struct mgs_thread_info *mgi = mgs_env_info(env);
3528 /* For various parameter settings, we have to figure out which logs
3529 care about them (e.g. both mdt and client for lov settings) */
3530 CDEBUG(D_MGS, "next param '%s'\n", ptr);
3532 /* The params are stored in MOUNT_DATA_FILE and modified via
3533 tunefs.lustre, or set using lctl conf_param */
3535 /* Processed in lustre_start_mgc */
3536 if (class_match_param(ptr, PARAM_MGSNODE, NULL) == 0)
3539 /* Processed in ost/mdt */
3540 if (class_match_param(ptr, PARAM_NETWORK, NULL) == 0)
3543 /* Processed in mgs_write_log_ost */
3544 if (class_match_param(ptr, PARAM_FAILMODE, NULL) == 0) {
3545 if (mti->mti_flags & LDD_F_PARAM) {
3546 LCONSOLE_ERROR_MSG(0x169, "%s can only be "
3547 "changed with tunefs.lustre"
3548 "and --writeconf\n", ptr);
3554 if (class_match_param(ptr, PARAM_SRPC, NULL) == 0) {
3555 rc = mgs_srpc_set_param(env, mgs, fsdb, mti, ptr);
3559 if (class_match_param(ptr, PARAM_FAILNODE, NULL) == 0) {
3560 /* Add a failover nidlist */
3562 /* We already processed failovers params for new
3563 targets in mgs_write_log_target */
3564 if (mti->mti_flags & LDD_F_PARAM) {
3565 CDEBUG(D_MGS, "Adding failnode\n");
3566 rc = mgs_write_log_add_failnid(env, mgs, fsdb, mti);
3571 if (class_match_param(ptr, PARAM_SYS, &tmp) == 0) {
3572 rc = mgs_write_log_sys(env, mgs, fsdb, mti, ptr, tmp);
3576 if (class_match_param(ptr, PARAM_QUOTA, &tmp) == 0) {
3577 rc = mgs_write_log_quota(env, mgs, fsdb, mti, ptr, tmp);
3581 if (class_match_param(ptr, PARAM_OSC PARAM_ACTIVE, &tmp) == 0 ||
3582 class_match_param(ptr, PARAM_MDC PARAM_ACTIVE, &tmp) == 0) {
3583 /* active=0 means off, anything else means on */
3584 int flag = (*tmp == '0') ? CM_EXCLUDE : 0;
3585 bool deactive_osc = memcmp(ptr, PARAM_OSC PARAM_ACTIVE,
3586 strlen(PARAM_OSC PARAM_ACTIVE)) == 0;
3589 if (!deactive_osc) {
3592 rc = server_name2index(mti->mti_svname, &index, NULL);
3597 LCONSOLE_ERROR_MSG(0x144, "%s: MDC0 can not be"
3598 " (de)activated.\n",
3600 GOTO(end, rc = -EPERM);
3604 LCONSOLE_WARN("Permanently %sactivating %s\n",
3605 flag ? "de" : "re", mti->mti_svname);
3607 rc = name_create(&logname, mti->mti_fsname, "-client");
3610 rc = mgs_modify(env, mgs, fsdb, mti, logname,
3612 deactive_osc ? "add osc" : "add mdc", flag);
3613 name_destroy(&logname);
3618 /* Add to all MDT logs for DNE */
3619 for (i = 0; i < INDEX_MAP_SIZE * 8; i++) {
3620 if (!test_bit(i, fsdb->fsdb_mdt_index_map))
3622 rc = name_create_mdt(&logname, mti->mti_fsname, i);
3625 rc = mgs_modify(env, mgs, fsdb, mti, logname,
3627 deactive_osc ? "add osc" : "add osp",
3629 name_destroy(&logname);
3635 LCONSOLE_ERROR_MSG(0x145, "Couldn't find %s in"
3636 "log (%d). No permanent "
3637 "changes were made to the "
3639 mti->mti_svname, rc);
3640 if (test_bit(FSDB_OLDLOG14, &fsdb->fsdb_flags))
3641 LCONSOLE_ERROR_MSG(0x146, "This may be"
3646 "update the logs.\n");
3649 /* Fall through to osc/mdc proc for deactivating live
3650 OSC/OSP on running MDT / clients. */
3652 /* Below here, let obd's XXX_process_config methods handle it */
3654 /* All lov. in proc */
3655 if (class_match_param(ptr, PARAM_LOV, NULL) == 0) {
3658 CDEBUG(D_MGS, "lov param %s\n", ptr);
3659 if (!(mti->mti_flags & LDD_F_SV_TYPE_MDT)) {
3660 LCONSOLE_ERROR_MSG(0x147, "LOV params must be "
3661 "set on the MDT, not %s. "
3668 if (mgs_log_is_empty(env, mgs, mti->mti_svname))
3669 GOTO(end, rc = -ENODEV);
3671 rc = name_create_mdt_and_lov(&logname, &mdtlovname, fsdb,
3672 mti->mti_stripe_index);
3675 rc = mgs_wlp_lcfg(env, mgs, fsdb, mti, mti->mti_svname,
3676 &mgi->mgi_bufs, mdtlovname, ptr);
3677 name_destroy(&logname);
3678 name_destroy(&mdtlovname);
3683 rc = name_create(&logname, mti->mti_fsname, "-client");
3686 rc = mgs_wlp_lcfg(env, mgs, fsdb, mti, logname, &mgi->mgi_bufs,
3687 fsdb->fsdb_clilov, ptr);
3688 name_destroy(&logname);
3692 /* All osc., mdc., llite. params in proc */
3693 if ((class_match_param(ptr, PARAM_OSC, NULL) == 0) ||
3694 (class_match_param(ptr, PARAM_MDC, NULL) == 0) ||
3695 (class_match_param(ptr, PARAM_LLITE, NULL) == 0)) {
3698 if (test_bit(FSDB_OLDLOG14, &fsdb->fsdb_flags)) {
3699 LCONSOLE_ERROR_MSG(0x148, "Upgraded client logs for %s"
3700 " cannot be modified. Consider"
3701 " updating the configuration with"
3704 GOTO(end, rc = -EINVAL);
3706 if (memcmp(ptr, PARAM_LLITE, strlen(PARAM_LLITE)) == 0) {
3707 rc = name_create(&cname, mti->mti_fsname, "-client");
3708 /* Add the client type to match the obdname in
3709 class_config_llog_handler */
3710 } else if (mti->mti_flags & LDD_F_SV_TYPE_MDT) {
3711 rc = name_create(&cname, mti->mti_svname, "-mdc");
3712 } else if (mti->mti_flags & LDD_F_SV_TYPE_OST) {
3713 rc = name_create(&cname, mti->mti_svname, "-osc");
3715 GOTO(end, rc = -EINVAL);
3720 /* Forbid direct update of llite root squash parameters.
3721 * These parameters are indirectly set via the MDT settings.
3723 if ((class_match_param(ptr, PARAM_LLITE, &tmp) == 0) &&
3724 ((memcmp(tmp, "root_squash=", 12) == 0) ||
3725 (memcmp(tmp, "nosquash_nids=", 14) == 0))) {
3726 LCONSOLE_ERROR("%s: root squash parameters can only "
3727 "be updated through MDT component\n",
3729 name_destroy(&cname);
3730 GOTO(end, rc = -EINVAL);
3733 CDEBUG(D_MGS, "%.3s param %s\n", ptr, ptr + 4);
3736 rc = name_create(&logname, mti->mti_fsname, "-client");
3738 name_destroy(&cname);
3741 rc = mgs_wlp_lcfg(env, mgs, fsdb, mti, logname, &mgi->mgi_bufs,
3744 /* osc params affect the MDT as well */
3745 if (!rc && (mti->mti_flags & LDD_F_SV_TYPE_OST)) {
3748 for (i = 0; i < INDEX_MAP_SIZE * 8; i++){
3749 if (!test_bit(i, fsdb->fsdb_mdt_index_map))
3751 name_destroy(&cname);
3752 rc = name_create_mdt_osc(&cname, mti->mti_svname,
3754 name_destroy(&logname);
3757 rc = name_create_mdt(&logname,
3758 mti->mti_fsname, i);
3761 if (!mgs_log_is_empty(env, mgs, logname)) {
3762 rc = mgs_wlp_lcfg(env, mgs, fsdb,
3772 /* For mdc activate/deactivate, it affects OSP on MDT as well */
3773 if (class_match_param(ptr, PARAM_MDC PARAM_ACTIVE, &tmp) == 0 &&
3776 char *lodname = NULL;
3777 char *param_str = NULL;
3781 /* replace mdc with osp */
3782 memcpy(ptr, PARAM_OSP, strlen(PARAM_OSP));
3783 rc = server_name2index(mti->mti_svname, &index, NULL);
3785 memcpy(ptr, PARAM_MDC, strlen(PARAM_MDC));
3789 for (i = 0; i < INDEX_MAP_SIZE * 8; i++) {
3790 if (!test_bit(i, fsdb->fsdb_mdt_index_map))
3796 name_destroy(&logname);
3797 rc = name_create_mdt(&logname, mti->mti_fsname,
3802 if (mgs_log_is_empty(env, mgs, logname))
3805 snprintf(suffix, sizeof(suffix), "-osp-MDT%04x",
3807 name_destroy(&cname);
3808 rc = name_create(&cname, mti->mti_svname,
3813 rc = mgs_wlp_lcfg(env, mgs, fsdb, mti, logname,
3814 &mgi->mgi_bufs, cname, ptr);
3818 /* Add configuration log for noitfying LOD
3819 * to active/deactive the OSP. */
3820 name_destroy(¶m_str);
3821 rc = name_create(¶m_str, cname,
3822 (*tmp == '0') ? ".active=0" :
3827 name_destroy(&lodname);
3828 rc = name_create(&lodname, logname, "-mdtlov");
3832 rc = mgs_wlp_lcfg(env, mgs, fsdb, mti, logname,
3833 &mgi->mgi_bufs, lodname,
3838 memcpy(ptr, PARAM_MDC, strlen(PARAM_MDC));
3839 name_destroy(&lodname);
3840 name_destroy(¶m_str);
3843 name_destroy(&logname);
3844 name_destroy(&cname);
3848 /* All mdt. params in proc */
3849 if (class_match_param(ptr, PARAM_MDT, &tmp) == 0) {
3853 CDEBUG(D_MGS, "%.3s param %s\n", ptr, ptr + 4);
3854 if (strncmp(mti->mti_svname, mti->mti_fsname,
3855 MTI_NAME_MAXLEN) == 0)
3856 /* device is unspecified completely? */
3857 rc = LDD_F_SV_TYPE_MDT | LDD_F_SV_ALL;
3859 rc = server_name2index(mti->mti_svname, &idx, NULL);
3862 if ((rc & LDD_F_SV_TYPE_MDT) == 0)
3864 if (rc & LDD_F_SV_ALL) {
3865 for (i = 0; i < INDEX_MAP_SIZE * 8; i++) {
3867 fsdb->fsdb_mdt_index_map))
3869 rc = name_create_mdt(&logname,
3870 mti->mti_fsname, i);
3873 rc = mgs_wlp_lcfg(env, mgs, fsdb, mti,
3874 logname, &mgi->mgi_bufs,
3876 name_destroy(&logname);
3881 if ((memcmp(tmp, "root_squash=", 12) == 0) ||
3882 (memcmp(tmp, "nosquash_nids=", 14) == 0)) {
3883 LCONSOLE_ERROR("%s: root squash parameters "
3884 "cannot be applied to a single MDT\n",
3886 GOTO(end, rc = -EINVAL);
3888 rc = mgs_wlp_lcfg(env, mgs, fsdb, mti,
3889 mti->mti_svname, &mgi->mgi_bufs,
3890 mti->mti_svname, ptr);
3895 /* root squash settings are also applied to llite
3896 * config log (see LU-1778) */
3898 ((memcmp(tmp, "root_squash=", 12) == 0) ||
3899 (memcmp(tmp, "nosquash_nids=", 14) == 0))) {
3903 rc = name_create(&cname, mti->mti_fsname, "-client");
3906 rc = name_create(&logname, mti->mti_fsname, "-client");
3908 name_destroy(&cname);
3911 rc = name_create(&ptr2, PARAM_LLITE, tmp);
3913 name_destroy(&cname);
3914 name_destroy(&logname);
3917 rc = mgs_wlp_lcfg(env, mgs, fsdb, mti, logname,
3918 &mgi->mgi_bufs, cname, ptr2);
3919 name_destroy(&ptr2);
3920 name_destroy(&logname);
3921 name_destroy(&cname);
3926 /* All mdd., ost. and osd. params in proc */
3927 if ((class_match_param(ptr, PARAM_MDD, NULL) == 0) ||
3928 (class_match_param(ptr, PARAM_LOD, NULL) == 0) ||
3929 (class_match_param(ptr, PARAM_OST, NULL) == 0) ||
3930 (class_match_param(ptr, PARAM_OSD, NULL) == 0)) {
3931 CDEBUG(D_MGS, "%.3s param %s\n", ptr, ptr + 4);
3932 if (mgs_log_is_empty(env, mgs, mti->mti_svname))
3933 GOTO(end, rc = -ENODEV);
3935 rc = mgs_wlp_lcfg(env, mgs, fsdb, mti, mti->mti_svname,
3936 &mgi->mgi_bufs, mti->mti_svname, ptr);
3940 LCONSOLE_WARN("Ignoring unrecognized param '%s'\n", ptr);
3944 CERROR("err %d on param '%s'\n", rc, ptr);
3949 int mgs_write_log_target(const struct lu_env *env, struct mgs_device *mgs,
3950 struct mgs_target_info *mti, struct fs_db *fsdb)
3957 /* set/check the new target index */
3958 rc = mgs_set_index(env, mgs, mti);
3962 if (rc == EALREADY) {
3963 LCONSOLE_WARN("Found index %d for %s, updating log\n",
3964 mti->mti_stripe_index, mti->mti_svname);
3965 /* We would like to mark old log sections as invalid
3966 and add new log sections in the client and mdt logs.
3967 But if we add new sections, then live clients will
3968 get repeat setup instructions for already running
3969 osc's. So don't update the client/mdt logs. */
3970 mti->mti_flags &= ~LDD_F_UPDATE;
3974 OBD_FAIL_TIMEOUT(OBD_FAIL_MGS_WRITE_TARGET_DELAY, cfs_fail_val > 0 ?
3977 mutex_lock(&fsdb->fsdb_mutex);
3979 if (mti->mti_flags &
3980 (LDD_F_VIRGIN | LDD_F_UPGRADE14 | LDD_F_WRITECONF)) {
3981 /* Generate a log from scratch */
3982 if (mti->mti_flags & LDD_F_SV_TYPE_MDT) {
3983 rc = mgs_write_log_mdt(env, mgs, fsdb, mti);
3984 } else if (mti->mti_flags & LDD_F_SV_TYPE_OST) {
3985 rc = mgs_write_log_ost(env, mgs, fsdb, mti);
3987 CERROR("Unknown target type %#x, can't create log for "
3988 "%s\n", mti->mti_flags, mti->mti_svname);
3991 CERROR("Can't write logs for %s (%d)\n",
3992 mti->mti_svname, rc);
3996 /* Just update the params from tunefs in mgs_write_log_params */
3997 CDEBUG(D_MGS, "Update params for %s\n", mti->mti_svname);
3998 mti->mti_flags |= LDD_F_PARAM;
4001 /* allocate temporary buffer, where class_get_next_param will
4002 make copy of a current parameter */
4003 OBD_ALLOC(buf, strlen(mti->mti_params) + 1);
4005 GOTO(out_up, rc = -ENOMEM);
4006 params = mti->mti_params;
4007 while (params != NULL) {
4008 rc = class_get_next_param(¶ms, buf);
4011 /* there is no next parameter, that is
4016 CDEBUG(D_MGS, "remaining string: '%s', param: '%s'\n",
4018 rc = mgs_write_log_param(env, mgs, fsdb, mti, buf);
4023 OBD_FREE(buf, strlen(mti->mti_params) + 1);
4026 mutex_unlock(&fsdb->fsdb_mutex);
4030 int mgs_erase_log(const struct lu_env *env, struct mgs_device *mgs, char *name)
4032 struct llog_ctxt *ctxt;
4035 ctxt = llog_get_context(mgs->mgs_obd, LLOG_CONFIG_ORIG_CTXT);
4037 CERROR("%s: MGS config context doesn't exist\n",
4038 mgs->mgs_obd->obd_name);
4041 rc = llog_erase(env, ctxt, NULL, name);
4042 /* llog may not exist */
4045 llog_ctxt_put(ctxt);
4049 CERROR("%s: failed to clear log %s: %d\n",
4050 mgs->mgs_obd->obd_name, name, rc);
4055 /* erase all logs for the given fs */
4056 int mgs_erase_logs(const struct lu_env *env, struct mgs_device *mgs,
4059 struct list_head log_list;
4060 struct mgs_direntry *dirent, *n;
4061 char barrier_name[20] = {};
4064 int rc, len = strlen(fsname);
4067 mutex_lock(&mgs->mgs_mutex);
4069 /* Find all the logs in the CONFIGS directory */
4070 rc = class_dentry_readdir(env, mgs, &log_list);
4072 mutex_unlock(&mgs->mgs_mutex);
4076 if (list_empty(&log_list)) {
4077 mutex_unlock(&mgs->mgs_mutex);
4081 snprintf(barrier_name, sizeof(barrier_name) - 1, "%s-%s",
4082 fsname, BARRIER_FILENAME);
4083 /* Delete the barrier fsdb */
4084 mgs_remove_fsdb_by_name(mgs, barrier_name);
4085 /* Delete the fs db */
4086 mgs_remove_fsdb_by_name(mgs, fsname);
4087 mutex_unlock(&mgs->mgs_mutex);
4089 list_for_each_entry_safe(dirent, n, &log_list, mde_list) {
4090 list_del_init(&dirent->mde_list);
4091 suffix = strrchr(dirent->mde_name, '-');
4092 if (suffix != NULL) {
4093 if ((len == suffix - dirent->mde_name) &&
4094 (strncmp(fsname, dirent->mde_name, len) == 0)) {
4095 CDEBUG(D_MGS, "Removing log %s\n",
4097 mgs_erase_log(env, mgs, dirent->mde_name);
4101 mgs_direntry_free(dirent);
4110 /* list all logs for the given fs */
4111 int mgs_list_logs(const struct lu_env *env, struct mgs_device *mgs,
4112 struct obd_ioctl_data *data)
4114 struct list_head log_list;
4115 struct mgs_direntry *dirent, *n;
4121 /* Find all the logs in the CONFIGS directory */
4122 rc = class_dentry_readdir(env, mgs, &log_list);
4126 out = data->ioc_bulk;
4127 remains = data->ioc_inllen1;
4128 list_for_each_entry_safe(dirent, n, &log_list, mde_list) {
4129 list_del_init(&dirent->mde_list);
4130 suffix = strrchr(dirent->mde_name, '-');
4131 if (suffix != NULL) {
4132 l = snprintf(out, remains, "config_log: %s\n",
4137 mgs_direntry_free(dirent);
4144 struct mgs_lcfg_fork_data {
4145 struct lustre_cfg_bufs mlfd_bufs;
4146 struct mgs_device *mlfd_mgs;
4147 struct llog_handle *mlfd_llh;
4148 const char *mlfd_oldname;
4149 const char *mlfd_newname;
4153 static bool contain_valid_fsname(char *buf, const char *fsname,
4154 int buflen, int namelen)
4156 if (buflen < namelen)
4159 if (memcmp(buf, fsname, namelen) != 0)
4162 if (buf[namelen] != '\0' && buf[namelen] != '-')
4168 static int mgs_lcfg_fork_handler(const struct lu_env *env,
4169 struct llog_handle *o_llh,
4170 struct llog_rec_hdr *o_rec, void *data)
4172 struct mgs_lcfg_fork_data *mlfd = data;
4173 struct lustre_cfg_bufs *n_bufs = &mlfd->mlfd_bufs;
4174 struct lustre_cfg *o_lcfg = (struct lustre_cfg *)(o_rec + 1);
4175 struct llog_cfg_rec *lcr;
4177 char *n_buf = mlfd->mlfd_data;
4179 int o_namelen = strlen(mlfd->mlfd_oldname);
4180 int n_namelen = strlen(mlfd->mlfd_newname);
4181 int diff = n_namelen - o_namelen;
4182 __u32 cmd = o_lcfg->lcfg_command;
4183 __u32 cnt = o_lcfg->lcfg_bufcount;
4189 o_buf = lustre_cfg_buf(o_lcfg, 0);
4190 o_buflen = o_lcfg->lcfg_buflens[0];
4191 if (contain_valid_fsname(o_buf, mlfd->mlfd_oldname, o_buflen,
4193 memcpy(n_buf, mlfd->mlfd_newname, n_namelen);
4194 memcpy(n_buf + n_namelen, o_buf + o_namelen,
4195 o_buflen - o_namelen);
4196 lustre_cfg_bufs_reset(n_bufs, n_buf);
4197 n_buf += cfs_size_round(o_buflen + diff);
4199 lustre_cfg_bufs_reset(n_bufs, o_buflen != 0 ? o_buf : NULL);
4204 struct cfg_marker *o_marker;
4205 struct cfg_marker *n_marker;
4209 CDEBUG(D_MGS, "Unknown cfg marker entry with %d "
4214 /* buf[1] is marker */
4215 o_buf = lustre_cfg_buf(o_lcfg, 1);
4216 o_buflen = o_lcfg->lcfg_buflens[1];
4217 o_marker = (struct cfg_marker *)o_buf;
4218 if (!contain_valid_fsname(o_marker->cm_tgtname,
4220 sizeof(o_marker->cm_tgtname),
4222 lustre_cfg_bufs_set(n_bufs, 1, o_marker,
4227 n_marker = (struct cfg_marker *)n_buf;
4228 *n_marker = *o_marker;
4229 memcpy(n_marker->cm_tgtname, mlfd->mlfd_newname, n_namelen);
4230 tgt_namelen = strlen(o_marker->cm_tgtname);
4231 if (tgt_namelen > o_namelen)
4232 memcpy(n_marker->cm_tgtname + n_namelen,
4233 o_marker->cm_tgtname + o_namelen,
4234 tgt_namelen - o_namelen);
4235 n_marker->cm_tgtname[tgt_namelen + diff] = '\0';
4236 lustre_cfg_bufs_set(n_bufs, 1, n_marker, sizeof(*n_marker));
4240 case LCFG_SET_PARAM: {
4241 for (i = 1; i < cnt; i++)
4242 /* buf[i] is the param value, reuse it directly */
4243 lustre_cfg_bufs_set(n_bufs, i,
4244 lustre_cfg_buf(o_lcfg, i),
4245 o_lcfg->lcfg_buflens[i]);
4251 case LCFG_POOL_DEL: {
4252 if (cnt < 3 || cnt > 4) {
4253 CDEBUG(D_MGS, "Unknown cfg pool (%x) entry with %d "
4254 "buffers\n", cmd, cnt);
4258 /* buf[1] is fsname */
4259 o_buf = lustre_cfg_buf(o_lcfg, 1);
4260 o_buflen = o_lcfg->lcfg_buflens[1];
4261 memcpy(n_buf, mlfd->mlfd_newname, n_namelen);
4262 memcpy(n_buf + n_namelen, o_buf + o_namelen,
4263 o_buflen - o_namelen);
4264 lustre_cfg_bufs_set(n_bufs, 1, n_buf, o_buflen + diff);
4265 n_buf += cfs_size_round(o_buflen + diff);
4267 /* buf[2] is the pool name, reuse it directly */
4268 lustre_cfg_bufs_set(n_bufs, 2, lustre_cfg_buf(o_lcfg, 2),
4269 o_lcfg->lcfg_buflens[2]);
4274 /* buf[3] is ostname */
4275 o_buf = lustre_cfg_buf(o_lcfg, 3);
4276 o_buflen = o_lcfg->lcfg_buflens[3];
4277 memcpy(n_buf, mlfd->mlfd_newname, n_namelen);
4278 memcpy(n_buf + n_namelen, o_buf + o_namelen,
4279 o_buflen - o_namelen);
4280 lustre_cfg_bufs_set(n_bufs, 3, n_buf, o_buflen + diff);
4285 o_buflen = o_lcfg->lcfg_buflens[1];
4286 if (o_buflen == sizeof(struct lov_desc) ||
4287 o_buflen == sizeof(struct lmv_desc)) {
4293 o_buf = lustre_cfg_buf(o_lcfg, 1);
4294 if (o_buflen == sizeof(struct lov_desc)) {
4295 struct lov_desc *o_desc =
4296 (struct lov_desc *)o_buf;
4297 struct lov_desc *n_desc =
4298 (struct lov_desc *)n_buf;
4301 o_uuid = o_desc->ld_uuid.uuid;
4302 n_uuid = n_desc->ld_uuid.uuid;
4303 uuid_len = sizeof(o_desc->ld_uuid.uuid);
4305 struct lmv_desc *o_desc =
4306 (struct lmv_desc *)o_buf;
4307 struct lmv_desc *n_desc =
4308 (struct lmv_desc *)n_buf;
4311 o_uuid = o_desc->ld_uuid.uuid;
4312 n_uuid = n_desc->ld_uuid.uuid;
4313 uuid_len = sizeof(o_desc->ld_uuid.uuid);
4316 if (unlikely(!contain_valid_fsname(o_uuid,
4317 mlfd->mlfd_oldname, uuid_len,
4319 lustre_cfg_bufs_set(n_bufs, 1, o_buf,
4324 memcpy(n_uuid, mlfd->mlfd_newname, n_namelen);
4325 uuid_len = strlen(o_uuid);
4326 if (uuid_len > o_namelen)
4327 memcpy(n_uuid + n_namelen,
4329 uuid_len - o_namelen);
4330 n_uuid[uuid_len + diff] = '\0';
4331 lustre_cfg_bufs_set(n_bufs, 1, n_buf, o_buflen);
4333 } /* else case fall through */
4334 } /* else case fall through */
4337 for (i = 1; i < cnt; i++) {
4338 o_buflen = o_lcfg->lcfg_buflens[i];
4342 o_buf = lustre_cfg_buf(o_lcfg, i);
4343 if (!contain_valid_fsname(o_buf, mlfd->mlfd_oldname,
4344 o_buflen, o_namelen)) {
4345 lustre_cfg_bufs_set(n_bufs, i, o_buf, o_buflen);
4349 memcpy(n_buf, mlfd->mlfd_newname, n_namelen);
4350 if (o_buflen == o_namelen) {
4351 lustre_cfg_bufs_set(n_bufs, i, n_buf,
4353 n_buf += cfs_size_round(n_namelen);
4357 memcpy(n_buf + n_namelen, o_buf + o_namelen,
4358 o_buflen - o_namelen);
4359 lustre_cfg_bufs_set(n_bufs, i, n_buf, o_buflen + diff);
4360 n_buf += cfs_size_round(o_buflen + diff);
4366 lcr = lustre_cfg_rec_new(cmd, n_bufs);
4370 lcr->lcr_cfg = *o_lcfg;
4371 rc = llog_write(env, mlfd->mlfd_llh, &lcr->lcr_hdr, LLOG_NEXT_IDX);
4372 lustre_cfg_rec_free(lcr);
4377 static int mgs_lcfg_fork_one(const struct lu_env *env, struct mgs_device *mgs,
4378 struct mgs_direntry *mde, const char *oldname,
4379 const char *newname)
4381 struct llog_handle *old_llh = NULL;
4382 struct llog_handle *new_llh = NULL;
4383 struct llog_ctxt *ctxt = NULL;
4384 struct mgs_lcfg_fork_data *mlfd = NULL;
4385 char *name_buf = NULL;
4387 int old_namelen = strlen(oldname);
4388 int new_namelen = strlen(newname);
4392 name_buflen = mde->mde_len + new_namelen - old_namelen;
4393 OBD_ALLOC(name_buf, name_buflen);
4397 memcpy(name_buf, newname, new_namelen);
4398 memcpy(name_buf + new_namelen, mde->mde_name + old_namelen,
4399 mde->mde_len - old_namelen);
4401 CDEBUG(D_MGS, "Fork the config-log from %s to %s\n",
4402 mde->mde_name, name_buf);
4404 ctxt = llog_get_context(mgs->mgs_obd, LLOG_CONFIG_ORIG_CTXT);
4407 rc = llog_open_create(env, ctxt, &new_llh, NULL, name_buf);
4411 rc = llog_init_handle(env, new_llh, LLOG_F_IS_PLAIN, NULL);
4415 if (unlikely(mgs_log_is_empty(env, mgs, mde->mde_name)))
4418 rc = llog_open(env, ctxt, &old_llh, NULL, mde->mde_name,
4423 rc = llog_init_handle(env, old_llh, LLOG_F_IS_PLAIN, NULL);
4427 new_llh->lgh_hdr->llh_tgtuuid = old_llh->lgh_hdr->llh_tgtuuid;
4429 OBD_ALLOC(mlfd, LLOG_MIN_CHUNK_SIZE);
4431 GOTO(out, rc = -ENOMEM);
4433 mlfd->mlfd_mgs = mgs;
4434 mlfd->mlfd_llh = new_llh;
4435 mlfd->mlfd_oldname = oldname;
4436 mlfd->mlfd_newname = newname;
4438 rc = llog_process(env, old_llh, mgs_lcfg_fork_handler, mlfd, NULL);
4439 OBD_FREE(mlfd, LLOG_MIN_CHUNK_SIZE);
4445 llog_close(env, old_llh);
4447 llog_close(env, new_llh);
4449 OBD_FREE(name_buf, name_buflen);
4451 llog_ctxt_put(ctxt);
4456 int mgs_lcfg_fork(const struct lu_env *env, struct mgs_device *mgs,
4457 const char *oldname, const char *newname)
4459 struct list_head log_list;
4460 struct mgs_direntry *dirent, *n;
4461 int olen = strlen(oldname);
4462 int nlen = strlen(newname);
4467 if (unlikely(!oldname || oldname[0] == '\0' ||
4468 !newname || newname[0] == '\0'))
4471 if (strcmp(oldname, newname) == 0)
4474 /* lock it to prevent fork/erase/register in parallel. */
4475 mutex_lock(&mgs->mgs_mutex);
4477 rc = class_dentry_readdir(env, mgs, &log_list);
4479 mutex_unlock(&mgs->mgs_mutex);
4483 if (list_empty(&log_list)) {
4484 mutex_unlock(&mgs->mgs_mutex);
4488 list_for_each_entry_safe(dirent, n, &log_list, mde_list) {
4491 ptr = strrchr(dirent->mde_name, '-');
4493 int tlen = ptr - dirent->mde_name;
4496 strncmp(newname, dirent->mde_name, tlen) == 0)
4497 GOTO(out, rc = -EEXIST);
4500 strncmp(oldname, dirent->mde_name, tlen) == 0)
4504 list_del_init(&dirent->mde_list);
4505 mgs_direntry_free(dirent);
4508 if (list_empty(&log_list)) {
4509 mutex_unlock(&mgs->mgs_mutex);
4513 list_for_each_entry(dirent, &log_list, mde_list) {
4514 rc = mgs_lcfg_fork_one(env, mgs, dirent, oldname, newname);
4522 mutex_unlock(&mgs->mgs_mutex);
4524 list_for_each_entry_safe(dirent, n, &log_list, mde_list) {
4525 list_del_init(&dirent->mde_list);
4526 mgs_direntry_free(dirent);
4529 if (rc && count > 0)
4530 mgs_erase_logs(env, mgs, newname);
4535 int mgs_lcfg_erase(const struct lu_env *env, struct mgs_device *mgs,
4541 if (unlikely(!fsname || fsname[0] == '\0'))
4544 rc = mgs_erase_logs(env, mgs, fsname);
4549 static int mgs_xattr_del(const struct lu_env *env, struct dt_object *obj)
4551 struct dt_device *dev;
4552 struct thandle *th = NULL;
4557 dev = container_of0(obj->do_lu.lo_dev, struct dt_device, dd_lu_dev);
4558 th = dt_trans_create(env, dev);
4560 RETURN(PTR_ERR(th));
4562 rc = dt_declare_xattr_del(env, obj, XATTR_TARGET_RENAME, th);
4566 rc = dt_trans_start_local(env, dev, th);
4570 dt_write_lock(env, obj, 0);
4571 rc = dt_xattr_del(env, obj, XATTR_TARGET_RENAME, th);
4576 dt_write_unlock(env, obj);
4579 dt_trans_stop(env, dev, th);
4584 int mgs_lcfg_rename(const struct lu_env *env, struct mgs_device *mgs)
4586 struct list_head log_list;
4587 struct mgs_direntry *dirent, *n;
4589 struct lu_buf buf = {
4591 .lb_len = sizeof(fsname)
4597 rc = class_dentry_readdir(env, mgs, &log_list);
4601 if (list_empty(&log_list))
4604 list_for_each_entry_safe(dirent, n, &log_list, mde_list) {
4605 struct dt_object *o = NULL;
4610 list_del_init(&dirent->mde_list);
4611 ptr = strrchr(dirent->mde_name, '-');
4615 len = ptr - dirent->mde_name;
4616 if (unlikely(len >= sizeof(oldname))) {
4617 CDEBUG(D_MGS, "Skip invalid configuration file %s\n",
4622 o = local_file_find(env, mgs->mgs_los, mgs->mgs_configs_dir,
4626 CDEBUG(D_MGS, "Fail to locate file %s: rc = %d\n",
4627 dirent->mde_name, rc);
4631 rc = dt_xattr_get(env, o, &buf, XATTR_TARGET_RENAME);
4637 "Fail to get EA for %s: rc = %d\n",
4638 dirent->mde_name, rc);
4642 if (unlikely(rc == len &&
4643 memcmp(fsname, dirent->mde_name, len) == 0)) {
4644 /* The new fsname is the same as the old one. */
4645 rc = mgs_xattr_del(env, o);
4649 memcpy(oldname, dirent->mde_name, len);
4650 oldname[len] = '\0';
4652 rc = mgs_lcfg_fork_one(env, mgs, dirent, oldname, fsname);
4653 if (rc && rc != -EEXIST) {
4654 CDEBUG(D_MGS, "Fail to fork %s: rc = %d\n",
4655 dirent->mde_name, rc);
4659 rc = mgs_erase_log(env, mgs, dirent->mde_name);
4661 CDEBUG(D_MGS, "Fail to erase old %s: rc = %d\n",
4662 dirent->mde_name, rc);
4663 /* keep it there if failed to remove it. */
4668 if (o && !IS_ERR(o))
4669 lu_object_put(env, &o->do_lu);
4671 mgs_direntry_free(dirent);
4676 list_for_each_entry_safe(dirent, n, &log_list, mde_list) {
4677 list_del_init(&dirent->mde_list);
4678 mgs_direntry_free(dirent);
4684 /* from llog_swab */
4685 static void print_lustre_cfg(struct lustre_cfg *lcfg)
4690 CDEBUG(D_MGS, "lustre_cfg: %p\n", lcfg);
4691 CDEBUG(D_MGS, "\tlcfg->lcfg_version: %#x\n", lcfg->lcfg_version);
4693 CDEBUG(D_MGS, "\tlcfg->lcfg_command: %#x\n", lcfg->lcfg_command);
4694 CDEBUG(D_MGS, "\tlcfg->lcfg_num: %#x\n", lcfg->lcfg_num);
4695 CDEBUG(D_MGS, "\tlcfg->lcfg_flags: %#x\n", lcfg->lcfg_flags);
4696 CDEBUG(D_MGS, "\tlcfg->lcfg_nid: %s\n", libcfs_nid2str(lcfg->lcfg_nid));
4698 CDEBUG(D_MGS, "\tlcfg->lcfg_bufcount: %d\n", lcfg->lcfg_bufcount);
4699 if (lcfg->lcfg_bufcount < LUSTRE_CFG_MAX_BUFCOUNT)
4700 for (i = 0; i < lcfg->lcfg_bufcount; i++) {
4701 CDEBUG(D_MGS, "\tlcfg->lcfg_buflens[%d]: %d %s\n",
4702 i, lcfg->lcfg_buflens[i],
4703 lustre_cfg_string(lcfg, i));
4708 /* Setup _mgs fsdb and log
4710 int mgs__mgs_fsdb_setup(const struct lu_env *env, struct mgs_device *mgs)
4712 struct fs_db *fsdb = NULL;
4716 rc = mgs_find_or_make_fsdb(env, mgs, MGSSELF_NAME, &fsdb);
4718 mgs_put_fsdb(mgs, fsdb);
4723 /* Setup params fsdb and log
4725 int mgs_params_fsdb_setup(const struct lu_env *env, struct mgs_device *mgs)
4727 struct fs_db *fsdb = NULL;
4728 struct llog_handle *params_llh = NULL;
4732 rc = mgs_find_or_make_fsdb(env, mgs, PARAMS_FILENAME, &fsdb);
4734 mutex_lock(&fsdb->fsdb_mutex);
4735 rc = record_start_log(env, mgs, ¶ms_llh, PARAMS_FILENAME);
4737 rc = record_end_log(env, ¶ms_llh);
4738 mutex_unlock(&fsdb->fsdb_mutex);
4739 mgs_put_fsdb(mgs, fsdb);
4745 /* Cleanup params fsdb and log
4747 int mgs_params_fsdb_cleanup(const struct lu_env *env, struct mgs_device *mgs)
4751 rc = mgs_erase_logs(env, mgs, PARAMS_FILENAME);
4752 return rc == -ENOENT ? 0 : rc;
4755 /* Set a permanent (config log) param for a target or fs
4756 * \param lcfg buf0 may contain the device (testfs-MDT0000) name
4757 * buf1 contains the single parameter
4759 int mgs_setparam(const struct lu_env *env, struct mgs_device *mgs,
4760 struct lustre_cfg *lcfg, char *fsname)
4762 struct fs_db *fsdb = NULL;
4763 struct mgs_target_info *mti = NULL;
4764 char *devname, *param;
4772 print_lustre_cfg(lcfg);
4774 /* lustre, lustre-mdtlov, lustre-client, lustre-MDT0000 */
4775 devname = lustre_cfg_string(lcfg, 0);
4776 param = lustre_cfg_string(lcfg, 1);
4778 /* Assume device name embedded in param:
4779 lustre-OST0000.osc.max_dirty_mb=32 */
4780 ptr = strchr(param, '.');
4788 LCONSOLE_ERROR_MSG(0x14d, "No target specified: %s\n", param);
4792 rc = mgs_parse_devname(devname, fsname, NULL);
4793 if (rc == 0 && !mgs_parse_devname(devname, NULL, &index)) {
4794 /* param related to llite isn't allowed to set by OST or MDT */
4795 if (rc == 0 && strncmp(param, PARAM_LLITE,
4796 sizeof(PARAM_LLITE) - 1) == 0)
4799 /* assume devname is the fsname */
4800 strlcpy(fsname, devname, MTI_NAME_MAXLEN);
4802 CDEBUG(D_MGS, "setparam fs='%s' device='%s'\n", fsname, devname);
4804 rc = mgs_find_or_make_fsdb(env, mgs,
4805 lcfg->lcfg_command == LCFG_SET_PARAM ?
4806 PARAMS_FILENAME : fsname, &fsdb);
4810 if (lcfg->lcfg_command != LCFG_SET_PARAM &&
4811 !test_bit(FSDB_MGS_SELF, &fsdb->fsdb_flags) &&
4812 test_bit(FSDB_LOG_EMPTY, &fsdb->fsdb_flags)) {
4813 CERROR("No filesystem targets for %s. cfg_device from lctl "
4814 "is '%s'\n", fsname, devname);
4816 GOTO(out, rc = -EINVAL);
4819 /* Create a fake mti to hold everything */
4822 GOTO(out, rc = -ENOMEM);
4823 if (strlcpy(mti->mti_fsname, fsname, sizeof(mti->mti_fsname))
4824 >= sizeof(mti->mti_fsname))
4825 GOTO(out, rc = -E2BIG);
4826 if (strlcpy(mti->mti_svname, devname, sizeof(mti->mti_svname))
4827 >= sizeof(mti->mti_svname))
4828 GOTO(out, rc = -E2BIG);
4829 if (strlcpy(mti->mti_params, param, sizeof(mti->mti_params))
4830 >= sizeof(mti->mti_params))
4831 GOTO(out, rc = -E2BIG);
4832 rc = server_name2index(mti->mti_svname, &mti->mti_stripe_index, &tmp);
4834 /* Not a valid server; may be only fsname */
4837 /* Strip -osc or -mdc suffix from svname */
4838 if (server_make_name(rc, mti->mti_stripe_index, mti->mti_fsname,
4839 mti->mti_svname, sizeof(mti->mti_svname)))
4840 GOTO(out, rc = -EINVAL);
4842 * Revoke lock so everyone updates. Should be alright if
4843 * someone was already reading while we were updating the logs,
4844 * so we don't really need to hold the lock while we're
4847 if (lcfg->lcfg_command == LCFG_SET_PARAM) {
4848 mti->mti_flags = rc | LDD_F_PARAM2;
4849 mutex_lock(&fsdb->fsdb_mutex);
4850 rc = mgs_write_log_param2(env, mgs, fsdb, mti, mti->mti_params);
4851 mutex_unlock(&fsdb->fsdb_mutex);
4852 mgs_revoke_lock(mgs, fsdb, CONFIG_T_PARAMS);
4854 mti->mti_flags = rc | LDD_F_PARAM;
4855 mutex_lock(&fsdb->fsdb_mutex);
4856 rc = mgs_write_log_param(env, mgs, fsdb, mti, mti->mti_params);
4857 mutex_unlock(&fsdb->fsdb_mutex);
4858 mgs_revoke_lock(mgs, fsdb, CONFIG_T_CONFIG);
4867 mgs_unlink_fsdb(mgs, fsdb);
4868 mgs_put_fsdb(mgs, fsdb);
4874 static int mgs_write_log_pool(const struct lu_env *env,
4875 struct mgs_device *mgs, char *logname,
4876 struct fs_db *fsdb, char *tgtname,
4877 enum lcfg_command_type cmd,
4878 char *fsname, char *poolname,
4879 char *ostname, char *comment)
4881 struct llog_handle *llh = NULL;
4884 rc = record_start_log(env, mgs, &llh, logname);
4887 rc = record_marker(env, llh, fsdb, CM_START, tgtname, comment);
4890 rc = record_base(env, llh, tgtname, 0, cmd,
4891 fsname, poolname, ostname, NULL);
4894 rc = record_marker(env, llh, fsdb, CM_END, tgtname, comment);
4896 record_end_log(env, &llh);
4900 int mgs_nodemap_cmd(const struct lu_env *env, struct mgs_device *mgs,
4901 enum lcfg_command_type cmd, const char *nodemap_name,
4912 case LCFG_NODEMAP_ADD:
4913 rc = nodemap_add(nodemap_name);
4915 case LCFG_NODEMAP_DEL:
4916 rc = nodemap_del(nodemap_name);
4918 case LCFG_NODEMAP_ADD_RANGE:
4919 rc = nodemap_parse_range(param, nid);
4922 rc = nodemap_add_range(nodemap_name, nid);
4924 case LCFG_NODEMAP_DEL_RANGE:
4925 rc = nodemap_parse_range(param, nid);
4928 rc = nodemap_del_range(nodemap_name, nid);
4930 case LCFG_NODEMAP_ADMIN:
4931 bool_switch = simple_strtoul(param, NULL, 10);
4932 rc = nodemap_set_allow_root(nodemap_name, bool_switch);
4934 case LCFG_NODEMAP_DENY_UNKNOWN:
4935 bool_switch = simple_strtoul(param, NULL, 10);
4936 rc = nodemap_set_deny_unknown(nodemap_name, bool_switch);
4938 case LCFG_NODEMAP_MAP_MODE:
4939 if (strcmp("both", param) == 0)
4940 rc = nodemap_set_mapping_mode(nodemap_name,
4942 else if (strcmp("uid_only", param) == 0)
4943 rc = nodemap_set_mapping_mode(nodemap_name,
4944 NODEMAP_MAP_UID_ONLY);
4945 else if (strcmp("gid_only", param) == 0)
4946 rc = nodemap_set_mapping_mode(nodemap_name,
4947 NODEMAP_MAP_GID_ONLY);
4951 case LCFG_NODEMAP_TRUSTED:
4952 bool_switch = simple_strtoul(param, NULL, 10);
4953 rc = nodemap_set_trust_client_ids(nodemap_name, bool_switch);
4955 case LCFG_NODEMAP_SQUASH_UID:
4956 int_id = simple_strtoul(param, NULL, 10);
4957 rc = nodemap_set_squash_uid(nodemap_name, int_id);
4959 case LCFG_NODEMAP_SQUASH_GID:
4960 int_id = simple_strtoul(param, NULL, 10);
4961 rc = nodemap_set_squash_gid(nodemap_name, int_id);
4963 case LCFG_NODEMAP_ADD_UIDMAP:
4964 case LCFG_NODEMAP_ADD_GIDMAP:
4965 rc = nodemap_parse_idmap(param, idmap);
4968 if (cmd == LCFG_NODEMAP_ADD_UIDMAP)
4969 rc = nodemap_add_idmap(nodemap_name, NODEMAP_UID,
4972 rc = nodemap_add_idmap(nodemap_name, NODEMAP_GID,
4975 case LCFG_NODEMAP_DEL_UIDMAP:
4976 case LCFG_NODEMAP_DEL_GIDMAP:
4977 rc = nodemap_parse_idmap(param, idmap);
4980 if (cmd == LCFG_NODEMAP_DEL_UIDMAP)
4981 rc = nodemap_del_idmap(nodemap_name, NODEMAP_UID,
4984 rc = nodemap_del_idmap(nodemap_name, NODEMAP_GID,
4987 case LCFG_NODEMAP_SET_FILESET:
4988 rc = nodemap_set_fileset(nodemap_name, param);
4997 int mgs_pool_cmd(const struct lu_env *env, struct mgs_device *mgs,
4998 enum lcfg_command_type cmd, char *fsname,
4999 char *poolname, char *ostname)
5004 char *label = NULL, *canceled_label = NULL;
5006 struct mgs_target_info *mti = NULL;
5007 bool checked = false;
5008 bool locked = false;
5013 rc = mgs_find_or_make_fsdb(env, mgs, fsname, &fsdb);
5015 CERROR("Can't get db for %s\n", fsname);
5018 if (test_bit(FSDB_LOG_EMPTY, &fsdb->fsdb_flags)) {
5019 CERROR("%s is not defined\n", fsname);
5021 GOTO(out_fsdb, rc = -EINVAL);
5024 label_sz = 10 + strlen(fsname) + strlen(poolname);
5026 /* check if ostname match fsname */
5027 if (ostname != NULL) {
5030 ptr = strrchr(ostname, '-');
5031 if ((ptr == NULL) ||
5032 (strncmp(fsname, ostname, ptr-ostname) != 0))
5034 label_sz += strlen(ostname);
5037 OBD_ALLOC(label, label_sz);
5039 GOTO(out_fsdb, rc = -ENOMEM);
5044 "new %s.%s", fsname, poolname);
5048 "add %s.%s.%s", fsname, poolname, ostname);
5051 OBD_ALLOC(canceled_label, label_sz);
5052 if (canceled_label == NULL)
5053 GOTO(out_label, rc = -ENOMEM);
5055 "rem %s.%s.%s", fsname, poolname, ostname);
5056 sprintf(canceled_label,
5057 "add %s.%s.%s", fsname, poolname, ostname);
5060 OBD_ALLOC(canceled_label, label_sz);
5061 if (canceled_label == NULL)
5062 GOTO(out_label, rc = -ENOMEM);
5064 "del %s.%s", fsname, poolname);
5065 sprintf(canceled_label,
5066 "new %s.%s", fsname, poolname);
5074 GOTO(out_cancel, rc = -ENOMEM);
5075 strncpy(mti->mti_svname, "lov pool", sizeof(mti->mti_svname));
5077 mutex_lock(&fsdb->fsdb_mutex);
5079 /* write pool def to all MDT logs */
5080 for (i = 0; i < INDEX_MAP_SIZE * 8; i++) {
5081 if (test_bit(i, fsdb->fsdb_mdt_index_map)) {
5082 rc = name_create_mdt_and_lov(&logname, &lovname,
5087 if (!checked && (canceled_label == NULL)) {
5088 rc = mgs_check_marker(env, mgs, fsdb, mti,
5089 logname, lovname, label);
5091 name_destroy(&logname);
5092 name_destroy(&lovname);
5094 rc = (rc == LLOG_PROC_BREAK ?
5099 if (canceled_label != NULL)
5100 rc = mgs_modify(env, mgs, fsdb, mti, logname,
5101 lovname, canceled_label,
5105 rc = mgs_write_log_pool(env, mgs, logname,
5109 name_destroy(&logname);
5110 name_destroy(&lovname);
5116 rc = name_create(&logname, fsname, "-client");
5120 if (!checked && (canceled_label == NULL)) {
5121 rc = mgs_check_marker(env, mgs, fsdb, mti, logname,
5122 fsdb->fsdb_clilov, label);
5124 name_destroy(&logname);
5125 GOTO(out_mti, rc = (rc == LLOG_PROC_BREAK ?
5129 if (canceled_label != NULL) {
5130 rc = mgs_modify(env, mgs, fsdb, mti, logname,
5131 fsdb->fsdb_clilov, canceled_label, CM_SKIP);
5133 name_destroy(&logname);
5138 rc = mgs_write_log_pool(env, mgs, logname, fsdb, fsdb->fsdb_clilov,
5139 cmd, fsname, poolname, ostname, label);
5140 mutex_unlock(&fsdb->fsdb_mutex);
5142 name_destroy(&logname);
5143 /* request for update */
5144 mgs_revoke_lock(mgs, fsdb, CONFIG_T_CONFIG);
5150 mutex_unlock(&fsdb->fsdb_mutex);
5154 if (canceled_label != NULL)
5155 OBD_FREE(canceled_label, label_sz);
5157 OBD_FREE(label, label_sz);
5160 mgs_unlink_fsdb(mgs, fsdb);
5161 mgs_put_fsdb(mgs, fsdb);