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) {
1916 if (sscanf(lustre_cfg_buf(lcfg, 2), "%d", &index) != 1)
1919 memcpy(tmti->mti_fsname, mti->mti_fsname,
1920 strlen(mti->mti_fsname));
1921 tmti->mti_stripe_index = index;
1923 rc = mgs_write_log_osp_to_mdt(env, mgs, fsdb, tmti,
1924 mti->mti_stripe_index,
1926 memset(tmti, 0, sizeof(*tmti));
1930 if (lcfg->lcfg_command == LCFG_LOV_ADD_OBD) {
1933 char *logname, *lovname;
1935 rc = name_create_mdt_and_lov(&logname, &lovname, fsdb,
1936 mti->mti_stripe_index);
1939 sprintf(mdt_index, "-MDT%04x", mti->mti_stripe_index);
1941 if (sscanf(lustre_cfg_buf(lcfg, 2), "%d", &index) != 1) {
1942 name_destroy(&logname);
1943 name_destroy(&lovname);
1947 tmti->mti_stripe_index = index;
1948 rc = mgs_write_log_osc_to_lov(env, mgs, fsdb, tmti, logname,
1951 name_destroy(&logname);
1952 name_destroy(&lovname);
1958 /* fsdb->fsdb_mutex is already held in mgs_write_log_target*/
1959 /* stealed from mgs_get_fsdb_from_llog*/
1960 static int mgs_steal_llog_for_mdt_from_client(const struct lu_env *env,
1961 struct mgs_device *mgs,
1963 struct temp_comp* comp)
1965 struct llog_handle *loghandle;
1966 struct mgs_target_info *tmti;
1967 struct llog_ctxt *ctxt;
1972 ctxt = llog_get_context(mgs->mgs_obd, LLOG_CONFIG_ORIG_CTXT);
1973 LASSERT(ctxt != NULL);
1975 OBD_ALLOC_PTR(tmti);
1977 GOTO(out_ctxt, rc = -ENOMEM);
1979 comp->comp_tmti = tmti;
1980 comp->comp_obd = mgs->mgs_obd;
1982 rc = llog_open(env, ctxt, &loghandle, NULL, client_name,
1990 rc = llog_init_handle(env, loghandle, LLOG_F_IS_PLAIN, NULL);
1992 GOTO(out_close, rc);
1994 rc = llog_process_or_fork(env, loghandle, mgs_steal_client_llog_handler,
1995 (void *)comp, NULL, false);
1996 CDEBUG(D_MGS, "steal llog re = %d\n", rc);
1998 llog_close(env, loghandle);
2002 llog_ctxt_put(ctxt);
2006 /* lmv is the second thing for client logs */
2007 /* copied from mgs_write_log_lov. Please refer to that. */
2008 static int mgs_write_log_lmv(const struct lu_env *env,
2009 struct mgs_device *mgs,
2011 struct mgs_target_info *mti,
2012 char *logname, char *lmvname)
2014 struct llog_handle *llh = NULL;
2015 struct lmv_desc *lmvdesc;
2020 CDEBUG(D_MGS, "Writing lmv(%s) log for %s\n", lmvname,logname);
2022 OBD_ALLOC_PTR(lmvdesc);
2023 if (lmvdesc == NULL)
2025 lmvdesc->ld_active_tgt_count = 0;
2026 lmvdesc->ld_tgt_count = 0;
2027 sprintf((char*)lmvdesc->ld_uuid.uuid, "%s_UUID", lmvname);
2028 uuid = (char *)lmvdesc->ld_uuid.uuid;
2030 rc = record_start_log(env, mgs, &llh, logname);
2033 rc = record_marker(env, llh, fsdb, CM_START, lmvname, "lmv setup");
2036 rc = record_attach(env, llh, lmvname, "lmv", uuid);
2039 rc = record_lmv_setup(env, llh, lmvname, lmvdesc);
2042 rc = record_marker(env, llh, fsdb, CM_END, lmvname, "lmv setup");
2046 record_end_log(env, &llh);
2048 OBD_FREE_PTR(lmvdesc);
2052 /* lov is the first thing in the mdt and client logs */
2053 static int mgs_write_log_lov(const struct lu_env *env, struct mgs_device *mgs,
2054 struct fs_db *fsdb, struct mgs_target_info *mti,
2055 char *logname, char *lovname)
2057 struct llog_handle *llh = NULL;
2058 struct lov_desc *lovdesc;
2063 CDEBUG(D_MGS, "Writing lov(%s) log for %s\n", lovname, logname);
2066 #01 L attach 0:lov_mdsA 1:lov 2:71ccb_lov_mdsA_19f961a9e1
2067 #02 L lov_setup 0:lov_mdsA 1:(struct lov_desc)
2068 uuid=lov1_UUID, stripe count=1, size=1048576, offset=0, pattern=0
2071 /* FIXME just make lov_setup accept empty desc (put uuid in buf 2) */
2072 OBD_ALLOC_PTR(lovdesc);
2073 if (lovdesc == NULL)
2075 lovdesc->ld_magic = LOV_DESC_MAGIC;
2076 lovdesc->ld_tgt_count = 0;
2077 /* Defaults. Can be changed later by lcfg config_param */
2078 lovdesc->ld_default_stripe_count = 1;
2079 lovdesc->ld_pattern = LOV_PATTERN_RAID0;
2080 lovdesc->ld_default_stripe_size = LOV_DESC_STRIPE_SIZE_DEFAULT;
2081 lovdesc->ld_default_stripe_offset = -1;
2082 lovdesc->ld_qos_maxage = LOV_DESC_QOS_MAXAGE_DEFAULT;
2083 sprintf((char*)lovdesc->ld_uuid.uuid, "%s_UUID", lovname);
2084 /* can these be the same? */
2085 uuid = (char *)lovdesc->ld_uuid.uuid;
2087 /* This should always be the first entry in a log.
2088 rc = mgs_clear_log(obd, logname); */
2089 rc = record_start_log(env, mgs, &llh, logname);
2092 /* FIXME these should be a single journal transaction */
2093 rc = record_marker(env, llh, fsdb, CM_START, lovname, "lov setup");
2096 rc = record_attach(env, llh, lovname, "lov", uuid);
2099 rc = record_lov_setup(env, llh, lovname, lovdesc);
2102 rc = record_marker(env, llh, fsdb, CM_END, lovname, "lov setup");
2107 record_end_log(env, &llh);
2109 OBD_FREE_PTR(lovdesc);
2113 /* add failnids to open log */
2114 static int mgs_write_log_failnids(const struct lu_env *env,
2115 struct mgs_target_info *mti,
2116 struct llog_handle *llh,
2119 char *failnodeuuid = NULL;
2120 char *ptr = mti->mti_params;
2125 #03 L add_uuid nid=uml1@tcp(0x20000c0a80201) nal=90 0: 1:uml1_UUID
2126 #04 L add_uuid nid=1@elan(0x1000000000001) nal=90 0: 1:uml1_UUID
2127 #05 L setup 0:OSC_uml1_ost1_mdsA 1:ost1_UUID 2:uml1_UUID
2128 #06 L add_uuid nid=uml2@tcp(0x20000c0a80202) nal=90 0: 1:uml2_UUID
2129 #0x L add_uuid nid=2@elan(0x1000000000002) nal=90 0: 1:uml2_UUID
2130 #07 L add_conn 0:OSC_uml1_ost1_mdsA 1:uml2_UUID
2134 * Pull failnid info out of params string, which may contain something
2135 * like "<nid1>,<nid2>:<nid3>,<nid4>". class_parse_nid() does not
2136 * complain about abnormal inputs like ",:<nid1>", "<nid1>:,<nid2>",
2137 * etc. However, convert_hostnames() should have caught those.
2139 while (class_find_param(ptr, PARAM_FAILNODE, &ptr) == 0) {
2140 while (class_parse_nid(ptr, &nid, &ptr) == 0) {
2141 char nidstr[LNET_NIDSTR_SIZE];
2143 if (failnodeuuid == NULL) {
2144 /* We don't know the failover node name,
2145 * so just use the first nid as the uuid */
2146 libcfs_nid2str_r(nid, nidstr, sizeof(nidstr));
2147 rc = name_create(&failnodeuuid, nidstr, "");
2151 CDEBUG(D_MGS, "add nid %s for failover uuid %s, "
2153 libcfs_nid2str_r(nid, nidstr, sizeof(nidstr)),
2154 failnodeuuid, cliname);
2155 rc = record_add_uuid(env, llh, nid, failnodeuuid);
2157 * If *ptr is ':', we have added all NIDs for
2161 rc = record_add_conn(env, llh, cliname,
2163 name_destroy(&failnodeuuid);
2164 failnodeuuid = NULL;
2168 rc = record_add_conn(env, llh, cliname, failnodeuuid);
2169 name_destroy(&failnodeuuid);
2170 failnodeuuid = NULL;
2177 static int mgs_write_log_mdc_to_lmv(const struct lu_env *env,
2178 struct mgs_device *mgs,
2180 struct mgs_target_info *mti,
2181 char *logname, char *lmvname)
2183 struct llog_handle *llh = NULL;
2184 char *mdcname = NULL;
2185 char *nodeuuid = NULL;
2186 char *mdcuuid = NULL;
2187 char *lmvuuid = NULL;
2189 char nidstr[LNET_NIDSTR_SIZE];
2193 if (mgs_log_is_empty(env, mgs, logname)) {
2194 CERROR("log is empty! Logical error\n");
2198 CDEBUG(D_MGS, "adding mdc for %s to log %s:lmv(%s)\n",
2199 mti->mti_svname, logname, lmvname);
2201 libcfs_nid2str_r(mti->mti_nids[0], nidstr, sizeof(nidstr));
2202 rc = name_create(&nodeuuid, nidstr, "");
2205 rc = name_create(&mdcname, mti->mti_svname, "-mdc");
2208 rc = name_create(&mdcuuid, mdcname, "_UUID");
2211 rc = name_create(&lmvuuid, lmvname, "_UUID");
2215 rc = record_start_log(env, mgs, &llh, logname);
2218 rc = record_marker(env, llh, fsdb, CM_START, mti->mti_svname,
2222 for (i = 0; i < mti->mti_nid_count; i++) {
2223 CDEBUG(D_MGS, "add nid %s for mdt\n",
2224 libcfs_nid2str_r(mti->mti_nids[i],
2225 nidstr, sizeof(nidstr)));
2227 rc = record_add_uuid(env, llh, mti->mti_nids[i], nodeuuid);
2232 rc = record_attach(env, llh, mdcname, LUSTRE_MDC_NAME, lmvuuid);
2235 rc = record_setup(env, llh, mdcname, mti->mti_uuid, nodeuuid,
2239 rc = mgs_write_log_failnids(env, mti, llh, mdcname);
2242 snprintf(index, sizeof(index), "%d", mti->mti_stripe_index);
2243 rc = record_mdc_add(env, llh, lmvname, mdcuuid, mti->mti_uuid,
2247 rc = record_marker(env, llh, fsdb, CM_END, mti->mti_svname,
2252 record_end_log(env, &llh);
2254 name_destroy(&lmvuuid);
2255 name_destroy(&mdcuuid);
2256 name_destroy(&mdcname);
2257 name_destroy(&nodeuuid);
2261 static inline int name_create_lov(char **lovname, char *mdtname,
2262 struct fs_db *fsdb, int index)
2265 if (index == 0 && test_bit(FSDB_OSCNAME18, &fsdb->fsdb_flags))
2266 return name_create(lovname, fsdb->fsdb_name, "-mdtlov");
2268 return name_create(lovname, mdtname, "-mdtlov");
2271 static int name_create_mdt_and_lov(char **logname, char **lovname,
2272 struct fs_db *fsdb, int i)
2276 rc = name_create_mdt(logname, fsdb->fsdb_name, i);
2280 if (i == 0 && test_bit(FSDB_OSCNAME18, &fsdb->fsdb_flags))
2281 rc = name_create(lovname, fsdb->fsdb_name, "-mdtlov");
2283 rc = name_create(lovname, *logname, "-mdtlov");
2285 name_destroy(logname);
2291 static inline int name_create_mdt_osc(char **oscname, char *ostname,
2292 struct fs_db *fsdb, int i)
2296 if (i == 0 && test_bit(FSDB_OSCNAME18, &fsdb->fsdb_flags))
2297 sprintf(suffix, "-osc");
2299 sprintf(suffix, "-osc-MDT%04x", i);
2300 return name_create(oscname, ostname, suffix);
2303 /* add new mdc to already existent MDS */
2304 static int mgs_write_log_osp_to_mdt(const struct lu_env *env,
2305 struct mgs_device *mgs,
2307 struct mgs_target_info *mti,
2308 int mdt_index, char *logname)
2310 struct llog_handle *llh = NULL;
2311 char *nodeuuid = NULL;
2312 char *ospname = NULL;
2313 char *lovuuid = NULL;
2314 char *mdtuuid = NULL;
2315 char *svname = NULL;
2316 char *mdtname = NULL;
2317 char *lovname = NULL;
2319 char nidstr[LNET_NIDSTR_SIZE];
2323 if (mgs_log_is_empty(env, mgs, mti->mti_svname)) {
2324 CERROR("log is empty! Logical error\n");
2328 CDEBUG(D_MGS, "adding osp index %d to %s\n", mti->mti_stripe_index,
2331 rc = name_create_mdt(&mdtname, fsdb->fsdb_name, mti->mti_stripe_index);
2335 libcfs_nid2str_r(mti->mti_nids[0], nidstr, sizeof(nidstr));
2336 rc = name_create(&nodeuuid, nidstr, "");
2338 GOTO(out_destory, rc);
2340 rc = name_create(&svname, mdtname, "-osp");
2342 GOTO(out_destory, rc);
2344 sprintf(index_str, "-MDT%04x", mdt_index);
2345 rc = name_create(&ospname, svname, index_str);
2347 GOTO(out_destory, rc);
2349 rc = name_create_lov(&lovname, logname, fsdb, mdt_index);
2351 GOTO(out_destory, rc);
2353 rc = name_create(&lovuuid, lovname, "_UUID");
2355 GOTO(out_destory, rc);
2357 rc = name_create(&mdtuuid, mdtname, "_UUID");
2359 GOTO(out_destory, rc);
2361 rc = record_start_log(env, mgs, &llh, logname);
2363 GOTO(out_destory, rc);
2365 rc = record_marker(env, llh, fsdb, CM_START, mti->mti_svname,
2368 GOTO(out_destory, rc);
2370 for (i = 0; i < mti->mti_nid_count; i++) {
2371 CDEBUG(D_MGS, "add nid %s for mdt\n",
2372 libcfs_nid2str_r(mti->mti_nids[i],
2373 nidstr, sizeof(nidstr)));
2374 rc = record_add_uuid(env, llh, mti->mti_nids[i], nodeuuid);
2379 rc = record_attach(env, llh, ospname, LUSTRE_OSP_NAME, lovuuid);
2383 rc = record_setup(env, llh, ospname, mti->mti_uuid, nodeuuid,
2388 rc = mgs_write_log_failnids(env, mti, llh, ospname);
2392 /* Add mdc(osp) to lod */
2393 snprintf(index_str, sizeof(index_str), "%d", mti->mti_stripe_index);
2394 rc = record_base(env, llh, lovname, 0, LCFG_ADD_MDC, mti->mti_uuid,
2395 index_str, "1", NULL);
2399 rc = record_marker(env, llh, fsdb, CM_END, mti->mti_svname, "add osp");
2404 record_end_log(env, &llh);
2407 name_destroy(&mdtuuid);
2408 name_destroy(&lovuuid);
2409 name_destroy(&lovname);
2410 name_destroy(&ospname);
2411 name_destroy(&svname);
2412 name_destroy(&nodeuuid);
2413 name_destroy(&mdtname);
2417 static int mgs_write_log_mdt0(const struct lu_env *env,
2418 struct mgs_device *mgs,
2420 struct mgs_target_info *mti)
2422 char *log = mti->mti_svname;
2423 struct llog_handle *llh = NULL;
2424 char *uuid, *lovname;
2426 char *ptr = mti->mti_params;
2427 int rc = 0, failout = 0;
2430 OBD_ALLOC(uuid, sizeof(struct obd_uuid));
2434 if (class_find_param(ptr, PARAM_FAILMODE, &ptr) == 0)
2435 failout = (strncmp(ptr, "failout", 7) == 0);
2437 rc = name_create(&lovname, log, "-mdtlov");
2440 if (mgs_log_is_empty(env, mgs, log)) {
2441 rc = mgs_write_log_lov(env, mgs, fsdb, mti, log, lovname);
2446 sprintf(mdt_index, "%d", mti->mti_stripe_index);
2448 rc = record_start_log(env, mgs, &llh, log);
2452 /* add MDT itself */
2454 /* FIXME this whole fn should be a single journal transaction */
2455 sprintf(uuid, "%s_UUID", log);
2456 rc = record_marker(env, llh, fsdb, CM_START, log, "add mdt");
2459 rc = record_attach(env, llh, log, LUSTRE_MDT_NAME, uuid);
2462 rc = record_mount_opt(env, llh, log, lovname, NULL);
2465 rc = record_setup(env, llh, log, uuid, mdt_index, lovname,
2466 failout ? "n" : "f");
2469 rc = record_marker(env, llh, fsdb, CM_END, log, "add mdt");
2473 record_end_log(env, &llh);
2475 name_destroy(&lovname);
2477 OBD_FREE(uuid, sizeof(struct obd_uuid));
2481 /* envelope method for all layers log */
2482 static int mgs_write_log_mdt(const struct lu_env *env,
2483 struct mgs_device *mgs,
2485 struct mgs_target_info *mti)
2487 struct mgs_thread_info *mgi = mgs_env_info(env);
2488 struct llog_handle *llh = NULL;
2493 CDEBUG(D_MGS, "writing new mdt %s\n", mti->mti_svname);
2495 if (mti->mti_uuid[0] == '\0') {
2496 /* Make up our own uuid */
2497 snprintf(mti->mti_uuid, sizeof(mti->mti_uuid),
2498 "%s_UUID", mti->mti_svname);
2502 rc = mgs_write_log_mdt0(env, mgs, fsdb, mti);
2505 /* Append the mdt info to the client log */
2506 rc = name_create(&cliname, mti->mti_fsname, "-client");
2510 if (mgs_log_is_empty(env, mgs, cliname)) {
2511 /* Start client log */
2512 rc = mgs_write_log_lov(env, mgs, fsdb, mti, cliname,
2516 rc = mgs_write_log_lmv(env, mgs, fsdb, mti, cliname,
2523 #09 L add_uuid nid=uml1@tcp(0x20000c0a80201) 0: 1:uml1_UUID
2524 #10 L attach 0:MDC_uml1_mdsA_MNT_client 1:mdc 2:1d834_MNT_client_03f
2525 #11 L setup 0:MDC_uml1_mdsA_MNT_client 1:mdsA_UUID 2:uml1_UUID
2526 #12 L add_uuid nid=uml2@tcp(0x20000c0a80202) 0: 1:uml2_UUID
2527 #13 L add_conn 0:MDC_uml1_mdsA_MNT_client 1:uml2_UUID
2528 #14 L mount_option 0: 1:client 2:lov1 3:MDC_uml1_mdsA_MNT_client
2531 /* copy client info about lov/lmv */
2532 mgi->mgi_comp.comp_mti = mti;
2533 mgi->mgi_comp.comp_fsdb = fsdb;
2535 rc = mgs_steal_llog_for_mdt_from_client(env, mgs, cliname,
2539 rc = mgs_write_log_mdc_to_lmv(env, mgs, fsdb, mti, cliname,
2545 rc = record_start_log(env, mgs, &llh, cliname);
2549 rc = record_marker(env, llh, fsdb, CM_START, cliname,
2553 rc = record_mount_opt(env, llh, cliname, fsdb->fsdb_clilov,
2557 rc = record_marker(env, llh, fsdb, CM_END, cliname,
2563 /* for_all_existing_mdt except current one */
2564 for (i = 0; i < INDEX_MAP_SIZE * 8; i++) {
2565 if (i != mti->mti_stripe_index &&
2566 test_bit(i, fsdb->fsdb_mdt_index_map)) {
2569 rc = name_create_mdt(&logname, fsdb->fsdb_name, i);
2573 /* NB: If the log for the MDT is empty, it means
2574 * the MDT is only added to the index
2575 * map, and not being process yet, i.e. this
2576 * is an unregistered MDT, see mgs_write_log_target().
2577 * so we should skip it. Otherwise
2579 * 1. MGS get register request for MDT1 and MDT2.
2581 * 2. Then both MDT1 and MDT2 are added into
2582 * fsdb_mdt_index_map. (see mgs_set_index()).
2584 * 3. Then MDT1 get the lock of fsdb_mutex, then
2585 * generate the config log, here, it will regard MDT2
2586 * as an existent MDT, and generate "add osp" for
2587 * lustre-MDT0001-osp-MDT0002. Note: at the moment
2588 * MDT0002 config log is still empty, so it will
2589 * add "add osp" even before "lov setup", which
2590 * will definitly cause trouble.
2592 * 4. MDT1 registeration finished, fsdb_mutex is
2593 * released, then MDT2 get in, then in above
2594 * mgs_steal_llog_for_mdt_from_client(), it will
2595 * add another osp log for lustre-MDT0001-osp-MDT0002,
2596 * which will cause another trouble.*/
2597 if (!mgs_log_is_empty(env, mgs, logname))
2598 rc = mgs_write_log_osp_to_mdt(env, mgs, fsdb,
2601 name_destroy(&logname);
2607 record_end_log(env, &llh);
2609 name_destroy(&cliname);
2613 /* Add the ost info to the client/mdt lov */
2614 static int mgs_write_log_osc_to_lov(const struct lu_env *env,
2615 struct mgs_device *mgs, struct fs_db *fsdb,
2616 struct mgs_target_info *mti,
2617 char *logname, char *suffix, char *lovname,
2618 enum lustre_sec_part sec_part, int flags)
2620 struct llog_handle *llh = NULL;
2621 char *nodeuuid = NULL;
2622 char *oscname = NULL;
2623 char *oscuuid = NULL;
2624 char *lovuuid = NULL;
2625 char *svname = NULL;
2627 char nidstr[LNET_NIDSTR_SIZE];
2631 CDEBUG(D_INFO, "adding osc for %s to log %s\n",
2632 mti->mti_svname, logname);
2634 if (mgs_log_is_empty(env, mgs, logname)) {
2635 CERROR("log is empty! Logical error\n");
2639 libcfs_nid2str_r(mti->mti_nids[0], nidstr, sizeof(nidstr));
2640 rc = name_create(&nodeuuid, nidstr, "");
2643 rc = name_create(&svname, mti->mti_svname, "-osc");
2647 /* for the system upgraded from old 1.8, keep using the old osc naming
2648 * style for mdt, see name_create_mdt_osc(). LU-1257 */
2649 if (test_bit(FSDB_OSCNAME18, &fsdb->fsdb_flags))
2650 rc = name_create(&oscname, svname, "");
2652 rc = name_create(&oscname, svname, suffix);
2656 rc = name_create(&oscuuid, oscname, "_UUID");
2659 rc = name_create(&lovuuid, lovname, "_UUID");
2665 #03 L add_uuid nid=uml1@tcp(0x20000c0a80201) 0: 1:uml1_UUID
2667 #04 L add_uuid nid=1@elan(0x1000000000001) nal=90 0: 1:uml1_UUID
2668 #04 L attach 0:OSC_uml1_ost1_MNT_client 1:osc 2:89070_lov1_a41dff51a
2669 #05 L setup 0:OSC_uml1_ost1_MNT_client 1:ost1_UUID 2:uml1_UUID
2671 #06 L add_uuid nid=uml2@tcp(0x20000c0a80202) 0: 1:uml2_UUID
2672 #07 L add_conn 0:OSC_uml1_ost1_MNT_client 1:uml2_UUID
2673 #08 L lov_modify_tgts add 0:lov1 1:ost1_UUID 2(index):0 3(gen):1
2676 rc = record_start_log(env, mgs, &llh, logname);
2680 /* FIXME these should be a single journal transaction */
2681 rc = record_marker(env, llh, fsdb, CM_START | flags, mti->mti_svname,
2686 /* NB: don't change record order, because upon MDT steal OSC config
2687 * from client, it treats all nids before LCFG_SETUP as target nids
2688 * (multiple interfaces), while nids after as failover node nids.
2689 * See mgs_steal_client_llog_handler() LCFG_ADD_UUID.
2691 for (i = 0; i < mti->mti_nid_count; i++) {
2692 CDEBUG(D_MGS, "add nid %s\n",
2693 libcfs_nid2str_r(mti->mti_nids[i],
2694 nidstr, sizeof(nidstr)));
2695 rc = record_add_uuid(env, llh, mti->mti_nids[i], nodeuuid);
2699 rc = record_attach(env, llh, oscname, LUSTRE_OSC_NAME, lovuuid);
2702 rc = record_setup(env, llh, oscname, mti->mti_uuid, nodeuuid,
2706 rc = mgs_write_log_failnids(env, mti, llh, oscname);
2710 snprintf(index, sizeof(index), "%d", mti->mti_stripe_index);
2712 rc = record_lov_add(env, llh, lovname, mti->mti_uuid, index, "1");
2715 rc = record_marker(env, llh, fsdb, CM_END | flags, mti->mti_svname,
2720 record_end_log(env, &llh);
2722 name_destroy(&lovuuid);
2723 name_destroy(&oscuuid);
2724 name_destroy(&oscname);
2725 name_destroy(&svname);
2726 name_destroy(&nodeuuid);
2730 static int mgs_write_log_ost(const struct lu_env *env,
2731 struct mgs_device *mgs, struct fs_db *fsdb,
2732 struct mgs_target_info *mti)
2734 struct llog_handle *llh = NULL;
2735 char *logname, *lovname;
2736 char *ptr = mti->mti_params;
2737 int rc, flags = 0, failout = 0, i;
2740 CDEBUG(D_MGS, "writing new ost %s\n", mti->mti_svname);
2742 /* The ost startup log */
2744 /* If the ost log already exists, that means that someone reformatted
2745 the ost and it called target_add again. */
2746 if (!mgs_log_is_empty(env, mgs, mti->mti_svname)) {
2747 LCONSOLE_ERROR_MSG(0x141, "The config log for %s already "
2748 "exists, yet the server claims it never "
2749 "registered. It may have been reformatted, "
2750 "or the index changed. writeconf the MDT to "
2751 "regenerate all logs.\n", mti->mti_svname);
2756 attach obdfilter ost1 ost1_UUID
2757 setup /dev/loop2 ldiskfs f|n errors=remount-ro,user_xattr
2759 if (class_find_param(ptr, PARAM_FAILMODE, &ptr) == 0)
2760 failout = (strncmp(ptr, "failout", 7) == 0);
2761 rc = record_start_log(env, mgs, &llh, mti->mti_svname);
2764 /* FIXME these should be a single journal transaction */
2765 rc = record_marker(env, llh, fsdb, CM_START, mti->mti_svname,"add ost");
2768 if (*mti->mti_uuid == '\0')
2769 snprintf(mti->mti_uuid, sizeof(mti->mti_uuid),
2770 "%s_UUID", mti->mti_svname);
2771 rc = record_attach(env, llh, mti->mti_svname,
2772 "obdfilter"/*LUSTRE_OST_NAME*/, mti->mti_uuid);
2775 rc = record_setup(env, llh, mti->mti_svname,
2776 "dev"/*ignored*/, "type"/*ignored*/,
2777 failout ? "n" : "f", NULL/*options*/);
2780 rc = record_marker(env, llh, fsdb, CM_END, mti->mti_svname, "add ost");
2784 record_end_log(env, &llh);
2787 /* We also have to update the other logs where this osc is part of
2790 if (test_bit(FSDB_OLDLOG14, &fsdb->fsdb_flags)) {
2791 /* If we're upgrading, the old mdt log already has our
2792 entry. Let's do a fake one for fun. */
2793 /* Note that we can't add any new failnids, since we don't
2794 know the old osc names. */
2795 flags = CM_SKIP | CM_UPGRADE146;
2797 } else if ((mti->mti_flags & LDD_F_UPDATE) != LDD_F_UPDATE) {
2798 /* If the update flag isn't set, don't update client/mdt
2801 LCONSOLE_WARN("Client log for %s was not updated; writeconf "
2802 "the MDT first to regenerate it.\n",
2806 /* Add ost to all MDT lov defs */
2807 for (i = 0; i < INDEX_MAP_SIZE * 8; i++){
2808 if (test_bit(i, fsdb->fsdb_mdt_index_map)) {
2811 rc = name_create_mdt_and_lov(&logname, &lovname, fsdb,
2815 sprintf(mdt_index, "-MDT%04x", i);
2816 rc = mgs_write_log_osc_to_lov(env, mgs, fsdb, mti,
2818 lovname, LUSTRE_SP_MDT,
2820 name_destroy(&logname);
2821 name_destroy(&lovname);
2827 /* Append ost info to the client log */
2828 rc = name_create(&logname, mti->mti_fsname, "-client");
2831 if (mgs_log_is_empty(env, mgs, logname)) {
2832 /* Start client log */
2833 rc = mgs_write_log_lov(env, mgs, fsdb, mti, logname,
2837 rc = mgs_write_log_lmv(env, mgs, fsdb, mti, logname,
2842 rc = mgs_write_log_osc_to_lov(env, mgs, fsdb, mti, logname, "",
2843 fsdb->fsdb_clilov, LUSTRE_SP_CLI, flags);
2845 name_destroy(&logname);
2849 static __inline__ int mgs_param_empty(char *ptr)
2853 if ((tmp = strchr(ptr, '=')) && (*(++tmp) == '\0'))
2858 static int mgs_write_log_failnid_internal(const struct lu_env *env,
2859 struct mgs_device *mgs,
2861 struct mgs_target_info *mti,
2862 char *logname, char *cliname)
2865 struct llog_handle *llh = NULL;
2867 if (mgs_param_empty(mti->mti_params)) {
2868 /* Remove _all_ failnids */
2869 rc = mgs_modify(env, mgs, fsdb, mti, logname,
2870 mti->mti_svname, "add failnid", CM_SKIP);
2871 return rc < 0 ? rc : 0;
2874 /* Otherwise failover nids are additive */
2875 rc = record_start_log(env, mgs, &llh, logname);
2878 /* FIXME this should be a single journal transaction */
2879 rc = record_marker(env, llh, fsdb, CM_START, mti->mti_svname,
2883 rc = mgs_write_log_failnids(env, mti, llh, cliname);
2886 rc = record_marker(env, llh, fsdb, CM_END,
2887 mti->mti_svname, "add failnid");
2889 record_end_log(env, &llh);
2894 /* Add additional failnids to an existing log.
2895 The mdc/osc must have been added to logs first */
2896 /* tcp nids must be in dotted-quad ascii -
2897 we can't resolve hostnames from the kernel. */
2898 static int mgs_write_log_add_failnid(const struct lu_env *env,
2899 struct mgs_device *mgs,
2901 struct mgs_target_info *mti)
2903 char *logname, *cliname;
2907 /* FIXME we currently can't erase the failnids
2908 * given when a target first registers, since they aren't part of
2909 * an "add uuid" stanza */
2911 /* Verify that we know about this target */
2912 if (mgs_log_is_empty(env, mgs, mti->mti_svname)) {
2913 LCONSOLE_ERROR_MSG(0x142, "The target %s has not registered "
2914 "yet. It must be started before failnids "
2915 "can be added.\n", mti->mti_svname);
2919 /* Create mdc/osc client name (e.g. lustre-OST0001-osc) */
2920 if (mti->mti_flags & LDD_F_SV_TYPE_MDT) {
2921 rc = name_create(&cliname, mti->mti_svname, "-mdc");
2922 } else if (mti->mti_flags & LDD_F_SV_TYPE_OST) {
2923 rc = name_create(&cliname, mti->mti_svname, "-osc");
2929 /* Add failover nids to the client log */
2930 rc = name_create(&logname, mti->mti_fsname, "-client");
2932 name_destroy(&cliname);
2935 rc = mgs_write_log_failnid_internal(env, mgs, fsdb,mti,logname,cliname);
2936 name_destroy(&logname);
2937 name_destroy(&cliname);
2941 if (mti->mti_flags & LDD_F_SV_TYPE_OST) {
2942 /* Add OST failover nids to the MDT logs as well */
2945 for (i = 0; i < INDEX_MAP_SIZE * 8; i++) {
2946 if (!test_bit(i, fsdb->fsdb_mdt_index_map))
2948 rc = name_create_mdt(&logname, mti->mti_fsname, i);
2951 rc = name_create_mdt_osc(&cliname, mti->mti_svname,
2954 name_destroy(&logname);
2957 rc = mgs_write_log_failnid_internal(env, mgs, fsdb,
2960 name_destroy(&cliname);
2961 name_destroy(&logname);
2970 static int mgs_wlp_lcfg(const struct lu_env *env,
2971 struct mgs_device *mgs, struct fs_db *fsdb,
2972 struct mgs_target_info *mti,
2973 char *logname, struct lustre_cfg_bufs *bufs,
2974 char *tgtname, char *ptr)
2976 char comment[MTI_NAME_MAXLEN];
2978 struct llog_cfg_rec *lcr;
2981 /* Erase any old settings of this same parameter */
2982 memcpy(comment, ptr, MTI_NAME_MAXLEN);
2983 comment[MTI_NAME_MAXLEN - 1] = 0;
2984 /* But don't try to match the value. */
2985 tmp = strchr(comment, '=');
2988 /* FIXME we should skip settings that are the same as old values */
2989 rc = mgs_modify(env, mgs, fsdb, mti, logname, tgtname, comment,CM_SKIP);
2992 del = mgs_param_empty(ptr);
2994 LCONSOLE_INFO("%s parameter %s.%s in log %s\n", del ? "Disabling" : rc ?
2995 "Setting" : "Modifying", tgtname, comment, logname);
2997 /* mgs_modify() will return 1 if nothing had to be done */
3003 lustre_cfg_bufs_reset(bufs, tgtname);
3004 lustre_cfg_bufs_set_string(bufs, 1, ptr);
3005 if (mti->mti_flags & LDD_F_PARAM2)
3006 lustre_cfg_bufs_set_string(bufs, 2, LCTL_UPCALL);
3008 lcr = lustre_cfg_rec_new((mti->mti_flags & LDD_F_PARAM2) ?
3009 LCFG_SET_PARAM : LCFG_PARAM, bufs);
3013 rc = mgs_write_log_direct(env, mgs, fsdb, logname, lcr, tgtname,
3015 lustre_cfg_rec_free(lcr);
3019 static int mgs_write_log_param2(const struct lu_env *env,
3020 struct mgs_device *mgs,
3022 struct mgs_target_info *mti, char *ptr)
3024 struct lustre_cfg_bufs bufs;
3028 CDEBUG(D_MGS, "next param '%s'\n", ptr);
3029 rc = mgs_wlp_lcfg(env, mgs, fsdb, mti, PARAMS_FILENAME, &bufs,
3030 mti->mti_svname, ptr);
3035 /* write global variable settings into log */
3036 static int mgs_write_log_sys(const struct lu_env *env,
3037 struct mgs_device *mgs, struct fs_db *fsdb,
3038 struct mgs_target_info *mti, char *sys, char *ptr)
3040 struct mgs_thread_info *mgi = mgs_env_info(env);
3041 struct lustre_cfg *lcfg;
3042 struct llog_cfg_rec *lcr;
3044 int rc, cmd, convert = 1;
3046 if (class_match_param(ptr, PARAM_TIMEOUT, &tmp) == 0) {
3047 cmd = LCFG_SET_TIMEOUT;
3048 } else if (class_match_param(ptr, PARAM_LDLM_TIMEOUT, &tmp) == 0) {
3049 cmd = LCFG_SET_LDLM_TIMEOUT;
3050 /* Check for known params here so we can return error to lctl */
3051 } else if ((class_match_param(ptr, PARAM_AT_MIN, &tmp) == 0) ||
3052 (class_match_param(ptr, PARAM_AT_MAX, &tmp) == 0) ||
3053 (class_match_param(ptr, PARAM_AT_EXTRA, &tmp) == 0) ||
3054 (class_match_param(ptr, PARAM_AT_EARLY_MARGIN, &tmp) == 0) ||
3055 (class_match_param(ptr, PARAM_AT_HISTORY, &tmp) == 0)) {
3057 } else if (class_match_param(ptr, PARAM_JOBID_VAR, &tmp) == 0) {
3058 convert = 0; /* Don't convert string value to integer */
3064 if (mgs_param_empty(ptr))
3065 CDEBUG(D_MGS, "global '%s' removed\n", sys);
3067 CDEBUG(D_MGS, "global '%s' val=%s\n", sys, tmp);
3069 lustre_cfg_bufs_reset(&mgi->mgi_bufs, NULL);
3070 lustre_cfg_bufs_set_string(&mgi->mgi_bufs, 1, sys);
3071 if (!convert && *tmp != '\0')
3072 lustre_cfg_bufs_set_string(&mgi->mgi_bufs, 2, tmp);
3073 lcr = lustre_cfg_rec_new(cmd, &mgi->mgi_bufs);
3077 lcfg = &lcr->lcr_cfg;
3078 lcfg->lcfg_num = convert ? simple_strtoul(tmp, NULL, 0) : 0;
3079 /* truncate the comment to the parameter name */
3083 /* modify all servers and clients */
3084 rc = mgs_write_log_direct_all(env, mgs, fsdb, mti,
3085 *tmp == '\0' ? NULL : lcr,
3086 mti->mti_fsname, sys, 0);
3087 if (rc == 0 && *tmp != '\0') {
3089 case LCFG_SET_TIMEOUT:
3090 if (!obd_timeout_set || lcfg->lcfg_num > obd_timeout)
3091 class_process_config(lcfg);
3093 case LCFG_SET_LDLM_TIMEOUT:
3094 if (!ldlm_timeout_set || lcfg->lcfg_num > ldlm_timeout)
3095 class_process_config(lcfg);
3102 lustre_cfg_rec_free(lcr);
3106 /* write quota settings into log */
3107 static int mgs_write_log_quota(const struct lu_env *env, struct mgs_device *mgs,
3108 struct fs_db *fsdb, struct mgs_target_info *mti,
3109 char *quota, char *ptr)
3111 struct mgs_thread_info *mgi = mgs_env_info(env);
3112 struct llog_cfg_rec *lcr;
3115 int rc, cmd = LCFG_PARAM;
3117 /* support only 'meta' and 'data' pools so far */
3118 if (class_match_param(ptr, QUOTA_METAPOOL_NAME, &tmp) != 0 &&
3119 class_match_param(ptr, QUOTA_DATAPOOL_NAME, &tmp) != 0) {
3120 CERROR("parameter quota.%s isn't supported (only quota.mdt "
3121 "& quota.ost are)\n", ptr);
3126 CDEBUG(D_MGS, "global '%s' removed\n", quota);
3128 CDEBUG(D_MGS, "global '%s'\n", quota);
3130 if (strchr(tmp, 'u') == NULL && strchr(tmp, 'g') == NULL &&
3131 strchr(tmp, 'p') == NULL &&
3132 strcmp(tmp, "none") != 0) {
3133 CERROR("enable option(%s) isn't supported\n", tmp);
3138 lustre_cfg_bufs_reset(&mgi->mgi_bufs, mti->mti_fsname);
3139 lustre_cfg_bufs_set_string(&mgi->mgi_bufs, 1, quota);
3140 lcr = lustre_cfg_rec_new(cmd, &mgi->mgi_bufs);
3144 /* truncate the comment to the parameter name */
3149 /* XXX we duplicated quota enable information in all server
3150 * config logs, it should be moved to a separate config
3151 * log once we cleanup the config log for global param. */
3152 /* modify all servers */
3153 rc = mgs_write_log_direct_all(env, mgs, fsdb, mti,
3154 *tmp == '\0' ? NULL : lcr,
3155 mti->mti_fsname, quota, 1);
3157 lustre_cfg_rec_free(lcr);
3158 return rc < 0 ? rc : 0;
3161 static int mgs_srpc_set_param_disk(const struct lu_env *env,
3162 struct mgs_device *mgs,
3164 struct mgs_target_info *mti,
3167 struct mgs_thread_info *mgi = mgs_env_info(env);
3168 struct llog_cfg_rec *lcr;
3169 struct llog_handle *llh = NULL;
3171 char *comment, *ptr;
3177 ptr = strchr(param, '=');
3178 LASSERT(ptr != NULL);
3181 OBD_ALLOC(comment, len + 1);
3182 if (comment == NULL)
3184 strncpy(comment, param, len);
3185 comment[len] = '\0';
3188 lustre_cfg_bufs_reset(&mgi->mgi_bufs, mti->mti_svname);
3189 lustre_cfg_bufs_set_string(&mgi->mgi_bufs, 1, param);
3190 lcr = lustre_cfg_rec_new(LCFG_SPTLRPC_CONF, &mgi->mgi_bufs);
3192 GOTO(out_comment, rc = -ENOMEM);
3194 /* construct log name */
3195 rc = name_create(&logname, mti->mti_fsname, "-sptlrpc");
3199 if (mgs_log_is_empty(env, mgs, logname)) {
3200 rc = record_start_log(env, mgs, &llh, logname);
3203 record_end_log(env, &llh);
3206 /* obsolete old one */
3207 rc = mgs_modify(env, mgs, fsdb, mti, logname, mti->mti_svname,
3211 /* write the new one */
3212 rc = mgs_write_log_direct(env, mgs, fsdb, logname, lcr,
3213 mti->mti_svname, comment);
3215 CERROR("%s: error writing log %s: rc = %d\n",
3216 mgs->mgs_obd->obd_name, logname, rc);
3218 name_destroy(&logname);
3220 lustre_cfg_rec_free(lcr);
3222 OBD_FREE(comment, len + 1);
3226 static int mgs_srpc_set_param_udesc_mem(struct fs_db *fsdb,
3231 /* disable the adjustable udesc parameter for now, i.e. use default
3232 * setting that client always ship udesc to MDT if possible. to enable
3233 * it simply remove the following line */
3236 ptr = strchr(param, '=');
3241 if (strcmp(param, PARAM_SRPC_UDESC))
3244 if (strcmp(ptr, "yes") == 0) {
3245 set_bit(FSDB_UDESC, &fsdb->fsdb_flags);
3246 CWARN("Enable user descriptor shipping from client to MDT\n");
3247 } else if (strcmp(ptr, "no") == 0) {
3248 clear_bit(FSDB_UDESC, &fsdb->fsdb_flags);
3249 CWARN("Disable user descriptor shipping from client to MDT\n");
3257 CERROR("Invalid param: %s\n", param);
3261 static int mgs_srpc_set_param_mem(struct fs_db *fsdb,
3265 struct sptlrpc_rule rule;
3266 struct sptlrpc_rule_set *rset;
3270 if (strncmp(param, PARAM_SRPC, sizeof(PARAM_SRPC) - 1) != 0) {
3271 CERROR("Invalid sptlrpc parameter: %s\n", param);
3275 if (strncmp(param, PARAM_SRPC_UDESC,
3276 sizeof(PARAM_SRPC_UDESC) - 1) == 0) {
3277 RETURN(mgs_srpc_set_param_udesc_mem(fsdb, param));
3280 if (strncmp(param, PARAM_SRPC_FLVR, sizeof(PARAM_SRPC_FLVR) - 1) != 0) {
3281 CERROR("Invalid sptlrpc flavor parameter: %s\n", param);
3285 param += sizeof(PARAM_SRPC_FLVR) - 1;
3287 rc = sptlrpc_parse_rule(param, &rule);
3291 /* mgs rules implies must be mgc->mgs */
3292 if (test_bit(FSDB_MGS_SELF, &fsdb->fsdb_flags)) {
3293 if ((rule.sr_from != LUSTRE_SP_MGC &&
3294 rule.sr_from != LUSTRE_SP_ANY) ||
3295 (rule.sr_to != LUSTRE_SP_MGS &&
3296 rule.sr_to != LUSTRE_SP_ANY))
3300 /* preapre room for this coming rule. svcname format should be:
3301 * - fsname: general rule
3302 * - fsname-tgtname: target-specific rule
3304 if (strchr(svname, '-')) {
3305 struct mgs_tgt_srpc_conf *tgtconf;
3308 for (tgtconf = fsdb->fsdb_srpc_tgt; tgtconf != NULL;
3309 tgtconf = tgtconf->mtsc_next) {
3310 if (!strcmp(tgtconf->mtsc_tgt, svname)) {
3319 OBD_ALLOC_PTR(tgtconf);
3320 if (tgtconf == NULL)
3323 name_len = strlen(svname);
3325 OBD_ALLOC(tgtconf->mtsc_tgt, name_len + 1);
3326 if (tgtconf->mtsc_tgt == NULL) {
3327 OBD_FREE_PTR(tgtconf);
3330 memcpy(tgtconf->mtsc_tgt, svname, name_len);
3332 tgtconf->mtsc_next = fsdb->fsdb_srpc_tgt;
3333 fsdb->fsdb_srpc_tgt = tgtconf;
3336 rset = &tgtconf->mtsc_rset;
3337 } else if (strcmp(svname, MGSSELF_NAME) == 0) {
3338 /* put _mgs related srpc rule directly in mgs ruleset */
3339 rset = &fsdb->fsdb_mgs->mgs_lut.lut_sptlrpc_rset;
3341 rset = &fsdb->fsdb_srpc_gen;
3344 rc = sptlrpc_rule_set_merge(rset, &rule);
3349 static int mgs_srpc_set_param(const struct lu_env *env,
3350 struct mgs_device *mgs,
3352 struct mgs_target_info *mti,
3362 /* keep a copy of original param, which could be destroied
3364 copy_size = strlen(param) + 1;
3365 OBD_ALLOC(copy, copy_size);
3368 memcpy(copy, param, copy_size);
3370 rc = mgs_srpc_set_param_mem(fsdb, mti->mti_svname, param);
3374 /* previous steps guaranteed the syntax is correct */
3375 rc = mgs_srpc_set_param_disk(env, mgs, fsdb, mti, copy);
3379 if (test_bit(FSDB_MGS_SELF, &fsdb->fsdb_flags)) {
3381 * for mgs rules, make them effective immediately.
3383 LASSERT(fsdb->fsdb_srpc_tgt == NULL);
3384 sptlrpc_target_update_exp_flavor(mgs->mgs_obd,
3385 &fsdb->fsdb_srpc_gen);
3389 OBD_FREE(copy, copy_size);
3393 struct mgs_srpc_read_data {
3394 struct fs_db *msrd_fsdb;
3398 static int mgs_srpc_read_handler(const struct lu_env *env,
3399 struct llog_handle *llh,
3400 struct llog_rec_hdr *rec, void *data)
3402 struct mgs_srpc_read_data *msrd = data;
3403 struct cfg_marker *marker;
3404 struct lustre_cfg *lcfg = REC_DATA(rec);
3405 char *svname, *param;
3409 if (rec->lrh_type != OBD_CFG_REC) {
3410 CERROR("unhandled lrh_type: %#x\n", rec->lrh_type);
3414 cfg_len = REC_DATA_LEN(rec);
3416 rc = lustre_cfg_sanity_check(lcfg, cfg_len);
3418 CERROR("Insane cfg\n");
3422 if (lcfg->lcfg_command == LCFG_MARKER) {
3423 marker = lustre_cfg_buf(lcfg, 1);
3425 if (marker->cm_flags & CM_START &&
3426 marker->cm_flags & CM_SKIP)
3427 msrd->msrd_skip = 1;
3428 if (marker->cm_flags & CM_END)
3429 msrd->msrd_skip = 0;
3434 if (msrd->msrd_skip)
3437 if (lcfg->lcfg_command != LCFG_SPTLRPC_CONF) {
3438 CERROR("invalid command (%x)\n", lcfg->lcfg_command);
3442 svname = lustre_cfg_string(lcfg, 0);
3443 if (svname == NULL) {
3444 CERROR("svname is empty\n");
3448 param = lustre_cfg_string(lcfg, 1);
3449 if (param == NULL) {
3450 CERROR("param is empty\n");
3454 rc = mgs_srpc_set_param_mem(msrd->msrd_fsdb, svname, param);
3456 CERROR("read sptlrpc record error (%d): %s\n", rc, param);
3461 int mgs_get_fsdb_srpc_from_llog(const struct lu_env *env,
3462 struct mgs_device *mgs,
3465 struct llog_handle *llh = NULL;
3466 struct llog_ctxt *ctxt;
3468 struct mgs_srpc_read_data msrd;
3472 /* construct log name */
3473 rc = name_create(&logname, fsdb->fsdb_name, "-sptlrpc");
3477 ctxt = llog_get_context(mgs->mgs_obd, LLOG_CONFIG_ORIG_CTXT);
3478 LASSERT(ctxt != NULL);
3480 if (mgs_log_is_empty(env, mgs, logname))
3483 rc = llog_open(env, ctxt, &llh, NULL, logname,
3491 rc = llog_init_handle(env, llh, LLOG_F_IS_PLAIN, NULL);
3493 GOTO(out_close, rc);
3495 if (llog_get_size(llh) <= 1)
3496 GOTO(out_close, rc = 0);
3498 msrd.msrd_fsdb = fsdb;
3501 rc = llog_process(env, llh, mgs_srpc_read_handler, (void *)&msrd,
3505 llog_close(env, llh);
3507 llog_ctxt_put(ctxt);
3508 name_destroy(&logname);
3511 CERROR("failed to read sptlrpc config database: %d\n", rc);
3515 /* Permanent settings of all parameters by writing into the appropriate
3516 * configuration logs.
3517 * A parameter with null value ("<param>='\0'") means to erase it out of
3520 static int mgs_write_log_param(const struct lu_env *env,
3521 struct mgs_device *mgs, struct fs_db *fsdb,
3522 struct mgs_target_info *mti, char *ptr)
3524 struct mgs_thread_info *mgi = mgs_env_info(env);
3530 /* For various parameter settings, we have to figure out which logs
3531 care about them (e.g. both mdt and client for lov settings) */
3532 CDEBUG(D_MGS, "next param '%s'\n", ptr);
3534 /* The params are stored in MOUNT_DATA_FILE and modified via
3535 tunefs.lustre, or set using lctl conf_param */
3537 /* Processed in lustre_start_mgc */
3538 if (class_match_param(ptr, PARAM_MGSNODE, NULL) == 0)
3541 /* Processed in ost/mdt */
3542 if (class_match_param(ptr, PARAM_NETWORK, NULL) == 0)
3545 /* Processed in mgs_write_log_ost */
3546 if (class_match_param(ptr, PARAM_FAILMODE, NULL) == 0) {
3547 if (mti->mti_flags & LDD_F_PARAM) {
3548 LCONSOLE_ERROR_MSG(0x169, "%s can only be "
3549 "changed with tunefs.lustre"
3550 "and --writeconf\n", ptr);
3556 if (class_match_param(ptr, PARAM_SRPC, NULL) == 0) {
3557 rc = mgs_srpc_set_param(env, mgs, fsdb, mti, ptr);
3561 if (class_match_param(ptr, PARAM_FAILNODE, NULL) == 0) {
3562 /* Add a failover nidlist */
3564 /* We already processed failovers params for new
3565 targets in mgs_write_log_target */
3566 if (mti->mti_flags & LDD_F_PARAM) {
3567 CDEBUG(D_MGS, "Adding failnode\n");
3568 rc = mgs_write_log_add_failnid(env, mgs, fsdb, mti);
3573 if (class_match_param(ptr, PARAM_SYS, &tmp) == 0) {
3574 rc = mgs_write_log_sys(env, mgs, fsdb, mti, ptr, tmp);
3578 if (class_match_param(ptr, PARAM_QUOTA, &tmp) == 0) {
3579 rc = mgs_write_log_quota(env, mgs, fsdb, mti, ptr, tmp);
3583 if (class_match_param(ptr, PARAM_OSC PARAM_ACTIVE, &tmp) == 0 ||
3584 class_match_param(ptr, PARAM_MDC PARAM_ACTIVE, &tmp) == 0) {
3585 /* active=0 means off, anything else means on */
3586 int flag = (*tmp == '0') ? CM_EXCLUDE : 0;
3587 bool deactive_osc = memcmp(ptr, PARAM_OSC PARAM_ACTIVE,
3588 strlen(PARAM_OSC PARAM_ACTIVE)) == 0;
3591 if (!deactive_osc) {
3594 rc = server_name2index(mti->mti_svname, &index, NULL);
3599 LCONSOLE_ERROR_MSG(0x144, "%s: MDC0 can not be"
3600 " (de)activated.\n",
3602 GOTO(end, rc = -EPERM);
3606 LCONSOLE_WARN("Permanently %sactivating %s\n",
3607 flag ? "de" : "re", mti->mti_svname);
3609 rc = name_create(&logname, mti->mti_fsname, "-client");
3612 rc = mgs_modify(env, mgs, fsdb, mti, logname,
3614 deactive_osc ? "add osc" : "add mdc", flag);
3615 name_destroy(&logname);
3620 /* Add to all MDT logs for DNE */
3621 for (i = 0; i < INDEX_MAP_SIZE * 8; i++) {
3622 if (!test_bit(i, fsdb->fsdb_mdt_index_map))
3624 rc = name_create_mdt(&logname, mti->mti_fsname, i);
3627 rc = mgs_modify(env, mgs, fsdb, mti, logname,
3629 deactive_osc ? "add osc" : "add osp",
3631 name_destroy(&logname);
3637 LCONSOLE_ERROR_MSG(0x145, "Couldn't find %s in"
3638 "log (%d). No permanent "
3639 "changes were made to the "
3641 mti->mti_svname, rc);
3642 if (test_bit(FSDB_OLDLOG14, &fsdb->fsdb_flags))
3643 LCONSOLE_ERROR_MSG(0x146, "This may be"
3648 "update the logs.\n");
3651 /* Fall through to osc/mdc proc for deactivating live
3652 OSC/OSP on running MDT / clients. */
3654 /* Below here, let obd's XXX_process_config methods handle it */
3656 /* All lov. in proc */
3657 if (class_match_param(ptr, PARAM_LOV, NULL) == 0) {
3660 CDEBUG(D_MGS, "lov param %s\n", ptr);
3661 if (!(mti->mti_flags & LDD_F_SV_TYPE_MDT)) {
3662 LCONSOLE_ERROR_MSG(0x147, "LOV params must be "
3663 "set on the MDT, not %s. "
3670 if (mgs_log_is_empty(env, mgs, mti->mti_svname))
3671 GOTO(end, rc = -ENODEV);
3673 rc = name_create_mdt_and_lov(&logname, &mdtlovname, fsdb,
3674 mti->mti_stripe_index);
3677 rc = mgs_wlp_lcfg(env, mgs, fsdb, mti, mti->mti_svname,
3678 &mgi->mgi_bufs, mdtlovname, ptr);
3679 name_destroy(&logname);
3680 name_destroy(&mdtlovname);
3685 rc = name_create(&logname, mti->mti_fsname, "-client");
3688 rc = mgs_wlp_lcfg(env, mgs, fsdb, mti, logname, &mgi->mgi_bufs,
3689 fsdb->fsdb_clilov, ptr);
3690 name_destroy(&logname);
3694 /* All osc., mdc., llite. params in proc */
3695 if ((class_match_param(ptr, PARAM_OSC, NULL) == 0) ||
3696 (class_match_param(ptr, PARAM_MDC, NULL) == 0) ||
3697 (class_match_param(ptr, PARAM_LLITE, NULL) == 0)) {
3700 if (test_bit(FSDB_OLDLOG14, &fsdb->fsdb_flags)) {
3701 LCONSOLE_ERROR_MSG(0x148, "Upgraded client logs for %s"
3702 " cannot be modified. Consider"
3703 " updating the configuration with"
3706 GOTO(end, rc = -EINVAL);
3708 if (memcmp(ptr, PARAM_LLITE, strlen(PARAM_LLITE)) == 0) {
3709 rc = name_create(&cname, mti->mti_fsname, "-client");
3710 /* Add the client type to match the obdname in
3711 class_config_llog_handler */
3712 } else if (mti->mti_flags & LDD_F_SV_TYPE_MDT) {
3713 rc = name_create(&cname, mti->mti_svname, "-mdc");
3714 } else if (mti->mti_flags & LDD_F_SV_TYPE_OST) {
3715 rc = name_create(&cname, mti->mti_svname, "-osc");
3717 GOTO(end, rc = -EINVAL);
3722 /* Forbid direct update of llite root squash parameters.
3723 * These parameters are indirectly set via the MDT settings.
3725 if ((class_match_param(ptr, PARAM_LLITE, &tmp) == 0) &&
3726 ((memcmp(tmp, "root_squash=", 12) == 0) ||
3727 (memcmp(tmp, "nosquash_nids=", 14) == 0))) {
3728 LCONSOLE_ERROR("%s: root squash parameters can only "
3729 "be updated through MDT component\n",
3731 name_destroy(&cname);
3732 GOTO(end, rc = -EINVAL);
3735 CDEBUG(D_MGS, "%.3s param %s\n", ptr, ptr + 4);
3738 rc = name_create(&logname, mti->mti_fsname, "-client");
3740 name_destroy(&cname);
3743 rc = mgs_wlp_lcfg(env, mgs, fsdb, mti, logname, &mgi->mgi_bufs,
3746 /* osc params affect the MDT as well */
3747 if (!rc && (mti->mti_flags & LDD_F_SV_TYPE_OST)) {
3750 for (i = 0; i < INDEX_MAP_SIZE * 8; i++){
3751 if (!test_bit(i, fsdb->fsdb_mdt_index_map))
3753 name_destroy(&cname);
3754 rc = name_create_mdt_osc(&cname, mti->mti_svname,
3756 name_destroy(&logname);
3759 rc = name_create_mdt(&logname,
3760 mti->mti_fsname, i);
3763 if (!mgs_log_is_empty(env, mgs, logname)) {
3764 rc = mgs_wlp_lcfg(env, mgs, fsdb,
3774 /* For mdc activate/deactivate, it affects OSP on MDT as well */
3775 if (class_match_param(ptr, PARAM_MDC PARAM_ACTIVE, &tmp) == 0 &&
3778 char *lodname = NULL;
3779 char *param_str = NULL;
3783 /* replace mdc with osp */
3784 memcpy(ptr, PARAM_OSP, strlen(PARAM_OSP));
3785 rc = server_name2index(mti->mti_svname, &index, NULL);
3787 memcpy(ptr, PARAM_MDC, strlen(PARAM_MDC));
3791 for (i = 0; i < INDEX_MAP_SIZE * 8; i++) {
3792 if (!test_bit(i, fsdb->fsdb_mdt_index_map))
3798 name_destroy(&logname);
3799 rc = name_create_mdt(&logname, mti->mti_fsname,
3804 if (mgs_log_is_empty(env, mgs, logname))
3807 snprintf(suffix, sizeof(suffix), "-osp-MDT%04x",
3809 name_destroy(&cname);
3810 rc = name_create(&cname, mti->mti_svname,
3815 rc = mgs_wlp_lcfg(env, mgs, fsdb, mti, logname,
3816 &mgi->mgi_bufs, cname, ptr);
3820 /* Add configuration log for noitfying LOD
3821 * to active/deactive the OSP. */
3822 name_destroy(¶m_str);
3823 rc = name_create(¶m_str, cname,
3824 (*tmp == '0') ? ".active=0" :
3829 name_destroy(&lodname);
3830 rc = name_create(&lodname, logname, "-mdtlov");
3834 rc = mgs_wlp_lcfg(env, mgs, fsdb, mti, logname,
3835 &mgi->mgi_bufs, lodname,
3840 memcpy(ptr, PARAM_MDC, strlen(PARAM_MDC));
3841 name_destroy(&lodname);
3842 name_destroy(¶m_str);
3845 name_destroy(&logname);
3846 name_destroy(&cname);
3850 /* All mdt. params in proc */
3851 if (class_match_param(ptr, PARAM_MDT, &tmp) == 0) {
3855 CDEBUG(D_MGS, "%.3s param %s\n", ptr, ptr + 4);
3856 if (strncmp(mti->mti_svname, mti->mti_fsname,
3857 MTI_NAME_MAXLEN) == 0)
3858 /* device is unspecified completely? */
3859 rc = LDD_F_SV_TYPE_MDT | LDD_F_SV_ALL;
3861 rc = server_name2index(mti->mti_svname, &idx, NULL);
3864 if ((rc & LDD_F_SV_TYPE_MDT) == 0)
3866 if (rc & LDD_F_SV_ALL) {
3867 for (i = 0; i < INDEX_MAP_SIZE * 8; i++) {
3869 fsdb->fsdb_mdt_index_map))
3871 rc = name_create_mdt(&logname,
3872 mti->mti_fsname, i);
3875 rc = mgs_wlp_lcfg(env, mgs, fsdb, mti,
3876 logname, &mgi->mgi_bufs,
3878 name_destroy(&logname);
3883 if ((memcmp(tmp, "root_squash=", 12) == 0) ||
3884 (memcmp(tmp, "nosquash_nids=", 14) == 0)) {
3885 LCONSOLE_ERROR("%s: root squash parameters "
3886 "cannot be applied to a single MDT\n",
3888 GOTO(end, rc = -EINVAL);
3890 rc = mgs_wlp_lcfg(env, mgs, fsdb, mti,
3891 mti->mti_svname, &mgi->mgi_bufs,
3892 mti->mti_svname, ptr);
3897 /* root squash settings are also applied to llite
3898 * config log (see LU-1778) */
3900 ((memcmp(tmp, "root_squash=", 12) == 0) ||
3901 (memcmp(tmp, "nosquash_nids=", 14) == 0))) {
3905 rc = name_create(&cname, mti->mti_fsname, "-client");
3908 rc = name_create(&logname, mti->mti_fsname, "-client");
3910 name_destroy(&cname);
3913 rc = name_create(&ptr2, PARAM_LLITE, tmp);
3915 name_destroy(&cname);
3916 name_destroy(&logname);
3919 rc = mgs_wlp_lcfg(env, mgs, fsdb, mti, logname,
3920 &mgi->mgi_bufs, cname, ptr2);
3921 name_destroy(&ptr2);
3922 name_destroy(&logname);
3923 name_destroy(&cname);
3928 /* All mdd., ost. and osd. params in proc */
3929 if ((class_match_param(ptr, PARAM_MDD, NULL) == 0) ||
3930 (class_match_param(ptr, PARAM_OST, NULL) == 0) ||
3931 (class_match_param(ptr, PARAM_OSD, NULL) == 0)) {
3932 CDEBUG(D_MGS, "%.3s param %s\n", ptr, ptr + 4);
3933 if (mgs_log_is_empty(env, mgs, mti->mti_svname))
3934 GOTO(end, rc = -ENODEV);
3936 rc = mgs_wlp_lcfg(env, mgs, fsdb, mti, mti->mti_svname,
3937 &mgi->mgi_bufs, mti->mti_svname, ptr);
3941 LCONSOLE_WARN("Ignoring unrecognized param '%s'\n", ptr);
3945 CERROR("err %d on param '%s'\n", rc, ptr);
3950 int mgs_write_log_target(const struct lu_env *env, struct mgs_device *mgs,
3951 struct mgs_target_info *mti, struct fs_db *fsdb)
3958 /* set/check the new target index */
3959 rc = mgs_set_index(env, mgs, mti);
3963 if (rc == EALREADY) {
3964 LCONSOLE_WARN("Found index %d for %s, updating log\n",
3965 mti->mti_stripe_index, mti->mti_svname);
3966 /* We would like to mark old log sections as invalid
3967 and add new log sections in the client and mdt logs.
3968 But if we add new sections, then live clients will
3969 get repeat setup instructions for already running
3970 osc's. So don't update the client/mdt logs. */
3971 mti->mti_flags &= ~LDD_F_UPDATE;
3975 OBD_FAIL_TIMEOUT(OBD_FAIL_MGS_WRITE_TARGET_DELAY, cfs_fail_val > 0 ?
3978 mutex_lock(&fsdb->fsdb_mutex);
3980 if (mti->mti_flags &
3981 (LDD_F_VIRGIN | LDD_F_UPGRADE14 | LDD_F_WRITECONF)) {
3982 /* Generate a log from scratch */
3983 if (mti->mti_flags & LDD_F_SV_TYPE_MDT) {
3984 rc = mgs_write_log_mdt(env, mgs, fsdb, mti);
3985 } else if (mti->mti_flags & LDD_F_SV_TYPE_OST) {
3986 rc = mgs_write_log_ost(env, mgs, fsdb, mti);
3988 CERROR("Unknown target type %#x, can't create log for "
3989 "%s\n", mti->mti_flags, mti->mti_svname);
3992 CERROR("Can't write logs for %s (%d)\n",
3993 mti->mti_svname, rc);
3997 /* Just update the params from tunefs in mgs_write_log_params */
3998 CDEBUG(D_MGS, "Update params for %s\n", mti->mti_svname);
3999 mti->mti_flags |= LDD_F_PARAM;
4002 /* allocate temporary buffer, where class_get_next_param will
4003 make copy of a current parameter */
4004 OBD_ALLOC(buf, strlen(mti->mti_params) + 1);
4006 GOTO(out_up, rc = -ENOMEM);
4007 params = mti->mti_params;
4008 while (params != NULL) {
4009 rc = class_get_next_param(¶ms, buf);
4012 /* there is no next parameter, that is
4017 CDEBUG(D_MGS, "remaining string: '%s', param: '%s'\n",
4019 rc = mgs_write_log_param(env, mgs, fsdb, mti, buf);
4024 OBD_FREE(buf, strlen(mti->mti_params) + 1);
4027 mutex_unlock(&fsdb->fsdb_mutex);
4031 int mgs_erase_log(const struct lu_env *env, struct mgs_device *mgs, char *name)
4033 struct llog_ctxt *ctxt;
4036 ctxt = llog_get_context(mgs->mgs_obd, LLOG_CONFIG_ORIG_CTXT);
4038 CERROR("%s: MGS config context doesn't exist\n",
4039 mgs->mgs_obd->obd_name);
4042 rc = llog_erase(env, ctxt, NULL, name);
4043 /* llog may not exist */
4046 llog_ctxt_put(ctxt);
4050 CERROR("%s: failed to clear log %s: %d\n",
4051 mgs->mgs_obd->obd_name, name, rc);
4056 /* erase all logs for the given fs */
4057 int mgs_erase_logs(const struct lu_env *env, struct mgs_device *mgs,
4060 struct list_head log_list;
4061 struct mgs_direntry *dirent, *n;
4062 char barrier_name[20] = {};
4065 int rc, len = strlen(fsname);
4068 mutex_lock(&mgs->mgs_mutex);
4070 /* Find all the logs in the CONFIGS directory */
4071 rc = class_dentry_readdir(env, mgs, &log_list);
4073 mutex_unlock(&mgs->mgs_mutex);
4077 if (list_empty(&log_list)) {
4078 mutex_unlock(&mgs->mgs_mutex);
4082 snprintf(barrier_name, sizeof(barrier_name) - 1, "%s-%s",
4083 fsname, BARRIER_FILENAME);
4084 /* Delete the barrier fsdb */
4085 mgs_remove_fsdb_by_name(mgs, barrier_name);
4086 /* Delete the fs db */
4087 mgs_remove_fsdb_by_name(mgs, fsname);
4088 mutex_unlock(&mgs->mgs_mutex);
4090 list_for_each_entry_safe(dirent, n, &log_list, mde_list) {
4091 list_del_init(&dirent->mde_list);
4092 suffix = strrchr(dirent->mde_name, '-');
4093 if (suffix != NULL) {
4094 if ((len == suffix - dirent->mde_name) &&
4095 (strncmp(fsname, dirent->mde_name, len) == 0)) {
4096 CDEBUG(D_MGS, "Removing log %s\n",
4098 mgs_erase_log(env, mgs, dirent->mde_name);
4102 mgs_direntry_free(dirent);
4111 /* list all logs for the given fs */
4112 int mgs_list_logs(const struct lu_env *env, struct mgs_device *mgs,
4113 struct obd_ioctl_data *data)
4115 struct list_head log_list;
4116 struct mgs_direntry *dirent, *n;
4122 /* Find all the logs in the CONFIGS directory */
4123 rc = class_dentry_readdir(env, mgs, &log_list);
4127 out = data->ioc_bulk;
4128 remains = data->ioc_inllen1;
4129 list_for_each_entry_safe(dirent, n, &log_list, mde_list) {
4130 list_del_init(&dirent->mde_list);
4131 suffix = strrchr(dirent->mde_name, '-');
4132 if (suffix != NULL) {
4133 l = snprintf(out, remains, "config_log: %s\n",
4138 mgs_direntry_free(dirent);
4145 struct mgs_lcfg_fork_data {
4146 struct lustre_cfg_bufs mlfd_bufs;
4147 struct mgs_device *mlfd_mgs;
4148 struct llog_handle *mlfd_llh;
4149 const char *mlfd_oldname;
4150 const char *mlfd_newname;
4154 static bool contain_valid_fsname(char *buf, const char *fsname,
4155 int buflen, int namelen)
4157 if (buflen < namelen)
4160 if (memcmp(buf, fsname, namelen) != 0)
4163 if (buf[namelen] != '\0' && buf[namelen] != '-')
4169 static int mgs_lcfg_fork_handler(const struct lu_env *env,
4170 struct llog_handle *o_llh,
4171 struct llog_rec_hdr *o_rec, void *data)
4173 struct mgs_lcfg_fork_data *mlfd = data;
4174 struct lustre_cfg_bufs *n_bufs = &mlfd->mlfd_bufs;
4175 struct lustre_cfg *o_lcfg = (struct lustre_cfg *)(o_rec + 1);
4176 struct llog_cfg_rec *lcr;
4178 char *n_buf = mlfd->mlfd_data;
4180 int o_namelen = strlen(mlfd->mlfd_oldname);
4181 int n_namelen = strlen(mlfd->mlfd_newname);
4182 int diff = n_namelen - o_namelen;
4183 __u32 cmd = o_lcfg->lcfg_command;
4184 __u32 cnt = o_lcfg->lcfg_bufcount;
4190 o_buf = lustre_cfg_buf(o_lcfg, 0);
4191 o_buflen = o_lcfg->lcfg_buflens[0];
4192 if (contain_valid_fsname(o_buf, mlfd->mlfd_oldname, o_buflen,
4194 memcpy(n_buf, mlfd->mlfd_newname, n_namelen);
4195 memcpy(n_buf + n_namelen, o_buf + o_namelen,
4196 o_buflen - o_namelen);
4197 lustre_cfg_bufs_reset(n_bufs, n_buf);
4198 n_buf += cfs_size_round(o_buflen + diff);
4200 lustre_cfg_bufs_reset(n_bufs, o_buflen != 0 ? o_buf : NULL);
4205 struct cfg_marker *o_marker;
4206 struct cfg_marker *n_marker;
4210 CDEBUG(D_MGS, "Unknown cfg marker entry with %d "
4215 /* buf[1] is marker */
4216 o_buf = lustre_cfg_buf(o_lcfg, 1);
4217 o_buflen = o_lcfg->lcfg_buflens[1];
4218 o_marker = (struct cfg_marker *)o_buf;
4219 if (!contain_valid_fsname(o_marker->cm_tgtname,
4221 sizeof(o_marker->cm_tgtname),
4223 lustre_cfg_bufs_set(n_bufs, 1, o_marker,
4228 n_marker = (struct cfg_marker *)n_buf;
4229 *n_marker = *o_marker;
4230 memcpy(n_marker->cm_tgtname, mlfd->mlfd_newname, n_namelen);
4231 tgt_namelen = strlen(o_marker->cm_tgtname);
4232 if (tgt_namelen > o_namelen)
4233 memcpy(n_marker->cm_tgtname + n_namelen,
4234 o_marker->cm_tgtname + o_namelen,
4235 tgt_namelen - o_namelen);
4236 n_marker->cm_tgtname[tgt_namelen + diff] = '\0';
4237 lustre_cfg_bufs_set(n_bufs, 1, n_marker, sizeof(*n_marker));
4241 case LCFG_SET_PARAM: {
4242 for (i = 1; i < cnt; i++)
4243 /* buf[i] is the param value, reuse it directly */
4244 lustre_cfg_bufs_set(n_bufs, i,
4245 lustre_cfg_buf(o_lcfg, i),
4246 o_lcfg->lcfg_buflens[i]);
4252 case LCFG_POOL_DEL: {
4253 if (cnt < 3 || cnt > 4) {
4254 CDEBUG(D_MGS, "Unknown cfg pool (%x) entry with %d "
4255 "buffers\n", cmd, cnt);
4259 /* buf[1] is fsname */
4260 o_buf = lustre_cfg_buf(o_lcfg, 1);
4261 o_buflen = o_lcfg->lcfg_buflens[1];
4262 memcpy(n_buf, mlfd->mlfd_newname, n_namelen);
4263 memcpy(n_buf + n_namelen, o_buf + o_namelen,
4264 o_buflen - o_namelen);
4265 lustre_cfg_bufs_set(n_bufs, 1, n_buf, o_buflen + diff);
4266 n_buf += cfs_size_round(o_buflen + diff);
4268 /* buf[2] is the pool name, reuse it directly */
4269 lustre_cfg_bufs_set(n_bufs, 2, lustre_cfg_buf(o_lcfg, 2),
4270 o_lcfg->lcfg_buflens[2]);
4275 /* buf[3] is ostname */
4276 o_buf = lustre_cfg_buf(o_lcfg, 3);
4277 o_buflen = o_lcfg->lcfg_buflens[3];
4278 memcpy(n_buf, mlfd->mlfd_newname, n_namelen);
4279 memcpy(n_buf + n_namelen, o_buf + o_namelen,
4280 o_buflen - o_namelen);
4281 lustre_cfg_bufs_set(n_bufs, 3, n_buf, o_buflen + diff);
4286 o_buflen = o_lcfg->lcfg_buflens[1];
4287 if (o_buflen == sizeof(struct lov_desc) ||
4288 o_buflen == sizeof(struct lmv_desc)) {
4294 o_buf = lustre_cfg_buf(o_lcfg, 1);
4295 if (o_buflen == sizeof(struct lov_desc)) {
4296 struct lov_desc *o_desc =
4297 (struct lov_desc *)o_buf;
4298 struct lov_desc *n_desc =
4299 (struct lov_desc *)n_buf;
4302 o_uuid = o_desc->ld_uuid.uuid;
4303 n_uuid = n_desc->ld_uuid.uuid;
4304 uuid_len = sizeof(o_desc->ld_uuid.uuid);
4306 struct lmv_desc *o_desc =
4307 (struct lmv_desc *)o_buf;
4308 struct lmv_desc *n_desc =
4309 (struct lmv_desc *)n_buf;
4312 o_uuid = o_desc->ld_uuid.uuid;
4313 n_uuid = n_desc->ld_uuid.uuid;
4314 uuid_len = sizeof(o_desc->ld_uuid.uuid);
4317 if (unlikely(!contain_valid_fsname(o_uuid,
4318 mlfd->mlfd_oldname, uuid_len,
4320 lustre_cfg_bufs_set(n_bufs, 1, o_buf,
4325 memcpy(n_uuid, mlfd->mlfd_newname, n_namelen);
4326 uuid_len = strlen(o_uuid);
4327 if (uuid_len > o_namelen)
4328 memcpy(n_uuid + n_namelen,
4330 uuid_len - o_namelen);
4331 n_uuid[uuid_len + diff] = '\0';
4332 lustre_cfg_bufs_set(n_bufs, 1, n_buf, o_buflen);
4334 } /* else case fall through */
4335 } /* else case fall through */
4338 for (i = 1; i < cnt; i++) {
4339 o_buflen = o_lcfg->lcfg_buflens[i];
4343 o_buf = lustre_cfg_buf(o_lcfg, i);
4344 if (!contain_valid_fsname(o_buf, mlfd->mlfd_oldname,
4345 o_buflen, o_namelen)) {
4346 lustre_cfg_bufs_set(n_bufs, i, o_buf, o_buflen);
4350 memcpy(n_buf, mlfd->mlfd_newname, n_namelen);
4351 if (o_buflen == o_namelen) {
4352 lustre_cfg_bufs_set(n_bufs, i, n_buf,
4354 n_buf += cfs_size_round(n_namelen);
4358 memcpy(n_buf + n_namelen, o_buf + o_namelen,
4359 o_buflen - o_namelen);
4360 lustre_cfg_bufs_set(n_bufs, i, n_buf, o_buflen + diff);
4361 n_buf += cfs_size_round(o_buflen + diff);
4367 lcr = lustre_cfg_rec_new(cmd, n_bufs);
4371 lcr->lcr_cfg = *o_lcfg;
4372 rc = llog_write(env, mlfd->mlfd_llh, &lcr->lcr_hdr, LLOG_NEXT_IDX);
4373 lustre_cfg_rec_free(lcr);
4378 static int mgs_lcfg_fork_one(const struct lu_env *env, struct mgs_device *mgs,
4379 struct mgs_direntry *mde, const char *oldname,
4380 const char *newname)
4382 struct llog_handle *old_llh = NULL;
4383 struct llog_handle *new_llh = NULL;
4384 struct llog_ctxt *ctxt = NULL;
4385 struct mgs_lcfg_fork_data *mlfd = NULL;
4386 char *name_buf = NULL;
4388 int old_namelen = strlen(oldname);
4389 int new_namelen = strlen(newname);
4393 name_buflen = mde->mde_len + new_namelen - old_namelen;
4394 OBD_ALLOC(name_buf, name_buflen);
4398 memcpy(name_buf, newname, new_namelen);
4399 memcpy(name_buf + new_namelen, mde->mde_name + old_namelen,
4400 mde->mde_len - old_namelen);
4402 CDEBUG(D_MGS, "Fork the config-log from %s to %s\n",
4403 mde->mde_name, name_buf);
4405 ctxt = llog_get_context(mgs->mgs_obd, LLOG_CONFIG_ORIG_CTXT);
4408 rc = llog_open_create(env, ctxt, &new_llh, NULL, name_buf);
4412 rc = llog_init_handle(env, new_llh, LLOG_F_IS_PLAIN, NULL);
4416 if (unlikely(mgs_log_is_empty(env, mgs, mde->mde_name)))
4419 rc = llog_open(env, ctxt, &old_llh, NULL, mde->mde_name,
4424 rc = llog_init_handle(env, old_llh, LLOG_F_IS_PLAIN, NULL);
4428 new_llh->lgh_hdr->llh_tgtuuid = old_llh->lgh_hdr->llh_tgtuuid;
4430 OBD_ALLOC(mlfd, LLOG_MIN_CHUNK_SIZE);
4432 GOTO(out, rc = -ENOMEM);
4434 mlfd->mlfd_mgs = mgs;
4435 mlfd->mlfd_llh = new_llh;
4436 mlfd->mlfd_oldname = oldname;
4437 mlfd->mlfd_newname = newname;
4439 rc = llog_process(env, old_llh, mgs_lcfg_fork_handler, mlfd, NULL);
4440 OBD_FREE(mlfd, LLOG_MIN_CHUNK_SIZE);
4446 llog_close(env, old_llh);
4448 llog_close(env, new_llh);
4450 OBD_FREE(name_buf, name_buflen);
4452 llog_ctxt_put(ctxt);
4457 int mgs_lcfg_fork(const struct lu_env *env, struct mgs_device *mgs,
4458 const char *oldname, const char *newname)
4460 struct list_head log_list;
4461 struct mgs_direntry *dirent, *n;
4462 int olen = strlen(oldname);
4463 int nlen = strlen(newname);
4468 if (unlikely(!oldname || oldname[0] == '\0' ||
4469 !newname || newname[0] == '\0'))
4472 if (strcmp(oldname, newname) == 0)
4475 /* lock it to prevent fork/erase/register in parallel. */
4476 mutex_lock(&mgs->mgs_mutex);
4478 rc = class_dentry_readdir(env, mgs, &log_list);
4480 mutex_unlock(&mgs->mgs_mutex);
4484 if (list_empty(&log_list)) {
4485 mutex_unlock(&mgs->mgs_mutex);
4489 list_for_each_entry_safe(dirent, n, &log_list, mde_list) {
4492 ptr = strrchr(dirent->mde_name, '-');
4494 int tlen = ptr - dirent->mde_name;
4497 strncmp(newname, dirent->mde_name, tlen) == 0)
4498 GOTO(out, rc = -EEXIST);
4501 strncmp(oldname, dirent->mde_name, tlen) == 0)
4505 list_del_init(&dirent->mde_list);
4506 mgs_direntry_free(dirent);
4509 if (list_empty(&log_list)) {
4510 mutex_unlock(&mgs->mgs_mutex);
4514 list_for_each_entry(dirent, &log_list, mde_list) {
4515 rc = mgs_lcfg_fork_one(env, mgs, dirent, oldname, newname);
4523 mutex_unlock(&mgs->mgs_mutex);
4525 list_for_each_entry_safe(dirent, n, &log_list, mde_list) {
4526 list_del_init(&dirent->mde_list);
4527 mgs_direntry_free(dirent);
4530 if (rc && count > 0)
4531 mgs_erase_logs(env, mgs, newname);
4536 int mgs_lcfg_erase(const struct lu_env *env, struct mgs_device *mgs,
4542 if (unlikely(!fsname || fsname[0] == '\0'))
4545 rc = mgs_erase_logs(env, mgs, fsname);
4550 static int mgs_xattr_del(const struct lu_env *env, struct dt_object *obj)
4552 struct dt_device *dev;
4553 struct thandle *th = NULL;
4558 dev = container_of0(obj->do_lu.lo_dev, struct dt_device, dd_lu_dev);
4559 th = dt_trans_create(env, dev);
4561 RETURN(PTR_ERR(th));
4563 rc = dt_declare_xattr_del(env, obj, XATTR_TARGET_RENAME, th);
4567 rc = dt_trans_start_local(env, dev, th);
4571 dt_write_lock(env, obj, 0);
4572 rc = dt_xattr_del(env, obj, XATTR_TARGET_RENAME, th);
4577 dt_write_unlock(env, obj);
4580 dt_trans_stop(env, dev, th);
4585 int mgs_lcfg_rename(const struct lu_env *env, struct mgs_device *mgs)
4587 struct list_head log_list;
4588 struct mgs_direntry *dirent, *n;
4590 struct lu_buf buf = {
4592 .lb_len = sizeof(fsname)
4598 rc = class_dentry_readdir(env, mgs, &log_list);
4602 if (list_empty(&log_list))
4605 list_for_each_entry_safe(dirent, n, &log_list, mde_list) {
4606 struct dt_object *o = NULL;
4611 list_del_init(&dirent->mde_list);
4612 ptr = strrchr(dirent->mde_name, '-');
4616 len = ptr - dirent->mde_name;
4617 if (unlikely(len >= sizeof(oldname))) {
4618 CDEBUG(D_MGS, "Skip invalid configuration file %s\n",
4623 o = local_file_find(env, mgs->mgs_los, mgs->mgs_configs_dir,
4627 CDEBUG(D_MGS, "Fail to locate file %s: rc = %d\n",
4628 dirent->mde_name, rc);
4632 rc = dt_xattr_get(env, o, &buf, XATTR_TARGET_RENAME);
4638 "Fail to get EA for %s: rc = %d\n",
4639 dirent->mde_name, rc);
4643 if (unlikely(rc == len &&
4644 memcmp(fsname, dirent->mde_name, len) == 0)) {
4645 /* The new fsname is the same as the old one. */
4646 rc = mgs_xattr_del(env, o);
4650 memcpy(oldname, dirent->mde_name, len);
4651 oldname[len] = '\0';
4653 rc = mgs_lcfg_fork_one(env, mgs, dirent, oldname, fsname);
4654 if (rc && rc != -EEXIST) {
4655 CDEBUG(D_MGS, "Fail to fork %s: rc = %d\n",
4656 dirent->mde_name, rc);
4660 rc = mgs_erase_log(env, mgs, dirent->mde_name);
4662 CDEBUG(D_MGS, "Fail to erase old %s: rc = %d\n",
4663 dirent->mde_name, rc);
4664 /* keep it there if failed to remove it. */
4669 if (o && !IS_ERR(o))
4670 lu_object_put(env, &o->do_lu);
4672 mgs_direntry_free(dirent);
4677 list_for_each_entry_safe(dirent, n, &log_list, mde_list) {
4678 list_del_init(&dirent->mde_list);
4679 mgs_direntry_free(dirent);
4685 /* from llog_swab */
4686 static void print_lustre_cfg(struct lustre_cfg *lcfg)
4691 CDEBUG(D_MGS, "lustre_cfg: %p\n", lcfg);
4692 CDEBUG(D_MGS, "\tlcfg->lcfg_version: %#x\n", lcfg->lcfg_version);
4694 CDEBUG(D_MGS, "\tlcfg->lcfg_command: %#x\n", lcfg->lcfg_command);
4695 CDEBUG(D_MGS, "\tlcfg->lcfg_num: %#x\n", lcfg->lcfg_num);
4696 CDEBUG(D_MGS, "\tlcfg->lcfg_flags: %#x\n", lcfg->lcfg_flags);
4697 CDEBUG(D_MGS, "\tlcfg->lcfg_nid: %s\n", libcfs_nid2str(lcfg->lcfg_nid));
4699 CDEBUG(D_MGS, "\tlcfg->lcfg_bufcount: %d\n", lcfg->lcfg_bufcount);
4700 if (lcfg->lcfg_bufcount < LUSTRE_CFG_MAX_BUFCOUNT)
4701 for (i = 0; i < lcfg->lcfg_bufcount; i++) {
4702 CDEBUG(D_MGS, "\tlcfg->lcfg_buflens[%d]: %d %s\n",
4703 i, lcfg->lcfg_buflens[i],
4704 lustre_cfg_string(lcfg, i));
4709 /* Setup _mgs fsdb and log
4711 int mgs__mgs_fsdb_setup(const struct lu_env *env, struct mgs_device *mgs)
4713 struct fs_db *fsdb = NULL;
4717 rc = mgs_find_or_make_fsdb(env, mgs, MGSSELF_NAME, &fsdb);
4719 mgs_put_fsdb(mgs, fsdb);
4724 /* Setup params fsdb and log
4726 int mgs_params_fsdb_setup(const struct lu_env *env, struct mgs_device *mgs)
4728 struct fs_db *fsdb = NULL;
4729 struct llog_handle *params_llh = NULL;
4733 rc = mgs_find_or_make_fsdb(env, mgs, PARAMS_FILENAME, &fsdb);
4735 mutex_lock(&fsdb->fsdb_mutex);
4736 rc = record_start_log(env, mgs, ¶ms_llh, PARAMS_FILENAME);
4738 rc = record_end_log(env, ¶ms_llh);
4739 mutex_unlock(&fsdb->fsdb_mutex);
4740 mgs_put_fsdb(mgs, fsdb);
4746 /* Cleanup params fsdb and log
4748 int mgs_params_fsdb_cleanup(const struct lu_env *env, struct mgs_device *mgs)
4752 rc = mgs_erase_logs(env, mgs, PARAMS_FILENAME);
4753 return rc == -ENOENT ? 0 : rc;
4756 /* Set a permanent (config log) param for a target or fs
4757 * \param lcfg buf0 may contain the device (testfs-MDT0000) name
4758 * buf1 contains the single parameter
4760 int mgs_setparam(const struct lu_env *env, struct mgs_device *mgs,
4761 struct lustre_cfg *lcfg, char *fsname)
4763 struct fs_db *fsdb = NULL;
4764 struct mgs_target_info *mti = NULL;
4765 char *devname, *param;
4773 print_lustre_cfg(lcfg);
4775 /* lustre, lustre-mdtlov, lustre-client, lustre-MDT0000 */
4776 devname = lustre_cfg_string(lcfg, 0);
4777 param = lustre_cfg_string(lcfg, 1);
4779 /* Assume device name embedded in param:
4780 lustre-OST0000.osc.max_dirty_mb=32 */
4781 ptr = strchr(param, '.');
4789 LCONSOLE_ERROR_MSG(0x14d, "No target specified: %s\n", param);
4793 rc = mgs_parse_devname(devname, fsname, NULL);
4794 if (rc == 0 && !mgs_parse_devname(devname, NULL, &index)) {
4795 /* param related to llite isn't allowed to set by OST or MDT */
4796 if (rc == 0 && strncmp(param, PARAM_LLITE,
4797 sizeof(PARAM_LLITE) - 1) == 0)
4800 /* assume devname is the fsname */
4801 strlcpy(fsname, devname, MTI_NAME_MAXLEN);
4803 CDEBUG(D_MGS, "setparam fs='%s' device='%s'\n", fsname, devname);
4805 rc = mgs_find_or_make_fsdb(env, mgs,
4806 lcfg->lcfg_command == LCFG_SET_PARAM ?
4807 PARAMS_FILENAME : fsname, &fsdb);
4811 if (lcfg->lcfg_command != LCFG_SET_PARAM &&
4812 !test_bit(FSDB_MGS_SELF, &fsdb->fsdb_flags) &&
4813 test_bit(FSDB_LOG_EMPTY, &fsdb->fsdb_flags)) {
4814 CERROR("No filesystem targets for %s. cfg_device from lctl "
4815 "is '%s'\n", fsname, devname);
4817 GOTO(out, rc = -EINVAL);
4820 /* Create a fake mti to hold everything */
4823 GOTO(out, rc = -ENOMEM);
4824 if (strlcpy(mti->mti_fsname, fsname, sizeof(mti->mti_fsname))
4825 >= sizeof(mti->mti_fsname))
4826 GOTO(out, rc = -E2BIG);
4827 if (strlcpy(mti->mti_svname, devname, sizeof(mti->mti_svname))
4828 >= sizeof(mti->mti_svname))
4829 GOTO(out, rc = -E2BIG);
4830 if (strlcpy(mti->mti_params, param, sizeof(mti->mti_params))
4831 >= sizeof(mti->mti_params))
4832 GOTO(out, rc = -E2BIG);
4833 rc = server_name2index(mti->mti_svname, &mti->mti_stripe_index, &tmp);
4835 /* Not a valid server; may be only fsname */
4838 /* Strip -osc or -mdc suffix from svname */
4839 if (server_make_name(rc, mti->mti_stripe_index, mti->mti_fsname,
4840 mti->mti_svname, sizeof(mti->mti_svname)))
4841 GOTO(out, rc = -EINVAL);
4843 * Revoke lock so everyone updates. Should be alright if
4844 * someone was already reading while we were updating the logs,
4845 * so we don't really need to hold the lock while we're
4848 if (lcfg->lcfg_command == LCFG_SET_PARAM) {
4849 mti->mti_flags = rc | LDD_F_PARAM2;
4850 mutex_lock(&fsdb->fsdb_mutex);
4851 rc = mgs_write_log_param2(env, mgs, fsdb, mti, mti->mti_params);
4852 mutex_unlock(&fsdb->fsdb_mutex);
4853 mgs_revoke_lock(mgs, fsdb, CONFIG_T_PARAMS);
4855 mti->mti_flags = rc | LDD_F_PARAM;
4856 mutex_lock(&fsdb->fsdb_mutex);
4857 rc = mgs_write_log_param(env, mgs, fsdb, mti, mti->mti_params);
4858 mutex_unlock(&fsdb->fsdb_mutex);
4859 mgs_revoke_lock(mgs, fsdb, CONFIG_T_CONFIG);
4868 mgs_unlink_fsdb(mgs, fsdb);
4869 mgs_put_fsdb(mgs, fsdb);
4875 static int mgs_write_log_pool(const struct lu_env *env,
4876 struct mgs_device *mgs, char *logname,
4877 struct fs_db *fsdb, char *tgtname,
4878 enum lcfg_command_type cmd,
4879 char *fsname, char *poolname,
4880 char *ostname, char *comment)
4882 struct llog_handle *llh = NULL;
4885 rc = record_start_log(env, mgs, &llh, logname);
4888 rc = record_marker(env, llh, fsdb, CM_START, tgtname, comment);
4891 rc = record_base(env, llh, tgtname, 0, cmd,
4892 fsname, poolname, ostname, NULL);
4895 rc = record_marker(env, llh, fsdb, CM_END, tgtname, comment);
4897 record_end_log(env, &llh);
4901 int mgs_nodemap_cmd(const struct lu_env *env, struct mgs_device *mgs,
4902 enum lcfg_command_type cmd, const char *nodemap_name,
4913 case LCFG_NODEMAP_ADD:
4914 rc = nodemap_add(nodemap_name);
4916 case LCFG_NODEMAP_DEL:
4917 rc = nodemap_del(nodemap_name);
4919 case LCFG_NODEMAP_ADD_RANGE:
4920 rc = nodemap_parse_range(param, nid);
4923 rc = nodemap_add_range(nodemap_name, nid);
4925 case LCFG_NODEMAP_DEL_RANGE:
4926 rc = nodemap_parse_range(param, nid);
4929 rc = nodemap_del_range(nodemap_name, nid);
4931 case LCFG_NODEMAP_ADMIN:
4932 bool_switch = simple_strtoul(param, NULL, 10);
4933 rc = nodemap_set_allow_root(nodemap_name, bool_switch);
4935 case LCFG_NODEMAP_DENY_UNKNOWN:
4936 bool_switch = simple_strtoul(param, NULL, 10);
4937 rc = nodemap_set_deny_unknown(nodemap_name, bool_switch);
4939 case LCFG_NODEMAP_MAP_MODE:
4940 if (strcmp("both", param) == 0)
4941 rc = nodemap_set_mapping_mode(nodemap_name,
4943 else if (strcmp("uid_only", param) == 0)
4944 rc = nodemap_set_mapping_mode(nodemap_name,
4945 NODEMAP_MAP_UID_ONLY);
4946 else if (strcmp("gid_only", param) == 0)
4947 rc = nodemap_set_mapping_mode(nodemap_name,
4948 NODEMAP_MAP_GID_ONLY);
4952 case LCFG_NODEMAP_TRUSTED:
4953 bool_switch = simple_strtoul(param, NULL, 10);
4954 rc = nodemap_set_trust_client_ids(nodemap_name, bool_switch);
4956 case LCFG_NODEMAP_SQUASH_UID:
4957 int_id = simple_strtoul(param, NULL, 10);
4958 rc = nodemap_set_squash_uid(nodemap_name, int_id);
4960 case LCFG_NODEMAP_SQUASH_GID:
4961 int_id = simple_strtoul(param, NULL, 10);
4962 rc = nodemap_set_squash_gid(nodemap_name, int_id);
4964 case LCFG_NODEMAP_ADD_UIDMAP:
4965 case LCFG_NODEMAP_ADD_GIDMAP:
4966 rc = nodemap_parse_idmap(param, idmap);
4969 if (cmd == LCFG_NODEMAP_ADD_UIDMAP)
4970 rc = nodemap_add_idmap(nodemap_name, NODEMAP_UID,
4973 rc = nodemap_add_idmap(nodemap_name, NODEMAP_GID,
4976 case LCFG_NODEMAP_DEL_UIDMAP:
4977 case LCFG_NODEMAP_DEL_GIDMAP:
4978 rc = nodemap_parse_idmap(param, idmap);
4981 if (cmd == LCFG_NODEMAP_DEL_UIDMAP)
4982 rc = nodemap_del_idmap(nodemap_name, NODEMAP_UID,
4985 rc = nodemap_del_idmap(nodemap_name, NODEMAP_GID,
4988 case LCFG_NODEMAP_SET_FILESET:
4989 rc = nodemap_set_fileset(nodemap_name, param);
4998 int mgs_pool_cmd(const struct lu_env *env, struct mgs_device *mgs,
4999 enum lcfg_command_type cmd, char *fsname,
5000 char *poolname, char *ostname)
5005 char *label = NULL, *canceled_label = NULL;
5007 struct mgs_target_info *mti = NULL;
5008 bool checked = false;
5009 bool locked = false;
5014 rc = mgs_find_or_make_fsdb(env, mgs, fsname, &fsdb);
5016 CERROR("Can't get db for %s\n", fsname);
5019 if (test_bit(FSDB_LOG_EMPTY, &fsdb->fsdb_flags)) {
5020 CERROR("%s is not defined\n", fsname);
5022 GOTO(out_fsdb, rc = -EINVAL);
5025 label_sz = 10 + strlen(fsname) + strlen(poolname);
5027 /* check if ostname match fsname */
5028 if (ostname != NULL) {
5031 ptr = strrchr(ostname, '-');
5032 if ((ptr == NULL) ||
5033 (strncmp(fsname, ostname, ptr-ostname) != 0))
5035 label_sz += strlen(ostname);
5038 OBD_ALLOC(label, label_sz);
5040 GOTO(out_fsdb, rc = -ENOMEM);
5045 "new %s.%s", fsname, poolname);
5049 "add %s.%s.%s", fsname, poolname, ostname);
5052 OBD_ALLOC(canceled_label, label_sz);
5053 if (canceled_label == NULL)
5054 GOTO(out_label, rc = -ENOMEM);
5056 "rem %s.%s.%s", fsname, poolname, ostname);
5057 sprintf(canceled_label,
5058 "add %s.%s.%s", fsname, poolname, ostname);
5061 OBD_ALLOC(canceled_label, label_sz);
5062 if (canceled_label == NULL)
5063 GOTO(out_label, rc = -ENOMEM);
5065 "del %s.%s", fsname, poolname);
5066 sprintf(canceled_label,
5067 "new %s.%s", fsname, poolname);
5075 GOTO(out_cancel, rc = -ENOMEM);
5076 strncpy(mti->mti_svname, "lov pool", sizeof(mti->mti_svname));
5078 mutex_lock(&fsdb->fsdb_mutex);
5080 /* write pool def to all MDT logs */
5081 for (i = 0; i < INDEX_MAP_SIZE * 8; i++) {
5082 if (test_bit(i, fsdb->fsdb_mdt_index_map)) {
5083 rc = name_create_mdt_and_lov(&logname, &lovname,
5088 if (!checked && (canceled_label == NULL)) {
5089 rc = mgs_check_marker(env, mgs, fsdb, mti,
5090 logname, lovname, label);
5092 name_destroy(&logname);
5093 name_destroy(&lovname);
5095 rc = (rc == LLOG_PROC_BREAK ?
5100 if (canceled_label != NULL)
5101 rc = mgs_modify(env, mgs, fsdb, mti, logname,
5102 lovname, canceled_label,
5106 rc = mgs_write_log_pool(env, mgs, logname,
5110 name_destroy(&logname);
5111 name_destroy(&lovname);
5117 rc = name_create(&logname, fsname, "-client");
5121 if (!checked && (canceled_label == NULL)) {
5122 rc = mgs_check_marker(env, mgs, fsdb, mti, logname,
5123 fsdb->fsdb_clilov, label);
5125 name_destroy(&logname);
5126 GOTO(out_mti, rc = (rc == LLOG_PROC_BREAK ?
5130 if (canceled_label != NULL) {
5131 rc = mgs_modify(env, mgs, fsdb, mti, logname,
5132 fsdb->fsdb_clilov, canceled_label, CM_SKIP);
5134 name_destroy(&logname);
5139 rc = mgs_write_log_pool(env, mgs, logname, fsdb, fsdb->fsdb_clilov,
5140 cmd, fsname, poolname, ostname, label);
5141 mutex_unlock(&fsdb->fsdb_mutex);
5143 name_destroy(&logname);
5144 /* request for update */
5145 mgs_revoke_lock(mgs, fsdb, CONFIG_T_CONFIG);
5151 mutex_unlock(&fsdb->fsdb_mutex);
5155 if (canceled_label != NULL)
5156 OBD_FREE(canceled_label, label_sz);
5158 OBD_FREE(label, label_sz);
5161 mgs_unlink_fsdb(mgs, fsdb);
5162 mgs_put_fsdb(mgs, fsdb);