4 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License version 2 only,
8 * as published by the Free Software Foundation.
10 * This program is distributed in the hope that it will be useful, but
11 * WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * General Public License version 2 for more details (a copy is included
14 * in the LICENSE file that accompanied this code).
16 * You should have received a copy of the GNU General Public License
17 * version 2 along with this program; If not, see
18 * http://www.gnu.org/licenses/gpl-2.0.html
23 * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved.
24 * Use is subject to license terms.
26 * Copyright (c) 2011, 2016, Intel Corporation.
29 * This file is part of Lustre, http://www.lustre.org/
30 * Lustre is a trademark of Sun Microsystems, Inc.
32 * lustre/mgs/mgs_llog.c
34 * Lustre Management Server (mgs) config llog creation
36 * Author: Nathan Rutman <nathan@clusterfs.com>
37 * Author: Alex Zhuravlev <bzzz@whamcloud.com>
38 * Author: Mikhail Pershin <tappro@whamcloud.com>
41 #define DEBUG_SUBSYSTEM S_MGS
42 #define D_MGS D_CONFIG
45 #include <uapi/linux/lustre/lustre_ioctl.h>
46 #include <uapi/linux/lustre/lustre_param.h>
47 #include <lustre_sec.h>
48 #include <lustre_quota.h>
50 #include "mgs_internal.h"
52 /********************** Class functions ********************/
55 * Find all logs in CONFIG directory and link then into list.
57 * \param[in] env pointer to the thread context
58 * \param[in] mgs pointer to the mgs device
59 * \param[out] log_list the list to hold the found llog name entry
61 * \retval 0 for success
62 * \retval negative error number on failure
64 int class_dentry_readdir(const struct lu_env *env, struct mgs_device *mgs,
65 struct list_head *log_list)
67 struct dt_object *dir = mgs->mgs_configs_dir;
68 const struct dt_it_ops *iops;
70 struct mgs_direntry *de;
74 INIT_LIST_HEAD(log_list);
77 LASSERT(dir->do_index_ops);
79 iops = &dir->do_index_ops->dio_it;
80 it = iops->init(env, dir, LUDA_64BITHASH);
84 rc = iops->load(env, it, 0);
90 key = (void *)iops->key(env, it);
92 CERROR("%s: key failed when listing %s: rc = %d\n",
93 mgs->mgs_obd->obd_name, MOUNT_CONFIGS_DIR,
97 key_sz = iops->key_size(env, it);
100 /* filter out "." and ".." entries */
104 if (key_sz == 2 && key[1] == '.')
108 /* filter out ".bak" files */
109 /* sizeof(".bak") - 1 == 3 */
111 !memcmp(".bak", key + key_sz - 3, 3)) {
112 CDEBUG(D_MGS, "Skipping backup file %.*s\n",
117 de = mgs_direntry_alloc(key_sz + 1);
123 memcpy(de->mde_name, key, key_sz);
124 de->mde_name[key_sz] = 0;
126 list_add(&de->mde_list, log_list);
129 rc = iops->next(env, it);
139 struct mgs_direntry *n;
141 CERROR("%s: key failed when listing %s: rc = %d\n",
142 mgs->mgs_obd->obd_name, MOUNT_CONFIGS_DIR, rc);
144 list_for_each_entry_safe(de, n, log_list, mde_list) {
145 list_del_init(&de->mde_list);
146 mgs_direntry_free(de);
153 /******************** DB functions *********************/
155 static inline int name_create(char **newname, char *prefix, char *suffix)
158 OBD_ALLOC(*newname, strlen(prefix) + strlen(suffix) + 1);
161 sprintf(*newname, "%s%s", prefix, suffix);
165 static inline void name_destroy(char **name)
168 OBD_FREE(*name, strlen(*name) + 1);
172 struct mgs_fsdb_handler_data
178 /* from the (client) config log, figure out:
179 1. which ost's/mdt's are configured (by index)
180 2. what the last config step is
181 3. COMPAT_18 osc name
183 /* It might be better to have a separate db file, instead of parsing the info
184 out of the client log. This is slow and potentially error-prone. */
185 static int mgs_fsdb_handler(const struct lu_env *env, struct llog_handle *llh,
186 struct llog_rec_hdr *rec, void *data)
188 struct mgs_fsdb_handler_data *d = data;
189 struct fs_db *fsdb = d->fsdb;
190 int cfg_len = rec->lrh_len;
191 char *cfg_buf = (char*) (rec + 1);
192 struct lustre_cfg *lcfg;
197 if (rec->lrh_type != OBD_CFG_REC) {
198 CERROR("unhandled lrh_type: %#x\n", rec->lrh_type);
202 rc = lustre_cfg_sanity_check(cfg_buf, cfg_len);
204 CERROR("Insane cfg\n");
208 lcfg = (struct lustre_cfg *)cfg_buf;
210 CDEBUG(D_INFO, "cmd %x %s %s\n", lcfg->lcfg_command,
211 lustre_cfg_string(lcfg, 0), lustre_cfg_string(lcfg, 1));
213 /* Figure out ost indicies */
214 /* lov_modify_tgts add 0:lov1 1:ost1_UUID 2(index):0 3(gen):1 */
215 if (lcfg->lcfg_command == LCFG_LOV_ADD_OBD ||
216 lcfg->lcfg_command == LCFG_LOV_DEL_OBD) {
217 index = simple_strtoul(lustre_cfg_string(lcfg, 2),
219 CDEBUG(D_MGS, "OST index for %s is %u (%s)\n",
220 lustre_cfg_string(lcfg, 1), index,
221 lustre_cfg_string(lcfg, 2));
222 set_bit(index, fsdb->fsdb_ost_index_map);
225 /* Figure out mdt indicies */
226 /* attach 0:MDC_uml1_mdsA_MNT_client 1:mdc 2:1d834_MNT_client_03f */
227 if ((lcfg->lcfg_command == LCFG_ATTACH) &&
228 (strcmp(lustre_cfg_string(lcfg, 1), LUSTRE_MDC_NAME) == 0)) {
229 rc = server_name2index(lustre_cfg_string(lcfg, 0),
231 if (rc != LDD_F_SV_TYPE_MDT) {
232 CWARN("Unparsable MDC name %s, assuming index 0\n",
233 lustre_cfg_string(lcfg, 0));
237 CDEBUG(D_MGS, "MDT index is %u\n", index);
238 if (!test_bit(index, fsdb->fsdb_mdt_index_map)) {
239 set_bit(index, fsdb->fsdb_mdt_index_map);
240 fsdb->fsdb_mdt_count++;
245 * figure out the old config. fsdb_gen = 0 means old log
246 * It is obsoleted and not supported anymore
248 if (fsdb->fsdb_gen == 0) {
249 CERROR("Old config format is not supported\n");
254 * compat to 1.8, check osc name used by MDT0 to OSTs, bz18548.
256 if (!test_bit(FSDB_OSCNAME18, &fsdb->fsdb_flags) &&
257 lcfg->lcfg_command == LCFG_ATTACH &&
258 strcmp(lustre_cfg_string(lcfg, 1), LUSTRE_OSC_NAME) == 0) {
259 if (OBD_OCD_VERSION_MAJOR(d->ver) == 1 &&
260 OBD_OCD_VERSION_MINOR(d->ver) <= 8) {
261 CWARN("MDT using 1.8 OSC name scheme\n");
262 set_bit(FSDB_OSCNAME18, &fsdb->fsdb_flags);
266 if (lcfg->lcfg_command == LCFG_MARKER) {
267 struct cfg_marker *marker;
268 marker = lustre_cfg_buf(lcfg, 1);
270 d->ver = marker->cm_vers;
272 /* Keep track of the latest marker step */
273 fsdb->fsdb_gen = max(fsdb->fsdb_gen, marker->cm_step);
279 /* fsdb->fsdb_mutex is already held in mgs_find_or_make_fsdb*/
280 static int mgs_get_fsdb_from_llog(const struct lu_env *env,
281 struct mgs_device *mgs,
285 struct llog_handle *loghandle;
286 struct llog_ctxt *ctxt;
287 struct mgs_fsdb_handler_data d = {
294 ctxt = llog_get_context(mgs->mgs_obd, LLOG_CONFIG_ORIG_CTXT);
295 LASSERT(ctxt != NULL);
296 rc = name_create(&logname, fsdb->fsdb_name, "-client");
299 rc = llog_open_create(env, ctxt, &loghandle, NULL, logname);
303 rc = llog_init_handle(env, loghandle, LLOG_F_IS_PLAIN, NULL);
307 if (llog_get_size(loghandle) <= 1)
308 set_bit(FSDB_LOG_EMPTY, &fsdb->fsdb_flags);
310 rc = llog_process(env, loghandle, mgs_fsdb_handler, (void *)&d, NULL);
311 CDEBUG(D_INFO, "get_db = %d\n", rc);
313 llog_close(env, loghandle);
315 name_destroy(&logname);
322 static void mgs_free_fsdb_srpc(struct fs_db *fsdb)
324 struct mgs_tgt_srpc_conf *tgtconf;
326 /* free target-specific rules */
327 while (fsdb->fsdb_srpc_tgt) {
328 tgtconf = fsdb->fsdb_srpc_tgt;
329 fsdb->fsdb_srpc_tgt = tgtconf->mtsc_next;
331 LASSERT(tgtconf->mtsc_tgt);
333 sptlrpc_rule_set_free(&tgtconf->mtsc_rset);
334 OBD_FREE(tgtconf->mtsc_tgt, strlen(tgtconf->mtsc_tgt) + 1);
335 OBD_FREE_PTR(tgtconf);
338 /* free general rules */
339 sptlrpc_rule_set_free(&fsdb->fsdb_srpc_gen);
342 static void mgs_unlink_fsdb(struct mgs_device *mgs, struct fs_db *fsdb)
344 mutex_lock(&mgs->mgs_mutex);
345 if (likely(!list_empty(&fsdb->fsdb_list))) {
346 LASSERTF(atomic_read(&fsdb->fsdb_ref) >= 2,
347 "Invalid ref %d on %s\n",
348 atomic_read(&fsdb->fsdb_ref),
351 list_del_init(&fsdb->fsdb_list);
352 /* Drop the reference on the list.*/
353 mgs_put_fsdb(mgs, fsdb);
355 mutex_unlock(&mgs->mgs_mutex);
358 /* The caller must hold mgs->mgs_mutex. */
359 static inline struct fs_db *
360 mgs_find_fsdb_noref(struct mgs_device *mgs, const char *fsname)
363 struct list_head *tmp;
365 list_for_each(tmp, &mgs->mgs_fs_db_list) {
366 fsdb = list_entry(tmp, struct fs_db, fsdb_list);
367 if (strcmp(fsdb->fsdb_name, fsname) == 0)
374 /* The caller must hold mgs->mgs_mutex. */
375 static void mgs_remove_fsdb_by_name(struct mgs_device *mgs, const char *name)
379 fsdb = mgs_find_fsdb_noref(mgs, name);
381 list_del_init(&fsdb->fsdb_list);
382 /* Drop the reference on the list.*/
383 mgs_put_fsdb(mgs, fsdb);
387 /* The caller must hold mgs->mgs_mutex. */
388 struct fs_db *mgs_find_fsdb(struct mgs_device *mgs, const char *fsname)
392 fsdb = mgs_find_fsdb_noref(mgs, fsname);
394 atomic_inc(&fsdb->fsdb_ref);
399 /* The caller must hold mgs->mgs_mutex. */
400 static struct fs_db *mgs_new_fsdb(const struct lu_env *env,
401 struct mgs_device *mgs, char *fsname)
407 if (strlen(fsname) >= sizeof(fsdb->fsdb_name)) {
408 CERROR("fsname %s is too long\n", fsname);
410 RETURN(ERR_PTR(-EINVAL));
415 RETURN(ERR_PTR(-ENOMEM));
417 strncpy(fsdb->fsdb_name, fsname, sizeof(fsdb->fsdb_name));
418 mutex_init(&fsdb->fsdb_mutex);
419 INIT_LIST_HEAD(&fsdb->fsdb_list);
420 set_bit(FSDB_UDESC, &fsdb->fsdb_flags);
422 INIT_LIST_HEAD(&fsdb->fsdb_clients);
423 atomic_set(&fsdb->fsdb_notify_phase, 0);
424 init_waitqueue_head(&fsdb->fsdb_notify_waitq);
425 init_completion(&fsdb->fsdb_notify_comp);
427 if (strcmp(fsname, MGSSELF_NAME) == 0) {
428 set_bit(FSDB_MGS_SELF, &fsdb->fsdb_flags);
429 fsdb->fsdb_mgs = mgs;
430 if (logname_is_barrier(fsname))
433 OBD_ALLOC(fsdb->fsdb_mdt_index_map, INDEX_MAP_SIZE);
434 if (!fsdb->fsdb_mdt_index_map) {
435 CERROR("No memory for MDT index maps\n");
437 GOTO(err, rc = -ENOMEM);
440 OBD_ALLOC(fsdb->fsdb_ost_index_map, INDEX_MAP_SIZE);
441 if (!fsdb->fsdb_ost_index_map) {
442 CERROR("No memory for OST index maps\n");
444 GOTO(err, rc = -ENOMEM);
447 if (logname_is_barrier(fsname))
450 rc = name_create(&fsdb->fsdb_clilov, fsname, "-clilov");
454 rc = name_create(&fsdb->fsdb_clilmv, fsname, "-clilmv");
458 /* initialise data for NID table */
459 mgs_ir_init_fs(env, mgs, fsdb);
460 lproc_mgs_add_live(mgs, fsdb);
463 if (!test_bit(FSDB_MGS_SELF, &fsdb->fsdb_flags) &&
464 strcmp(PARAMS_FILENAME, fsname) != 0) {
465 /* populate the db from the client llog */
466 rc = mgs_get_fsdb_from_llog(env, mgs, fsdb);
468 CERROR("Can't get db from client log %d\n", rc);
474 /* populate srpc rules from params llog */
475 rc = mgs_get_fsdb_srpc_from_llog(env, mgs, fsdb);
477 CERROR("Can't get db from params log %d\n", rc);
483 /* One ref is for the fsdb on the list.
484 * The other ref is for the caller. */
485 atomic_set(&fsdb->fsdb_ref, 2);
486 list_add(&fsdb->fsdb_list, &mgs->mgs_fs_db_list);
491 atomic_set(&fsdb->fsdb_ref, 1);
492 mgs_put_fsdb(mgs, fsdb);
497 static void mgs_free_fsdb(struct mgs_device *mgs, struct fs_db *fsdb)
499 LASSERT(list_empty(&fsdb->fsdb_list));
501 lproc_mgs_del_live(mgs, fsdb);
503 /* deinitialize fsr */
505 mgs_ir_fini_fs(mgs, fsdb);
507 if (fsdb->fsdb_ost_index_map)
508 OBD_FREE(fsdb->fsdb_ost_index_map, INDEX_MAP_SIZE);
509 if (fsdb->fsdb_mdt_index_map)
510 OBD_FREE(fsdb->fsdb_mdt_index_map, INDEX_MAP_SIZE);
511 name_destroy(&fsdb->fsdb_clilov);
512 name_destroy(&fsdb->fsdb_clilmv);
513 mgs_free_fsdb_srpc(fsdb);
517 void mgs_put_fsdb(struct mgs_device *mgs, struct fs_db *fsdb)
519 if (atomic_dec_and_test(&fsdb->fsdb_ref))
520 mgs_free_fsdb(mgs, fsdb);
523 int mgs_init_fsdb_list(struct mgs_device *mgs)
525 INIT_LIST_HEAD(&mgs->mgs_fs_db_list);
529 int mgs_cleanup_fsdb_list(struct mgs_device *mgs)
532 struct list_head *tmp, *tmp2;
534 mutex_lock(&mgs->mgs_mutex);
535 list_for_each_safe(tmp, tmp2, &mgs->mgs_fs_db_list) {
536 fsdb = list_entry(tmp, struct fs_db, fsdb_list);
537 list_del_init(&fsdb->fsdb_list);
538 mgs_put_fsdb(mgs, fsdb);
540 mutex_unlock(&mgs->mgs_mutex);
544 int mgs_find_or_make_fsdb(const struct lu_env *env, struct mgs_device *mgs,
545 char *name, struct fs_db **dbh)
551 mutex_lock(&mgs->mgs_mutex);
552 fsdb = mgs_find_fsdb(mgs, name);
554 fsdb = mgs_new_fsdb(env, mgs, name);
558 CDEBUG(D_MGS, "Created new db: rc = %d\n", rc);
560 mutex_unlock(&mgs->mgs_mutex);
570 -1= empty client log */
571 int mgs_check_index(const struct lu_env *env,
572 struct mgs_device *mgs,
573 struct mgs_target_info *mti)
580 LASSERT(!(mti->mti_flags & LDD_F_NEED_INDEX));
582 rc = mgs_find_or_make_fsdb(env, mgs, mti->mti_fsname, &fsdb);
584 CERROR("Can't get db for %s\n", mti->mti_fsname);
588 if (test_bit(FSDB_LOG_EMPTY, &fsdb->fsdb_flags))
591 if (mti->mti_flags & LDD_F_SV_TYPE_OST)
592 imap = fsdb->fsdb_ost_index_map;
593 else if (mti->mti_flags & LDD_F_SV_TYPE_MDT)
594 imap = fsdb->fsdb_mdt_index_map;
596 GOTO(out, rc = -EINVAL);
598 if (test_bit(mti->mti_stripe_index, imap))
604 mgs_put_fsdb(mgs, fsdb);
608 static __inline__ int next_index(void *index_map, int map_len)
611 for (i = 0; i < map_len * 8; i++)
612 if (!test_bit(i, index_map)) {
615 CERROR("max index %d exceeded.\n", i);
619 /* Make the mdt/ost server obd name based on the filesystem name */
620 static bool server_make_name(u32 flags, u16 index, const char *fs,
621 char *name_buf, size_t name_buf_size)
623 bool invalid_flag = false;
625 if (flags & (LDD_F_SV_TYPE_MDT | LDD_F_SV_TYPE_OST)) {
626 if (!(flags & LDD_F_SV_ALL))
627 snprintf(name_buf, name_buf_size, "%.8s%c%s%04x", fs,
628 (flags & LDD_F_VIRGIN) ? ':' :
629 ((flags & LDD_F_WRITECONF) ? '=' : '-'),
630 (flags & LDD_F_SV_TYPE_MDT) ? "MDT" : "OST",
632 } else if (flags & LDD_F_SV_TYPE_MGS) {
633 snprintf(name_buf, name_buf_size, "MGS");
635 CERROR("unknown server type %#x\n", flags);
642 0 newly marked as in use
644 +EALREADY for update of an old index */
645 static int mgs_set_index(const struct lu_env *env,
646 struct mgs_device *mgs,
647 struct mgs_target_info *mti)
654 rc = mgs_find_or_make_fsdb(env, mgs, mti->mti_fsname, &fsdb);
656 CERROR("Can't get db for %s\n", mti->mti_fsname);
660 mutex_lock(&fsdb->fsdb_mutex);
661 if (mti->mti_flags & LDD_F_SV_TYPE_OST) {
662 imap = fsdb->fsdb_ost_index_map;
663 } else if (mti->mti_flags & LDD_F_SV_TYPE_MDT) {
664 imap = fsdb->fsdb_mdt_index_map;
666 GOTO(out_up, rc = -EINVAL);
669 if (mti->mti_flags & LDD_F_NEED_INDEX) {
670 rc = next_index(imap, INDEX_MAP_SIZE);
672 GOTO(out_up, rc = -ERANGE);
673 mti->mti_stripe_index = rc;
676 /* the last index(0xffff) is reserved for default value. */
677 if (mti->mti_stripe_index >= INDEX_MAP_SIZE * 8 - 1) {
678 LCONSOLE_ERROR_MSG(0x13f, "Server %s requested index %u, "
679 "but index must be less than %u.\n",
680 mti->mti_svname, mti->mti_stripe_index,
681 INDEX_MAP_SIZE * 8 - 1);
682 GOTO(out_up, rc = -ERANGE);
685 if (test_bit(mti->mti_stripe_index, imap)) {
686 if ((mti->mti_flags & LDD_F_VIRGIN) &&
687 !(mti->mti_flags & LDD_F_WRITECONF)) {
688 LCONSOLE_ERROR_MSG(0x140, "Server %s requested index "
689 "%d, but that index is already in "
690 "use. Use --writeconf to force\n",
692 mti->mti_stripe_index);
693 GOTO(out_up, rc = -EADDRINUSE);
695 CDEBUG(D_MGS, "Server %s updating index %d\n",
696 mti->mti_svname, mti->mti_stripe_index);
697 GOTO(out_up, rc = EALREADY);
700 set_bit(mti->mti_stripe_index, imap);
701 if (mti->mti_flags & LDD_F_SV_TYPE_MDT)
702 fsdb->fsdb_mdt_count++;
705 set_bit(mti->mti_stripe_index, imap);
706 clear_bit(FSDB_LOG_EMPTY, &fsdb->fsdb_flags);
707 if (server_make_name(mti->mti_flags & ~(LDD_F_VIRGIN | LDD_F_WRITECONF),
708 mti->mti_stripe_index, mti->mti_fsname,
709 mti->mti_svname, sizeof(mti->mti_svname))) {
710 CERROR("unknown server type %#x\n", mti->mti_flags);
711 GOTO(out_up, rc = -EINVAL);
714 CDEBUG(D_MGS, "Set index for %s to %d\n", mti->mti_svname,
715 mti->mti_stripe_index);
717 GOTO(out_up, rc = 0);
720 mutex_unlock(&fsdb->fsdb_mutex);
721 mgs_put_fsdb(mgs, fsdb);
725 struct mgs_modify_lookup {
726 struct cfg_marker mml_marker;
730 static int mgs_check_record_match(const struct lu_env *env,
731 struct llog_handle *llh,
732 struct llog_rec_hdr *rec, void *data)
734 struct cfg_marker *mc_marker = data;
735 struct cfg_marker *marker;
736 struct lustre_cfg *lcfg = REC_DATA(rec);
737 int cfg_len = REC_DATA_LEN(rec);
742 if (rec->lrh_type != OBD_CFG_REC) {
743 CDEBUG(D_ERROR, "Unhandled lrh_type: %#x\n", rec->lrh_type);
747 rc = lustre_cfg_sanity_check(lcfg, cfg_len);
749 CDEBUG(D_ERROR, "Insane cfg\n");
753 /* We only care about markers */
754 if (lcfg->lcfg_command != LCFG_MARKER)
757 marker = lustre_cfg_buf(lcfg, 1);
759 if (marker->cm_flags & CM_SKIP)
762 if ((strcmp(mc_marker->cm_comment, marker->cm_comment) == 0) &&
763 (strcmp(mc_marker->cm_tgtname, marker->cm_tgtname) == 0)) {
764 /* Found a non-skipped marker match */
765 CDEBUG(D_MGS, "Matched rec %u marker %d flag %x %s %s\n",
766 rec->lrh_index, marker->cm_step,
767 marker->cm_flags, marker->cm_tgtname,
769 rc = LLOG_PROC_BREAK;
776 * Check an existing config log record with matching comment and device
778 * 0 - checked successfully,
779 * LLOG_PROC_BREAK - record matches
782 static int mgs_check_marker(const struct lu_env *env, struct mgs_device *mgs,
783 struct fs_db *fsdb, struct mgs_target_info *mti,
784 char *logname, char *devname, char *comment)
786 struct llog_handle *loghandle;
787 struct llog_ctxt *ctxt;
788 struct cfg_marker *mc_marker;
793 LASSERT(mutex_is_locked(&fsdb->fsdb_mutex));
794 CDEBUG(D_MGS, "mgs check %s/%s/%s\n", logname, devname, comment);
796 ctxt = llog_get_context(mgs->mgs_obd, LLOG_CONFIG_ORIG_CTXT);
797 LASSERT(ctxt != NULL);
798 rc = llog_open(env, ctxt, &loghandle, NULL, logname, LLOG_OPEN_EXISTS);
805 rc = llog_init_handle(env, loghandle, LLOG_F_IS_PLAIN, NULL);
809 if (llog_get_size(loghandle) <= 1)
810 GOTO(out_close, rc = 0);
812 OBD_ALLOC_PTR(mc_marker);
814 GOTO(out_close, rc = -ENOMEM);
815 if (strlcpy(mc_marker->cm_comment, comment,
816 sizeof(mc_marker->cm_comment)) >=
817 sizeof(mc_marker->cm_comment))
818 GOTO(out_free, rc = -E2BIG);
819 if (strlcpy(mc_marker->cm_tgtname, devname,
820 sizeof(mc_marker->cm_tgtname)) >=
821 sizeof(mc_marker->cm_tgtname))
822 GOTO(out_free, rc = -E2BIG);
824 rc = llog_process(env, loghandle, mgs_check_record_match,
825 (void *)mc_marker, NULL);
828 OBD_FREE_PTR(mc_marker);
831 llog_close(env, loghandle);
833 if (rc && rc != LLOG_PROC_BREAK)
834 CDEBUG(D_ERROR, "%s: mgs check %s/%s failed: rc = %d\n",
835 mgs->mgs_obd->obd_name, mti->mti_svname, comment, rc);
840 static int mgs_modify_handler(const struct lu_env *env,
841 struct llog_handle *llh,
842 struct llog_rec_hdr *rec, void *data)
844 struct mgs_modify_lookup *mml = data;
845 struct cfg_marker *marker;
846 struct lustre_cfg *lcfg = REC_DATA(rec);
847 int cfg_len = REC_DATA_LEN(rec);
851 if (rec->lrh_type != OBD_CFG_REC) {
852 CERROR("unhandled lrh_type: %#x\n", rec->lrh_type);
856 rc = lustre_cfg_sanity_check(lcfg, cfg_len);
858 CERROR("Insane cfg\n");
862 /* We only care about markers */
863 if (lcfg->lcfg_command != LCFG_MARKER)
866 marker = lustre_cfg_buf(lcfg, 1);
867 if ((strcmp(mml->mml_marker.cm_comment, marker->cm_comment) == 0) &&
868 (strcmp(mml->mml_marker.cm_tgtname, marker->cm_tgtname) == 0) &&
869 !(marker->cm_flags & CM_SKIP)) {
870 /* Found a non-skipped marker match */
871 CDEBUG(D_MGS, "Changing rec %u marker %d %x->%x: %s %s\n",
872 rec->lrh_index, marker->cm_step,
873 marker->cm_flags, mml->mml_marker.cm_flags,
874 marker->cm_tgtname, marker->cm_comment);
875 /* Overwrite the old marker llog entry */
876 marker->cm_flags &= ~CM_EXCLUDE; /* in case we're unexcluding */
877 marker->cm_flags |= mml->mml_marker.cm_flags;
878 marker->cm_canceltime = mml->mml_marker.cm_canceltime;
879 rc = llog_write(env, llh, rec, rec->lrh_index);
888 * Modify an existing config log record (for CM_SKIP or CM_EXCLUDE)
890 * 0 - modified successfully,
891 * 1 - no modification was done
894 static int mgs_modify(const struct lu_env *env, struct mgs_device *mgs,
895 struct fs_db *fsdb, struct mgs_target_info *mti,
896 char *logname, char *devname, char *comment, int flags)
898 struct llog_handle *loghandle;
899 struct llog_ctxt *ctxt;
900 struct mgs_modify_lookup *mml;
905 LASSERT(mutex_is_locked(&fsdb->fsdb_mutex));
906 CDEBUG(D_MGS, "modify %s/%s/%s fl=%x\n", logname, devname, comment,
909 ctxt = llog_get_context(mgs->mgs_obd, LLOG_CONFIG_ORIG_CTXT);
910 LASSERT(ctxt != NULL);
911 rc = llog_open(env, ctxt, &loghandle, NULL, logname, LLOG_OPEN_EXISTS);
918 rc = llog_init_handle(env, loghandle, LLOG_F_IS_PLAIN, NULL);
922 if (llog_get_size(loghandle) <= 1)
923 GOTO(out_close, rc = 0);
927 GOTO(out_close, rc = -ENOMEM);
928 if (strlcpy(mml->mml_marker.cm_comment, comment,
929 sizeof(mml->mml_marker.cm_comment)) >=
930 sizeof(mml->mml_marker.cm_comment))
931 GOTO(out_free, rc = -E2BIG);
932 if (strlcpy(mml->mml_marker.cm_tgtname, devname,
933 sizeof(mml->mml_marker.cm_tgtname)) >=
934 sizeof(mml->mml_marker.cm_tgtname))
935 GOTO(out_free, rc = -E2BIG);
936 /* Modify mostly means cancel */
937 mml->mml_marker.cm_flags = flags;
938 mml->mml_marker.cm_canceltime = flags ? ktime_get_real_seconds() : 0;
939 mml->mml_modified = 0;
940 rc = llog_process(env, loghandle, mgs_modify_handler, (void *)mml,
942 if (!rc && !mml->mml_modified)
949 llog_close(env, loghandle);
952 CERROR("%s: modify %s/%s failed: rc = %d\n",
953 mgs->mgs_obd->obd_name, mti->mti_svname, comment, rc);
958 /** This structure is passed to mgs_replace_handler */
959 struct mgs_replace_uuid_lookup {
960 /* Nids are replaced for this target device */
961 struct mgs_target_info target;
962 /* Temporary modified llog */
963 struct llog_handle *temp_llh;
964 /* Flag is set if in target block*/
965 int in_target_device;
966 /* Nids already added. Just skip (multiple nids) */
967 int device_nids_added;
968 /* Flag is set if this block should not be copied */
973 * Check: a) if block should be skipped
974 * b) is it target block
979 * \retval 0 should not to be skipped
980 * \retval 1 should to be skipped
982 static int check_markers(struct lustre_cfg *lcfg,
983 struct mgs_replace_uuid_lookup *mrul)
985 struct cfg_marker *marker;
987 /* Track markers. Find given device */
988 if (lcfg->lcfg_command == LCFG_MARKER) {
989 marker = lustre_cfg_buf(lcfg, 1);
990 /* Clean llog from records marked as CM_EXCLUDE.
991 CM_SKIP records are used for "active" command
992 and can be restored if needed */
993 if ((marker->cm_flags & (CM_EXCLUDE | CM_START)) ==
994 (CM_EXCLUDE | CM_START)) {
999 if ((marker->cm_flags & (CM_EXCLUDE | CM_END)) ==
1000 (CM_EXCLUDE | CM_END)) {
1005 if (strcmp(mrul->target.mti_svname, marker->cm_tgtname) == 0) {
1006 LASSERT(!(marker->cm_flags & CM_START) ||
1007 !(marker->cm_flags & CM_END));
1008 if (marker->cm_flags & CM_START) {
1009 mrul->in_target_device = 1;
1010 mrul->device_nids_added = 0;
1011 } else if (marker->cm_flags & CM_END)
1012 mrul->in_target_device = 0;
1019 static int record_base(const struct lu_env *env, struct llog_handle *llh,
1020 char *cfgname, lnet_nid_t nid, int cmd,
1021 char *s1, char *s2, char *s3, char *s4)
1023 struct mgs_thread_info *mgi = mgs_env_info(env);
1024 struct llog_cfg_rec *lcr;
1027 CDEBUG(D_MGS, "lcfg %s %#x %s %s %s %s\n", cfgname,
1028 cmd, s1, s2, s3, s4);
1030 lustre_cfg_bufs_reset(&mgi->mgi_bufs, cfgname);
1032 lustre_cfg_bufs_set_string(&mgi->mgi_bufs, 1, s1);
1034 lustre_cfg_bufs_set_string(&mgi->mgi_bufs, 2, s2);
1036 lustre_cfg_bufs_set_string(&mgi->mgi_bufs, 3, s3);
1038 lustre_cfg_bufs_set_string(&mgi->mgi_bufs, 4, s4);
1040 lcr = lustre_cfg_rec_new(cmd, &mgi->mgi_bufs);
1044 lcr->lcr_cfg.lcfg_nid = nid;
1045 rc = llog_write(env, llh, &lcr->lcr_hdr, LLOG_NEXT_IDX);
1047 lustre_cfg_rec_free(lcr);
1051 "failed to write lcfg %s %#x %s %s %s %s: rc = %d\n",
1052 cfgname, cmd, s1, s2, s3, s4, rc);
1056 static inline int record_add_uuid(const struct lu_env *env,
1057 struct llog_handle *llh,
1058 uint64_t nid, char *uuid)
1060 return record_base(env, llh, NULL, nid, LCFG_ADD_UUID, uuid,
1064 static inline int record_add_conn(const struct lu_env *env,
1065 struct llog_handle *llh,
1066 char *devname, char *uuid)
1068 return record_base(env, llh, devname, 0, LCFG_ADD_CONN, uuid,
1072 static inline int record_attach(const struct lu_env *env,
1073 struct llog_handle *llh, char *devname,
1074 char *type, char *uuid)
1076 return record_base(env, llh, devname, 0, LCFG_ATTACH, type, uuid,
1080 static inline int record_setup(const struct lu_env *env,
1081 struct llog_handle *llh, char *devname,
1082 char *s1, char *s2, char *s3, char *s4)
1084 return record_base(env, llh, devname, 0, LCFG_SETUP, s1, s2, s3, s4);
1088 * \retval <0 record processing error
1089 * \retval n record is processed. No need copy original one.
1090 * \retval 0 record is not processed.
1092 static int process_command(const struct lu_env *env, struct lustre_cfg *lcfg,
1093 struct mgs_replace_uuid_lookup *mrul)
1100 if (lcfg->lcfg_command == LCFG_ADD_UUID) {
1101 /* LCFG_ADD_UUID command found. Let's skip original command
1102 and add passed nids */
1103 ptr = mrul->target.mti_params;
1104 while (class_parse_nid(ptr, &nid, &ptr) == 0) {
1105 CDEBUG(D_MGS, "add nid %s with uuid %s, "
1106 "device %s\n", libcfs_nid2str(nid),
1107 mrul->target.mti_params,
1108 mrul->target.mti_svname);
1109 rc = record_add_uuid(env,
1110 mrul->temp_llh, nid,
1111 mrul->target.mti_params);
1116 if (nids_added == 0) {
1117 CERROR("No new nids were added, nid %s with uuid %s, "
1118 "device %s\n", libcfs_nid2str(nid),
1119 mrul->target.mti_params,
1120 mrul->target.mti_svname);
1123 mrul->device_nids_added = 1;
1129 if (mrul->device_nids_added && lcfg->lcfg_command == LCFG_SETUP) {
1130 /* LCFG_SETUP command found. UUID should be changed */
1131 rc = record_setup(env,
1133 /* devname the same */
1134 lustre_cfg_string(lcfg, 0),
1135 /* s1 is not changed */
1136 lustre_cfg_string(lcfg, 1),
1137 /* new uuid should be
1139 mrul->target.mti_params,
1140 /* s3 is not changed */
1141 lustre_cfg_string(lcfg, 3),
1142 /* s4 is not changed */
1143 lustre_cfg_string(lcfg, 4));
1147 /* Another commands in target device block */
1152 * Handler that called for every record in llog.
1153 * Records are processed in order they placed in llog.
1155 * \param[in] llh log to be processed
1156 * \param[in] rec current record
1157 * \param[in] data mgs_replace_uuid_lookup structure
1161 static int mgs_replace_handler(const struct lu_env *env,
1162 struct llog_handle *llh,
1163 struct llog_rec_hdr *rec,
1166 struct mgs_replace_uuid_lookup *mrul;
1167 struct lustre_cfg *lcfg = REC_DATA(rec);
1168 int cfg_len = REC_DATA_LEN(rec);
1172 mrul = (struct mgs_replace_uuid_lookup *)data;
1174 if (rec->lrh_type != OBD_CFG_REC) {
1175 CERROR("unhandled lrh_type: %#x, cmd %x %s %s\n",
1176 rec->lrh_type, lcfg->lcfg_command,
1177 lustre_cfg_string(lcfg, 0),
1178 lustre_cfg_string(lcfg, 1));
1182 rc = lustre_cfg_sanity_check(lcfg, cfg_len);
1184 /* Do not copy any invalidated records */
1185 GOTO(skip_out, rc = 0);
1188 rc = check_markers(lcfg, mrul);
1189 if (rc || mrul->skip_it)
1190 GOTO(skip_out, rc = 0);
1192 /* Write to new log all commands outside target device block */
1193 if (!mrul->in_target_device)
1194 GOTO(copy_out, rc = 0);
1196 /* Skip all other LCFG_ADD_UUID and LCFG_ADD_CONN records
1197 (failover nids) for this target, assuming that if then
1198 primary is changing then so is the failover */
1199 if (mrul->device_nids_added &&
1200 (lcfg->lcfg_command == LCFG_ADD_UUID ||
1201 lcfg->lcfg_command == LCFG_ADD_CONN))
1202 GOTO(skip_out, rc = 0);
1204 rc = process_command(env, lcfg, mrul);
1211 /* Record is placed in temporary llog as is */
1212 rc = llog_write(env, mrul->temp_llh, rec, LLOG_NEXT_IDX);
1214 CDEBUG(D_MGS, "Copied idx=%d, rc=%d, len=%d, cmd %x %s %s\n",
1215 rec->lrh_index, rc, rec->lrh_len, lcfg->lcfg_command,
1216 lustre_cfg_string(lcfg, 0), lustre_cfg_string(lcfg, 1));
1220 CDEBUG(D_MGS, "Skipped idx=%d, rc=%d, len=%d, cmd %x %s %s\n",
1221 rec->lrh_index, rc, rec->lrh_len, lcfg->lcfg_command,
1222 lustre_cfg_string(lcfg, 0), lustre_cfg_string(lcfg, 1));
1226 static int mgs_log_is_empty(const struct lu_env *env,
1227 struct mgs_device *mgs, char *name)
1229 struct llog_ctxt *ctxt;
1232 ctxt = llog_get_context(mgs->mgs_obd, LLOG_CONFIG_ORIG_CTXT);
1233 LASSERT(ctxt != NULL);
1235 rc = llog_is_empty(env, ctxt, name);
1236 llog_ctxt_put(ctxt);
1240 static int mgs_replace_nids_log(const struct lu_env *env,
1241 struct obd_device *mgs, struct fs_db *fsdb,
1242 char *logname, char *devname, char *nids)
1244 struct llog_handle *orig_llh, *backup_llh;
1245 struct llog_ctxt *ctxt;
1246 struct mgs_replace_uuid_lookup *mrul;
1247 struct mgs_device *mgs_dev = lu2mgs_dev(mgs->obd_lu_dev);
1248 static struct obd_uuid cfg_uuid = { .uuid = "config_uuid" };
1253 CDEBUG(D_MGS, "Replace nids for %s in %s\n", devname, logname);
1255 ctxt = llog_get_context(mgs, LLOG_CONFIG_ORIG_CTXT);
1256 LASSERT(ctxt != NULL);
1258 if (mgs_log_is_empty(env, mgs_dev, logname)) {
1259 /* Log is empty. Nothing to replace */
1260 GOTO(out_put, rc = 0);
1263 OBD_ALLOC(backup, strlen(logname) + strlen(".bak") + 1);
1265 GOTO(out_put, rc = -ENOMEM);
1267 sprintf(backup, "%s.bak", logname);
1269 rc = llog_backup(env, mgs, ctxt, ctxt, logname, backup);
1271 /* Now erase original log file. Connections are not allowed.
1272 Backup is already saved */
1273 rc = llog_erase(env, ctxt, NULL, logname);
1276 } else if (rc != -ENOENT) {
1277 CERROR("%s: can't make backup for %s: rc = %d\n",
1278 mgs->obd_name, logname, rc);
1282 /* open local log */
1283 rc = llog_open_create(env, ctxt, &orig_llh, NULL, logname);
1285 GOTO(out_restore, rc);
1287 rc = llog_init_handle(env, orig_llh, LLOG_F_IS_PLAIN, &cfg_uuid);
1289 GOTO(out_closel, rc);
1291 /* open backup llog */
1292 rc = llog_open(env, ctxt, &backup_llh, NULL, backup,
1295 GOTO(out_closel, rc);
1297 rc = llog_init_handle(env, backup_llh, LLOG_F_IS_PLAIN, NULL);
1299 GOTO(out_close, rc);
1301 if (llog_get_size(backup_llh) <= 1)
1302 GOTO(out_close, rc = 0);
1304 OBD_ALLOC_PTR(mrul);
1306 GOTO(out_close, rc = -ENOMEM);
1307 /* devname is only needed information to replace UUID records */
1308 strlcpy(mrul->target.mti_svname, devname,
1309 sizeof(mrul->target.mti_svname));
1310 /* parse nids later */
1311 strlcpy(mrul->target.mti_params, nids, sizeof(mrul->target.mti_params));
1312 /* Copy records to this temporary llog */
1313 mrul->temp_llh = orig_llh;
1315 rc = llog_process(env, backup_llh, mgs_replace_handler,
1316 (void *)mrul, NULL);
1319 rc2 = llog_close(NULL, backup_llh);
1323 rc2 = llog_close(NULL, orig_llh);
1329 CERROR("%s: llog should be restored: rc = %d\n",
1331 rc2 = llog_backup(env, mgs, ctxt, ctxt, backup,
1334 CERROR("%s: can't restore backup %s: rc = %d\n",
1335 mgs->obd_name, logname, rc2);
1339 OBD_FREE(backup, strlen(backup) + 1);
1342 llog_ctxt_put(ctxt);
1345 CERROR("%s: failed to replace nids in log %s: rc = %d\n",
1346 mgs->obd_name, logname, rc);
1352 * Parse device name and get file system name and/or device index
1354 * \param[in] devname device name (ex. lustre-MDT0000)
1355 * \param[out] fsname file system name(optional)
1356 * \param[out] index device index(optional)
1360 static int mgs_parse_devname(char *devname, char *fsname, __u32 *index)
1365 /* Extract fsname */
1367 rc = server_name2fsname(devname, fsname, NULL);
1369 CDEBUG(D_MGS, "Device name %s without fsname\n",
1376 rc = server_name2index(devname, index, NULL);
1378 CDEBUG(D_MGS, "Device name %s with wrong index\n",
1387 /* This is only called during replace_nids */
1388 static int only_mgs_is_running(struct obd_device *mgs_obd)
1390 /* TDB: Is global variable with devices count exists? */
1391 int num_devices = get_devices_count();
1392 int num_exports = 0;
1393 struct obd_export *exp;
1395 spin_lock(&mgs_obd->obd_dev_lock);
1396 list_for_each_entry(exp, &mgs_obd->obd_exports, exp_obd_chain) {
1397 /* skip self export */
1398 if (exp == mgs_obd->obd_self_export)
1400 if (exp_connect_flags(exp) & OBD_CONNECT_MDS_MDS)
1405 CERROR("%s: node %s still connected during replace_nids "
1406 "connect_flags:%llx\n",
1408 libcfs_nid2str(exp->exp_nid_stats->nid),
1409 exp_connect_flags(exp));
1412 spin_unlock(&mgs_obd->obd_dev_lock);
1414 /* osd, MGS and MGC + self_export
1415 (wc -l /proc/fs/lustre/devices <= 2) && (non self exports == 0) */
1416 return (num_devices <= 3) && (num_exports == 0);
1419 static int name_create_mdt(char **logname, char *fsname, int i)
1423 sprintf(mdt_index, "-MDT%04x", i);
1424 return name_create(logname, fsname, mdt_index);
1428 * Replace nids for \a device to \a nids values
1430 * \param obd MGS obd device
1431 * \param devname nids need to be replaced for this device
1432 * (ex. lustre-OST0000)
1433 * \param nids nids list (ex. nid1,nid2,nid3)
1437 int mgs_replace_nids(const struct lu_env *env,
1438 struct mgs_device *mgs,
1439 char *devname, char *nids)
1441 /* Assume fsname is part of device name */
1442 char fsname[MTI_NAME_MAXLEN];
1446 struct fs_db *fsdb = NULL;
1449 struct obd_device *mgs_obd = mgs->mgs_obd;
1452 /* We can only change NIDs if no other nodes are connected */
1453 spin_lock(&mgs_obd->obd_dev_lock);
1454 conn_state = mgs_obd->obd_no_conn;
1455 mgs_obd->obd_no_conn = 1;
1456 spin_unlock(&mgs_obd->obd_dev_lock);
1458 /* We can not change nids if not only MGS is started */
1459 if (!only_mgs_is_running(mgs_obd)) {
1460 CERROR("Only MGS is allowed to be started\n");
1461 GOTO(out, rc = -EINPROGRESS);
1464 /* Get fsname and index*/
1465 rc = mgs_parse_devname(devname, fsname, &index);
1469 rc = mgs_find_or_make_fsdb(env, mgs, fsname, &fsdb);
1471 CERROR("%s: can't find fsdb: rc = %d\n", fsname, rc);
1475 /* Process client llogs */
1476 name_create(&logname, fsname, "-client");
1477 rc = mgs_replace_nids_log(env, mgs_obd, fsdb, logname, devname, nids);
1478 name_destroy(&logname);
1480 CERROR("%s: error while replacing NIDs for %s: rc = %d\n",
1481 fsname, devname, rc);
1485 /* Process MDT llogs */
1486 for (i = 0; i < INDEX_MAP_SIZE * 8; i++) {
1487 if (!test_bit(i, fsdb->fsdb_mdt_index_map))
1489 name_create_mdt(&logname, fsname, i);
1490 rc = mgs_replace_nids_log(env, mgs_obd, fsdb, logname, devname, nids);
1491 name_destroy(&logname);
1497 spin_lock(&mgs_obd->obd_dev_lock);
1498 mgs_obd->obd_no_conn = conn_state;
1499 spin_unlock(&mgs_obd->obd_dev_lock);
1502 mgs_put_fsdb(mgs, fsdb);
1507 static int record_lov_setup(const struct lu_env *env, struct llog_handle *llh,
1508 char *devname, struct lov_desc *desc)
1510 struct mgs_thread_info *mgi = mgs_env_info(env);
1511 struct llog_cfg_rec *lcr;
1514 lustre_cfg_bufs_reset(&mgi->mgi_bufs, devname);
1515 lustre_cfg_bufs_set(&mgi->mgi_bufs, 1, desc, sizeof(*desc));
1516 lcr = lustre_cfg_rec_new(LCFG_SETUP, &mgi->mgi_bufs);
1520 rc = llog_write(env, llh, &lcr->lcr_hdr, LLOG_NEXT_IDX);
1521 lustre_cfg_rec_free(lcr);
1525 static int record_lmv_setup(const struct lu_env *env, struct llog_handle *llh,
1526 char *devname, struct lmv_desc *desc)
1528 struct mgs_thread_info *mgi = mgs_env_info(env);
1529 struct llog_cfg_rec *lcr;
1532 lustre_cfg_bufs_reset(&mgi->mgi_bufs, devname);
1533 lustre_cfg_bufs_set(&mgi->mgi_bufs, 1, desc, sizeof(*desc));
1534 lcr = lustre_cfg_rec_new(LCFG_SETUP, &mgi->mgi_bufs);
1538 rc = llog_write(env, llh, &lcr->lcr_hdr, LLOG_NEXT_IDX);
1539 lustre_cfg_rec_free(lcr);
1543 static inline int record_mdc_add(const struct lu_env *env,
1544 struct llog_handle *llh,
1545 char *logname, char *mdcuuid,
1546 char *mdtuuid, char *index,
1549 return record_base(env,llh,logname,0,LCFG_ADD_MDC,
1550 mdtuuid,index,gen,mdcuuid);
1553 static inline int record_lov_add(const struct lu_env *env,
1554 struct llog_handle *llh,
1555 char *lov_name, char *ost_uuid,
1556 char *index, char *gen)
1558 return record_base(env, llh, lov_name, 0, LCFG_LOV_ADD_OBD,
1559 ost_uuid, index, gen, NULL);
1562 static inline int record_mount_opt(const struct lu_env *env,
1563 struct llog_handle *llh,
1564 char *profile, char *lov_name,
1567 return record_base(env, llh, NULL, 0, LCFG_MOUNTOPT,
1568 profile, lov_name, mdc_name, NULL);
1571 static int record_marker(const struct lu_env *env,
1572 struct llog_handle *llh,
1573 struct fs_db *fsdb, __u32 flags,
1574 char *tgtname, char *comment)
1576 struct mgs_thread_info *mgi = mgs_env_info(env);
1577 struct llog_cfg_rec *lcr;
1581 if (flags & CM_START)
1583 mgi->mgi_marker.cm_step = fsdb->fsdb_gen;
1584 mgi->mgi_marker.cm_flags = flags;
1585 mgi->mgi_marker.cm_vers = LUSTRE_VERSION_CODE;
1586 cplen = strlcpy(mgi->mgi_marker.cm_tgtname, tgtname,
1587 sizeof(mgi->mgi_marker.cm_tgtname));
1588 if (cplen >= sizeof(mgi->mgi_marker.cm_tgtname))
1590 cplen = strlcpy(mgi->mgi_marker.cm_comment, comment,
1591 sizeof(mgi->mgi_marker.cm_comment));
1592 if (cplen >= sizeof(mgi->mgi_marker.cm_comment))
1594 mgi->mgi_marker.cm_createtime = ktime_get_real_seconds();
1595 mgi->mgi_marker.cm_canceltime = 0;
1596 lustre_cfg_bufs_reset(&mgi->mgi_bufs, NULL);
1597 lustre_cfg_bufs_set(&mgi->mgi_bufs, 1, &mgi->mgi_marker,
1598 sizeof(mgi->mgi_marker));
1599 lcr = lustre_cfg_rec_new(LCFG_MARKER, &mgi->mgi_bufs);
1603 rc = llog_write(env, llh, &lcr->lcr_hdr, LLOG_NEXT_IDX);
1604 lustre_cfg_rec_free(lcr);
1608 static int record_start_log(const struct lu_env *env, struct mgs_device *mgs,
1609 struct llog_handle **llh, char *name)
1611 static struct obd_uuid cfg_uuid = { .uuid = "config_uuid" };
1612 struct llog_ctxt *ctxt;
1617 GOTO(out, rc = -EBUSY);
1619 ctxt = llog_get_context(mgs->mgs_obd, LLOG_CONFIG_ORIG_CTXT);
1621 GOTO(out, rc = -ENODEV);
1622 LASSERT(ctxt->loc_obd == mgs->mgs_obd);
1624 rc = llog_open_create(env, ctxt, llh, NULL, name);
1627 rc = llog_init_handle(env, *llh, LLOG_F_IS_PLAIN, &cfg_uuid);
1629 llog_close(env, *llh);
1631 llog_ctxt_put(ctxt);
1634 CERROR("%s: can't start log %s: rc = %d\n",
1635 mgs->mgs_obd->obd_name, name, rc);
1641 static int record_end_log(const struct lu_env *env, struct llog_handle **llh)
1645 rc = llog_close(env, *llh);
1651 /******************** config "macros" *********************/
1653 /* write an lcfg directly into a log (with markers) */
1654 static int mgs_write_log_direct(const struct lu_env *env,
1655 struct mgs_device *mgs, struct fs_db *fsdb,
1656 char *logname, struct llog_cfg_rec *lcr,
1657 char *devname, char *comment)
1659 struct llog_handle *llh = NULL;
1664 rc = record_start_log(env, mgs, &llh, logname);
1668 /* FIXME These should be a single journal transaction */
1669 rc = record_marker(env, llh, fsdb, CM_START, devname, comment);
1672 rc = llog_write(env, llh, &lcr->lcr_hdr, LLOG_NEXT_IDX);
1675 rc = record_marker(env, llh, fsdb, CM_END, devname, comment);
1679 record_end_log(env, &llh);
1683 /* write the lcfg in all logs for the given fs */
1684 static int mgs_write_log_direct_all(const struct lu_env *env,
1685 struct mgs_device *mgs,
1687 struct mgs_target_info *mti,
1688 struct llog_cfg_rec *lcr, char *devname,
1689 char *comment, int server_only)
1691 struct list_head log_list;
1692 struct mgs_direntry *dirent, *n;
1693 char *fsname = mti->mti_fsname;
1694 int rc = 0, len = strlen(fsname);
1697 /* Find all the logs in the CONFIGS directory */
1698 rc = class_dentry_readdir(env, mgs, &log_list);
1702 /* Could use fsdb index maps instead of directory listing */
1703 list_for_each_entry_safe(dirent, n, &log_list, mde_list) {
1704 list_del_init(&dirent->mde_list);
1705 /* don't write to sptlrpc rule log */
1706 if (strstr(dirent->mde_name, "-sptlrpc") != NULL)
1709 /* caller wants write server logs only */
1710 if (server_only && strstr(dirent->mde_name, "-client") != NULL)
1713 if (strlen(dirent->mde_name) <= len ||
1714 strncmp(fsname, dirent->mde_name, len) != 0 ||
1715 dirent->mde_name[len] != '-')
1718 CDEBUG(D_MGS, "Changing log %s\n", dirent->mde_name);
1719 /* Erase any old settings of this same parameter */
1720 rc = mgs_modify(env, mgs, fsdb, mti, dirent->mde_name,
1721 devname, comment, CM_SKIP);
1723 CERROR("%s: Can't modify llog %s: rc = %d\n",
1724 mgs->mgs_obd->obd_name, dirent->mde_name, rc);
1727 /* Write the new one */
1728 rc = mgs_write_log_direct(env, mgs, fsdb, dirent->mde_name,
1729 lcr, devname, comment);
1731 CERROR("%s: writing log %s: rc = %d\n",
1732 mgs->mgs_obd->obd_name, dirent->mde_name, rc);
1734 mgs_direntry_free(dirent);
1740 static int mgs_write_log_osp_to_mdt(const struct lu_env *env,
1741 struct mgs_device *mgs,
1743 struct mgs_target_info *mti,
1744 int index, char *logname);
1745 static int mgs_write_log_osc_to_lov(const struct lu_env *env,
1746 struct mgs_device *mgs,
1748 struct mgs_target_info *mti,
1749 char *logname, char *suffix, char *lovname,
1750 enum lustre_sec_part sec_part, int flags);
1751 static int name_create_mdt_and_lov(char **logname, char **lovname,
1752 struct fs_db *fsdb, int i);
1754 static int add_param(char *params, char *key, char *val)
1756 char *start = params + strlen(params);
1757 char *end = params + sizeof(((struct mgs_target_info *)0)->mti_params);
1761 keylen = strlen(key);
1762 if (start + 1 + keylen + strlen(val) >= end) {
1763 CERROR("params are too long: %s %s%s\n",
1764 params, key != NULL ? key : "", val);
1768 sprintf(start, " %s%s", key != NULL ? key : "", val);
1773 * Walk through client config log record and convert the related records
1776 static int mgs_steal_client_llog_handler(const struct lu_env *env,
1777 struct llog_handle *llh,
1778 struct llog_rec_hdr *rec, void *data)
1780 struct mgs_device *mgs;
1781 struct obd_device *obd;
1782 struct mgs_target_info *mti, *tmti;
1784 int cfg_len = rec->lrh_len;
1785 char *cfg_buf = (char*) (rec + 1);
1786 struct lustre_cfg *lcfg;
1788 struct llog_handle *mdt_llh = NULL;
1789 static int got_an_osc_or_mdc = 0;
1790 /* 0: not found any osc/mdc;
1794 static int last_step = -1;
1799 mti = ((struct temp_comp*)data)->comp_mti;
1800 tmti = ((struct temp_comp*)data)->comp_tmti;
1801 fsdb = ((struct temp_comp*)data)->comp_fsdb;
1802 obd = ((struct temp_comp *)data)->comp_obd;
1803 mgs = lu2mgs_dev(obd->obd_lu_dev);
1806 if (rec->lrh_type != OBD_CFG_REC) {
1807 CERROR("unhandled lrh_type: %#x\n", rec->lrh_type);
1811 rc = lustre_cfg_sanity_check(cfg_buf, cfg_len);
1813 CERROR("Insane cfg\n");
1817 lcfg = (struct lustre_cfg *)cfg_buf;
1819 if (lcfg->lcfg_command == LCFG_MARKER) {
1820 struct cfg_marker *marker;
1821 marker = lustre_cfg_buf(lcfg, 1);
1822 if (!strncmp(marker->cm_comment, "add osc", 7) &&
1823 (marker->cm_flags & CM_START) &&
1824 !(marker->cm_flags & CM_SKIP)) {
1825 got_an_osc_or_mdc = 1;
1826 cplen = strlcpy(tmti->mti_svname, marker->cm_tgtname,
1827 sizeof(tmti->mti_svname));
1828 if (cplen >= sizeof(tmti->mti_svname))
1830 rc = record_start_log(env, mgs, &mdt_llh,
1834 rc = record_marker(env, mdt_llh, fsdb, CM_START,
1835 mti->mti_svname, "add osc(copied)");
1836 record_end_log(env, &mdt_llh);
1837 last_step = marker->cm_step;
1840 if (!strncmp(marker->cm_comment, "add osc", 7) &&
1841 (marker->cm_flags & CM_END) &&
1842 !(marker->cm_flags & CM_SKIP)) {
1843 LASSERT(last_step == marker->cm_step);
1845 got_an_osc_or_mdc = 0;
1846 memset(tmti, 0, sizeof(*tmti));
1847 rc = record_start_log(env, mgs, &mdt_llh,
1851 rc = record_marker(env, mdt_llh, fsdb, CM_END,
1852 mti->mti_svname, "add osc(copied)");
1853 record_end_log(env, &mdt_llh);
1856 if (!strncmp(marker->cm_comment, "add mdc", 7) &&
1857 (marker->cm_flags & CM_START) &&
1858 !(marker->cm_flags & CM_SKIP)) {
1859 got_an_osc_or_mdc = 2;
1860 last_step = marker->cm_step;
1861 memcpy(tmti->mti_svname, marker->cm_tgtname,
1862 strlen(marker->cm_tgtname));
1866 if (!strncmp(marker->cm_comment, "add mdc", 7) &&
1867 (marker->cm_flags & CM_END) &&
1868 !(marker->cm_flags & CM_SKIP)) {
1869 LASSERT(last_step == marker->cm_step);
1871 got_an_osc_or_mdc = 0;
1872 memset(tmti, 0, sizeof(*tmti));
1877 if (got_an_osc_or_mdc == 0 || last_step < 0)
1880 if (lcfg->lcfg_command == LCFG_ADD_UUID) {
1881 __u64 nodenid = lcfg->lcfg_nid;
1883 if (strlen(tmti->mti_uuid) == 0) {
1884 /* target uuid not set, this config record is before
1885 * LCFG_SETUP, this nid is one of target node nid.
1887 tmti->mti_nids[tmti->mti_nid_count] = nodenid;
1888 tmti->mti_nid_count++;
1890 char nidstr[LNET_NIDSTR_SIZE];
1892 /* failover node nid */
1893 libcfs_nid2str_r(nodenid, nidstr, sizeof(nidstr));
1894 rc = add_param(tmti->mti_params, PARAM_FAILNODE,
1901 if (lcfg->lcfg_command == LCFG_SETUP) {
1904 target = lustre_cfg_string(lcfg, 1);
1905 memcpy(tmti->mti_uuid, target, strlen(target));
1909 /* ignore client side sptlrpc_conf_log */
1910 if (lcfg->lcfg_command == LCFG_SPTLRPC_CONF)
1913 if (lcfg->lcfg_command == LCFG_ADD_MDC &&
1914 strstr(lustre_cfg_string(lcfg, 0), "-clilmv") != NULL) {
1917 if (sscanf(lustre_cfg_buf(lcfg, 2), "%d", &index) != 1)
1920 memcpy(tmti->mti_fsname, mti->mti_fsname,
1921 strlen(mti->mti_fsname));
1922 tmti->mti_stripe_index = index;
1924 rc = mgs_write_log_osp_to_mdt(env, mgs, fsdb, tmti,
1925 mti->mti_stripe_index,
1927 memset(tmti, 0, sizeof(*tmti));
1931 if (lcfg->lcfg_command == LCFG_LOV_ADD_OBD) {
1934 char *logname, *lovname;
1936 rc = name_create_mdt_and_lov(&logname, &lovname, fsdb,
1937 mti->mti_stripe_index);
1940 sprintf(mdt_index, "-MDT%04x", mti->mti_stripe_index);
1942 if (sscanf(lustre_cfg_buf(lcfg, 2), "%d", &index) != 1) {
1943 name_destroy(&logname);
1944 name_destroy(&lovname);
1948 tmti->mti_stripe_index = index;
1949 rc = mgs_write_log_osc_to_lov(env, mgs, fsdb, tmti, logname,
1952 name_destroy(&logname);
1953 name_destroy(&lovname);
1959 /* fsdb->fsdb_mutex is already held in mgs_write_log_target*/
1960 /* stealed from mgs_get_fsdb_from_llog*/
1961 static int mgs_steal_llog_for_mdt_from_client(const struct lu_env *env,
1962 struct mgs_device *mgs,
1964 struct temp_comp* comp)
1966 struct llog_handle *loghandle;
1967 struct mgs_target_info *tmti;
1968 struct llog_ctxt *ctxt;
1973 ctxt = llog_get_context(mgs->mgs_obd, LLOG_CONFIG_ORIG_CTXT);
1974 LASSERT(ctxt != NULL);
1976 OBD_ALLOC_PTR(tmti);
1978 GOTO(out_ctxt, rc = -ENOMEM);
1980 comp->comp_tmti = tmti;
1981 comp->comp_obd = mgs->mgs_obd;
1983 rc = llog_open(env, ctxt, &loghandle, NULL, client_name,
1991 rc = llog_init_handle(env, loghandle, LLOG_F_IS_PLAIN, NULL);
1993 GOTO(out_close, rc);
1995 rc = llog_process_or_fork(env, loghandle, mgs_steal_client_llog_handler,
1996 (void *)comp, NULL, false);
1997 CDEBUG(D_MGS, "steal llog re = %d\n", rc);
1999 llog_close(env, loghandle);
2003 llog_ctxt_put(ctxt);
2007 /* lmv is the second thing for client logs */
2008 /* copied from mgs_write_log_lov. Please refer to that. */
2009 static int mgs_write_log_lmv(const struct lu_env *env,
2010 struct mgs_device *mgs,
2012 struct mgs_target_info *mti,
2013 char *logname, char *lmvname)
2015 struct llog_handle *llh = NULL;
2016 struct lmv_desc *lmvdesc;
2021 CDEBUG(D_MGS, "Writing lmv(%s) log for %s\n", lmvname,logname);
2023 OBD_ALLOC_PTR(lmvdesc);
2024 if (lmvdesc == NULL)
2026 lmvdesc->ld_active_tgt_count = 0;
2027 lmvdesc->ld_tgt_count = 0;
2028 sprintf((char*)lmvdesc->ld_uuid.uuid, "%s_UUID", lmvname);
2029 uuid = (char *)lmvdesc->ld_uuid.uuid;
2031 rc = record_start_log(env, mgs, &llh, logname);
2034 rc = record_marker(env, llh, fsdb, CM_START, lmvname, "lmv setup");
2037 rc = record_attach(env, llh, lmvname, "lmv", uuid);
2040 rc = record_lmv_setup(env, llh, lmvname, lmvdesc);
2043 rc = record_marker(env, llh, fsdb, CM_END, lmvname, "lmv setup");
2047 record_end_log(env, &llh);
2049 OBD_FREE_PTR(lmvdesc);
2053 /* lov is the first thing in the mdt and client logs */
2054 static int mgs_write_log_lov(const struct lu_env *env, struct mgs_device *mgs,
2055 struct fs_db *fsdb, struct mgs_target_info *mti,
2056 char *logname, char *lovname)
2058 struct llog_handle *llh = NULL;
2059 struct lov_desc *lovdesc;
2064 CDEBUG(D_MGS, "Writing lov(%s) log for %s\n", lovname, logname);
2067 #01 L attach 0:lov_mdsA 1:lov 2:71ccb_lov_mdsA_19f961a9e1
2068 #02 L lov_setup 0:lov_mdsA 1:(struct lov_desc)
2069 uuid=lov1_UUID, stripe count=1, size=1048576, offset=0, pattern=0
2072 /* FIXME just make lov_setup accept empty desc (put uuid in buf 2) */
2073 OBD_ALLOC_PTR(lovdesc);
2074 if (lovdesc == NULL)
2076 lovdesc->ld_magic = LOV_DESC_MAGIC;
2077 lovdesc->ld_tgt_count = 0;
2078 /* Defaults. Can be changed later by lcfg config_param */
2079 lovdesc->ld_default_stripe_count = 1;
2080 lovdesc->ld_pattern = LOV_PATTERN_RAID0;
2081 lovdesc->ld_default_stripe_size = LOV_DESC_STRIPE_SIZE_DEFAULT;
2082 lovdesc->ld_default_stripe_offset = -1;
2083 lovdesc->ld_qos_maxage = LOV_DESC_QOS_MAXAGE_DEFAULT;
2084 sprintf((char*)lovdesc->ld_uuid.uuid, "%s_UUID", lovname);
2085 /* can these be the same? */
2086 uuid = (char *)lovdesc->ld_uuid.uuid;
2088 /* This should always be the first entry in a log.
2089 rc = mgs_clear_log(obd, logname); */
2090 rc = record_start_log(env, mgs, &llh, logname);
2093 /* FIXME these should be a single journal transaction */
2094 rc = record_marker(env, llh, fsdb, CM_START, lovname, "lov setup");
2097 rc = record_attach(env, llh, lovname, "lov", uuid);
2100 rc = record_lov_setup(env, llh, lovname, lovdesc);
2103 rc = record_marker(env, llh, fsdb, CM_END, lovname, "lov setup");
2108 record_end_log(env, &llh);
2110 OBD_FREE_PTR(lovdesc);
2114 /* add failnids to open log */
2115 static int mgs_write_log_failnids(const struct lu_env *env,
2116 struct mgs_target_info *mti,
2117 struct llog_handle *llh,
2120 char *failnodeuuid = NULL;
2121 char *ptr = mti->mti_params;
2126 #03 L add_uuid nid=uml1@tcp(0x20000c0a80201) nal=90 0: 1:uml1_UUID
2127 #04 L add_uuid nid=1@elan(0x1000000000001) nal=90 0: 1:uml1_UUID
2128 #05 L setup 0:OSC_uml1_ost1_mdsA 1:ost1_UUID 2:uml1_UUID
2129 #06 L add_uuid nid=uml2@tcp(0x20000c0a80202) nal=90 0: 1:uml2_UUID
2130 #0x L add_uuid nid=2@elan(0x1000000000002) nal=90 0: 1:uml2_UUID
2131 #07 L add_conn 0:OSC_uml1_ost1_mdsA 1:uml2_UUID
2135 * Pull failnid info out of params string, which may contain something
2136 * like "<nid1>,<nid2>:<nid3>,<nid4>". class_parse_nid() does not
2137 * complain about abnormal inputs like ",:<nid1>", "<nid1>:,<nid2>",
2138 * etc. However, convert_hostnames() should have caught those.
2140 while (class_find_param(ptr, PARAM_FAILNODE, &ptr) == 0) {
2141 while (class_parse_nid(ptr, &nid, &ptr) == 0) {
2142 char nidstr[LNET_NIDSTR_SIZE];
2144 if (failnodeuuid == NULL) {
2145 /* We don't know the failover node name,
2146 * so just use the first nid as the uuid */
2147 libcfs_nid2str_r(nid, nidstr, sizeof(nidstr));
2148 rc = name_create(&failnodeuuid, nidstr, "");
2152 CDEBUG(D_MGS, "add nid %s for failover uuid %s, "
2154 libcfs_nid2str_r(nid, nidstr, sizeof(nidstr)),
2155 failnodeuuid, cliname);
2156 rc = record_add_uuid(env, llh, nid, failnodeuuid);
2158 * If *ptr is ':', we have added all NIDs for
2162 rc = record_add_conn(env, llh, cliname,
2164 name_destroy(&failnodeuuid);
2165 failnodeuuid = NULL;
2169 rc = record_add_conn(env, llh, cliname, failnodeuuid);
2170 name_destroy(&failnodeuuid);
2171 failnodeuuid = NULL;
2178 static int mgs_write_log_mdc_to_lmv(const struct lu_env *env,
2179 struct mgs_device *mgs,
2181 struct mgs_target_info *mti,
2182 char *logname, char *lmvname)
2184 struct llog_handle *llh = NULL;
2185 char *mdcname = NULL;
2186 char *nodeuuid = NULL;
2187 char *mdcuuid = NULL;
2188 char *lmvuuid = NULL;
2190 char nidstr[LNET_NIDSTR_SIZE];
2194 if (mgs_log_is_empty(env, mgs, logname)) {
2195 CERROR("log is empty! Logical error\n");
2199 CDEBUG(D_MGS, "adding mdc for %s to log %s:lmv(%s)\n",
2200 mti->mti_svname, logname, lmvname);
2202 libcfs_nid2str_r(mti->mti_nids[0], nidstr, sizeof(nidstr));
2203 rc = name_create(&nodeuuid, nidstr, "");
2206 rc = name_create(&mdcname, mti->mti_svname, "-mdc");
2209 rc = name_create(&mdcuuid, mdcname, "_UUID");
2212 rc = name_create(&lmvuuid, lmvname, "_UUID");
2216 rc = record_start_log(env, mgs, &llh, logname);
2219 rc = record_marker(env, llh, fsdb, CM_START, mti->mti_svname,
2223 for (i = 0; i < mti->mti_nid_count; i++) {
2224 CDEBUG(D_MGS, "add nid %s for mdt\n",
2225 libcfs_nid2str_r(mti->mti_nids[i],
2226 nidstr, sizeof(nidstr)));
2228 rc = record_add_uuid(env, llh, mti->mti_nids[i], nodeuuid);
2233 rc = record_attach(env, llh, mdcname, LUSTRE_MDC_NAME, lmvuuid);
2236 rc = record_setup(env, llh, mdcname, mti->mti_uuid, nodeuuid,
2240 rc = mgs_write_log_failnids(env, mti, llh, mdcname);
2243 snprintf(index, sizeof(index), "%d", mti->mti_stripe_index);
2244 rc = record_mdc_add(env, llh, lmvname, mdcuuid, mti->mti_uuid,
2248 rc = record_marker(env, llh, fsdb, CM_END, mti->mti_svname,
2253 record_end_log(env, &llh);
2255 name_destroy(&lmvuuid);
2256 name_destroy(&mdcuuid);
2257 name_destroy(&mdcname);
2258 name_destroy(&nodeuuid);
2262 static inline int name_create_lov(char **lovname, char *mdtname,
2263 struct fs_db *fsdb, int index)
2266 if (index == 0 && test_bit(FSDB_OSCNAME18, &fsdb->fsdb_flags))
2267 return name_create(lovname, fsdb->fsdb_name, "-mdtlov");
2269 return name_create(lovname, mdtname, "-mdtlov");
2272 static int name_create_mdt_and_lov(char **logname, char **lovname,
2273 struct fs_db *fsdb, int i)
2277 rc = name_create_mdt(logname, fsdb->fsdb_name, i);
2281 if (i == 0 && test_bit(FSDB_OSCNAME18, &fsdb->fsdb_flags))
2282 rc = name_create(lovname, fsdb->fsdb_name, "-mdtlov");
2284 rc = name_create(lovname, *logname, "-mdtlov");
2286 name_destroy(logname);
2292 static inline int name_create_mdt_osc(char **oscname, char *ostname,
2293 struct fs_db *fsdb, int i)
2297 if (i == 0 && test_bit(FSDB_OSCNAME18, &fsdb->fsdb_flags))
2298 sprintf(suffix, "-osc");
2300 sprintf(suffix, "-osc-MDT%04x", i);
2301 return name_create(oscname, ostname, suffix);
2304 /* add new mdc to already existent MDS */
2305 static int mgs_write_log_osp_to_mdt(const struct lu_env *env,
2306 struct mgs_device *mgs,
2308 struct mgs_target_info *mti,
2309 int mdt_index, char *logname)
2311 struct llog_handle *llh = NULL;
2312 char *nodeuuid = NULL;
2313 char *ospname = NULL;
2314 char *lovuuid = NULL;
2315 char *mdtuuid = NULL;
2316 char *svname = NULL;
2317 char *mdtname = NULL;
2318 char *lovname = NULL;
2320 char nidstr[LNET_NIDSTR_SIZE];
2324 if (mgs_log_is_empty(env, mgs, mti->mti_svname)) {
2325 CERROR("log is empty! Logical error\n");
2329 CDEBUG(D_MGS, "adding osp index %d to %s\n", mti->mti_stripe_index,
2332 rc = name_create_mdt(&mdtname, fsdb->fsdb_name, mti->mti_stripe_index);
2336 libcfs_nid2str_r(mti->mti_nids[0], nidstr, sizeof(nidstr));
2337 rc = name_create(&nodeuuid, nidstr, "");
2339 GOTO(out_destory, rc);
2341 rc = name_create(&svname, mdtname, "-osp");
2343 GOTO(out_destory, rc);
2345 sprintf(index_str, "-MDT%04x", mdt_index);
2346 rc = name_create(&ospname, svname, index_str);
2348 GOTO(out_destory, rc);
2350 rc = name_create_lov(&lovname, logname, fsdb, mdt_index);
2352 GOTO(out_destory, rc);
2354 rc = name_create(&lovuuid, lovname, "_UUID");
2356 GOTO(out_destory, rc);
2358 rc = name_create(&mdtuuid, mdtname, "_UUID");
2360 GOTO(out_destory, rc);
2362 rc = record_start_log(env, mgs, &llh, logname);
2364 GOTO(out_destory, rc);
2366 rc = record_marker(env, llh, fsdb, CM_START, mti->mti_svname,
2369 GOTO(out_destory, rc);
2371 for (i = 0; i < mti->mti_nid_count; i++) {
2372 CDEBUG(D_MGS, "add nid %s for mdt\n",
2373 libcfs_nid2str_r(mti->mti_nids[i],
2374 nidstr, sizeof(nidstr)));
2375 rc = record_add_uuid(env, llh, mti->mti_nids[i], nodeuuid);
2380 rc = record_attach(env, llh, ospname, LUSTRE_OSP_NAME, lovuuid);
2384 rc = record_setup(env, llh, ospname, mti->mti_uuid, nodeuuid,
2389 rc = mgs_write_log_failnids(env, mti, llh, ospname);
2393 /* Add mdc(osp) to lod */
2394 snprintf(index_str, sizeof(index_str), "%d", mti->mti_stripe_index);
2395 rc = record_base(env, llh, lovname, 0, LCFG_ADD_MDC, mti->mti_uuid,
2396 index_str, "1", NULL);
2400 rc = record_marker(env, llh, fsdb, CM_END, mti->mti_svname, "add osp");
2405 record_end_log(env, &llh);
2408 name_destroy(&mdtuuid);
2409 name_destroy(&lovuuid);
2410 name_destroy(&lovname);
2411 name_destroy(&ospname);
2412 name_destroy(&svname);
2413 name_destroy(&nodeuuid);
2414 name_destroy(&mdtname);
2418 static int mgs_write_log_mdt0(const struct lu_env *env,
2419 struct mgs_device *mgs,
2421 struct mgs_target_info *mti)
2423 char *log = mti->mti_svname;
2424 struct llog_handle *llh = NULL;
2425 char *uuid, *lovname;
2427 char *ptr = mti->mti_params;
2428 int rc = 0, failout = 0;
2431 OBD_ALLOC(uuid, sizeof(struct obd_uuid));
2435 if (class_find_param(ptr, PARAM_FAILMODE, &ptr) == 0)
2436 failout = (strncmp(ptr, "failout", 7) == 0);
2438 rc = name_create(&lovname, log, "-mdtlov");
2441 if (mgs_log_is_empty(env, mgs, log)) {
2442 rc = mgs_write_log_lov(env, mgs, fsdb, mti, log, lovname);
2447 sprintf(mdt_index, "%d", mti->mti_stripe_index);
2449 rc = record_start_log(env, mgs, &llh, log);
2453 /* add MDT itself */
2455 /* FIXME this whole fn should be a single journal transaction */
2456 sprintf(uuid, "%s_UUID", log);
2457 rc = record_marker(env, llh, fsdb, CM_START, log, "add mdt");
2460 rc = record_attach(env, llh, log, LUSTRE_MDT_NAME, uuid);
2463 rc = record_mount_opt(env, llh, log, lovname, NULL);
2466 rc = record_setup(env, llh, log, uuid, mdt_index, lovname,
2467 failout ? "n" : "f");
2470 rc = record_marker(env, llh, fsdb, CM_END, log, "add mdt");
2474 record_end_log(env, &llh);
2476 name_destroy(&lovname);
2478 OBD_FREE(uuid, sizeof(struct obd_uuid));
2482 /* envelope method for all layers log */
2483 static int mgs_write_log_mdt(const struct lu_env *env,
2484 struct mgs_device *mgs,
2486 struct mgs_target_info *mti)
2488 struct mgs_thread_info *mgi = mgs_env_info(env);
2489 struct llog_handle *llh = NULL;
2494 CDEBUG(D_MGS, "writing new mdt %s\n", mti->mti_svname);
2496 if (mti->mti_uuid[0] == '\0') {
2497 /* Make up our own uuid */
2498 snprintf(mti->mti_uuid, sizeof(mti->mti_uuid),
2499 "%s_UUID", mti->mti_svname);
2503 rc = mgs_write_log_mdt0(env, mgs, fsdb, mti);
2506 /* Append the mdt info to the client log */
2507 rc = name_create(&cliname, mti->mti_fsname, "-client");
2511 if (mgs_log_is_empty(env, mgs, cliname)) {
2512 /* Start client log */
2513 rc = mgs_write_log_lov(env, mgs, fsdb, mti, cliname,
2517 rc = mgs_write_log_lmv(env, mgs, fsdb, mti, cliname,
2524 #09 L add_uuid nid=uml1@tcp(0x20000c0a80201) 0: 1:uml1_UUID
2525 #10 L attach 0:MDC_uml1_mdsA_MNT_client 1:mdc 2:1d834_MNT_client_03f
2526 #11 L setup 0:MDC_uml1_mdsA_MNT_client 1:mdsA_UUID 2:uml1_UUID
2527 #12 L add_uuid nid=uml2@tcp(0x20000c0a80202) 0: 1:uml2_UUID
2528 #13 L add_conn 0:MDC_uml1_mdsA_MNT_client 1:uml2_UUID
2529 #14 L mount_option 0: 1:client 2:lov1 3:MDC_uml1_mdsA_MNT_client
2532 /* copy client info about lov/lmv */
2533 mgi->mgi_comp.comp_mti = mti;
2534 mgi->mgi_comp.comp_fsdb = fsdb;
2536 rc = mgs_steal_llog_for_mdt_from_client(env, mgs, cliname,
2540 rc = mgs_write_log_mdc_to_lmv(env, mgs, fsdb, mti, cliname,
2546 rc = record_start_log(env, mgs, &llh, cliname);
2550 rc = record_marker(env, llh, fsdb, CM_START, cliname, "mount opts");
2553 rc = record_mount_opt(env, llh, cliname, fsdb->fsdb_clilov,
2557 rc = record_marker(env, llh, fsdb, CM_END, cliname, "mount opts");
2561 /* for_all_existing_mdt except current one */
2562 for (i = 0; i < INDEX_MAP_SIZE * 8; i++) {
2563 if (i != mti->mti_stripe_index &&
2564 test_bit(i, fsdb->fsdb_mdt_index_map)) {
2567 rc = name_create_mdt(&logname, fsdb->fsdb_name, i);
2571 /* NB: If the log for the MDT is empty, it means
2572 * the MDT is only added to the index
2573 * map, and not being process yet, i.e. this
2574 * is an unregistered MDT, see mgs_write_log_target().
2575 * so we should skip it. Otherwise
2577 * 1. MGS get register request for MDT1 and MDT2.
2579 * 2. Then both MDT1 and MDT2 are added into
2580 * fsdb_mdt_index_map. (see mgs_set_index()).
2582 * 3. Then MDT1 get the lock of fsdb_mutex, then
2583 * generate the config log, here, it will regard MDT2
2584 * as an existent MDT, and generate "add osp" for
2585 * lustre-MDT0001-osp-MDT0002. Note: at the moment
2586 * MDT0002 config log is still empty, so it will
2587 * add "add osp" even before "lov setup", which
2588 * will definitly cause trouble.
2590 * 4. MDT1 registeration finished, fsdb_mutex is
2591 * released, then MDT2 get in, then in above
2592 * mgs_steal_llog_for_mdt_from_client(), it will
2593 * add another osp log for lustre-MDT0001-osp-MDT0002,
2594 * which will cause another trouble.*/
2595 if (!mgs_log_is_empty(env, mgs, logname))
2596 rc = mgs_write_log_osp_to_mdt(env, mgs, fsdb,
2599 name_destroy(&logname);
2605 record_end_log(env, &llh);
2607 name_destroy(&cliname);
2611 /* Add the ost info to the client/mdt lov */
2612 static int mgs_write_log_osc_to_lov(const struct lu_env *env,
2613 struct mgs_device *mgs, struct fs_db *fsdb,
2614 struct mgs_target_info *mti,
2615 char *logname, char *suffix, char *lovname,
2616 enum lustre_sec_part sec_part, int flags)
2618 struct llog_handle *llh = NULL;
2619 char *nodeuuid = NULL;
2620 char *oscname = NULL;
2621 char *oscuuid = NULL;
2622 char *lovuuid = NULL;
2623 char *svname = NULL;
2625 char nidstr[LNET_NIDSTR_SIZE];
2629 CDEBUG(D_INFO, "adding osc for %s to log %s\n",
2630 mti->mti_svname, logname);
2632 if (mgs_log_is_empty(env, mgs, logname)) {
2633 CERROR("log is empty! Logical error\n");
2637 libcfs_nid2str_r(mti->mti_nids[0], nidstr, sizeof(nidstr));
2638 rc = name_create(&nodeuuid, nidstr, "");
2641 rc = name_create(&svname, mti->mti_svname, "-osc");
2645 /* for the system upgraded from old 1.8, keep using the old osc naming
2646 * style for mdt, see name_create_mdt_osc(). LU-1257 */
2647 if (test_bit(FSDB_OSCNAME18, &fsdb->fsdb_flags))
2648 rc = name_create(&oscname, svname, "");
2650 rc = name_create(&oscname, svname, suffix);
2654 rc = name_create(&oscuuid, oscname, "_UUID");
2657 rc = name_create(&lovuuid, lovname, "_UUID");
2663 #03 L add_uuid nid=uml1@tcp(0x20000c0a80201) 0: 1:uml1_UUID
2665 #04 L add_uuid nid=1@elan(0x1000000000001) nal=90 0: 1:uml1_UUID
2666 #04 L attach 0:OSC_uml1_ost1_MNT_client 1:osc 2:89070_lov1_a41dff51a
2667 #05 L setup 0:OSC_uml1_ost1_MNT_client 1:ost1_UUID 2:uml1_UUID
2669 #06 L add_uuid nid=uml2@tcp(0x20000c0a80202) 0: 1:uml2_UUID
2670 #07 L add_conn 0:OSC_uml1_ost1_MNT_client 1:uml2_UUID
2671 #08 L lov_modify_tgts add 0:lov1 1:ost1_UUID 2(index):0 3(gen):1
2674 rc = record_start_log(env, mgs, &llh, logname);
2678 /* FIXME these should be a single journal transaction */
2679 rc = record_marker(env, llh, fsdb, CM_START | flags, mti->mti_svname,
2684 /* NB: don't change record order, because upon MDT steal OSC config
2685 * from client, it treats all nids before LCFG_SETUP as target nids
2686 * (multiple interfaces), while nids after as failover node nids.
2687 * See mgs_steal_client_llog_handler() LCFG_ADD_UUID.
2689 for (i = 0; i < mti->mti_nid_count; i++) {
2690 CDEBUG(D_MGS, "add nid %s\n",
2691 libcfs_nid2str_r(mti->mti_nids[i],
2692 nidstr, sizeof(nidstr)));
2693 rc = record_add_uuid(env, llh, mti->mti_nids[i], nodeuuid);
2697 rc = record_attach(env, llh, oscname, LUSTRE_OSC_NAME, lovuuid);
2700 rc = record_setup(env, llh, oscname, mti->mti_uuid, nodeuuid,
2704 rc = mgs_write_log_failnids(env, mti, llh, oscname);
2708 snprintf(index, sizeof(index), "%d", mti->mti_stripe_index);
2710 rc = record_lov_add(env, llh, lovname, mti->mti_uuid, index, "1");
2713 rc = record_marker(env, llh, fsdb, CM_END | flags, mti->mti_svname,
2718 record_end_log(env, &llh);
2720 name_destroy(&lovuuid);
2721 name_destroy(&oscuuid);
2722 name_destroy(&oscname);
2723 name_destroy(&svname);
2724 name_destroy(&nodeuuid);
2728 static int mgs_write_log_ost(const struct lu_env *env,
2729 struct mgs_device *mgs, struct fs_db *fsdb,
2730 struct mgs_target_info *mti)
2732 struct llog_handle *llh = NULL;
2733 char *logname, *lovname;
2734 char *ptr = mti->mti_params;
2735 int rc, flags = 0, failout = 0, i;
2738 CDEBUG(D_MGS, "writing new ost %s\n", mti->mti_svname);
2740 /* The ost startup log */
2742 /* If the ost log already exists, that means that someone reformatted
2743 the ost and it called target_add again. */
2744 if (!mgs_log_is_empty(env, mgs, mti->mti_svname)) {
2745 LCONSOLE_ERROR_MSG(0x141, "The config log for %s already "
2746 "exists, yet the server claims it never "
2747 "registered. It may have been reformatted, "
2748 "or the index changed. writeconf the MDT to "
2749 "regenerate all logs.\n", mti->mti_svname);
2754 attach obdfilter ost1 ost1_UUID
2755 setup /dev/loop2 ldiskfs f|n errors=remount-ro,user_xattr
2757 if (class_find_param(ptr, PARAM_FAILMODE, &ptr) == 0)
2758 failout = (strncmp(ptr, "failout", 7) == 0);
2759 rc = record_start_log(env, mgs, &llh, mti->mti_svname);
2762 /* FIXME these should be a single journal transaction */
2763 rc = record_marker(env, llh, fsdb, CM_START, mti->mti_svname,"add ost");
2766 if (*mti->mti_uuid == '\0')
2767 snprintf(mti->mti_uuid, sizeof(mti->mti_uuid),
2768 "%s_UUID", mti->mti_svname);
2769 rc = record_attach(env, llh, mti->mti_svname,
2770 "obdfilter"/*LUSTRE_OST_NAME*/, mti->mti_uuid);
2773 rc = record_setup(env, llh, mti->mti_svname,
2774 "dev"/*ignored*/, "type"/*ignored*/,
2775 failout ? "n" : "f", NULL/*options*/);
2778 rc = record_marker(env, llh, fsdb, CM_END, mti->mti_svname, "add ost");
2782 record_end_log(env, &llh);
2785 /* We also have to update the other logs where this osc is part of
2788 if (test_bit(FSDB_OLDLOG14, &fsdb->fsdb_flags)) {
2789 /* If we're upgrading, the old mdt log already has our
2790 entry. Let's do a fake one for fun. */
2791 /* Note that we can't add any new failnids, since we don't
2792 know the old osc names. */
2793 flags = CM_SKIP | CM_UPGRADE146;
2795 } else if ((mti->mti_flags & LDD_F_UPDATE) != LDD_F_UPDATE) {
2796 /* If the update flag isn't set, don't update client/mdt
2799 LCONSOLE_WARN("Client log for %s was not updated; writeconf "
2800 "the MDT first to regenerate it.\n",
2804 /* Add ost to all MDT lov defs */
2805 for (i = 0; i < INDEX_MAP_SIZE * 8; i++){
2806 if (test_bit(i, fsdb->fsdb_mdt_index_map)) {
2809 rc = name_create_mdt_and_lov(&logname, &lovname, fsdb,
2813 sprintf(mdt_index, "-MDT%04x", i);
2814 rc = mgs_write_log_osc_to_lov(env, mgs, fsdb, mti,
2816 lovname, LUSTRE_SP_MDT,
2818 name_destroy(&logname);
2819 name_destroy(&lovname);
2825 /* Append ost info to the client log */
2826 rc = name_create(&logname, mti->mti_fsname, "-client");
2829 if (mgs_log_is_empty(env, mgs, logname)) {
2830 /* Start client log */
2831 rc = mgs_write_log_lov(env, mgs, fsdb, mti, logname,
2835 rc = mgs_write_log_lmv(env, mgs, fsdb, mti, logname,
2840 rc = mgs_write_log_osc_to_lov(env, mgs, fsdb, mti, logname, "",
2841 fsdb->fsdb_clilov, LUSTRE_SP_CLI, flags);
2843 name_destroy(&logname);
2847 static __inline__ int mgs_param_empty(char *ptr)
2851 if ((tmp = strchr(ptr, '=')) && (*(++tmp) == '\0'))
2856 static int mgs_write_log_failnid_internal(const struct lu_env *env,
2857 struct mgs_device *mgs,
2859 struct mgs_target_info *mti,
2860 char *logname, char *cliname)
2863 struct llog_handle *llh = NULL;
2865 if (mgs_param_empty(mti->mti_params)) {
2866 /* Remove _all_ failnids */
2867 rc = mgs_modify(env, mgs, fsdb, mti, logname,
2868 mti->mti_svname, "add failnid", CM_SKIP);
2869 return rc < 0 ? rc : 0;
2872 /* Otherwise failover nids are additive */
2873 rc = record_start_log(env, mgs, &llh, logname);
2876 /* FIXME this should be a single journal transaction */
2877 rc = record_marker(env, llh, fsdb, CM_START, mti->mti_svname,
2881 rc = mgs_write_log_failnids(env, mti, llh, cliname);
2884 rc = record_marker(env, llh, fsdb, CM_END,
2885 mti->mti_svname, "add failnid");
2887 record_end_log(env, &llh);
2892 /* Add additional failnids to an existing log.
2893 The mdc/osc must have been added to logs first */
2894 /* tcp nids must be in dotted-quad ascii -
2895 we can't resolve hostnames from the kernel. */
2896 static int mgs_write_log_add_failnid(const struct lu_env *env,
2897 struct mgs_device *mgs,
2899 struct mgs_target_info *mti)
2901 char *logname, *cliname;
2905 /* FIXME we currently can't erase the failnids
2906 * given when a target first registers, since they aren't part of
2907 * an "add uuid" stanza */
2909 /* Verify that we know about this target */
2910 if (mgs_log_is_empty(env, mgs, mti->mti_svname)) {
2911 LCONSOLE_ERROR_MSG(0x142, "The target %s has not registered "
2912 "yet. It must be started before failnids "
2913 "can be added.\n", mti->mti_svname);
2917 /* Create mdc/osc client name (e.g. lustre-OST0001-osc) */
2918 if (mti->mti_flags & LDD_F_SV_TYPE_MDT) {
2919 rc = name_create(&cliname, mti->mti_svname, "-mdc");
2920 } else if (mti->mti_flags & LDD_F_SV_TYPE_OST) {
2921 rc = name_create(&cliname, mti->mti_svname, "-osc");
2927 /* Add failover nids to the client log */
2928 rc = name_create(&logname, mti->mti_fsname, "-client");
2930 name_destroy(&cliname);
2933 rc = mgs_write_log_failnid_internal(env, mgs, fsdb,mti,logname,cliname);
2934 name_destroy(&logname);
2935 name_destroy(&cliname);
2939 if (mti->mti_flags & LDD_F_SV_TYPE_OST) {
2940 /* Add OST failover nids to the MDT logs as well */
2943 for (i = 0; i < INDEX_MAP_SIZE * 8; i++) {
2944 if (!test_bit(i, fsdb->fsdb_mdt_index_map))
2946 rc = name_create_mdt(&logname, mti->mti_fsname, i);
2949 rc = name_create_mdt_osc(&cliname, mti->mti_svname,
2952 name_destroy(&logname);
2955 rc = mgs_write_log_failnid_internal(env, mgs, fsdb,
2958 name_destroy(&cliname);
2959 name_destroy(&logname);
2968 static int mgs_wlp_lcfg(const struct lu_env *env,
2969 struct mgs_device *mgs, struct fs_db *fsdb,
2970 struct mgs_target_info *mti,
2971 char *logname, struct lustre_cfg_bufs *bufs,
2972 char *tgtname, char *ptr)
2974 char comment[MTI_NAME_MAXLEN];
2976 struct llog_cfg_rec *lcr;
2979 /* Erase any old settings of this same parameter */
2980 memcpy(comment, ptr, MTI_NAME_MAXLEN);
2981 comment[MTI_NAME_MAXLEN - 1] = 0;
2982 /* But don't try to match the value. */
2983 tmp = strchr(comment, '=');
2986 /* FIXME we should skip settings that are the same as old values */
2987 rc = mgs_modify(env, mgs, fsdb, mti, logname, tgtname, comment,CM_SKIP);
2990 del = mgs_param_empty(ptr);
2992 LCONSOLE_INFO("%s parameter %s.%s in log %s\n", del ? "Disabling" : rc ?
2993 "Setting" : "Modifying", tgtname, comment, logname);
2995 /* mgs_modify() will return 1 if nothing had to be done */
3001 lustre_cfg_bufs_reset(bufs, tgtname);
3002 lustre_cfg_bufs_set_string(bufs, 1, ptr);
3003 if (mti->mti_flags & LDD_F_PARAM2)
3004 lustre_cfg_bufs_set_string(bufs, 2, LCTL_UPCALL);
3006 lcr = lustre_cfg_rec_new((mti->mti_flags & LDD_F_PARAM2) ?
3007 LCFG_SET_PARAM : LCFG_PARAM, bufs);
3011 rc = mgs_write_log_direct(env, mgs, fsdb, logname, lcr, tgtname,
3013 lustre_cfg_rec_free(lcr);
3017 static int mgs_write_log_param2(const struct lu_env *env,
3018 struct mgs_device *mgs,
3020 struct mgs_target_info *mti, char *ptr)
3022 struct lustre_cfg_bufs bufs;
3026 CDEBUG(D_MGS, "next param '%s'\n", ptr);
3027 rc = mgs_wlp_lcfg(env, mgs, fsdb, mti, PARAMS_FILENAME, &bufs,
3028 mti->mti_svname, ptr);
3033 /* write global variable settings into log */
3034 static int mgs_write_log_sys(const struct lu_env *env,
3035 struct mgs_device *mgs, struct fs_db *fsdb,
3036 struct mgs_target_info *mti, char *sys, char *ptr)
3038 struct mgs_thread_info *mgi = mgs_env_info(env);
3039 struct lustre_cfg *lcfg;
3040 struct llog_cfg_rec *lcr;
3042 int rc, cmd, convert = 1;
3044 if (class_match_param(ptr, PARAM_TIMEOUT, &tmp) == 0) {
3045 cmd = LCFG_SET_TIMEOUT;
3046 } else if (class_match_param(ptr, PARAM_LDLM_TIMEOUT, &tmp) == 0) {
3047 cmd = LCFG_SET_LDLM_TIMEOUT;
3048 /* Check for known params here so we can return error to lctl */
3049 } else if ((class_match_param(ptr, PARAM_AT_MIN, &tmp) == 0) ||
3050 (class_match_param(ptr, PARAM_AT_MAX, &tmp) == 0) ||
3051 (class_match_param(ptr, PARAM_AT_EXTRA, &tmp) == 0) ||
3052 (class_match_param(ptr, PARAM_AT_EARLY_MARGIN, &tmp) == 0) ||
3053 (class_match_param(ptr, PARAM_AT_HISTORY, &tmp) == 0)) {
3055 } else if (class_match_param(ptr, PARAM_JOBID_VAR, &tmp) == 0) {
3056 convert = 0; /* Don't convert string value to integer */
3062 if (mgs_param_empty(ptr))
3063 CDEBUG(D_MGS, "global '%s' removed\n", sys);
3065 CDEBUG(D_MGS, "global '%s' val=%s\n", sys, tmp);
3067 lustre_cfg_bufs_reset(&mgi->mgi_bufs, NULL);
3068 lustre_cfg_bufs_set_string(&mgi->mgi_bufs, 1, sys);
3069 if (!convert && *tmp != '\0')
3070 lustre_cfg_bufs_set_string(&mgi->mgi_bufs, 2, tmp);
3071 lcr = lustre_cfg_rec_new(cmd, &mgi->mgi_bufs);
3075 lcfg = &lcr->lcr_cfg;
3076 lcfg->lcfg_num = convert ? simple_strtoul(tmp, NULL, 0) : 0;
3077 /* truncate the comment to the parameter name */
3081 /* modify all servers and clients */
3082 rc = mgs_write_log_direct_all(env, mgs, fsdb, mti,
3083 *tmp == '\0' ? NULL : lcr,
3084 mti->mti_fsname, sys, 0);
3085 if (rc == 0 && *tmp != '\0') {
3087 case LCFG_SET_TIMEOUT:
3088 if (!obd_timeout_set || lcfg->lcfg_num > obd_timeout)
3089 class_process_config(lcfg);
3091 case LCFG_SET_LDLM_TIMEOUT:
3092 if (!ldlm_timeout_set || lcfg->lcfg_num > ldlm_timeout)
3093 class_process_config(lcfg);
3100 lustre_cfg_rec_free(lcr);
3104 /* write quota settings into log */
3105 static int mgs_write_log_quota(const struct lu_env *env, struct mgs_device *mgs,
3106 struct fs_db *fsdb, struct mgs_target_info *mti,
3107 char *quota, char *ptr)
3109 struct mgs_thread_info *mgi = mgs_env_info(env);
3110 struct llog_cfg_rec *lcr;
3113 int rc, cmd = LCFG_PARAM;
3115 /* support only 'meta' and 'data' pools so far */
3116 if (class_match_param(ptr, QUOTA_METAPOOL_NAME, &tmp) != 0 &&
3117 class_match_param(ptr, QUOTA_DATAPOOL_NAME, &tmp) != 0) {
3118 CERROR("parameter quota.%s isn't supported (only quota.mdt "
3119 "& quota.ost are)\n", ptr);
3124 CDEBUG(D_MGS, "global '%s' removed\n", quota);
3126 CDEBUG(D_MGS, "global '%s'\n", quota);
3128 if (strchr(tmp, 'u') == NULL && strchr(tmp, 'g') == NULL &&
3129 strchr(tmp, 'p') == NULL &&
3130 strcmp(tmp, "none") != 0) {
3131 CERROR("enable option(%s) isn't supported\n", tmp);
3136 lustre_cfg_bufs_reset(&mgi->mgi_bufs, mti->mti_fsname);
3137 lustre_cfg_bufs_set_string(&mgi->mgi_bufs, 1, quota);
3138 lcr = lustre_cfg_rec_new(cmd, &mgi->mgi_bufs);
3142 /* truncate the comment to the parameter name */
3147 /* XXX we duplicated quota enable information in all server
3148 * config logs, it should be moved to a separate config
3149 * log once we cleanup the config log for global param. */
3150 /* modify all servers */
3151 rc = mgs_write_log_direct_all(env, mgs, fsdb, mti,
3152 *tmp == '\0' ? NULL : lcr,
3153 mti->mti_fsname, quota, 1);
3155 lustre_cfg_rec_free(lcr);
3156 return rc < 0 ? rc : 0;
3159 static int mgs_srpc_set_param_disk(const struct lu_env *env,
3160 struct mgs_device *mgs,
3162 struct mgs_target_info *mti,
3165 struct mgs_thread_info *mgi = mgs_env_info(env);
3166 struct llog_cfg_rec *lcr;
3167 struct llog_handle *llh = NULL;
3169 char *comment, *ptr;
3175 ptr = strchr(param, '=');
3176 LASSERT(ptr != NULL);
3179 OBD_ALLOC(comment, len + 1);
3180 if (comment == NULL)
3182 strncpy(comment, param, len);
3183 comment[len] = '\0';
3186 lustre_cfg_bufs_reset(&mgi->mgi_bufs, mti->mti_svname);
3187 lustre_cfg_bufs_set_string(&mgi->mgi_bufs, 1, param);
3188 lcr = lustre_cfg_rec_new(LCFG_SPTLRPC_CONF, &mgi->mgi_bufs);
3190 GOTO(out_comment, rc = -ENOMEM);
3192 /* construct log name */
3193 rc = name_create(&logname, mti->mti_fsname, "-sptlrpc");
3197 if (mgs_log_is_empty(env, mgs, logname)) {
3198 rc = record_start_log(env, mgs, &llh, logname);
3201 record_end_log(env, &llh);
3204 /* obsolete old one */
3205 rc = mgs_modify(env, mgs, fsdb, mti, logname, mti->mti_svname,
3209 /* write the new one */
3210 rc = mgs_write_log_direct(env, mgs, fsdb, logname, lcr,
3211 mti->mti_svname, comment);
3213 CERROR("%s: error writing log %s: rc = %d\n",
3214 mgs->mgs_obd->obd_name, logname, rc);
3216 name_destroy(&logname);
3218 lustre_cfg_rec_free(lcr);
3220 OBD_FREE(comment, len + 1);
3224 static int mgs_srpc_set_param_udesc_mem(struct fs_db *fsdb,
3229 /* disable the adjustable udesc parameter for now, i.e. use default
3230 * setting that client always ship udesc to MDT if possible. to enable
3231 * it simply remove the following line */
3234 ptr = strchr(param, '=');
3239 if (strcmp(param, PARAM_SRPC_UDESC))
3242 if (strcmp(ptr, "yes") == 0) {
3243 set_bit(FSDB_UDESC, &fsdb->fsdb_flags);
3244 CWARN("Enable user descriptor shipping from client to MDT\n");
3245 } else if (strcmp(ptr, "no") == 0) {
3246 clear_bit(FSDB_UDESC, &fsdb->fsdb_flags);
3247 CWARN("Disable user descriptor shipping from client to MDT\n");
3255 CERROR("Invalid param: %s\n", param);
3259 static int mgs_srpc_set_param_mem(struct fs_db *fsdb,
3263 struct sptlrpc_rule rule;
3264 struct sptlrpc_rule_set *rset;
3268 if (strncmp(param, PARAM_SRPC, sizeof(PARAM_SRPC) - 1) != 0) {
3269 CERROR("Invalid sptlrpc parameter: %s\n", param);
3273 if (strncmp(param, PARAM_SRPC_UDESC,
3274 sizeof(PARAM_SRPC_UDESC) - 1) == 0) {
3275 RETURN(mgs_srpc_set_param_udesc_mem(fsdb, param));
3278 if (strncmp(param, PARAM_SRPC_FLVR, sizeof(PARAM_SRPC_FLVR) - 1) != 0) {
3279 CERROR("Invalid sptlrpc flavor parameter: %s\n", param);
3283 param += sizeof(PARAM_SRPC_FLVR) - 1;
3285 rc = sptlrpc_parse_rule(param, &rule);
3289 /* mgs rules implies must be mgc->mgs */
3290 if (test_bit(FSDB_MGS_SELF, &fsdb->fsdb_flags)) {
3291 if ((rule.sr_from != LUSTRE_SP_MGC &&
3292 rule.sr_from != LUSTRE_SP_ANY) ||
3293 (rule.sr_to != LUSTRE_SP_MGS &&
3294 rule.sr_to != LUSTRE_SP_ANY))
3298 /* preapre room for this coming rule. svcname format should be:
3299 * - fsname: general rule
3300 * - fsname-tgtname: target-specific rule
3302 if (strchr(svname, '-')) {
3303 struct mgs_tgt_srpc_conf *tgtconf;
3306 for (tgtconf = fsdb->fsdb_srpc_tgt; tgtconf != NULL;
3307 tgtconf = tgtconf->mtsc_next) {
3308 if (!strcmp(tgtconf->mtsc_tgt, svname)) {
3317 OBD_ALLOC_PTR(tgtconf);
3318 if (tgtconf == NULL)
3321 name_len = strlen(svname);
3323 OBD_ALLOC(tgtconf->mtsc_tgt, name_len + 1);
3324 if (tgtconf->mtsc_tgt == NULL) {
3325 OBD_FREE_PTR(tgtconf);
3328 memcpy(tgtconf->mtsc_tgt, svname, name_len);
3330 tgtconf->mtsc_next = fsdb->fsdb_srpc_tgt;
3331 fsdb->fsdb_srpc_tgt = tgtconf;
3334 rset = &tgtconf->mtsc_rset;
3335 } else if (strcmp(svname, MGSSELF_NAME) == 0) {
3336 /* put _mgs related srpc rule directly in mgs ruleset */
3337 rset = &fsdb->fsdb_mgs->mgs_lut.lut_sptlrpc_rset;
3339 rset = &fsdb->fsdb_srpc_gen;
3342 rc = sptlrpc_rule_set_merge(rset, &rule);
3347 static int mgs_srpc_set_param(const struct lu_env *env,
3348 struct mgs_device *mgs,
3350 struct mgs_target_info *mti,
3360 /* keep a copy of original param, which could be destroied
3362 copy_size = strlen(param) + 1;
3363 OBD_ALLOC(copy, copy_size);
3366 memcpy(copy, param, copy_size);
3368 rc = mgs_srpc_set_param_mem(fsdb, mti->mti_svname, param);
3372 /* previous steps guaranteed the syntax is correct */
3373 rc = mgs_srpc_set_param_disk(env, mgs, fsdb, mti, copy);
3377 if (test_bit(FSDB_MGS_SELF, &fsdb->fsdb_flags)) {
3379 * for mgs rules, make them effective immediately.
3381 LASSERT(fsdb->fsdb_srpc_tgt == NULL);
3382 sptlrpc_target_update_exp_flavor(mgs->mgs_obd,
3383 &fsdb->fsdb_srpc_gen);
3387 OBD_FREE(copy, copy_size);
3391 struct mgs_srpc_read_data {
3392 struct fs_db *msrd_fsdb;
3396 static int mgs_srpc_read_handler(const struct lu_env *env,
3397 struct llog_handle *llh,
3398 struct llog_rec_hdr *rec, void *data)
3400 struct mgs_srpc_read_data *msrd = data;
3401 struct cfg_marker *marker;
3402 struct lustre_cfg *lcfg = REC_DATA(rec);
3403 char *svname, *param;
3407 if (rec->lrh_type != OBD_CFG_REC) {
3408 CERROR("unhandled lrh_type: %#x\n", rec->lrh_type);
3412 cfg_len = REC_DATA_LEN(rec);
3414 rc = lustre_cfg_sanity_check(lcfg, cfg_len);
3416 CERROR("Insane cfg\n");
3420 if (lcfg->lcfg_command == LCFG_MARKER) {
3421 marker = lustre_cfg_buf(lcfg, 1);
3423 if (marker->cm_flags & CM_START &&
3424 marker->cm_flags & CM_SKIP)
3425 msrd->msrd_skip = 1;
3426 if (marker->cm_flags & CM_END)
3427 msrd->msrd_skip = 0;
3432 if (msrd->msrd_skip)
3435 if (lcfg->lcfg_command != LCFG_SPTLRPC_CONF) {
3436 CERROR("invalid command (%x)\n", lcfg->lcfg_command);
3440 svname = lustre_cfg_string(lcfg, 0);
3441 if (svname == NULL) {
3442 CERROR("svname is empty\n");
3446 param = lustre_cfg_string(lcfg, 1);
3447 if (param == NULL) {
3448 CERROR("param is empty\n");
3452 rc = mgs_srpc_set_param_mem(msrd->msrd_fsdb, svname, param);
3454 CERROR("read sptlrpc record error (%d): %s\n", rc, param);
3459 int mgs_get_fsdb_srpc_from_llog(const struct lu_env *env,
3460 struct mgs_device *mgs,
3463 struct llog_handle *llh = NULL;
3464 struct llog_ctxt *ctxt;
3466 struct mgs_srpc_read_data msrd;
3470 /* construct log name */
3471 rc = name_create(&logname, fsdb->fsdb_name, "-sptlrpc");
3475 ctxt = llog_get_context(mgs->mgs_obd, LLOG_CONFIG_ORIG_CTXT);
3476 LASSERT(ctxt != NULL);
3478 if (mgs_log_is_empty(env, mgs, logname))
3481 rc = llog_open(env, ctxt, &llh, NULL, logname,
3489 rc = llog_init_handle(env, llh, LLOG_F_IS_PLAIN, NULL);
3491 GOTO(out_close, rc);
3493 if (llog_get_size(llh) <= 1)
3494 GOTO(out_close, rc = 0);
3496 msrd.msrd_fsdb = fsdb;
3499 rc = llog_process(env, llh, mgs_srpc_read_handler, (void *)&msrd,
3503 llog_close(env, llh);
3505 llog_ctxt_put(ctxt);
3506 name_destroy(&logname);
3509 CERROR("failed to read sptlrpc config database: %d\n", rc);
3513 /* Permanent settings of all parameters by writing into the appropriate
3514 * configuration logs.
3515 * A parameter with null value ("<param>='\0'") means to erase it out of
3518 static int mgs_write_log_param(const struct lu_env *env,
3519 struct mgs_device *mgs, struct fs_db *fsdb,
3520 struct mgs_target_info *mti, char *ptr)
3522 struct mgs_thread_info *mgi = mgs_env_info(env);
3528 /* For various parameter settings, we have to figure out which logs
3529 care about them (e.g. both mdt and client for lov settings) */
3530 CDEBUG(D_MGS, "next param '%s'\n", ptr);
3532 /* The params are stored in MOUNT_DATA_FILE and modified via
3533 tunefs.lustre, or set using lctl conf_param */
3535 /* Processed in lustre_start_mgc */
3536 if (class_match_param(ptr, PARAM_MGSNODE, NULL) == 0)
3539 /* Processed in ost/mdt */
3540 if (class_match_param(ptr, PARAM_NETWORK, NULL) == 0)
3543 /* Processed in mgs_write_log_ost */
3544 if (class_match_param(ptr, PARAM_FAILMODE, NULL) == 0) {
3545 if (mti->mti_flags & LDD_F_PARAM) {
3546 LCONSOLE_ERROR_MSG(0x169, "%s can only be "
3547 "changed with tunefs.lustre"
3548 "and --writeconf\n", ptr);
3554 if (class_match_param(ptr, PARAM_SRPC, NULL) == 0) {
3555 rc = mgs_srpc_set_param(env, mgs, fsdb, mti, ptr);
3559 if (class_match_param(ptr, PARAM_FAILNODE, NULL) == 0) {
3560 /* Add a failover nidlist */
3562 /* We already processed failovers params for new
3563 targets in mgs_write_log_target */
3564 if (mti->mti_flags & LDD_F_PARAM) {
3565 CDEBUG(D_MGS, "Adding failnode\n");
3566 rc = mgs_write_log_add_failnid(env, mgs, fsdb, mti);
3571 if (class_match_param(ptr, PARAM_SYS, &tmp) == 0) {
3572 rc = mgs_write_log_sys(env, mgs, fsdb, mti, ptr, tmp);
3576 if (class_match_param(ptr, PARAM_QUOTA, &tmp) == 0) {
3577 rc = mgs_write_log_quota(env, mgs, fsdb, mti, ptr, tmp);
3581 if (class_match_param(ptr, PARAM_OSC PARAM_ACTIVE, &tmp) == 0 ||
3582 class_match_param(ptr, PARAM_MDC PARAM_ACTIVE, &tmp) == 0) {
3583 /* active=0 means off, anything else means on */
3584 int flag = (*tmp == '0') ? CM_EXCLUDE : 0;
3585 bool deactive_osc = memcmp(ptr, PARAM_OSC PARAM_ACTIVE,
3586 strlen(PARAM_OSC PARAM_ACTIVE)) == 0;
3589 if (!deactive_osc) {
3592 rc = server_name2index(mti->mti_svname, &index, NULL);
3597 LCONSOLE_ERROR_MSG(0x144, "%s: MDC0 can not be"
3598 " (de)activated.\n",
3600 GOTO(end, rc = -EPERM);
3604 LCONSOLE_WARN("Permanently %sactivating %s\n",
3605 flag ? "de" : "re", mti->mti_svname);
3607 rc = name_create(&logname, mti->mti_fsname, "-client");
3610 rc = mgs_modify(env, mgs, fsdb, mti, logname,
3612 deactive_osc ? "add osc" : "add mdc", flag);
3613 name_destroy(&logname);
3618 /* Add to all MDT logs for DNE */
3619 for (i = 0; i < INDEX_MAP_SIZE * 8; i++) {
3620 if (!test_bit(i, fsdb->fsdb_mdt_index_map))
3622 rc = name_create_mdt(&logname, mti->mti_fsname, i);
3625 rc = mgs_modify(env, mgs, fsdb, mti, logname,
3627 deactive_osc ? "add osc" : "add osp",
3629 name_destroy(&logname);
3635 LCONSOLE_ERROR_MSG(0x145, "Couldn't find %s in"
3636 "log (%d). No permanent "
3637 "changes were made to the "
3639 mti->mti_svname, rc);
3640 if (test_bit(FSDB_OLDLOG14, &fsdb->fsdb_flags))
3641 LCONSOLE_ERROR_MSG(0x146, "This may be"
3646 "update the logs.\n");
3649 /* Fall through to osc/mdc proc for deactivating live
3650 OSC/OSP on running MDT / clients. */
3652 /* Below here, let obd's XXX_process_config methods handle it */
3654 /* All lov. in proc */
3655 if (class_match_param(ptr, PARAM_LOV, NULL) == 0) {
3658 CDEBUG(D_MGS, "lov param %s\n", ptr);
3659 if (!(mti->mti_flags & LDD_F_SV_TYPE_MDT)) {
3660 LCONSOLE_ERROR_MSG(0x147, "LOV params must be "
3661 "set on the MDT, not %s. "
3668 if (mgs_log_is_empty(env, mgs, mti->mti_svname))
3669 GOTO(end, rc = -ENODEV);
3671 rc = name_create_mdt_and_lov(&logname, &mdtlovname, fsdb,
3672 mti->mti_stripe_index);
3675 rc = mgs_wlp_lcfg(env, mgs, fsdb, mti, mti->mti_svname,
3676 &mgi->mgi_bufs, mdtlovname, ptr);
3677 name_destroy(&logname);
3678 name_destroy(&mdtlovname);
3683 rc = name_create(&logname, mti->mti_fsname, "-client");
3686 rc = mgs_wlp_lcfg(env, mgs, fsdb, mti, logname, &mgi->mgi_bufs,
3687 fsdb->fsdb_clilov, ptr);
3688 name_destroy(&logname);
3692 /* All osc., mdc., llite. params in proc */
3693 if ((class_match_param(ptr, PARAM_OSC, NULL) == 0) ||
3694 (class_match_param(ptr, PARAM_MDC, NULL) == 0) ||
3695 (class_match_param(ptr, PARAM_LLITE, NULL) == 0)) {
3698 if (test_bit(FSDB_OLDLOG14, &fsdb->fsdb_flags)) {
3699 LCONSOLE_ERROR_MSG(0x148, "Upgraded client logs for %s"
3700 " cannot be modified. Consider"
3701 " updating the configuration with"
3704 GOTO(end, rc = -EINVAL);
3706 if (memcmp(ptr, PARAM_LLITE, strlen(PARAM_LLITE)) == 0) {
3707 rc = name_create(&cname, mti->mti_fsname, "-client");
3708 /* Add the client type to match the obdname in
3709 class_config_llog_handler */
3710 } else if (mti->mti_flags & LDD_F_SV_TYPE_MDT) {
3711 rc = name_create(&cname, mti->mti_svname, "-mdc");
3712 } else if (mti->mti_flags & LDD_F_SV_TYPE_OST) {
3713 rc = name_create(&cname, mti->mti_svname, "-osc");
3715 GOTO(end, rc = -EINVAL);
3720 /* Forbid direct update of llite root squash parameters.
3721 * These parameters are indirectly set via the MDT settings.
3723 if ((class_match_param(ptr, PARAM_LLITE, &tmp) == 0) &&
3724 ((memcmp(tmp, "root_squash=", 12) == 0) ||
3725 (memcmp(tmp, "nosquash_nids=", 14) == 0))) {
3726 LCONSOLE_ERROR("%s: root squash parameters can only "
3727 "be updated through MDT component\n",
3729 name_destroy(&cname);
3730 GOTO(end, rc = -EINVAL);
3733 CDEBUG(D_MGS, "%.3s param %s\n", ptr, ptr + 4);
3736 rc = name_create(&logname, mti->mti_fsname, "-client");
3738 name_destroy(&cname);
3741 rc = mgs_wlp_lcfg(env, mgs, fsdb, mti, logname, &mgi->mgi_bufs,
3744 /* osc params affect the MDT as well */
3745 if (!rc && (mti->mti_flags & LDD_F_SV_TYPE_OST)) {
3748 for (i = 0; i < INDEX_MAP_SIZE * 8; i++){
3749 if (!test_bit(i, fsdb->fsdb_mdt_index_map))
3751 name_destroy(&cname);
3752 rc = name_create_mdt_osc(&cname, mti->mti_svname,
3754 name_destroy(&logname);
3757 rc = name_create_mdt(&logname,
3758 mti->mti_fsname, i);
3761 if (!mgs_log_is_empty(env, mgs, logname)) {
3762 rc = mgs_wlp_lcfg(env, mgs, fsdb,
3772 /* For mdc activate/deactivate, it affects OSP on MDT as well */
3773 if (class_match_param(ptr, PARAM_MDC PARAM_ACTIVE, &tmp) == 0 &&
3776 char *lodname = NULL;
3777 char *param_str = NULL;
3781 /* replace mdc with osp */
3782 memcpy(ptr, PARAM_OSP, strlen(PARAM_OSP));
3783 rc = server_name2index(mti->mti_svname, &index, NULL);
3785 memcpy(ptr, PARAM_MDC, strlen(PARAM_MDC));
3789 for (i = 0; i < INDEX_MAP_SIZE * 8; i++) {
3790 if (!test_bit(i, fsdb->fsdb_mdt_index_map))
3796 name_destroy(&logname);
3797 rc = name_create_mdt(&logname, mti->mti_fsname,
3802 if (mgs_log_is_empty(env, mgs, logname))
3805 snprintf(suffix, sizeof(suffix), "-osp-MDT%04x",
3807 name_destroy(&cname);
3808 rc = name_create(&cname, mti->mti_svname,
3813 rc = mgs_wlp_lcfg(env, mgs, fsdb, mti, logname,
3814 &mgi->mgi_bufs, cname, ptr);
3818 /* Add configuration log for noitfying LOD
3819 * to active/deactive the OSP. */
3820 name_destroy(¶m_str);
3821 rc = name_create(¶m_str, cname,
3822 (*tmp == '0') ? ".active=0" :
3827 name_destroy(&lodname);
3828 rc = name_create(&lodname, logname, "-mdtlov");
3832 rc = mgs_wlp_lcfg(env, mgs, fsdb, mti, logname,
3833 &mgi->mgi_bufs, lodname,
3838 memcpy(ptr, PARAM_MDC, strlen(PARAM_MDC));
3839 name_destroy(&lodname);
3840 name_destroy(¶m_str);
3843 name_destroy(&logname);
3844 name_destroy(&cname);
3848 /* All mdt. params in proc */
3849 if (class_match_param(ptr, PARAM_MDT, &tmp) == 0) {
3853 CDEBUG(D_MGS, "%.3s param %s\n", ptr, ptr + 4);
3854 if (strncmp(mti->mti_svname, mti->mti_fsname,
3855 MTI_NAME_MAXLEN) == 0)
3856 /* device is unspecified completely? */
3857 rc = LDD_F_SV_TYPE_MDT | LDD_F_SV_ALL;
3859 rc = server_name2index(mti->mti_svname, &idx, NULL);
3862 if ((rc & LDD_F_SV_TYPE_MDT) == 0)
3864 if (rc & LDD_F_SV_ALL) {
3865 for (i = 0; i < INDEX_MAP_SIZE * 8; i++) {
3867 fsdb->fsdb_mdt_index_map))
3869 rc = name_create_mdt(&logname,
3870 mti->mti_fsname, i);
3873 rc = mgs_wlp_lcfg(env, mgs, fsdb, mti,
3874 logname, &mgi->mgi_bufs,
3876 name_destroy(&logname);
3881 if ((memcmp(tmp, "root_squash=", 12) == 0) ||
3882 (memcmp(tmp, "nosquash_nids=", 14) == 0)) {
3883 LCONSOLE_ERROR("%s: root squash parameters "
3884 "cannot be applied to a single MDT\n",
3886 GOTO(end, rc = -EINVAL);
3888 rc = mgs_wlp_lcfg(env, mgs, fsdb, mti,
3889 mti->mti_svname, &mgi->mgi_bufs,
3890 mti->mti_svname, ptr);
3895 /* root squash settings are also applied to llite
3896 * config log (see LU-1778) */
3898 ((memcmp(tmp, "root_squash=", 12) == 0) ||
3899 (memcmp(tmp, "nosquash_nids=", 14) == 0))) {
3903 rc = name_create(&cname, mti->mti_fsname, "-client");
3906 rc = name_create(&logname, mti->mti_fsname, "-client");
3908 name_destroy(&cname);
3911 rc = name_create(&ptr2, PARAM_LLITE, tmp);
3913 name_destroy(&cname);
3914 name_destroy(&logname);
3917 rc = mgs_wlp_lcfg(env, mgs, fsdb, mti, logname,
3918 &mgi->mgi_bufs, cname, ptr2);
3919 name_destroy(&ptr2);
3920 name_destroy(&logname);
3921 name_destroy(&cname);
3926 /* All mdd., ost. and osd. params in proc */
3927 if ((class_match_param(ptr, PARAM_MDD, NULL) == 0) ||
3928 (class_match_param(ptr, PARAM_OST, NULL) == 0) ||
3929 (class_match_param(ptr, PARAM_OSD, NULL) == 0)) {
3930 CDEBUG(D_MGS, "%.3s param %s\n", ptr, ptr + 4);
3931 if (mgs_log_is_empty(env, mgs, mti->mti_svname))
3932 GOTO(end, rc = -ENODEV);
3934 rc = mgs_wlp_lcfg(env, mgs, fsdb, mti, mti->mti_svname,
3935 &mgi->mgi_bufs, mti->mti_svname, ptr);
3939 LCONSOLE_WARN("Ignoring unrecognized param '%s'\n", ptr);
3943 CERROR("err %d on param '%s'\n", rc, ptr);
3948 int mgs_write_log_target(const struct lu_env *env, struct mgs_device *mgs,
3949 struct mgs_target_info *mti, struct fs_db *fsdb)
3956 /* set/check the new target index */
3957 rc = mgs_set_index(env, mgs, mti);
3961 if (rc == EALREADY) {
3962 LCONSOLE_WARN("Found index %d for %s, updating log\n",
3963 mti->mti_stripe_index, mti->mti_svname);
3964 /* We would like to mark old log sections as invalid
3965 and add new log sections in the client and mdt logs.
3966 But if we add new sections, then live clients will
3967 get repeat setup instructions for already running
3968 osc's. So don't update the client/mdt logs. */
3969 mti->mti_flags &= ~LDD_F_UPDATE;
3973 OBD_FAIL_TIMEOUT(OBD_FAIL_MGS_WRITE_TARGET_DELAY, cfs_fail_val > 0 ?
3976 mutex_lock(&fsdb->fsdb_mutex);
3978 if (mti->mti_flags &
3979 (LDD_F_VIRGIN | LDD_F_UPGRADE14 | LDD_F_WRITECONF)) {
3980 /* Generate a log from scratch */
3981 if (mti->mti_flags & LDD_F_SV_TYPE_MDT) {
3982 rc = mgs_write_log_mdt(env, mgs, fsdb, mti);
3983 } else if (mti->mti_flags & LDD_F_SV_TYPE_OST) {
3984 rc = mgs_write_log_ost(env, mgs, fsdb, mti);
3986 CERROR("Unknown target type %#x, can't create log for "
3987 "%s\n", mti->mti_flags, mti->mti_svname);
3990 CERROR("Can't write logs for %s (%d)\n",
3991 mti->mti_svname, rc);
3995 /* Just update the params from tunefs in mgs_write_log_params */
3996 CDEBUG(D_MGS, "Update params for %s\n", mti->mti_svname);
3997 mti->mti_flags |= LDD_F_PARAM;
4000 /* allocate temporary buffer, where class_get_next_param will
4001 make copy of a current parameter */
4002 OBD_ALLOC(buf, strlen(mti->mti_params) + 1);
4004 GOTO(out_up, rc = -ENOMEM);
4005 params = mti->mti_params;
4006 while (params != NULL) {
4007 rc = class_get_next_param(¶ms, buf);
4010 /* there is no next parameter, that is
4015 CDEBUG(D_MGS, "remaining string: '%s', param: '%s'\n",
4017 rc = mgs_write_log_param(env, mgs, fsdb, mti, buf);
4022 OBD_FREE(buf, strlen(mti->mti_params) + 1);
4025 mutex_unlock(&fsdb->fsdb_mutex);
4029 int mgs_erase_log(const struct lu_env *env, struct mgs_device *mgs, char *name)
4031 struct llog_ctxt *ctxt;
4034 ctxt = llog_get_context(mgs->mgs_obd, LLOG_CONFIG_ORIG_CTXT);
4036 CERROR("%s: MGS config context doesn't exist\n",
4037 mgs->mgs_obd->obd_name);
4040 rc = llog_erase(env, ctxt, NULL, name);
4041 /* llog may not exist */
4044 llog_ctxt_put(ctxt);
4048 CERROR("%s: failed to clear log %s: %d\n",
4049 mgs->mgs_obd->obd_name, name, rc);
4054 /* erase all logs for the given fs */
4055 int mgs_erase_logs(const struct lu_env *env, struct mgs_device *mgs,
4058 struct list_head log_list;
4059 struct mgs_direntry *dirent, *n;
4060 char barrier_name[20] = {};
4063 int rc, len = strlen(fsname);
4066 mutex_lock(&mgs->mgs_mutex);
4068 /* Find all the logs in the CONFIGS directory */
4069 rc = class_dentry_readdir(env, mgs, &log_list);
4071 mutex_unlock(&mgs->mgs_mutex);
4075 if (list_empty(&log_list)) {
4076 mutex_unlock(&mgs->mgs_mutex);
4080 snprintf(barrier_name, sizeof(barrier_name) - 1, "%s-%s",
4081 fsname, BARRIER_FILENAME);
4082 /* Delete the barrier fsdb */
4083 mgs_remove_fsdb_by_name(mgs, barrier_name);
4084 /* Delete the fs db */
4085 mgs_remove_fsdb_by_name(mgs, fsname);
4086 mutex_unlock(&mgs->mgs_mutex);
4088 list_for_each_entry_safe(dirent, n, &log_list, mde_list) {
4089 list_del_init(&dirent->mde_list);
4090 suffix = strrchr(dirent->mde_name, '-');
4091 if (suffix != NULL) {
4092 if ((len == suffix - dirent->mde_name) &&
4093 (strncmp(fsname, dirent->mde_name, len) == 0)) {
4094 CDEBUG(D_MGS, "Removing log %s\n",
4096 mgs_erase_log(env, mgs, dirent->mde_name);
4100 mgs_direntry_free(dirent);
4109 /* list all logs for the given fs */
4110 int mgs_list_logs(const struct lu_env *env, struct mgs_device *mgs,
4111 struct obd_ioctl_data *data)
4113 struct list_head log_list;
4114 struct mgs_direntry *dirent, *n;
4120 /* Find all the logs in the CONFIGS directory */
4121 rc = class_dentry_readdir(env, mgs, &log_list);
4125 out = data->ioc_bulk;
4126 remains = data->ioc_inllen1;
4127 list_for_each_entry_safe(dirent, n, &log_list, mde_list) {
4128 list_del_init(&dirent->mde_list);
4129 suffix = strrchr(dirent->mde_name, '-');
4130 if (suffix != NULL) {
4131 l = snprintf(out, remains, "config_log: %s\n",
4136 mgs_direntry_free(dirent);
4143 struct mgs_lcfg_fork_data {
4144 struct lustre_cfg_bufs mlfd_bufs;
4145 struct mgs_device *mlfd_mgs;
4146 struct llog_handle *mlfd_llh;
4147 const char *mlfd_oldname;
4148 const char *mlfd_newname;
4152 static bool contain_valid_fsname(char *buf, const char *fsname,
4153 int buflen, int namelen)
4155 if (buflen < namelen)
4158 if (memcmp(buf, fsname, namelen) != 0)
4161 if (buf[namelen] != '\0' && buf[namelen] != '-')
4167 static int mgs_lcfg_fork_handler(const struct lu_env *env,
4168 struct llog_handle *o_llh,
4169 struct llog_rec_hdr *o_rec, void *data)
4171 struct mgs_lcfg_fork_data *mlfd = data;
4172 struct lustre_cfg_bufs *n_bufs = &mlfd->mlfd_bufs;
4173 struct lustre_cfg *o_lcfg = (struct lustre_cfg *)(o_rec + 1);
4174 struct llog_cfg_rec *lcr;
4176 char *n_buf = mlfd->mlfd_data;
4178 int o_namelen = strlen(mlfd->mlfd_oldname);
4179 int n_namelen = strlen(mlfd->mlfd_newname);
4180 int diff = n_namelen - o_namelen;
4181 __u32 cmd = o_lcfg->lcfg_command;
4182 __u32 cnt = o_lcfg->lcfg_bufcount;
4188 o_buf = lustre_cfg_buf(o_lcfg, 0);
4189 o_buflen = o_lcfg->lcfg_buflens[0];
4190 if (contain_valid_fsname(o_buf, mlfd->mlfd_oldname, o_buflen,
4192 memcpy(n_buf, mlfd->mlfd_newname, n_namelen);
4193 memcpy(n_buf + n_namelen, o_buf + o_namelen,
4194 o_buflen - o_namelen);
4195 lustre_cfg_bufs_reset(n_bufs, n_buf);
4196 n_buf += cfs_size_round(o_buflen + diff);
4198 lustre_cfg_bufs_reset(n_bufs, o_buflen != 0 ? o_buf : NULL);
4203 struct cfg_marker *o_marker;
4204 struct cfg_marker *n_marker;
4208 CDEBUG(D_MGS, "Unknown cfg marker entry with %d "
4213 /* buf[1] is marker */
4214 o_buf = lustre_cfg_buf(o_lcfg, 1);
4215 o_buflen = o_lcfg->lcfg_buflens[1];
4216 o_marker = (struct cfg_marker *)o_buf;
4217 if (!contain_valid_fsname(o_marker->cm_tgtname,
4219 sizeof(o_marker->cm_tgtname),
4221 lustre_cfg_bufs_set(n_bufs, 1, o_marker,
4226 n_marker = (struct cfg_marker *)n_buf;
4227 *n_marker = *o_marker;
4228 memcpy(n_marker->cm_tgtname, mlfd->mlfd_newname, n_namelen);
4229 tgt_namelen = strlen(o_marker->cm_tgtname);
4230 if (tgt_namelen > o_namelen)
4231 memcpy(n_marker->cm_tgtname + n_namelen,
4232 o_marker->cm_tgtname + o_namelen,
4233 tgt_namelen - o_namelen);
4234 n_marker->cm_tgtname[tgt_namelen + diff] = '\0';
4235 lustre_cfg_bufs_set(n_bufs, 1, n_marker, sizeof(*n_marker));
4239 case LCFG_SET_PARAM: {
4240 for (i = 1; i < cnt; i++)
4241 /* buf[i] is the param value, reuse it directly */
4242 lustre_cfg_bufs_set(n_bufs, i,
4243 lustre_cfg_buf(o_lcfg, i),
4244 o_lcfg->lcfg_buflens[i]);
4250 case LCFG_POOL_DEL: {
4251 if (cnt < 3 || cnt > 4) {
4252 CDEBUG(D_MGS, "Unknown cfg pool (%x) entry with %d "
4253 "buffers\n", cmd, cnt);
4257 /* buf[1] is fsname */
4258 o_buf = lustre_cfg_buf(o_lcfg, 1);
4259 o_buflen = o_lcfg->lcfg_buflens[1];
4260 memcpy(n_buf, mlfd->mlfd_newname, n_namelen);
4261 memcpy(n_buf + n_namelen, o_buf + o_namelen,
4262 o_buflen - o_namelen);
4263 lustre_cfg_bufs_set(n_bufs, 1, n_buf, o_buflen + diff);
4264 n_buf += cfs_size_round(o_buflen + diff);
4266 /* buf[2] is the pool name, reuse it directly */
4267 lustre_cfg_bufs_set(n_bufs, 2, lustre_cfg_buf(o_lcfg, 2),
4268 o_lcfg->lcfg_buflens[2]);
4273 /* buf[3] is ostname */
4274 o_buf = lustre_cfg_buf(o_lcfg, 3);
4275 o_buflen = o_lcfg->lcfg_buflens[3];
4276 memcpy(n_buf, mlfd->mlfd_newname, n_namelen);
4277 memcpy(n_buf + n_namelen, o_buf + o_namelen,
4278 o_buflen - o_namelen);
4279 lustre_cfg_bufs_set(n_bufs, 3, n_buf, o_buflen + diff);
4284 o_buflen = o_lcfg->lcfg_buflens[1];
4285 if (o_buflen == sizeof(struct lov_desc) ||
4286 o_buflen == sizeof(struct lmv_desc)) {
4292 o_buf = lustre_cfg_buf(o_lcfg, 1);
4293 if (o_buflen == sizeof(struct lov_desc)) {
4294 struct lov_desc *o_desc =
4295 (struct lov_desc *)o_buf;
4296 struct lov_desc *n_desc =
4297 (struct lov_desc *)n_buf;
4300 o_uuid = o_desc->ld_uuid.uuid;
4301 n_uuid = n_desc->ld_uuid.uuid;
4302 uuid_len = sizeof(o_desc->ld_uuid.uuid);
4304 struct lmv_desc *o_desc =
4305 (struct lmv_desc *)o_buf;
4306 struct lmv_desc *n_desc =
4307 (struct lmv_desc *)n_buf;
4310 o_uuid = o_desc->ld_uuid.uuid;
4311 n_uuid = n_desc->ld_uuid.uuid;
4312 uuid_len = sizeof(o_desc->ld_uuid.uuid);
4315 if (unlikely(!contain_valid_fsname(o_uuid,
4316 mlfd->mlfd_oldname, uuid_len,
4318 lustre_cfg_bufs_set(n_bufs, 1, o_buf,
4323 memcpy(n_uuid, mlfd->mlfd_newname, n_namelen);
4324 uuid_len = strlen(o_uuid);
4325 if (uuid_len > o_namelen)
4326 memcpy(n_uuid + n_namelen,
4328 uuid_len - o_namelen);
4329 n_uuid[uuid_len + diff] = '\0';
4330 lustre_cfg_bufs_set(n_bufs, 1, n_buf, o_buflen);
4332 } /* else case fall through */
4333 } /* else case fall through */
4336 for (i = 1; i < cnt; i++) {
4337 o_buflen = o_lcfg->lcfg_buflens[i];
4341 o_buf = lustre_cfg_buf(o_lcfg, i);
4342 if (!contain_valid_fsname(o_buf, mlfd->mlfd_oldname,
4343 o_buflen, o_namelen)) {
4344 lustre_cfg_bufs_set(n_bufs, i, o_buf, o_buflen);
4348 memcpy(n_buf, mlfd->mlfd_newname, n_namelen);
4349 if (o_buflen == o_namelen) {
4350 lustre_cfg_bufs_set(n_bufs, i, n_buf,
4352 n_buf += cfs_size_round(n_namelen);
4356 memcpy(n_buf + n_namelen, o_buf + o_namelen,
4357 o_buflen - o_namelen);
4358 lustre_cfg_bufs_set(n_bufs, i, n_buf, o_buflen + diff);
4359 n_buf += cfs_size_round(o_buflen + diff);
4365 lcr = lustre_cfg_rec_new(cmd, n_bufs);
4369 lcr->lcr_cfg = *o_lcfg;
4370 rc = llog_write(env, mlfd->mlfd_llh, &lcr->lcr_hdr, LLOG_NEXT_IDX);
4371 lustre_cfg_rec_free(lcr);
4376 static int mgs_lcfg_fork_one(const struct lu_env *env, struct mgs_device *mgs,
4377 struct mgs_direntry *mde, const char *oldname,
4378 const char *newname)
4380 struct llog_handle *old_llh = NULL;
4381 struct llog_handle *new_llh = NULL;
4382 struct llog_ctxt *ctxt = NULL;
4383 struct mgs_lcfg_fork_data *mlfd = NULL;
4384 char *name_buf = NULL;
4386 int old_namelen = strlen(oldname);
4387 int new_namelen = strlen(newname);
4391 name_buflen = mde->mde_len + new_namelen - old_namelen;
4392 OBD_ALLOC(name_buf, name_buflen);
4396 memcpy(name_buf, newname, new_namelen);
4397 memcpy(name_buf + new_namelen, mde->mde_name + old_namelen,
4398 mde->mde_len - old_namelen);
4400 CDEBUG(D_MGS, "Fork the config-log from %s to %s\n",
4401 mde->mde_name, name_buf);
4403 ctxt = llog_get_context(mgs->mgs_obd, LLOG_CONFIG_ORIG_CTXT);
4406 rc = llog_open_create(env, ctxt, &new_llh, NULL, name_buf);
4410 rc = llog_init_handle(env, new_llh, LLOG_F_IS_PLAIN, NULL);
4414 if (unlikely(mgs_log_is_empty(env, mgs, mde->mde_name)))
4417 rc = llog_open(env, ctxt, &old_llh, NULL, mde->mde_name,
4422 rc = llog_init_handle(env, old_llh, LLOG_F_IS_PLAIN, NULL);
4426 new_llh->lgh_hdr->llh_tgtuuid = old_llh->lgh_hdr->llh_tgtuuid;
4428 OBD_ALLOC(mlfd, LLOG_MIN_CHUNK_SIZE);
4430 GOTO(out, rc = -ENOMEM);
4432 mlfd->mlfd_mgs = mgs;
4433 mlfd->mlfd_llh = new_llh;
4434 mlfd->mlfd_oldname = oldname;
4435 mlfd->mlfd_newname = newname;
4437 rc = llog_process(env, old_llh, mgs_lcfg_fork_handler, mlfd, NULL);
4438 OBD_FREE(mlfd, LLOG_MIN_CHUNK_SIZE);
4444 llog_close(env, old_llh);
4446 llog_close(env, new_llh);
4448 OBD_FREE(name_buf, name_buflen);
4450 llog_ctxt_put(ctxt);
4455 int mgs_lcfg_fork(const struct lu_env *env, struct mgs_device *mgs,
4456 const char *oldname, const char *newname)
4458 struct list_head log_list;
4459 struct mgs_direntry *dirent, *n;
4460 int olen = strlen(oldname);
4461 int nlen = strlen(newname);
4466 if (unlikely(!oldname || oldname[0] == '\0' ||
4467 !newname || newname[0] == '\0'))
4470 if (strcmp(oldname, newname) == 0)
4473 /* lock it to prevent fork/erase/register in parallel. */
4474 mutex_lock(&mgs->mgs_mutex);
4476 rc = class_dentry_readdir(env, mgs, &log_list);
4478 mutex_unlock(&mgs->mgs_mutex);
4482 if (list_empty(&log_list)) {
4483 mutex_unlock(&mgs->mgs_mutex);
4487 list_for_each_entry_safe(dirent, n, &log_list, mde_list) {
4490 ptr = strrchr(dirent->mde_name, '-');
4492 int tlen = ptr - dirent->mde_name;
4495 strncmp(newname, dirent->mde_name, tlen) == 0)
4496 GOTO(out, rc = -EEXIST);
4499 strncmp(oldname, dirent->mde_name, tlen) == 0)
4503 list_del_init(&dirent->mde_list);
4504 mgs_direntry_free(dirent);
4507 if (list_empty(&log_list)) {
4508 mutex_unlock(&mgs->mgs_mutex);
4512 list_for_each_entry(dirent, &log_list, mde_list) {
4513 rc = mgs_lcfg_fork_one(env, mgs, dirent, oldname, newname);
4521 mutex_unlock(&mgs->mgs_mutex);
4523 list_for_each_entry_safe(dirent, n, &log_list, mde_list) {
4524 list_del_init(&dirent->mde_list);
4525 mgs_direntry_free(dirent);
4528 if (rc && count > 0)
4529 mgs_erase_logs(env, mgs, newname);
4534 int mgs_lcfg_erase(const struct lu_env *env, struct mgs_device *mgs,
4540 if (unlikely(!fsname || fsname[0] == '\0'))
4543 rc = mgs_erase_logs(env, mgs, fsname);
4548 static int mgs_xattr_del(const struct lu_env *env, struct dt_object *obj)
4550 struct dt_device *dev;
4551 struct thandle *th = NULL;
4556 dev = container_of0(obj->do_lu.lo_dev, struct dt_device, dd_lu_dev);
4557 th = dt_trans_create(env, dev);
4559 RETURN(PTR_ERR(th));
4561 rc = dt_declare_xattr_del(env, obj, XATTR_TARGET_RENAME, th);
4565 rc = dt_trans_start_local(env, dev, th);
4569 dt_write_lock(env, obj, 0);
4570 rc = dt_xattr_del(env, obj, XATTR_TARGET_RENAME, th);
4575 dt_write_unlock(env, obj);
4578 dt_trans_stop(env, dev, th);
4583 int mgs_lcfg_rename(const struct lu_env *env, struct mgs_device *mgs)
4585 struct list_head log_list;
4586 struct mgs_direntry *dirent, *n;
4588 struct lu_buf buf = {
4590 .lb_len = sizeof(fsname)
4596 rc = class_dentry_readdir(env, mgs, &log_list);
4600 if (list_empty(&log_list))
4603 list_for_each_entry_safe(dirent, n, &log_list, mde_list) {
4604 struct dt_object *o = NULL;
4609 list_del_init(&dirent->mde_list);
4610 ptr = strrchr(dirent->mde_name, '-');
4614 len = ptr - dirent->mde_name;
4615 if (unlikely(len >= sizeof(oldname))) {
4616 CDEBUG(D_MGS, "Skip invalid configuration file %s\n",
4621 o = local_file_find(env, mgs->mgs_los, mgs->mgs_configs_dir,
4625 CDEBUG(D_MGS, "Fail to locate file %s: rc = %d\n",
4626 dirent->mde_name, rc);
4630 rc = dt_xattr_get(env, o, &buf, XATTR_TARGET_RENAME);
4636 "Fail to get EA for %s: rc = %d\n",
4637 dirent->mde_name, rc);
4641 if (unlikely(rc == len &&
4642 memcmp(fsname, dirent->mde_name, len) == 0)) {
4643 /* The new fsname is the same as the old one. */
4644 rc = mgs_xattr_del(env, o);
4648 memcpy(oldname, dirent->mde_name, len);
4649 oldname[len] = '\0';
4651 rc = mgs_lcfg_fork_one(env, mgs, dirent, oldname, fsname);
4652 if (rc && rc != -EEXIST) {
4653 CDEBUG(D_MGS, "Fail to fork %s: rc = %d\n",
4654 dirent->mde_name, rc);
4658 rc = mgs_erase_log(env, mgs, dirent->mde_name);
4660 CDEBUG(D_MGS, "Fail to erase old %s: rc = %d\n",
4661 dirent->mde_name, rc);
4662 /* keep it there if failed to remove it. */
4667 if (o && !IS_ERR(o))
4668 lu_object_put(env, &o->do_lu);
4670 mgs_direntry_free(dirent);
4675 list_for_each_entry_safe(dirent, n, &log_list, mde_list) {
4676 list_del_init(&dirent->mde_list);
4677 mgs_direntry_free(dirent);
4683 /* from llog_swab */
4684 static void print_lustre_cfg(struct lustre_cfg *lcfg)
4689 CDEBUG(D_MGS, "lustre_cfg: %p\n", lcfg);
4690 CDEBUG(D_MGS, "\tlcfg->lcfg_version: %#x\n", lcfg->lcfg_version);
4692 CDEBUG(D_MGS, "\tlcfg->lcfg_command: %#x\n", lcfg->lcfg_command);
4693 CDEBUG(D_MGS, "\tlcfg->lcfg_num: %#x\n", lcfg->lcfg_num);
4694 CDEBUG(D_MGS, "\tlcfg->lcfg_flags: %#x\n", lcfg->lcfg_flags);
4695 CDEBUG(D_MGS, "\tlcfg->lcfg_nid: %s\n", libcfs_nid2str(lcfg->lcfg_nid));
4697 CDEBUG(D_MGS, "\tlcfg->lcfg_bufcount: %d\n", lcfg->lcfg_bufcount);
4698 if (lcfg->lcfg_bufcount < LUSTRE_CFG_MAX_BUFCOUNT)
4699 for (i = 0; i < lcfg->lcfg_bufcount; i++) {
4700 CDEBUG(D_MGS, "\tlcfg->lcfg_buflens[%d]: %d %s\n",
4701 i, lcfg->lcfg_buflens[i],
4702 lustre_cfg_string(lcfg, i));
4707 /* Setup _mgs fsdb and log
4709 int mgs__mgs_fsdb_setup(const struct lu_env *env, struct mgs_device *mgs)
4711 struct fs_db *fsdb = NULL;
4715 rc = mgs_find_or_make_fsdb(env, mgs, MGSSELF_NAME, &fsdb);
4717 mgs_put_fsdb(mgs, fsdb);
4722 /* Setup params fsdb and log
4724 int mgs_params_fsdb_setup(const struct lu_env *env, struct mgs_device *mgs)
4726 struct fs_db *fsdb = NULL;
4727 struct llog_handle *params_llh = NULL;
4731 rc = mgs_find_or_make_fsdb(env, mgs, PARAMS_FILENAME, &fsdb);
4733 mutex_lock(&fsdb->fsdb_mutex);
4734 rc = record_start_log(env, mgs, ¶ms_llh, PARAMS_FILENAME);
4736 rc = record_end_log(env, ¶ms_llh);
4737 mutex_unlock(&fsdb->fsdb_mutex);
4738 mgs_put_fsdb(mgs, fsdb);
4744 /* Cleanup params fsdb and log
4746 int mgs_params_fsdb_cleanup(const struct lu_env *env, struct mgs_device *mgs)
4750 rc = mgs_erase_logs(env, mgs, PARAMS_FILENAME);
4751 return rc == -ENOENT ? 0 : rc;
4754 /* Set a permanent (config log) param for a target or fs
4755 * \param lcfg buf0 may contain the device (testfs-MDT0000) name
4756 * buf1 contains the single parameter
4758 int mgs_setparam(const struct lu_env *env, struct mgs_device *mgs,
4759 struct lustre_cfg *lcfg, char *fsname)
4761 struct fs_db *fsdb = NULL;
4762 struct mgs_target_info *mti = NULL;
4763 char *devname, *param;
4771 print_lustre_cfg(lcfg);
4773 /* lustre, lustre-mdtlov, lustre-client, lustre-MDT0000 */
4774 devname = lustre_cfg_string(lcfg, 0);
4775 param = lustre_cfg_string(lcfg, 1);
4777 /* Assume device name embedded in param:
4778 lustre-OST0000.osc.max_dirty_mb=32 */
4779 ptr = strchr(param, '.');
4787 LCONSOLE_ERROR_MSG(0x14d, "No target specified: %s\n", param);
4791 rc = mgs_parse_devname(devname, fsname, NULL);
4792 if (rc == 0 && !mgs_parse_devname(devname, NULL, &index)) {
4793 /* param related to llite isn't allowed to set by OST or MDT */
4794 if (rc == 0 && strncmp(param, PARAM_LLITE,
4795 sizeof(PARAM_LLITE) - 1) == 0)
4798 /* assume devname is the fsname */
4799 strlcpy(fsname, devname, MTI_NAME_MAXLEN);
4801 CDEBUG(D_MGS, "setparam fs='%s' device='%s'\n", fsname, devname);
4803 rc = mgs_find_or_make_fsdb(env, mgs,
4804 lcfg->lcfg_command == LCFG_SET_PARAM ?
4805 PARAMS_FILENAME : fsname, &fsdb);
4809 if (lcfg->lcfg_command != LCFG_SET_PARAM &&
4810 !test_bit(FSDB_MGS_SELF, &fsdb->fsdb_flags) &&
4811 test_bit(FSDB_LOG_EMPTY, &fsdb->fsdb_flags)) {
4812 CERROR("No filesystem targets for %s. cfg_device from lctl "
4813 "is '%s'\n", fsname, devname);
4815 GOTO(out, rc = -EINVAL);
4818 /* Create a fake mti to hold everything */
4821 GOTO(out, rc = -ENOMEM);
4822 if (strlcpy(mti->mti_fsname, fsname, sizeof(mti->mti_fsname))
4823 >= sizeof(mti->mti_fsname))
4824 GOTO(out, rc = -E2BIG);
4825 if (strlcpy(mti->mti_svname, devname, sizeof(mti->mti_svname))
4826 >= sizeof(mti->mti_svname))
4827 GOTO(out, rc = -E2BIG);
4828 if (strlcpy(mti->mti_params, param, sizeof(mti->mti_params))
4829 >= sizeof(mti->mti_params))
4830 GOTO(out, rc = -E2BIG);
4831 rc = server_name2index(mti->mti_svname, &mti->mti_stripe_index, &tmp);
4833 /* Not a valid server; may be only fsname */
4836 /* Strip -osc or -mdc suffix from svname */
4837 if (server_make_name(rc, mti->mti_stripe_index, mti->mti_fsname,
4838 mti->mti_svname, sizeof(mti->mti_svname)))
4839 GOTO(out, rc = -EINVAL);
4841 * Revoke lock so everyone updates. Should be alright if
4842 * someone was already reading while we were updating the logs,
4843 * so we don't really need to hold the lock while we're
4846 if (lcfg->lcfg_command == LCFG_SET_PARAM) {
4847 mti->mti_flags = rc | LDD_F_PARAM2;
4848 mutex_lock(&fsdb->fsdb_mutex);
4849 rc = mgs_write_log_param2(env, mgs, fsdb, mti, mti->mti_params);
4850 mutex_unlock(&fsdb->fsdb_mutex);
4851 mgs_revoke_lock(mgs, fsdb, CONFIG_T_PARAMS);
4853 mti->mti_flags = rc | LDD_F_PARAM;
4854 mutex_lock(&fsdb->fsdb_mutex);
4855 rc = mgs_write_log_param(env, mgs, fsdb, mti, mti->mti_params);
4856 mutex_unlock(&fsdb->fsdb_mutex);
4857 mgs_revoke_lock(mgs, fsdb, CONFIG_T_CONFIG);
4866 mgs_unlink_fsdb(mgs, fsdb);
4867 mgs_put_fsdb(mgs, fsdb);
4873 static int mgs_write_log_pool(const struct lu_env *env,
4874 struct mgs_device *mgs, char *logname,
4875 struct fs_db *fsdb, char *tgtname,
4876 enum lcfg_command_type cmd,
4877 char *fsname, char *poolname,
4878 char *ostname, char *comment)
4880 struct llog_handle *llh = NULL;
4883 rc = record_start_log(env, mgs, &llh, logname);
4886 rc = record_marker(env, llh, fsdb, CM_START, tgtname, comment);
4889 rc = record_base(env, llh, tgtname, 0, cmd,
4890 fsname, poolname, ostname, NULL);
4893 rc = record_marker(env, llh, fsdb, CM_END, tgtname, comment);
4895 record_end_log(env, &llh);
4899 int mgs_nodemap_cmd(const struct lu_env *env, struct mgs_device *mgs,
4900 enum lcfg_command_type cmd, const char *nodemap_name,
4911 case LCFG_NODEMAP_ADD:
4912 rc = nodemap_add(nodemap_name);
4914 case LCFG_NODEMAP_DEL:
4915 rc = nodemap_del(nodemap_name);
4917 case LCFG_NODEMAP_ADD_RANGE:
4918 rc = nodemap_parse_range(param, nid);
4921 rc = nodemap_add_range(nodemap_name, nid);
4923 case LCFG_NODEMAP_DEL_RANGE:
4924 rc = nodemap_parse_range(param, nid);
4927 rc = nodemap_del_range(nodemap_name, nid);
4929 case LCFG_NODEMAP_ADMIN:
4930 bool_switch = simple_strtoul(param, NULL, 10);
4931 rc = nodemap_set_allow_root(nodemap_name, bool_switch);
4933 case LCFG_NODEMAP_DENY_UNKNOWN:
4934 bool_switch = simple_strtoul(param, NULL, 10);
4935 rc = nodemap_set_deny_unknown(nodemap_name, bool_switch);
4937 case LCFG_NODEMAP_MAP_MODE:
4938 if (strcmp("both", param) == 0)
4939 rc = nodemap_set_mapping_mode(nodemap_name,
4941 else if (strcmp("uid_only", param) == 0)
4942 rc = nodemap_set_mapping_mode(nodemap_name,
4943 NODEMAP_MAP_UID_ONLY);
4944 else if (strcmp("gid_only", param) == 0)
4945 rc = nodemap_set_mapping_mode(nodemap_name,
4946 NODEMAP_MAP_GID_ONLY);
4950 case LCFG_NODEMAP_TRUSTED:
4951 bool_switch = simple_strtoul(param, NULL, 10);
4952 rc = nodemap_set_trust_client_ids(nodemap_name, bool_switch);
4954 case LCFG_NODEMAP_SQUASH_UID:
4955 int_id = simple_strtoul(param, NULL, 10);
4956 rc = nodemap_set_squash_uid(nodemap_name, int_id);
4958 case LCFG_NODEMAP_SQUASH_GID:
4959 int_id = simple_strtoul(param, NULL, 10);
4960 rc = nodemap_set_squash_gid(nodemap_name, int_id);
4962 case LCFG_NODEMAP_ADD_UIDMAP:
4963 case LCFG_NODEMAP_ADD_GIDMAP:
4964 rc = nodemap_parse_idmap(param, idmap);
4967 if (cmd == LCFG_NODEMAP_ADD_UIDMAP)
4968 rc = nodemap_add_idmap(nodemap_name, NODEMAP_UID,
4971 rc = nodemap_add_idmap(nodemap_name, NODEMAP_GID,
4974 case LCFG_NODEMAP_DEL_UIDMAP:
4975 case LCFG_NODEMAP_DEL_GIDMAP:
4976 rc = nodemap_parse_idmap(param, idmap);
4979 if (cmd == LCFG_NODEMAP_DEL_UIDMAP)
4980 rc = nodemap_del_idmap(nodemap_name, NODEMAP_UID,
4983 rc = nodemap_del_idmap(nodemap_name, NODEMAP_GID,
4986 case LCFG_NODEMAP_SET_FILESET:
4987 rc = nodemap_set_fileset(nodemap_name, param);
4996 int mgs_pool_cmd(const struct lu_env *env, struct mgs_device *mgs,
4997 enum lcfg_command_type cmd, char *fsname,
4998 char *poolname, char *ostname)
5003 char *label = NULL, *canceled_label = NULL;
5005 struct mgs_target_info *mti = NULL;
5006 bool checked = false;
5007 bool locked = false;
5012 rc = mgs_find_or_make_fsdb(env, mgs, fsname, &fsdb);
5014 CERROR("Can't get db for %s\n", fsname);
5017 if (test_bit(FSDB_LOG_EMPTY, &fsdb->fsdb_flags)) {
5018 CERROR("%s is not defined\n", fsname);
5020 GOTO(out_fsdb, rc = -EINVAL);
5023 label_sz = 10 + strlen(fsname) + strlen(poolname);
5025 /* check if ostname match fsname */
5026 if (ostname != NULL) {
5029 ptr = strrchr(ostname, '-');
5030 if ((ptr == NULL) ||
5031 (strncmp(fsname, ostname, ptr-ostname) != 0))
5033 label_sz += strlen(ostname);
5036 OBD_ALLOC(label, label_sz);
5038 GOTO(out_fsdb, rc = -ENOMEM);
5043 "new %s.%s", fsname, poolname);
5047 "add %s.%s.%s", fsname, poolname, ostname);
5050 OBD_ALLOC(canceled_label, label_sz);
5051 if (canceled_label == NULL)
5052 GOTO(out_label, rc = -ENOMEM);
5054 "rem %s.%s.%s", fsname, poolname, ostname);
5055 sprintf(canceled_label,
5056 "add %s.%s.%s", fsname, poolname, ostname);
5059 OBD_ALLOC(canceled_label, label_sz);
5060 if (canceled_label == NULL)
5061 GOTO(out_label, rc = -ENOMEM);
5063 "del %s.%s", fsname, poolname);
5064 sprintf(canceled_label,
5065 "new %s.%s", fsname, poolname);
5073 GOTO(out_cancel, rc = -ENOMEM);
5074 strncpy(mti->mti_svname, "lov pool", sizeof(mti->mti_svname));
5076 mutex_lock(&fsdb->fsdb_mutex);
5078 /* write pool def to all MDT logs */
5079 for (i = 0; i < INDEX_MAP_SIZE * 8; i++) {
5080 if (test_bit(i, fsdb->fsdb_mdt_index_map)) {
5081 rc = name_create_mdt_and_lov(&logname, &lovname,
5086 if (!checked && (canceled_label == NULL)) {
5087 rc = mgs_check_marker(env, mgs, fsdb, mti,
5088 logname, lovname, label);
5090 name_destroy(&logname);
5091 name_destroy(&lovname);
5093 rc = (rc == LLOG_PROC_BREAK ?
5098 if (canceled_label != NULL)
5099 rc = mgs_modify(env, mgs, fsdb, mti, logname,
5100 lovname, canceled_label,
5104 rc = mgs_write_log_pool(env, mgs, logname,
5108 name_destroy(&logname);
5109 name_destroy(&lovname);
5115 rc = name_create(&logname, fsname, "-client");
5119 if (!checked && (canceled_label == NULL)) {
5120 rc = mgs_check_marker(env, mgs, fsdb, mti, logname,
5121 fsdb->fsdb_clilov, label);
5123 name_destroy(&logname);
5124 GOTO(out_mti, rc = (rc == LLOG_PROC_BREAK ?
5128 if (canceled_label != NULL) {
5129 rc = mgs_modify(env, mgs, fsdb, mti, logname,
5130 fsdb->fsdb_clilov, canceled_label, CM_SKIP);
5132 name_destroy(&logname);
5137 rc = mgs_write_log_pool(env, mgs, logname, fsdb, fsdb->fsdb_clilov,
5138 cmd, fsname, poolname, ostname, label);
5139 mutex_unlock(&fsdb->fsdb_mutex);
5141 name_destroy(&logname);
5142 /* request for update */
5143 mgs_revoke_lock(mgs, fsdb, CONFIG_T_CONFIG);
5149 mutex_unlock(&fsdb->fsdb_mutex);
5153 if (canceled_label != NULL)
5154 OBD_FREE(canceled_label, label_sz);
5156 OBD_FREE(label, label_sz);
5159 mgs_unlink_fsdb(mgs, fsdb);
5160 mgs_put_fsdb(mgs, fsdb);