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 <lustre_ioctl.h>
46 #include <lustre_param.h>
47 #include <lustre_sec.h>
48 #include <lustre_quota.h>
50 #include "mgs_internal.h"
52 /********************** Class functions ********************/
54 /* Find all logs in CONFIG directory and link then into list */
55 int class_dentry_readdir(const struct lu_env *env,
56 struct mgs_device *mgs, struct list_head *log_list)
58 struct dt_object *dir = mgs->mgs_configs_dir;
59 const struct dt_it_ops *iops;
61 struct mgs_direntry *de;
65 INIT_LIST_HEAD(log_list);
68 LASSERT(dir->do_index_ops);
70 iops = &dir->do_index_ops->dio_it;
71 it = iops->init(env, dir, LUDA_64BITHASH);
75 rc = iops->load(env, it, 0);
81 key = (void *)iops->key(env, it);
83 CERROR("%s: key failed when listing %s: rc = %d\n",
84 mgs->mgs_obd->obd_name, MOUNT_CONFIGS_DIR,
88 key_sz = iops->key_size(env, it);
91 /* filter out "." and ".." entries */
95 if (key_sz == 2 && key[1] == '.')
99 /* filter out ".bak" files */
100 /* sizeof(".bak") - 1 == 3 */
102 !memcmp(".bak", key + key_sz - 3, 3)) {
103 CDEBUG(D_MGS, "Skipping backup file %.*s\n",
108 de = mgs_direntry_alloc(key_sz + 1);
114 memcpy(de->mde_name, key, key_sz);
115 de->mde_name[key_sz] = 0;
117 list_add(&de->mde_list, log_list);
120 rc = iops->next(env, it);
130 CERROR("%s: key failed when listing %s: rc = %d\n",
131 mgs->mgs_obd->obd_name, MOUNT_CONFIGS_DIR, rc);
135 /******************** DB functions *********************/
137 static inline int name_create(char **newname, char *prefix, char *suffix)
140 OBD_ALLOC(*newname, strlen(prefix) + strlen(suffix) + 1);
143 sprintf(*newname, "%s%s", prefix, suffix);
147 static inline void name_destroy(char **name)
150 OBD_FREE(*name, strlen(*name) + 1);
154 struct mgs_fsdb_handler_data
160 /* from the (client) config log, figure out:
161 1. which ost's/mdt's are configured (by index)
162 2. what the last config step is
163 3. COMPAT_18 osc name
165 /* It might be better to have a separate db file, instead of parsing the info
166 out of the client log. This is slow and potentially error-prone. */
167 static int mgs_fsdb_handler(const struct lu_env *env, struct llog_handle *llh,
168 struct llog_rec_hdr *rec, void *data)
170 struct mgs_fsdb_handler_data *d = data;
171 struct fs_db *fsdb = d->fsdb;
172 int cfg_len = rec->lrh_len;
173 char *cfg_buf = (char*) (rec + 1);
174 struct lustre_cfg *lcfg;
179 if (rec->lrh_type != OBD_CFG_REC) {
180 CERROR("unhandled lrh_type: %#x\n", rec->lrh_type);
184 rc = lustre_cfg_sanity_check(cfg_buf, cfg_len);
186 CERROR("Insane cfg\n");
190 lcfg = (struct lustre_cfg *)cfg_buf;
192 CDEBUG(D_INFO, "cmd %x %s %s\n", lcfg->lcfg_command,
193 lustre_cfg_string(lcfg, 0), lustre_cfg_string(lcfg, 1));
195 /* Figure out ost indicies */
196 /* lov_modify_tgts add 0:lov1 1:ost1_UUID 2(index):0 3(gen):1 */
197 if (lcfg->lcfg_command == LCFG_LOV_ADD_OBD ||
198 lcfg->lcfg_command == LCFG_LOV_DEL_OBD) {
199 index = simple_strtoul(lustre_cfg_string(lcfg, 2),
201 CDEBUG(D_MGS, "OST index for %s is %u (%s)\n",
202 lustre_cfg_string(lcfg, 1), index,
203 lustre_cfg_string(lcfg, 2));
204 set_bit(index, fsdb->fsdb_ost_index_map);
207 /* Figure out mdt indicies */
208 /* attach 0:MDC_uml1_mdsA_MNT_client 1:mdc 2:1d834_MNT_client_03f */
209 if ((lcfg->lcfg_command == LCFG_ATTACH) &&
210 (strcmp(lustre_cfg_string(lcfg, 1), LUSTRE_MDC_NAME) == 0)) {
211 rc = server_name2index(lustre_cfg_string(lcfg, 0),
213 if (rc != LDD_F_SV_TYPE_MDT) {
214 CWARN("Unparsable MDC name %s, assuming index 0\n",
215 lustre_cfg_string(lcfg, 0));
219 CDEBUG(D_MGS, "MDT index is %u\n", index);
220 set_bit(index, fsdb->fsdb_mdt_index_map);
221 fsdb->fsdb_mdt_count ++;
225 * figure out the old config. fsdb_gen = 0 means old log
226 * It is obsoleted and not supported anymore
228 if (fsdb->fsdb_gen == 0) {
229 CERROR("Old config format is not supported\n");
234 * compat to 1.8, check osc name used by MDT0 to OSTs, bz18548.
236 if (!test_bit(FSDB_OSCNAME18, &fsdb->fsdb_flags) &&
237 lcfg->lcfg_command == LCFG_ATTACH &&
238 strcmp(lustre_cfg_string(lcfg, 1), LUSTRE_OSC_NAME) == 0) {
239 if (OBD_OCD_VERSION_MAJOR(d->ver) == 1 &&
240 OBD_OCD_VERSION_MINOR(d->ver) <= 8) {
241 CWARN("MDT using 1.8 OSC name scheme\n");
242 set_bit(FSDB_OSCNAME18, &fsdb->fsdb_flags);
246 if (lcfg->lcfg_command == LCFG_MARKER) {
247 struct cfg_marker *marker;
248 marker = lustre_cfg_buf(lcfg, 1);
250 d->ver = marker->cm_vers;
252 /* Keep track of the latest marker step */
253 fsdb->fsdb_gen = max(fsdb->fsdb_gen, marker->cm_step);
259 /* fsdb->fsdb_mutex is already held in mgs_find_or_make_fsdb*/
260 static int mgs_get_fsdb_from_llog(const struct lu_env *env,
261 struct mgs_device *mgs,
265 struct llog_handle *loghandle;
266 struct llog_ctxt *ctxt;
267 struct mgs_fsdb_handler_data d = { fsdb, 0 };
272 ctxt = llog_get_context(mgs->mgs_obd, LLOG_CONFIG_ORIG_CTXT);
273 LASSERT(ctxt != NULL);
274 rc = name_create(&logname, fsdb->fsdb_name, "-client");
277 rc = llog_open_create(env, ctxt, &loghandle, NULL, logname);
281 rc = llog_init_handle(env, loghandle, LLOG_F_IS_PLAIN, NULL);
285 if (llog_get_size(loghandle) <= 1)
286 set_bit(FSDB_LOG_EMPTY, &fsdb->fsdb_flags);
288 rc = llog_process(env, loghandle, mgs_fsdb_handler, (void *)&d, NULL);
289 CDEBUG(D_INFO, "get_db = %d\n", rc);
291 llog_close(env, loghandle);
293 name_destroy(&logname);
300 static void mgs_free_fsdb_srpc(struct fs_db *fsdb)
302 struct mgs_tgt_srpc_conf *tgtconf;
304 /* free target-specific rules */
305 while (fsdb->fsdb_srpc_tgt) {
306 tgtconf = fsdb->fsdb_srpc_tgt;
307 fsdb->fsdb_srpc_tgt = tgtconf->mtsc_next;
309 LASSERT(tgtconf->mtsc_tgt);
311 sptlrpc_rule_set_free(&tgtconf->mtsc_rset);
312 OBD_FREE(tgtconf->mtsc_tgt, strlen(tgtconf->mtsc_tgt) + 1);
313 OBD_FREE_PTR(tgtconf);
316 /* free general rules */
317 sptlrpc_rule_set_free(&fsdb->fsdb_srpc_gen);
320 struct fs_db *mgs_find_fsdb(struct mgs_device *mgs, char *fsname)
323 struct list_head *tmp;
325 list_for_each(tmp, &mgs->mgs_fs_db_list) {
326 fsdb = list_entry(tmp, struct fs_db, fsdb_list);
327 if (strcmp(fsdb->fsdb_name, fsname) == 0)
333 /* caller must hold the mgs->mgs_fs_db_lock */
334 static struct fs_db *mgs_new_fsdb(const struct lu_env *env,
335 struct mgs_device *mgs, char *fsname)
341 if (strlen(fsname) >= sizeof(fsdb->fsdb_name)) {
342 CERROR("fsname %s is too long\n", fsname);
343 RETURN(ERR_PTR(-EINVAL));
348 RETURN(ERR_PTR(-ENOMEM));
350 strcpy(fsdb->fsdb_name, fsname);
351 mutex_init(&fsdb->fsdb_mutex);
352 set_bit(FSDB_UDESC, &fsdb->fsdb_flags);
355 if (strcmp(fsname, MGSSELF_NAME) == 0) {
356 set_bit(FSDB_MGS_SELF, &fsdb->fsdb_flags);
357 fsdb->fsdb_mgs = mgs;
359 OBD_ALLOC(fsdb->fsdb_ost_index_map, INDEX_MAP_SIZE);
360 OBD_ALLOC(fsdb->fsdb_mdt_index_map, INDEX_MAP_SIZE);
361 if (!fsdb->fsdb_ost_index_map || !fsdb->fsdb_mdt_index_map) {
362 CERROR("No memory for index maps\n");
363 GOTO(err, rc = -ENOMEM);
366 rc = name_create(&fsdb->fsdb_clilov, fsname, "-clilov");
369 rc = name_create(&fsdb->fsdb_clilmv, fsname, "-clilmv");
373 /* initialise data for NID table */
374 mgs_ir_init_fs(env, mgs, fsdb);
376 lproc_mgs_add_live(mgs, fsdb);
379 list_add(&fsdb->fsdb_list, &mgs->mgs_fs_db_list);
383 if (fsdb->fsdb_ost_index_map)
384 OBD_FREE(fsdb->fsdb_ost_index_map, INDEX_MAP_SIZE);
385 if (fsdb->fsdb_mdt_index_map)
386 OBD_FREE(fsdb->fsdb_mdt_index_map, INDEX_MAP_SIZE);
387 name_destroy(&fsdb->fsdb_clilov);
388 name_destroy(&fsdb->fsdb_clilmv);
393 static void mgs_free_fsdb(struct mgs_device *mgs, struct fs_db *fsdb)
395 /* wait for anyone with the sem */
396 mutex_lock(&fsdb->fsdb_mutex);
397 lproc_mgs_del_live(mgs, fsdb);
398 list_del(&fsdb->fsdb_list);
400 /* deinitialize fsr */
401 mgs_ir_fini_fs(mgs, fsdb);
403 if (fsdb->fsdb_ost_index_map)
404 OBD_FREE(fsdb->fsdb_ost_index_map, INDEX_MAP_SIZE);
405 if (fsdb->fsdb_mdt_index_map)
406 OBD_FREE(fsdb->fsdb_mdt_index_map, INDEX_MAP_SIZE);
407 name_destroy(&fsdb->fsdb_clilov);
408 name_destroy(&fsdb->fsdb_clilmv);
409 mgs_free_fsdb_srpc(fsdb);
410 mutex_unlock(&fsdb->fsdb_mutex);
414 int mgs_init_fsdb_list(struct mgs_device *mgs)
416 INIT_LIST_HEAD(&mgs->mgs_fs_db_list);
420 int mgs_cleanup_fsdb_list(struct mgs_device *mgs)
423 struct list_head *tmp, *tmp2;
425 mutex_lock(&mgs->mgs_mutex);
426 list_for_each_safe(tmp, tmp2, &mgs->mgs_fs_db_list) {
427 fsdb = list_entry(tmp, struct fs_db, fsdb_list);
428 mgs_free_fsdb(mgs, fsdb);
430 mutex_unlock(&mgs->mgs_mutex);
434 int mgs_find_or_make_fsdb(const struct lu_env *env,
435 struct mgs_device *mgs, char *name,
442 mutex_lock(&mgs->mgs_mutex);
443 fsdb = mgs_find_fsdb(mgs, name);
445 mutex_unlock(&mgs->mgs_mutex);
450 CDEBUG(D_MGS, "Creating new db\n");
451 fsdb = mgs_new_fsdb(env, mgs, name);
452 /* lock fsdb_mutex until the db is loaded from llogs */
454 mutex_lock(&fsdb->fsdb_mutex);
455 mutex_unlock(&mgs->mgs_mutex);
457 RETURN(PTR_ERR(fsdb));
459 if (!test_bit(FSDB_MGS_SELF, &fsdb->fsdb_flags)) {
460 /* populate the db from the client llog */
461 rc = mgs_get_fsdb_from_llog(env, mgs, fsdb);
463 CERROR("Can't get db from client log %d\n", rc);
468 /* populate srpc rules from params llog */
469 rc = mgs_get_fsdb_srpc_from_llog(env, mgs, fsdb);
471 CERROR("Can't get db from params log %d\n", rc);
475 mutex_unlock(&fsdb->fsdb_mutex);
481 mutex_unlock(&fsdb->fsdb_mutex);
482 mgs_free_fsdb(mgs, fsdb);
488 -1= empty client log */
489 int mgs_check_index(const struct lu_env *env,
490 struct mgs_device *mgs,
491 struct mgs_target_info *mti)
498 LASSERT(!(mti->mti_flags & LDD_F_NEED_INDEX));
500 rc = mgs_find_or_make_fsdb(env, mgs, mti->mti_fsname, &fsdb);
502 CERROR("Can't get db for %s\n", mti->mti_fsname);
506 if (test_bit(FSDB_LOG_EMPTY, &fsdb->fsdb_flags))
509 if (mti->mti_flags & LDD_F_SV_TYPE_OST)
510 imap = fsdb->fsdb_ost_index_map;
511 else if (mti->mti_flags & LDD_F_SV_TYPE_MDT)
512 imap = fsdb->fsdb_mdt_index_map;
516 if (test_bit(mti->mti_stripe_index, imap))
521 static __inline__ int next_index(void *index_map, int map_len)
524 for (i = 0; i < map_len * 8; i++)
525 if (!test_bit(i, index_map)) {
528 CERROR("max index %d exceeded.\n", i);
533 0 newly marked as in use
535 +EALREADY for update of an old index */
536 static int mgs_set_index(const struct lu_env *env,
537 struct mgs_device *mgs,
538 struct mgs_target_info *mti)
545 rc = mgs_find_or_make_fsdb(env, mgs, mti->mti_fsname, &fsdb);
547 CERROR("Can't get db for %s\n", mti->mti_fsname);
551 mutex_lock(&fsdb->fsdb_mutex);
552 if (mti->mti_flags & LDD_F_SV_TYPE_OST) {
553 imap = fsdb->fsdb_ost_index_map;
554 } else if (mti->mti_flags & LDD_F_SV_TYPE_MDT) {
555 imap = fsdb->fsdb_mdt_index_map;
557 GOTO(out_up, rc = -EINVAL);
560 if (mti->mti_flags & LDD_F_NEED_INDEX) {
561 rc = next_index(imap, INDEX_MAP_SIZE);
563 GOTO(out_up, rc = -ERANGE);
564 mti->mti_stripe_index = rc;
565 if (mti->mti_flags & LDD_F_SV_TYPE_MDT)
566 fsdb->fsdb_mdt_count ++;
569 /* the last index(0xffff) is reserved for default value. */
570 if (mti->mti_stripe_index >= INDEX_MAP_SIZE * 8 - 1) {
571 LCONSOLE_ERROR_MSG(0x13f, "Server %s requested index %u, "
572 "but index must be less than %u.\n",
573 mti->mti_svname, mti->mti_stripe_index,
574 INDEX_MAP_SIZE * 8 - 1);
575 GOTO(out_up, rc = -ERANGE);
578 if (test_bit(mti->mti_stripe_index, imap)) {
579 if ((mti->mti_flags & LDD_F_VIRGIN) &&
580 !(mti->mti_flags & LDD_F_WRITECONF)) {
581 LCONSOLE_ERROR_MSG(0x140, "Server %s requested index "
582 "%d, but that index is already in "
583 "use. Use --writeconf to force\n",
585 mti->mti_stripe_index);
586 GOTO(out_up, rc = -EADDRINUSE);
588 CDEBUG(D_MGS, "Server %s updating index %d\n",
589 mti->mti_svname, mti->mti_stripe_index);
590 GOTO(out_up, rc = EALREADY);
594 set_bit(mti->mti_stripe_index, imap);
595 clear_bit(FSDB_LOG_EMPTY, &fsdb->fsdb_flags);
596 mutex_unlock(&fsdb->fsdb_mutex);
597 if (server_make_name(mti->mti_flags & ~(LDD_F_VIRGIN | LDD_F_WRITECONF),
598 mti->mti_stripe_index, mti->mti_fsname,
600 CERROR("unknown server type %#x\n", mti->mti_flags);
604 CDEBUG(D_MGS, "Set index for %s to %d\n", mti->mti_svname,
605 mti->mti_stripe_index);
609 mutex_unlock(&fsdb->fsdb_mutex);
613 struct mgs_modify_lookup {
614 struct cfg_marker mml_marker;
618 static int mgs_check_record_match(const struct lu_env *env,
619 struct llog_handle *llh,
620 struct llog_rec_hdr *rec, void *data)
622 struct cfg_marker *mc_marker = data;
623 struct cfg_marker *marker;
624 struct lustre_cfg *lcfg = REC_DATA(rec);
625 int cfg_len = REC_DATA_LEN(rec);
630 if (rec->lrh_type != OBD_CFG_REC) {
631 CDEBUG(D_ERROR, "Unhandled lrh_type: %#x\n", rec->lrh_type);
635 rc = lustre_cfg_sanity_check(lcfg, cfg_len);
637 CDEBUG(D_ERROR, "Insane cfg\n");
641 /* We only care about markers */
642 if (lcfg->lcfg_command != LCFG_MARKER)
645 marker = lustre_cfg_buf(lcfg, 1);
647 if (marker->cm_flags & CM_SKIP)
650 if ((strcmp(mc_marker->cm_comment, marker->cm_comment) == 0) &&
651 (strcmp(mc_marker->cm_tgtname, marker->cm_tgtname) == 0)) {
652 /* Found a non-skipped marker match */
653 CDEBUG(D_MGS, "Matched rec %u marker %d flag %x %s %s\n",
654 rec->lrh_index, marker->cm_step,
655 marker->cm_flags, marker->cm_tgtname,
657 rc = LLOG_PROC_BREAK;
664 * Check an existing config log record with matching comment and device
666 * 0 - checked successfully,
667 * LLOG_PROC_BREAK - record matches
670 static int mgs_check_marker(const struct lu_env *env, struct mgs_device *mgs,
671 struct fs_db *fsdb, struct mgs_target_info *mti,
672 char *logname, char *devname, char *comment)
674 struct llog_handle *loghandle;
675 struct llog_ctxt *ctxt;
676 struct cfg_marker *mc_marker;
681 LASSERT(mutex_is_locked(&fsdb->fsdb_mutex));
682 CDEBUG(D_MGS, "mgs check %s/%s/%s\n", logname, devname, comment);
684 ctxt = llog_get_context(mgs->mgs_obd, LLOG_CONFIG_ORIG_CTXT);
685 LASSERT(ctxt != NULL);
686 rc = llog_open(env, ctxt, &loghandle, NULL, logname, LLOG_OPEN_EXISTS);
693 rc = llog_init_handle(env, loghandle, LLOG_F_IS_PLAIN, NULL);
697 if (llog_get_size(loghandle) <= 1)
698 GOTO(out_close, rc = 0);
700 OBD_ALLOC_PTR(mc_marker);
702 GOTO(out_close, rc = -ENOMEM);
703 if (strlcpy(mc_marker->cm_comment, comment,
704 sizeof(mc_marker->cm_comment)) >=
705 sizeof(mc_marker->cm_comment))
706 GOTO(out_free, rc = -E2BIG);
707 if (strlcpy(mc_marker->cm_tgtname, devname,
708 sizeof(mc_marker->cm_tgtname)) >=
709 sizeof(mc_marker->cm_tgtname))
710 GOTO(out_free, rc = -E2BIG);
712 rc = llog_process(env, loghandle, mgs_check_record_match,
713 (void *)mc_marker, NULL);
716 OBD_FREE_PTR(mc_marker);
719 llog_close(env, loghandle);
721 if (rc && rc != LLOG_PROC_BREAK)
722 CDEBUG(D_ERROR, "%s: mgs check %s/%s failed: rc = %d\n",
723 mgs->mgs_obd->obd_name, mti->mti_svname, comment, rc);
728 static int mgs_modify_handler(const struct lu_env *env,
729 struct llog_handle *llh,
730 struct llog_rec_hdr *rec, void *data)
732 struct mgs_modify_lookup *mml = data;
733 struct cfg_marker *marker;
734 struct lustre_cfg *lcfg = REC_DATA(rec);
735 int cfg_len = REC_DATA_LEN(rec);
739 if (rec->lrh_type != OBD_CFG_REC) {
740 CERROR("unhandled lrh_type: %#x\n", rec->lrh_type);
744 rc = lustre_cfg_sanity_check(lcfg, cfg_len);
746 CERROR("Insane cfg\n");
750 /* We only care about markers */
751 if (lcfg->lcfg_command != LCFG_MARKER)
754 marker = lustre_cfg_buf(lcfg, 1);
755 if ((strcmp(mml->mml_marker.cm_comment, marker->cm_comment) == 0) &&
756 (strcmp(mml->mml_marker.cm_tgtname, marker->cm_tgtname) == 0) &&
757 !(marker->cm_flags & CM_SKIP)) {
758 /* Found a non-skipped marker match */
759 CDEBUG(D_MGS, "Changing rec %u marker %d %x->%x: %s %s\n",
760 rec->lrh_index, marker->cm_step,
761 marker->cm_flags, mml->mml_marker.cm_flags,
762 marker->cm_tgtname, marker->cm_comment);
763 /* Overwrite the old marker llog entry */
764 marker->cm_flags &= ~CM_EXCLUDE; /* in case we're unexcluding */
765 marker->cm_flags |= mml->mml_marker.cm_flags;
766 marker->cm_canceltime = mml->mml_marker.cm_canceltime;
767 rc = llog_write(env, llh, rec, rec->lrh_index);
776 * Modify an existing config log record (for CM_SKIP or CM_EXCLUDE)
778 * 0 - modified successfully,
779 * 1 - no modification was done
782 static int mgs_modify(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, int flags)
786 struct llog_handle *loghandle;
787 struct llog_ctxt *ctxt;
788 struct mgs_modify_lookup *mml;
793 LASSERT(mutex_is_locked(&fsdb->fsdb_mutex));
794 CDEBUG(D_MGS, "modify %s/%s/%s fl=%x\n", logname, devname, comment,
797 ctxt = llog_get_context(mgs->mgs_obd, LLOG_CONFIG_ORIG_CTXT);
798 LASSERT(ctxt != NULL);
799 rc = llog_open(env, ctxt, &loghandle, NULL, logname, LLOG_OPEN_EXISTS);
806 rc = llog_init_handle(env, loghandle, LLOG_F_IS_PLAIN, NULL);
810 if (llog_get_size(loghandle) <= 1)
811 GOTO(out_close, rc = 0);
815 GOTO(out_close, rc = -ENOMEM);
816 if (strlcpy(mml->mml_marker.cm_comment, comment,
817 sizeof(mml->mml_marker.cm_comment)) >=
818 sizeof(mml->mml_marker.cm_comment))
819 GOTO(out_free, rc = -E2BIG);
820 if (strlcpy(mml->mml_marker.cm_tgtname, devname,
821 sizeof(mml->mml_marker.cm_tgtname)) >=
822 sizeof(mml->mml_marker.cm_tgtname))
823 GOTO(out_free, rc = -E2BIG);
824 /* Modify mostly means cancel */
825 mml->mml_marker.cm_flags = flags;
826 mml->mml_marker.cm_canceltime = flags ? cfs_time_current_sec() : 0;
827 mml->mml_modified = 0;
828 rc = llog_process(env, loghandle, mgs_modify_handler, (void *)mml,
830 if (!rc && !mml->mml_modified)
837 llog_close(env, loghandle);
840 CERROR("%s: modify %s/%s failed: rc = %d\n",
841 mgs->mgs_obd->obd_name, mti->mti_svname, comment, rc);
846 /** This structure is passed to mgs_replace_handler */
847 struct mgs_replace_uuid_lookup {
848 /* Nids are replaced for this target device */
849 struct mgs_target_info target;
850 /* Temporary modified llog */
851 struct llog_handle *temp_llh;
852 /* Flag is set if in target block*/
853 int in_target_device;
854 /* Nids already added. Just skip (multiple nids) */
855 int device_nids_added;
856 /* Flag is set if this block should not be copied */
861 * Check: a) if block should be skipped
862 * b) is it target block
867 * \retval 0 should not to be skipped
868 * \retval 1 should to be skipped
870 static int check_markers(struct lustre_cfg *lcfg,
871 struct mgs_replace_uuid_lookup *mrul)
873 struct cfg_marker *marker;
875 /* Track markers. Find given device */
876 if (lcfg->lcfg_command == LCFG_MARKER) {
877 marker = lustre_cfg_buf(lcfg, 1);
878 /* Clean llog from records marked as CM_EXCLUDE.
879 CM_SKIP records are used for "active" command
880 and can be restored if needed */
881 if ((marker->cm_flags & (CM_EXCLUDE | CM_START)) ==
882 (CM_EXCLUDE | CM_START)) {
887 if ((marker->cm_flags & (CM_EXCLUDE | CM_END)) ==
888 (CM_EXCLUDE | CM_END)) {
893 if (strcmp(mrul->target.mti_svname, marker->cm_tgtname) == 0) {
894 LASSERT(!(marker->cm_flags & CM_START) ||
895 !(marker->cm_flags & CM_END));
896 if (marker->cm_flags & CM_START) {
897 mrul->in_target_device = 1;
898 mrul->device_nids_added = 0;
899 } else if (marker->cm_flags & CM_END)
900 mrul->in_target_device = 0;
907 static int record_base(const struct lu_env *env, struct llog_handle *llh,
908 char *cfgname, lnet_nid_t nid, int cmd,
909 char *s1, char *s2, char *s3, char *s4)
911 struct mgs_thread_info *mgi = mgs_env_info(env);
912 struct llog_cfg_rec *lcr;
915 CDEBUG(D_MGS, "lcfg %s %#x %s %s %s %s\n", cfgname,
916 cmd, s1, s2, s3, s4);
918 lustre_cfg_bufs_reset(&mgi->mgi_bufs, cfgname);
920 lustre_cfg_bufs_set_string(&mgi->mgi_bufs, 1, s1);
922 lustre_cfg_bufs_set_string(&mgi->mgi_bufs, 2, s2);
924 lustre_cfg_bufs_set_string(&mgi->mgi_bufs, 3, s3);
926 lustre_cfg_bufs_set_string(&mgi->mgi_bufs, 4, s4);
928 lcr = lustre_cfg_rec_new(cmd, &mgi->mgi_bufs);
932 lcr->lcr_cfg.lcfg_nid = nid;
933 rc = llog_write(env, llh, &lcr->lcr_hdr, LLOG_NEXT_IDX);
935 lustre_cfg_rec_free(lcr);
939 "failed to write lcfg %s %#x %s %s %s %s: rc = %d\n",
940 cfgname, cmd, s1, s2, s3, s4, rc);
944 static inline int record_add_uuid(const struct lu_env *env,
945 struct llog_handle *llh,
946 uint64_t nid, char *uuid)
948 return record_base(env, llh, NULL, nid, LCFG_ADD_UUID, uuid,
952 static inline int record_add_conn(const struct lu_env *env,
953 struct llog_handle *llh,
954 char *devname, char *uuid)
956 return record_base(env, llh, devname, 0, LCFG_ADD_CONN, uuid,
960 static inline int record_attach(const struct lu_env *env,
961 struct llog_handle *llh, char *devname,
962 char *type, char *uuid)
964 return record_base(env, llh, devname, 0, LCFG_ATTACH, type, uuid,
968 static inline int record_setup(const struct lu_env *env,
969 struct llog_handle *llh, char *devname,
970 char *s1, char *s2, char *s3, char *s4)
972 return record_base(env, llh, devname, 0, LCFG_SETUP, s1, s2, s3, s4);
976 * \retval <0 record processing error
977 * \retval n record is processed. No need copy original one.
978 * \retval 0 record is not processed.
980 static int process_command(const struct lu_env *env, struct lustre_cfg *lcfg,
981 struct mgs_replace_uuid_lookup *mrul)
988 if (lcfg->lcfg_command == LCFG_ADD_UUID) {
989 /* LCFG_ADD_UUID command found. Let's skip original command
990 and add passed nids */
991 ptr = mrul->target.mti_params;
992 while (class_parse_nid(ptr, &nid, &ptr) == 0) {
993 CDEBUG(D_MGS, "add nid %s with uuid %s, "
994 "device %s\n", libcfs_nid2str(nid),
995 mrul->target.mti_params,
996 mrul->target.mti_svname);
997 rc = record_add_uuid(env,
999 mrul->target.mti_params);
1004 if (nids_added == 0) {
1005 CERROR("No new nids were added, nid %s with uuid %s, "
1006 "device %s\n", libcfs_nid2str(nid),
1007 mrul->target.mti_params,
1008 mrul->target.mti_svname);
1011 mrul->device_nids_added = 1;
1017 if (mrul->device_nids_added && lcfg->lcfg_command == LCFG_SETUP) {
1018 /* LCFG_SETUP command found. UUID should be changed */
1019 rc = record_setup(env,
1021 /* devname the same */
1022 lustre_cfg_string(lcfg, 0),
1023 /* s1 is not changed */
1024 lustre_cfg_string(lcfg, 1),
1025 /* new uuid should be
1027 mrul->target.mti_params,
1028 /* s3 is not changed */
1029 lustre_cfg_string(lcfg, 3),
1030 /* s4 is not changed */
1031 lustre_cfg_string(lcfg, 4));
1035 /* Another commands in target device block */
1040 * Handler that called for every record in llog.
1041 * Records are processed in order they placed in llog.
1043 * \param[in] llh log to be processed
1044 * \param[in] rec current record
1045 * \param[in] data mgs_replace_uuid_lookup structure
1049 static int mgs_replace_handler(const struct lu_env *env,
1050 struct llog_handle *llh,
1051 struct llog_rec_hdr *rec,
1054 struct mgs_replace_uuid_lookup *mrul;
1055 struct lustre_cfg *lcfg = REC_DATA(rec);
1056 int cfg_len = REC_DATA_LEN(rec);
1060 mrul = (struct mgs_replace_uuid_lookup *)data;
1062 if (rec->lrh_type != OBD_CFG_REC) {
1063 CERROR("unhandled lrh_type: %#x, cmd %x %s %s\n",
1064 rec->lrh_type, lcfg->lcfg_command,
1065 lustre_cfg_string(lcfg, 0),
1066 lustre_cfg_string(lcfg, 1));
1070 rc = lustre_cfg_sanity_check(lcfg, cfg_len);
1072 /* Do not copy any invalidated records */
1073 GOTO(skip_out, rc = 0);
1076 rc = check_markers(lcfg, mrul);
1077 if (rc || mrul->skip_it)
1078 GOTO(skip_out, rc = 0);
1080 /* Write to new log all commands outside target device block */
1081 if (!mrul->in_target_device)
1082 GOTO(copy_out, rc = 0);
1084 /* Skip all other LCFG_ADD_UUID and LCFG_ADD_CONN records
1085 (failover nids) for this target, assuming that if then
1086 primary is changing then so is the failover */
1087 if (mrul->device_nids_added &&
1088 (lcfg->lcfg_command == LCFG_ADD_UUID ||
1089 lcfg->lcfg_command == LCFG_ADD_CONN))
1090 GOTO(skip_out, rc = 0);
1092 rc = process_command(env, lcfg, mrul);
1099 /* Record is placed in temporary llog as is */
1100 rc = llog_write(env, mrul->temp_llh, rec, LLOG_NEXT_IDX);
1102 CDEBUG(D_MGS, "Copied idx=%d, rc=%d, len=%d, cmd %x %s %s\n",
1103 rec->lrh_index, rc, rec->lrh_len, lcfg->lcfg_command,
1104 lustre_cfg_string(lcfg, 0), lustre_cfg_string(lcfg, 1));
1108 CDEBUG(D_MGS, "Skipped idx=%d, rc=%d, len=%d, cmd %x %s %s\n",
1109 rec->lrh_index, rc, rec->lrh_len, lcfg->lcfg_command,
1110 lustre_cfg_string(lcfg, 0), lustre_cfg_string(lcfg, 1));
1114 static int mgs_log_is_empty(const struct lu_env *env,
1115 struct mgs_device *mgs, char *name)
1117 struct llog_ctxt *ctxt;
1120 ctxt = llog_get_context(mgs->mgs_obd, LLOG_CONFIG_ORIG_CTXT);
1121 LASSERT(ctxt != NULL);
1123 rc = llog_is_empty(env, ctxt, name);
1124 llog_ctxt_put(ctxt);
1128 static int mgs_replace_nids_log(const struct lu_env *env,
1129 struct obd_device *mgs, struct fs_db *fsdb,
1130 char *logname, char *devname, char *nids)
1132 struct llog_handle *orig_llh, *backup_llh;
1133 struct llog_ctxt *ctxt;
1134 struct mgs_replace_uuid_lookup *mrul;
1135 struct mgs_device *mgs_dev = lu2mgs_dev(mgs->obd_lu_dev);
1136 static struct obd_uuid cfg_uuid = { .uuid = "config_uuid" };
1141 CDEBUG(D_MGS, "Replace nids for %s in %s\n", devname, logname);
1143 ctxt = llog_get_context(mgs, LLOG_CONFIG_ORIG_CTXT);
1144 LASSERT(ctxt != NULL);
1146 if (mgs_log_is_empty(env, mgs_dev, logname)) {
1147 /* Log is empty. Nothing to replace */
1148 GOTO(out_put, rc = 0);
1151 OBD_ALLOC(backup, strlen(logname) + strlen(".bak") + 1);
1153 GOTO(out_put, rc = -ENOMEM);
1155 sprintf(backup, "%s.bak", logname);
1157 rc = llog_backup(env, mgs, ctxt, ctxt, logname, backup);
1159 /* Now erase original log file. Connections are not allowed.
1160 Backup is already saved */
1161 rc = llog_erase(env, ctxt, NULL, logname);
1164 } else if (rc != -ENOENT) {
1165 CERROR("%s: can't make backup for %s: rc = %d\n",
1166 mgs->obd_name, logname, rc);
1170 /* open local log */
1171 rc = llog_open_create(env, ctxt, &orig_llh, NULL, logname);
1173 GOTO(out_restore, rc);
1175 rc = llog_init_handle(env, orig_llh, LLOG_F_IS_PLAIN, &cfg_uuid);
1177 GOTO(out_closel, rc);
1179 /* open backup llog */
1180 rc = llog_open(env, ctxt, &backup_llh, NULL, backup,
1183 GOTO(out_closel, rc);
1185 rc = llog_init_handle(env, backup_llh, LLOG_F_IS_PLAIN, NULL);
1187 GOTO(out_close, rc);
1189 if (llog_get_size(backup_llh) <= 1)
1190 GOTO(out_close, rc = 0);
1192 OBD_ALLOC_PTR(mrul);
1194 GOTO(out_close, rc = -ENOMEM);
1195 /* devname is only needed information to replace UUID records */
1196 strlcpy(mrul->target.mti_svname, devname,
1197 sizeof(mrul->target.mti_svname));
1198 /* parse nids later */
1199 strlcpy(mrul->target.mti_params, nids, sizeof(mrul->target.mti_params));
1200 /* Copy records to this temporary llog */
1201 mrul->temp_llh = orig_llh;
1203 rc = llog_process(env, backup_llh, mgs_replace_handler,
1204 (void *)mrul, NULL);
1207 rc2 = llog_close(NULL, backup_llh);
1211 rc2 = llog_close(NULL, orig_llh);
1217 CERROR("%s: llog should be restored: rc = %d\n",
1219 rc2 = llog_backup(env, mgs, ctxt, ctxt, backup,
1222 CERROR("%s: can't restore backup %s: rc = %d\n",
1223 mgs->obd_name, logname, rc2);
1227 OBD_FREE(backup, strlen(backup) + 1);
1230 llog_ctxt_put(ctxt);
1233 CERROR("%s: failed to replace nids in log %s: rc = %d\n",
1234 mgs->obd_name, logname, rc);
1240 * Parse device name and get file system name and/or device index
1242 * \param[in] devname device name (ex. lustre-MDT0000)
1243 * \param[out] fsname file system name(optional)
1244 * \param[out] index device index(optional)
1248 static int mgs_parse_devname(char *devname, char *fsname, __u32 *index)
1253 /* Extract fsname */
1255 rc = server_name2fsname(devname, fsname, NULL);
1257 CDEBUG(D_MGS, "Device name %s without fsname\n",
1264 rc = server_name2index(devname, index, NULL);
1266 CDEBUG(D_MGS, "Device name %s with wrong index\n",
1275 /* This is only called during replace_nids */
1276 static int only_mgs_is_running(struct obd_device *mgs_obd)
1278 /* TDB: Is global variable with devices count exists? */
1279 int num_devices = get_devices_count();
1280 int num_exports = 0;
1281 struct obd_export *exp;
1283 spin_lock(&mgs_obd->obd_dev_lock);
1284 list_for_each_entry(exp, &mgs_obd->obd_exports, exp_obd_chain) {
1285 /* skip self export */
1286 if (exp == mgs_obd->obd_self_export)
1288 if (exp_connect_flags(exp) & OBD_CONNECT_MDS_MDS)
1293 CERROR("%s: node %s still connected during replace_nids "
1294 "connect_flags:%llx\n",
1296 libcfs_nid2str(exp->exp_nid_stats->nid),
1297 exp_connect_flags(exp));
1300 spin_unlock(&mgs_obd->obd_dev_lock);
1302 /* osd, MGS and MGC + self_export
1303 (wc -l /proc/fs/lustre/devices <= 2) && (non self exports == 0) */
1304 return (num_devices <= 3) && (num_exports == 0);
1307 static int name_create_mdt(char **logname, char *fsname, int i)
1311 sprintf(mdt_index, "-MDT%04x", i);
1312 return name_create(logname, fsname, mdt_index);
1316 * Replace nids for \a device to \a nids values
1318 * \param obd MGS obd device
1319 * \param devname nids need to be replaced for this device
1320 * (ex. lustre-OST0000)
1321 * \param nids nids list (ex. nid1,nid2,nid3)
1325 int mgs_replace_nids(const struct lu_env *env,
1326 struct mgs_device *mgs,
1327 char *devname, char *nids)
1329 /* Assume fsname is part of device name */
1330 char fsname[MTI_NAME_MAXLEN];
1337 struct obd_device *mgs_obd = mgs->mgs_obd;
1340 /* We can only change NIDs if no other nodes are connected */
1341 spin_lock(&mgs_obd->obd_dev_lock);
1342 conn_state = mgs_obd->obd_no_conn;
1343 mgs_obd->obd_no_conn = 1;
1344 spin_unlock(&mgs_obd->obd_dev_lock);
1346 /* We can not change nids if not only MGS is started */
1347 if (!only_mgs_is_running(mgs_obd)) {
1348 CERROR("Only MGS is allowed to be started\n");
1349 GOTO(out, rc = -EINPROGRESS);
1352 /* Get fsname and index*/
1353 rc = mgs_parse_devname(devname, fsname, &index);
1357 rc = mgs_find_or_make_fsdb(env, mgs, fsname, &fsdb);
1359 CERROR("%s: can't find fsdb: rc = %d\n", fsname, rc);
1363 /* Process client llogs */
1364 name_create(&logname, fsname, "-client");
1365 rc = mgs_replace_nids_log(env, mgs_obd, fsdb, logname, devname, nids);
1366 name_destroy(&logname);
1368 CERROR("%s: error while replacing NIDs for %s: rc = %d\n",
1369 fsname, devname, rc);
1373 /* Process MDT llogs */
1374 for (i = 0; i < INDEX_MAP_SIZE * 8; i++) {
1375 if (!test_bit(i, fsdb->fsdb_mdt_index_map))
1377 name_create_mdt(&logname, fsname, i);
1378 rc = mgs_replace_nids_log(env, mgs_obd, fsdb, logname, devname, nids);
1379 name_destroy(&logname);
1385 spin_lock(&mgs_obd->obd_dev_lock);
1386 mgs_obd->obd_no_conn = conn_state;
1387 spin_unlock(&mgs_obd->obd_dev_lock);
1392 static int record_lov_setup(const struct lu_env *env, struct llog_handle *llh,
1393 char *devname, struct lov_desc *desc)
1395 struct mgs_thread_info *mgi = mgs_env_info(env);
1396 struct llog_cfg_rec *lcr;
1399 lustre_cfg_bufs_reset(&mgi->mgi_bufs, devname);
1400 lustre_cfg_bufs_set(&mgi->mgi_bufs, 1, desc, sizeof(*desc));
1401 lcr = lustre_cfg_rec_new(LCFG_SETUP, &mgi->mgi_bufs);
1405 rc = llog_write(env, llh, &lcr->lcr_hdr, LLOG_NEXT_IDX);
1406 lustre_cfg_rec_free(lcr);
1410 static int record_lmv_setup(const struct lu_env *env, struct llog_handle *llh,
1411 char *devname, struct lmv_desc *desc)
1413 struct mgs_thread_info *mgi = mgs_env_info(env);
1414 struct llog_cfg_rec *lcr;
1417 lustre_cfg_bufs_reset(&mgi->mgi_bufs, devname);
1418 lustre_cfg_bufs_set(&mgi->mgi_bufs, 1, desc, sizeof(*desc));
1419 lcr = lustre_cfg_rec_new(LCFG_SETUP, &mgi->mgi_bufs);
1423 rc = llog_write(env, llh, &lcr->lcr_hdr, LLOG_NEXT_IDX);
1424 lustre_cfg_rec_free(lcr);
1428 static inline int record_mdc_add(const struct lu_env *env,
1429 struct llog_handle *llh,
1430 char *logname, char *mdcuuid,
1431 char *mdtuuid, char *index,
1434 return record_base(env,llh,logname,0,LCFG_ADD_MDC,
1435 mdtuuid,index,gen,mdcuuid);
1438 static inline int record_lov_add(const struct lu_env *env,
1439 struct llog_handle *llh,
1440 char *lov_name, char *ost_uuid,
1441 char *index, char *gen)
1443 return record_base(env, llh, lov_name, 0, LCFG_LOV_ADD_OBD,
1444 ost_uuid, index, gen, NULL);
1447 static inline int record_mount_opt(const struct lu_env *env,
1448 struct llog_handle *llh,
1449 char *profile, char *lov_name,
1452 return record_base(env, llh, NULL, 0, LCFG_MOUNTOPT,
1453 profile, lov_name, mdc_name, NULL);
1456 static int record_marker(const struct lu_env *env,
1457 struct llog_handle *llh,
1458 struct fs_db *fsdb, __u32 flags,
1459 char *tgtname, char *comment)
1461 struct mgs_thread_info *mgi = mgs_env_info(env);
1462 struct llog_cfg_rec *lcr;
1466 if (flags & CM_START)
1468 mgi->mgi_marker.cm_step = fsdb->fsdb_gen;
1469 mgi->mgi_marker.cm_flags = flags;
1470 mgi->mgi_marker.cm_vers = LUSTRE_VERSION_CODE;
1471 cplen = strlcpy(mgi->mgi_marker.cm_tgtname, tgtname,
1472 sizeof(mgi->mgi_marker.cm_tgtname));
1473 if (cplen >= sizeof(mgi->mgi_marker.cm_tgtname))
1475 cplen = strlcpy(mgi->mgi_marker.cm_comment, comment,
1476 sizeof(mgi->mgi_marker.cm_comment));
1477 if (cplen >= sizeof(mgi->mgi_marker.cm_comment))
1479 mgi->mgi_marker.cm_createtime = cfs_time_current_sec();
1480 mgi->mgi_marker.cm_canceltime = 0;
1481 lustre_cfg_bufs_reset(&mgi->mgi_bufs, NULL);
1482 lustre_cfg_bufs_set(&mgi->mgi_bufs, 1, &mgi->mgi_marker,
1483 sizeof(mgi->mgi_marker));
1484 lcr = lustre_cfg_rec_new(LCFG_MARKER, &mgi->mgi_bufs);
1488 rc = llog_write(env, llh, &lcr->lcr_hdr, LLOG_NEXT_IDX);
1489 lustre_cfg_rec_free(lcr);
1493 static int record_start_log(const struct lu_env *env, struct mgs_device *mgs,
1494 struct llog_handle **llh, char *name)
1496 static struct obd_uuid cfg_uuid = { .uuid = "config_uuid" };
1497 struct llog_ctxt *ctxt;
1502 GOTO(out, rc = -EBUSY);
1504 ctxt = llog_get_context(mgs->mgs_obd, LLOG_CONFIG_ORIG_CTXT);
1506 GOTO(out, rc = -ENODEV);
1507 LASSERT(ctxt->loc_obd == mgs->mgs_obd);
1509 rc = llog_open_create(env, ctxt, llh, NULL, name);
1512 rc = llog_init_handle(env, *llh, LLOG_F_IS_PLAIN, &cfg_uuid);
1514 llog_close(env, *llh);
1516 llog_ctxt_put(ctxt);
1519 CERROR("%s: can't start log %s: rc = %d\n",
1520 mgs->mgs_obd->obd_name, name, rc);
1526 static int record_end_log(const struct lu_env *env, struct llog_handle **llh)
1530 rc = llog_close(env, *llh);
1536 /******************** config "macros" *********************/
1538 /* write an lcfg directly into a log (with markers) */
1539 static int mgs_write_log_direct(const struct lu_env *env,
1540 struct mgs_device *mgs, struct fs_db *fsdb,
1541 char *logname, struct llog_cfg_rec *lcr,
1542 char *devname, char *comment)
1544 struct llog_handle *llh = NULL;
1549 rc = record_start_log(env, mgs, &llh, logname);
1553 /* FIXME These should be a single journal transaction */
1554 rc = record_marker(env, llh, fsdb, CM_START, devname, comment);
1557 rc = llog_write(env, llh, &lcr->lcr_hdr, LLOG_NEXT_IDX);
1560 rc = record_marker(env, llh, fsdb, CM_END, devname, comment);
1564 record_end_log(env, &llh);
1568 /* write the lcfg in all logs for the given fs */
1569 static int mgs_write_log_direct_all(const struct lu_env *env,
1570 struct mgs_device *mgs,
1572 struct mgs_target_info *mti,
1573 struct llog_cfg_rec *lcr, char *devname,
1574 char *comment, int server_only)
1576 struct list_head log_list;
1577 struct mgs_direntry *dirent, *n;
1578 char *fsname = mti->mti_fsname;
1579 int rc = 0, len = strlen(fsname);
1582 /* Find all the logs in the CONFIGS directory */
1583 rc = class_dentry_readdir(env, mgs, &log_list);
1587 /* Could use fsdb index maps instead of directory listing */
1588 list_for_each_entry_safe(dirent, n, &log_list, mde_list) {
1589 list_del_init(&dirent->mde_list);
1590 /* don't write to sptlrpc rule log */
1591 if (strstr(dirent->mde_name, "-sptlrpc") != NULL)
1594 /* caller wants write server logs only */
1595 if (server_only && strstr(dirent->mde_name, "-client") != NULL)
1598 if (strlen(dirent->mde_name) <= len ||
1599 strncmp(fsname, dirent->mde_name, len) != 0 ||
1600 dirent->mde_name[len] != '-')
1603 CDEBUG(D_MGS, "Changing log %s\n", dirent->mde_name);
1604 /* Erase any old settings of this same parameter */
1605 rc = mgs_modify(env, mgs, fsdb, mti, dirent->mde_name,
1606 devname, comment, CM_SKIP);
1608 CERROR("%s: Can't modify llog %s: rc = %d\n",
1609 mgs->mgs_obd->obd_name, dirent->mde_name, rc);
1612 /* Write the new one */
1613 rc = mgs_write_log_direct(env, mgs, fsdb, dirent->mde_name,
1614 lcr, devname, comment);
1616 CERROR("%s: writing log %s: rc = %d\n",
1617 mgs->mgs_obd->obd_name, dirent->mde_name, rc);
1619 mgs_direntry_free(dirent);
1625 static int mgs_write_log_osp_to_mdt(const struct lu_env *env,
1626 struct mgs_device *mgs,
1628 struct mgs_target_info *mti,
1629 int index, char *logname);
1630 static int mgs_write_log_osc_to_lov(const struct lu_env *env,
1631 struct mgs_device *mgs,
1633 struct mgs_target_info *mti,
1634 char *logname, char *suffix, char *lovname,
1635 enum lustre_sec_part sec_part, int flags);
1636 static int name_create_mdt_and_lov(char **logname, char **lovname,
1637 struct fs_db *fsdb, int i);
1639 static int add_param(char *params, char *key, char *val)
1641 char *start = params + strlen(params);
1642 char *end = params + sizeof(((struct mgs_target_info *)0)->mti_params);
1646 keylen = strlen(key);
1647 if (start + 1 + keylen + strlen(val) >= end) {
1648 CERROR("params are too long: %s %s%s\n",
1649 params, key != NULL ? key : "", val);
1653 sprintf(start, " %s%s", key != NULL ? key : "", val);
1658 * Walk through client config log record and convert the related records
1661 static int mgs_steal_client_llog_handler(const struct lu_env *env,
1662 struct llog_handle *llh,
1663 struct llog_rec_hdr *rec, void *data)
1665 struct mgs_device *mgs;
1666 struct obd_device *obd;
1667 struct mgs_target_info *mti, *tmti;
1669 int cfg_len = rec->lrh_len;
1670 char *cfg_buf = (char*) (rec + 1);
1671 struct lustre_cfg *lcfg;
1673 struct llog_handle *mdt_llh = NULL;
1674 static int got_an_osc_or_mdc = 0;
1675 /* 0: not found any osc/mdc;
1679 static int last_step = -1;
1684 mti = ((struct temp_comp*)data)->comp_mti;
1685 tmti = ((struct temp_comp*)data)->comp_tmti;
1686 fsdb = ((struct temp_comp*)data)->comp_fsdb;
1687 obd = ((struct temp_comp *)data)->comp_obd;
1688 mgs = lu2mgs_dev(obd->obd_lu_dev);
1691 if (rec->lrh_type != OBD_CFG_REC) {
1692 CERROR("unhandled lrh_type: %#x\n", rec->lrh_type);
1696 rc = lustre_cfg_sanity_check(cfg_buf, cfg_len);
1698 CERROR("Insane cfg\n");
1702 lcfg = (struct lustre_cfg *)cfg_buf;
1704 if (lcfg->lcfg_command == LCFG_MARKER) {
1705 struct cfg_marker *marker;
1706 marker = lustre_cfg_buf(lcfg, 1);
1707 if (!strncmp(marker->cm_comment, "add osc", 7) &&
1708 (marker->cm_flags & CM_START) &&
1709 !(marker->cm_flags & CM_SKIP)) {
1710 got_an_osc_or_mdc = 1;
1711 cplen = strlcpy(tmti->mti_svname, marker->cm_tgtname,
1712 sizeof(tmti->mti_svname));
1713 if (cplen >= sizeof(tmti->mti_svname))
1715 rc = record_start_log(env, mgs, &mdt_llh,
1719 rc = record_marker(env, mdt_llh, fsdb, CM_START,
1720 mti->mti_svname, "add osc(copied)");
1721 record_end_log(env, &mdt_llh);
1722 last_step = marker->cm_step;
1725 if (!strncmp(marker->cm_comment, "add osc", 7) &&
1726 (marker->cm_flags & CM_END) &&
1727 !(marker->cm_flags & CM_SKIP)) {
1728 LASSERT(last_step == marker->cm_step);
1730 got_an_osc_or_mdc = 0;
1731 memset(tmti, 0, sizeof(*tmti));
1732 rc = record_start_log(env, mgs, &mdt_llh,
1736 rc = record_marker(env, mdt_llh, fsdb, CM_END,
1737 mti->mti_svname, "add osc(copied)");
1738 record_end_log(env, &mdt_llh);
1741 if (!strncmp(marker->cm_comment, "add mdc", 7) &&
1742 (marker->cm_flags & CM_START) &&
1743 !(marker->cm_flags & CM_SKIP)) {
1744 got_an_osc_or_mdc = 2;
1745 last_step = marker->cm_step;
1746 memcpy(tmti->mti_svname, marker->cm_tgtname,
1747 strlen(marker->cm_tgtname));
1751 if (!strncmp(marker->cm_comment, "add mdc", 7) &&
1752 (marker->cm_flags & CM_END) &&
1753 !(marker->cm_flags & CM_SKIP)) {
1754 LASSERT(last_step == marker->cm_step);
1756 got_an_osc_or_mdc = 0;
1757 memset(tmti, 0, sizeof(*tmti));
1762 if (got_an_osc_or_mdc == 0 || last_step < 0)
1765 if (lcfg->lcfg_command == LCFG_ADD_UUID) {
1766 __u64 nodenid = lcfg->lcfg_nid;
1768 if (strlen(tmti->mti_uuid) == 0) {
1769 /* target uuid not set, this config record is before
1770 * LCFG_SETUP, this nid is one of target node nid.
1772 tmti->mti_nids[tmti->mti_nid_count] = nodenid;
1773 tmti->mti_nid_count++;
1775 char nidstr[LNET_NIDSTR_SIZE];
1777 /* failover node nid */
1778 libcfs_nid2str_r(nodenid, nidstr, sizeof(nidstr));
1779 rc = add_param(tmti->mti_params, PARAM_FAILNODE,
1786 if (lcfg->lcfg_command == LCFG_SETUP) {
1789 target = lustre_cfg_string(lcfg, 1);
1790 memcpy(tmti->mti_uuid, target, strlen(target));
1794 /* ignore client side sptlrpc_conf_log */
1795 if (lcfg->lcfg_command == LCFG_SPTLRPC_CONF)
1798 if (lcfg->lcfg_command == LCFG_ADD_MDC) {
1801 if (sscanf(lustre_cfg_buf(lcfg, 2), "%d", &index) != 1)
1804 memcpy(tmti->mti_fsname, mti->mti_fsname,
1805 strlen(mti->mti_fsname));
1806 tmti->mti_stripe_index = index;
1808 rc = mgs_write_log_osp_to_mdt(env, mgs, fsdb, tmti,
1809 mti->mti_stripe_index,
1811 memset(tmti, 0, sizeof(*tmti));
1815 if (lcfg->lcfg_command == LCFG_LOV_ADD_OBD) {
1818 char *logname, *lovname;
1820 rc = name_create_mdt_and_lov(&logname, &lovname, fsdb,
1821 mti->mti_stripe_index);
1824 sprintf(mdt_index, "-MDT%04x", mti->mti_stripe_index);
1826 if (sscanf(lustre_cfg_buf(lcfg, 2), "%d", &index) != 1) {
1827 name_destroy(&logname);
1828 name_destroy(&lovname);
1832 tmti->mti_stripe_index = index;
1833 rc = mgs_write_log_osc_to_lov(env, mgs, fsdb, tmti, logname,
1836 name_destroy(&logname);
1837 name_destroy(&lovname);
1843 /* fsdb->fsdb_mutex is already held in mgs_write_log_target*/
1844 /* stealed from mgs_get_fsdb_from_llog*/
1845 static int mgs_steal_llog_for_mdt_from_client(const struct lu_env *env,
1846 struct mgs_device *mgs,
1848 struct temp_comp* comp)
1850 struct llog_handle *loghandle;
1851 struct mgs_target_info *tmti;
1852 struct llog_ctxt *ctxt;
1857 ctxt = llog_get_context(mgs->mgs_obd, LLOG_CONFIG_ORIG_CTXT);
1858 LASSERT(ctxt != NULL);
1860 OBD_ALLOC_PTR(tmti);
1862 GOTO(out_ctxt, rc = -ENOMEM);
1864 comp->comp_tmti = tmti;
1865 comp->comp_obd = mgs->mgs_obd;
1867 rc = llog_open(env, ctxt, &loghandle, NULL, client_name,
1875 rc = llog_init_handle(env, loghandle, LLOG_F_IS_PLAIN, NULL);
1877 GOTO(out_close, rc);
1879 rc = llog_process_or_fork(env, loghandle, mgs_steal_client_llog_handler,
1880 (void *)comp, NULL, false);
1881 CDEBUG(D_MGS, "steal llog re = %d\n", rc);
1883 llog_close(env, loghandle);
1887 llog_ctxt_put(ctxt);
1891 /* lmv is the second thing for client logs */
1892 /* copied from mgs_write_log_lov. Please refer to that. */
1893 static int mgs_write_log_lmv(const struct lu_env *env,
1894 struct mgs_device *mgs,
1896 struct mgs_target_info *mti,
1897 char *logname, char *lmvname)
1899 struct llog_handle *llh = NULL;
1900 struct lmv_desc *lmvdesc;
1905 CDEBUG(D_MGS, "Writing lmv(%s) log for %s\n", lmvname,logname);
1907 OBD_ALLOC_PTR(lmvdesc);
1908 if (lmvdesc == NULL)
1910 lmvdesc->ld_active_tgt_count = 0;
1911 lmvdesc->ld_tgt_count = 0;
1912 sprintf((char*)lmvdesc->ld_uuid.uuid, "%s_UUID", lmvname);
1913 uuid = (char *)lmvdesc->ld_uuid.uuid;
1915 rc = record_start_log(env, mgs, &llh, logname);
1918 rc = record_marker(env, llh, fsdb, CM_START, lmvname, "lmv setup");
1921 rc = record_attach(env, llh, lmvname, "lmv", uuid);
1924 rc = record_lmv_setup(env, llh, lmvname, lmvdesc);
1927 rc = record_marker(env, llh, fsdb, CM_END, lmvname, "lmv setup");
1931 record_end_log(env, &llh);
1933 OBD_FREE_PTR(lmvdesc);
1937 /* lov is the first thing in the mdt and client logs */
1938 static int mgs_write_log_lov(const struct lu_env *env, struct mgs_device *mgs,
1939 struct fs_db *fsdb, struct mgs_target_info *mti,
1940 char *logname, char *lovname)
1942 struct llog_handle *llh = NULL;
1943 struct lov_desc *lovdesc;
1948 CDEBUG(D_MGS, "Writing lov(%s) log for %s\n", lovname, logname);
1951 #01 L attach 0:lov_mdsA 1:lov 2:71ccb_lov_mdsA_19f961a9e1
1952 #02 L lov_setup 0:lov_mdsA 1:(struct lov_desc)
1953 uuid=lov1_UUID, stripe count=1, size=1048576, offset=0, pattern=0
1956 /* FIXME just make lov_setup accept empty desc (put uuid in buf 2) */
1957 OBD_ALLOC_PTR(lovdesc);
1958 if (lovdesc == NULL)
1960 lovdesc->ld_magic = LOV_DESC_MAGIC;
1961 lovdesc->ld_tgt_count = 0;
1962 /* Defaults. Can be changed later by lcfg config_param */
1963 lovdesc->ld_default_stripe_count = 1;
1964 lovdesc->ld_pattern = LOV_PATTERN_RAID0;
1965 lovdesc->ld_default_stripe_size = LOV_DESC_STRIPE_SIZE_DEFAULT;
1966 lovdesc->ld_default_stripe_offset = -1;
1967 lovdesc->ld_qos_maxage = LOV_DESC_QOS_MAXAGE_DEFAULT;
1968 sprintf((char*)lovdesc->ld_uuid.uuid, "%s_UUID", lovname);
1969 /* can these be the same? */
1970 uuid = (char *)lovdesc->ld_uuid.uuid;
1972 /* This should always be the first entry in a log.
1973 rc = mgs_clear_log(obd, logname); */
1974 rc = record_start_log(env, mgs, &llh, logname);
1977 /* FIXME these should be a single journal transaction */
1978 rc = record_marker(env, llh, fsdb, CM_START, lovname, "lov setup");
1981 rc = record_attach(env, llh, lovname, "lov", uuid);
1984 rc = record_lov_setup(env, llh, lovname, lovdesc);
1987 rc = record_marker(env, llh, fsdb, CM_END, lovname, "lov setup");
1992 record_end_log(env, &llh);
1994 OBD_FREE_PTR(lovdesc);
1998 /* add failnids to open log */
1999 static int mgs_write_log_failnids(const struct lu_env *env,
2000 struct mgs_target_info *mti,
2001 struct llog_handle *llh,
2004 char *failnodeuuid = NULL;
2005 char *ptr = mti->mti_params;
2010 #03 L add_uuid nid=uml1@tcp(0x20000c0a80201) nal=90 0: 1:uml1_UUID
2011 #04 L add_uuid nid=1@elan(0x1000000000001) nal=90 0: 1:uml1_UUID
2012 #05 L setup 0:OSC_uml1_ost1_mdsA 1:ost1_UUID 2:uml1_UUID
2013 #06 L add_uuid nid=uml2@tcp(0x20000c0a80202) nal=90 0: 1:uml2_UUID
2014 #0x L add_uuid nid=2@elan(0x1000000000002) nal=90 0: 1:uml2_UUID
2015 #07 L add_conn 0:OSC_uml1_ost1_mdsA 1:uml2_UUID
2019 * Pull failnid info out of params string, which may contain something
2020 * like "<nid1>,<nid2>:<nid3>,<nid4>". class_parse_nid() does not
2021 * complain about abnormal inputs like ",:<nid1>", "<nid1>:,<nid2>",
2022 * etc. However, convert_hostnames() should have caught those.
2024 while (class_find_param(ptr, PARAM_FAILNODE, &ptr) == 0) {
2025 while (class_parse_nid(ptr, &nid, &ptr) == 0) {
2026 char nidstr[LNET_NIDSTR_SIZE];
2028 if (failnodeuuid == NULL) {
2029 /* We don't know the failover node name,
2030 * so just use the first nid as the uuid */
2031 libcfs_nid2str_r(nid, nidstr, sizeof(nidstr));
2032 rc = name_create(&failnodeuuid, nidstr, "");
2036 CDEBUG(D_MGS, "add nid %s for failover uuid %s, "
2038 libcfs_nid2str_r(nid, nidstr, sizeof(nidstr)),
2039 failnodeuuid, cliname);
2040 rc = record_add_uuid(env, llh, nid, failnodeuuid);
2042 * If *ptr is ':', we have added all NIDs for
2046 rc = record_add_conn(env, llh, cliname,
2048 name_destroy(&failnodeuuid);
2049 failnodeuuid = NULL;
2053 rc = record_add_conn(env, llh, cliname, failnodeuuid);
2054 name_destroy(&failnodeuuid);
2055 failnodeuuid = NULL;
2062 static int mgs_write_log_mdc_to_lmv(const struct lu_env *env,
2063 struct mgs_device *mgs,
2065 struct mgs_target_info *mti,
2066 char *logname, char *lmvname)
2068 struct llog_handle *llh = NULL;
2069 char *mdcname = NULL;
2070 char *nodeuuid = NULL;
2071 char *mdcuuid = NULL;
2072 char *lmvuuid = NULL;
2074 char nidstr[LNET_NIDSTR_SIZE];
2078 if (mgs_log_is_empty(env, mgs, logname)) {
2079 CERROR("log is empty! Logical error\n");
2083 CDEBUG(D_MGS, "adding mdc for %s to log %s:lmv(%s)\n",
2084 mti->mti_svname, logname, lmvname);
2086 libcfs_nid2str_r(mti->mti_nids[0], nidstr, sizeof(nidstr));
2087 rc = name_create(&nodeuuid, nidstr, "");
2090 rc = name_create(&mdcname, mti->mti_svname, "-mdc");
2093 rc = name_create(&mdcuuid, mdcname, "_UUID");
2096 rc = name_create(&lmvuuid, lmvname, "_UUID");
2100 rc = record_start_log(env, mgs, &llh, logname);
2103 rc = record_marker(env, llh, fsdb, CM_START, mti->mti_svname,
2107 for (i = 0; i < mti->mti_nid_count; i++) {
2108 CDEBUG(D_MGS, "add nid %s for mdt\n",
2109 libcfs_nid2str_r(mti->mti_nids[i],
2110 nidstr, sizeof(nidstr)));
2112 rc = record_add_uuid(env, llh, mti->mti_nids[i], nodeuuid);
2117 rc = record_attach(env, llh, mdcname, LUSTRE_MDC_NAME, lmvuuid);
2120 rc = record_setup(env, llh, mdcname, mti->mti_uuid, nodeuuid,
2124 rc = mgs_write_log_failnids(env, mti, llh, mdcname);
2127 snprintf(index, sizeof(index), "%d", mti->mti_stripe_index);
2128 rc = record_mdc_add(env, llh, lmvname, mdcuuid, mti->mti_uuid,
2132 rc = record_marker(env, llh, fsdb, CM_END, mti->mti_svname,
2137 record_end_log(env, &llh);
2139 name_destroy(&lmvuuid);
2140 name_destroy(&mdcuuid);
2141 name_destroy(&mdcname);
2142 name_destroy(&nodeuuid);
2146 static inline int name_create_lov(char **lovname, char *mdtname,
2147 struct fs_db *fsdb, int index)
2150 if (index == 0 && test_bit(FSDB_OSCNAME18, &fsdb->fsdb_flags))
2151 return name_create(lovname, fsdb->fsdb_name, "-mdtlov");
2153 return name_create(lovname, mdtname, "-mdtlov");
2156 static int name_create_mdt_and_lov(char **logname, char **lovname,
2157 struct fs_db *fsdb, int i)
2161 rc = name_create_mdt(logname, fsdb->fsdb_name, i);
2165 if (i == 0 && test_bit(FSDB_OSCNAME18, &fsdb->fsdb_flags))
2166 rc = name_create(lovname, fsdb->fsdb_name, "-mdtlov");
2168 rc = name_create(lovname, *logname, "-mdtlov");
2170 name_destroy(logname);
2176 static inline int name_create_mdt_osc(char **oscname, char *ostname,
2177 struct fs_db *fsdb, int i)
2181 if (i == 0 && test_bit(FSDB_OSCNAME18, &fsdb->fsdb_flags))
2182 sprintf(suffix, "-osc");
2184 sprintf(suffix, "-osc-MDT%04x", i);
2185 return name_create(oscname, ostname, suffix);
2188 /* add new mdc to already existent MDS */
2189 static int mgs_write_log_osp_to_mdt(const struct lu_env *env,
2190 struct mgs_device *mgs,
2192 struct mgs_target_info *mti,
2193 int mdt_index, char *logname)
2195 struct llog_handle *llh = NULL;
2196 char *nodeuuid = NULL;
2197 char *ospname = NULL;
2198 char *lovuuid = NULL;
2199 char *mdtuuid = NULL;
2200 char *svname = NULL;
2201 char *mdtname = NULL;
2202 char *lovname = NULL;
2204 char nidstr[LNET_NIDSTR_SIZE];
2208 if (mgs_log_is_empty(env, mgs, mti->mti_svname)) {
2209 CERROR("log is empty! Logical error\n");
2213 CDEBUG(D_MGS, "adding osp index %d to %s\n", mti->mti_stripe_index,
2216 rc = name_create_mdt(&mdtname, fsdb->fsdb_name, mti->mti_stripe_index);
2220 libcfs_nid2str_r(mti->mti_nids[0], nidstr, sizeof(nidstr));
2221 rc = name_create(&nodeuuid, nidstr, "");
2223 GOTO(out_destory, rc);
2225 rc = name_create(&svname, mdtname, "-osp");
2227 GOTO(out_destory, rc);
2229 sprintf(index_str, "-MDT%04x", mdt_index);
2230 rc = name_create(&ospname, svname, index_str);
2232 GOTO(out_destory, rc);
2234 rc = name_create_lov(&lovname, logname, fsdb, mdt_index);
2236 GOTO(out_destory, rc);
2238 rc = name_create(&lovuuid, lovname, "_UUID");
2240 GOTO(out_destory, rc);
2242 rc = name_create(&mdtuuid, mdtname, "_UUID");
2244 GOTO(out_destory, rc);
2246 rc = record_start_log(env, mgs, &llh, logname);
2248 GOTO(out_destory, rc);
2250 rc = record_marker(env, llh, fsdb, CM_START, mti->mti_svname,
2253 GOTO(out_destory, rc);
2255 for (i = 0; i < mti->mti_nid_count; i++) {
2256 CDEBUG(D_MGS, "add nid %s for mdt\n",
2257 libcfs_nid2str_r(mti->mti_nids[i],
2258 nidstr, sizeof(nidstr)));
2259 rc = record_add_uuid(env, llh, mti->mti_nids[i], nodeuuid);
2264 rc = record_attach(env, llh, ospname, LUSTRE_OSP_NAME, lovuuid);
2268 rc = record_setup(env, llh, ospname, mti->mti_uuid, nodeuuid,
2273 rc = mgs_write_log_failnids(env, mti, llh, ospname);
2277 /* Add mdc(osp) to lod */
2278 snprintf(index_str, sizeof(index_str), "%d", mti->mti_stripe_index);
2279 rc = record_base(env, llh, lovname, 0, LCFG_ADD_MDC, mti->mti_uuid,
2280 index_str, "1", NULL);
2284 rc = record_marker(env, llh, fsdb, CM_END, mti->mti_svname, "add osp");
2289 record_end_log(env, &llh);
2292 name_destroy(&mdtuuid);
2293 name_destroy(&lovuuid);
2294 name_destroy(&lovname);
2295 name_destroy(&ospname);
2296 name_destroy(&svname);
2297 name_destroy(&nodeuuid);
2298 name_destroy(&mdtname);
2302 static int mgs_write_log_mdt0(const struct lu_env *env,
2303 struct mgs_device *mgs,
2305 struct mgs_target_info *mti)
2307 char *log = mti->mti_svname;
2308 struct llog_handle *llh = NULL;
2309 char *uuid, *lovname;
2311 char *ptr = mti->mti_params;
2312 int rc = 0, failout = 0;
2315 OBD_ALLOC(uuid, sizeof(struct obd_uuid));
2319 if (class_find_param(ptr, PARAM_FAILMODE, &ptr) == 0)
2320 failout = (strncmp(ptr, "failout", 7) == 0);
2322 rc = name_create(&lovname, log, "-mdtlov");
2325 if (mgs_log_is_empty(env, mgs, log)) {
2326 rc = mgs_write_log_lov(env, mgs, fsdb, mti, log, lovname);
2331 sprintf(mdt_index, "%d", mti->mti_stripe_index);
2333 rc = record_start_log(env, mgs, &llh, log);
2337 /* add MDT itself */
2339 /* FIXME this whole fn should be a single journal transaction */
2340 sprintf(uuid, "%s_UUID", log);
2341 rc = record_marker(env, llh, fsdb, CM_START, log, "add mdt");
2344 rc = record_attach(env, llh, log, LUSTRE_MDT_NAME, uuid);
2347 rc = record_mount_opt(env, llh, log, lovname, NULL);
2350 rc = record_setup(env, llh, log, uuid, mdt_index, lovname,
2351 failout ? "n" : "f");
2354 rc = record_marker(env, llh, fsdb, CM_END, log, "add mdt");
2358 record_end_log(env, &llh);
2360 name_destroy(&lovname);
2362 OBD_FREE(uuid, sizeof(struct obd_uuid));
2366 /* envelope method for all layers log */
2367 static int mgs_write_log_mdt(const struct lu_env *env,
2368 struct mgs_device *mgs,
2370 struct mgs_target_info *mti)
2372 struct mgs_thread_info *mgi = mgs_env_info(env);
2373 struct llog_handle *llh = NULL;
2378 CDEBUG(D_MGS, "writing new mdt %s\n", mti->mti_svname);
2380 if (mti->mti_uuid[0] == '\0') {
2381 /* Make up our own uuid */
2382 snprintf(mti->mti_uuid, sizeof(mti->mti_uuid),
2383 "%s_UUID", mti->mti_svname);
2387 rc = mgs_write_log_mdt0(env, mgs, fsdb, mti);
2390 /* Append the mdt info to the client log */
2391 rc = name_create(&cliname, mti->mti_fsname, "-client");
2395 if (mgs_log_is_empty(env, mgs, cliname)) {
2396 /* Start client log */
2397 rc = mgs_write_log_lov(env, mgs, fsdb, mti, cliname,
2401 rc = mgs_write_log_lmv(env, mgs, fsdb, mti, cliname,
2408 #09 L add_uuid nid=uml1@tcp(0x20000c0a80201) 0: 1:uml1_UUID
2409 #10 L attach 0:MDC_uml1_mdsA_MNT_client 1:mdc 2:1d834_MNT_client_03f
2410 #11 L setup 0:MDC_uml1_mdsA_MNT_client 1:mdsA_UUID 2:uml1_UUID
2411 #12 L add_uuid nid=uml2@tcp(0x20000c0a80202) 0: 1:uml2_UUID
2412 #13 L add_conn 0:MDC_uml1_mdsA_MNT_client 1:uml2_UUID
2413 #14 L mount_option 0: 1:client 2:lov1 3:MDC_uml1_mdsA_MNT_client
2416 /* copy client info about lov/lmv */
2417 mgi->mgi_comp.comp_mti = mti;
2418 mgi->mgi_comp.comp_fsdb = fsdb;
2420 rc = mgs_steal_llog_for_mdt_from_client(env, mgs, cliname,
2424 rc = mgs_write_log_mdc_to_lmv(env, mgs, fsdb, mti, cliname,
2430 rc = record_start_log(env, mgs, &llh, cliname);
2434 rc = record_marker(env, llh, fsdb, CM_START, cliname,
2438 rc = record_mount_opt(env, llh, cliname, fsdb->fsdb_clilov,
2442 rc = record_marker(env, llh, fsdb, CM_END, cliname,
2448 /* for_all_existing_mdt except current one */
2449 for (i = 0; i < INDEX_MAP_SIZE * 8; i++) {
2450 if (i != mti->mti_stripe_index &&
2451 test_bit(i, fsdb->fsdb_mdt_index_map)) {
2454 rc = name_create_mdt(&logname, fsdb->fsdb_name, i);
2458 /* NB: If the log for the MDT is empty, it means
2459 * the MDT is only added to the index
2460 * map, and not being process yet, i.e. this
2461 * is an unregistered MDT, see mgs_write_log_target().
2462 * so we should skip it. Otherwise
2464 * 1. MGS get register request for MDT1 and MDT2.
2466 * 2. Then both MDT1 and MDT2 are added into
2467 * fsdb_mdt_index_map. (see mgs_set_index()).
2469 * 3. Then MDT1 get the lock of fsdb_mutex, then
2470 * generate the config log, here, it will regard MDT2
2471 * as an existent MDT, and generate "add osp" for
2472 * lustre-MDT0001-osp-MDT0002. Note: at the moment
2473 * MDT0002 config log is still empty, so it will
2474 * add "add osp" even before "lov setup", which
2475 * will definitly cause trouble.
2477 * 4. MDT1 registeration finished, fsdb_mutex is
2478 * released, then MDT2 get in, then in above
2479 * mgs_steal_llog_for_mdt_from_client(), it will
2480 * add another osp log for lustre-MDT0001-osp-MDT0002,
2481 * which will cause another trouble.*/
2482 if (!mgs_log_is_empty(env, mgs, logname))
2483 rc = mgs_write_log_osp_to_mdt(env, mgs, fsdb,
2486 name_destroy(&logname);
2492 record_end_log(env, &llh);
2494 name_destroy(&cliname);
2498 /* Add the ost info to the client/mdt lov */
2499 static int mgs_write_log_osc_to_lov(const struct lu_env *env,
2500 struct mgs_device *mgs, struct fs_db *fsdb,
2501 struct mgs_target_info *mti,
2502 char *logname, char *suffix, char *lovname,
2503 enum lustre_sec_part sec_part, int flags)
2505 struct llog_handle *llh = NULL;
2506 char *nodeuuid = NULL;
2507 char *oscname = NULL;
2508 char *oscuuid = NULL;
2509 char *lovuuid = NULL;
2510 char *svname = NULL;
2512 char nidstr[LNET_NIDSTR_SIZE];
2516 CDEBUG(D_INFO, "adding osc for %s to log %s\n",
2517 mti->mti_svname, logname);
2519 if (mgs_log_is_empty(env, mgs, logname)) {
2520 CERROR("log is empty! Logical error\n");
2524 libcfs_nid2str_r(mti->mti_nids[0], nidstr, sizeof(nidstr));
2525 rc = name_create(&nodeuuid, nidstr, "");
2528 rc = name_create(&svname, mti->mti_svname, "-osc");
2532 /* for the system upgraded from old 1.8, keep using the old osc naming
2533 * style for mdt, see name_create_mdt_osc(). LU-1257 */
2534 if (test_bit(FSDB_OSCNAME18, &fsdb->fsdb_flags))
2535 rc = name_create(&oscname, svname, "");
2537 rc = name_create(&oscname, svname, suffix);
2541 rc = name_create(&oscuuid, oscname, "_UUID");
2544 rc = name_create(&lovuuid, lovname, "_UUID");
2550 #03 L add_uuid nid=uml1@tcp(0x20000c0a80201) 0: 1:uml1_UUID
2552 #04 L add_uuid nid=1@elan(0x1000000000001) nal=90 0: 1:uml1_UUID
2553 #04 L attach 0:OSC_uml1_ost1_MNT_client 1:osc 2:89070_lov1_a41dff51a
2554 #05 L setup 0:OSC_uml1_ost1_MNT_client 1:ost1_UUID 2:uml1_UUID
2556 #06 L add_uuid nid=uml2@tcp(0x20000c0a80202) 0: 1:uml2_UUID
2557 #07 L add_conn 0:OSC_uml1_ost1_MNT_client 1:uml2_UUID
2558 #08 L lov_modify_tgts add 0:lov1 1:ost1_UUID 2(index):0 3(gen):1
2561 rc = record_start_log(env, mgs, &llh, logname);
2565 /* FIXME these should be a single journal transaction */
2566 rc = record_marker(env, llh, fsdb, CM_START | flags, mti->mti_svname,
2571 /* NB: don't change record order, because upon MDT steal OSC config
2572 * from client, it treats all nids before LCFG_SETUP as target nids
2573 * (multiple interfaces), while nids after as failover node nids.
2574 * See mgs_steal_client_llog_handler() LCFG_ADD_UUID.
2576 for (i = 0; i < mti->mti_nid_count; i++) {
2577 CDEBUG(D_MGS, "add nid %s\n",
2578 libcfs_nid2str_r(mti->mti_nids[i],
2579 nidstr, sizeof(nidstr)));
2580 rc = record_add_uuid(env, llh, mti->mti_nids[i], nodeuuid);
2584 rc = record_attach(env, llh, oscname, LUSTRE_OSC_NAME, lovuuid);
2587 rc = record_setup(env, llh, oscname, mti->mti_uuid, nodeuuid,
2591 rc = mgs_write_log_failnids(env, mti, llh, oscname);
2595 snprintf(index, sizeof(index), "%d", mti->mti_stripe_index);
2597 rc = record_lov_add(env, llh, lovname, mti->mti_uuid, index, "1");
2600 rc = record_marker(env, llh, fsdb, CM_END | flags, mti->mti_svname,
2605 record_end_log(env, &llh);
2607 name_destroy(&lovuuid);
2608 name_destroy(&oscuuid);
2609 name_destroy(&oscname);
2610 name_destroy(&svname);
2611 name_destroy(&nodeuuid);
2615 static int mgs_write_log_ost(const struct lu_env *env,
2616 struct mgs_device *mgs, struct fs_db *fsdb,
2617 struct mgs_target_info *mti)
2619 struct llog_handle *llh = NULL;
2620 char *logname, *lovname;
2621 char *ptr = mti->mti_params;
2622 int rc, flags = 0, failout = 0, i;
2625 CDEBUG(D_MGS, "writing new ost %s\n", mti->mti_svname);
2627 /* The ost startup log */
2629 /* If the ost log already exists, that means that someone reformatted
2630 the ost and it called target_add again. */
2631 if (!mgs_log_is_empty(env, mgs, mti->mti_svname)) {
2632 LCONSOLE_ERROR_MSG(0x141, "The config log for %s already "
2633 "exists, yet the server claims it never "
2634 "registered. It may have been reformatted, "
2635 "or the index changed. writeconf the MDT to "
2636 "regenerate all logs.\n", mti->mti_svname);
2641 attach obdfilter ost1 ost1_UUID
2642 setup /dev/loop2 ldiskfs f|n errors=remount-ro,user_xattr
2644 if (class_find_param(ptr, PARAM_FAILMODE, &ptr) == 0)
2645 failout = (strncmp(ptr, "failout", 7) == 0);
2646 rc = record_start_log(env, mgs, &llh, mti->mti_svname);
2649 /* FIXME these should be a single journal transaction */
2650 rc = record_marker(env, llh, fsdb, CM_START, mti->mti_svname,"add ost");
2653 if (*mti->mti_uuid == '\0')
2654 snprintf(mti->mti_uuid, sizeof(mti->mti_uuid),
2655 "%s_UUID", mti->mti_svname);
2656 rc = record_attach(env, llh, mti->mti_svname,
2657 "obdfilter"/*LUSTRE_OST_NAME*/, mti->mti_uuid);
2660 rc = record_setup(env, llh, mti->mti_svname,
2661 "dev"/*ignored*/, "type"/*ignored*/,
2662 failout ? "n" : "f", NULL/*options*/);
2665 rc = record_marker(env, llh, fsdb, CM_END, mti->mti_svname, "add ost");
2669 record_end_log(env, &llh);
2672 /* We also have to update the other logs where this osc is part of
2675 if (test_bit(FSDB_OLDLOG14, &fsdb->fsdb_flags)) {
2676 /* If we're upgrading, the old mdt log already has our
2677 entry. Let's do a fake one for fun. */
2678 /* Note that we can't add any new failnids, since we don't
2679 know the old osc names. */
2680 flags = CM_SKIP | CM_UPGRADE146;
2682 } else if ((mti->mti_flags & LDD_F_UPDATE) != LDD_F_UPDATE) {
2683 /* If the update flag isn't set, don't update client/mdt
2686 LCONSOLE_WARN("Client log for %s was not updated; writeconf "
2687 "the MDT first to regenerate it.\n",
2691 /* Add ost to all MDT lov defs */
2692 for (i = 0; i < INDEX_MAP_SIZE * 8; i++){
2693 if (test_bit(i, fsdb->fsdb_mdt_index_map)) {
2696 rc = name_create_mdt_and_lov(&logname, &lovname, fsdb,
2700 sprintf(mdt_index, "-MDT%04x", i);
2701 rc = mgs_write_log_osc_to_lov(env, mgs, fsdb, mti,
2703 lovname, LUSTRE_SP_MDT,
2705 name_destroy(&logname);
2706 name_destroy(&lovname);
2712 /* Append ost info to the client log */
2713 rc = name_create(&logname, mti->mti_fsname, "-client");
2716 if (mgs_log_is_empty(env, mgs, logname)) {
2717 /* Start client log */
2718 rc = mgs_write_log_lov(env, mgs, fsdb, mti, logname,
2722 rc = mgs_write_log_lmv(env, mgs, fsdb, mti, logname,
2727 rc = mgs_write_log_osc_to_lov(env, mgs, fsdb, mti, logname, "",
2728 fsdb->fsdb_clilov, LUSTRE_SP_CLI, flags);
2730 name_destroy(&logname);
2734 static __inline__ int mgs_param_empty(char *ptr)
2738 if ((tmp = strchr(ptr, '=')) && (*(++tmp) == '\0'))
2743 static int mgs_write_log_failnid_internal(const struct lu_env *env,
2744 struct mgs_device *mgs,
2746 struct mgs_target_info *mti,
2747 char *logname, char *cliname)
2750 struct llog_handle *llh = NULL;
2752 if (mgs_param_empty(mti->mti_params)) {
2753 /* Remove _all_ failnids */
2754 rc = mgs_modify(env, mgs, fsdb, mti, logname,
2755 mti->mti_svname, "add failnid", CM_SKIP);
2756 return rc < 0 ? rc : 0;
2759 /* Otherwise failover nids are additive */
2760 rc = record_start_log(env, mgs, &llh, logname);
2763 /* FIXME this should be a single journal transaction */
2764 rc = record_marker(env, llh, fsdb, CM_START, mti->mti_svname,
2768 rc = mgs_write_log_failnids(env, mti, llh, cliname);
2771 rc = record_marker(env, llh, fsdb, CM_END,
2772 mti->mti_svname, "add failnid");
2774 record_end_log(env, &llh);
2779 /* Add additional failnids to an existing log.
2780 The mdc/osc must have been added to logs first */
2781 /* tcp nids must be in dotted-quad ascii -
2782 we can't resolve hostnames from the kernel. */
2783 static int mgs_write_log_add_failnid(const struct lu_env *env,
2784 struct mgs_device *mgs,
2786 struct mgs_target_info *mti)
2788 char *logname, *cliname;
2792 /* FIXME we currently can't erase the failnids
2793 * given when a target first registers, since they aren't part of
2794 * an "add uuid" stanza */
2796 /* Verify that we know about this target */
2797 if (mgs_log_is_empty(env, mgs, mti->mti_svname)) {
2798 LCONSOLE_ERROR_MSG(0x142, "The target %s has not registered "
2799 "yet. It must be started before failnids "
2800 "can be added.\n", mti->mti_svname);
2804 /* Create mdc/osc client name (e.g. lustre-OST0001-osc) */
2805 if (mti->mti_flags & LDD_F_SV_TYPE_MDT) {
2806 rc = name_create(&cliname, mti->mti_svname, "-mdc");
2807 } else if (mti->mti_flags & LDD_F_SV_TYPE_OST) {
2808 rc = name_create(&cliname, mti->mti_svname, "-osc");
2814 /* Add failover nids to the client log */
2815 rc = name_create(&logname, mti->mti_fsname, "-client");
2817 name_destroy(&cliname);
2820 rc = mgs_write_log_failnid_internal(env, mgs, fsdb,mti,logname,cliname);
2821 name_destroy(&logname);
2822 name_destroy(&cliname);
2826 if (mti->mti_flags & LDD_F_SV_TYPE_OST) {
2827 /* Add OST failover nids to the MDT logs as well */
2830 for (i = 0; i < INDEX_MAP_SIZE * 8; i++) {
2831 if (!test_bit(i, fsdb->fsdb_mdt_index_map))
2833 rc = name_create_mdt(&logname, mti->mti_fsname, i);
2836 rc = name_create_mdt_osc(&cliname, mti->mti_svname,
2839 name_destroy(&logname);
2842 rc = mgs_write_log_failnid_internal(env, mgs, fsdb,
2845 name_destroy(&cliname);
2846 name_destroy(&logname);
2855 static int mgs_wlp_lcfg(const struct lu_env *env,
2856 struct mgs_device *mgs, struct fs_db *fsdb,
2857 struct mgs_target_info *mti,
2858 char *logname, struct lustre_cfg_bufs *bufs,
2859 char *tgtname, char *ptr)
2861 char comment[MTI_NAME_MAXLEN];
2863 struct llog_cfg_rec *lcr;
2866 /* Erase any old settings of this same parameter */
2867 memcpy(comment, ptr, MTI_NAME_MAXLEN);
2868 comment[MTI_NAME_MAXLEN - 1] = 0;
2869 /* But don't try to match the value. */
2870 tmp = strchr(comment, '=');
2873 /* FIXME we should skip settings that are the same as old values */
2874 rc = mgs_modify(env, mgs, fsdb, mti, logname, tgtname, comment,CM_SKIP);
2877 del = mgs_param_empty(ptr);
2879 LCONSOLE_INFO("%s parameter %s.%s in log %s\n", del ? "Disabling" : rc ?
2880 "Setting" : "Modifying", tgtname, comment, logname);
2882 /* mgs_modify() will return 1 if nothing had to be done */
2888 lustre_cfg_bufs_reset(bufs, tgtname);
2889 lustre_cfg_bufs_set_string(bufs, 1, ptr);
2890 if (mti->mti_flags & LDD_F_PARAM2)
2891 lustre_cfg_bufs_set_string(bufs, 2, LCTL_UPCALL);
2893 lcr = lustre_cfg_rec_new((mti->mti_flags & LDD_F_PARAM2) ?
2894 LCFG_SET_PARAM : LCFG_PARAM, bufs);
2898 rc = mgs_write_log_direct(env, mgs, fsdb, logname, lcr, tgtname,
2900 lustre_cfg_rec_free(lcr);
2904 static int mgs_write_log_param2(const struct lu_env *env,
2905 struct mgs_device *mgs,
2907 struct mgs_target_info *mti, char *ptr)
2909 struct lustre_cfg_bufs bufs;
2913 CDEBUG(D_MGS, "next param '%s'\n", ptr);
2914 rc = mgs_wlp_lcfg(env, mgs, fsdb, mti, PARAMS_FILENAME, &bufs,
2915 mti->mti_svname, ptr);
2920 /* write global variable settings into log */
2921 static int mgs_write_log_sys(const struct lu_env *env,
2922 struct mgs_device *mgs, struct fs_db *fsdb,
2923 struct mgs_target_info *mti, char *sys, char *ptr)
2925 struct mgs_thread_info *mgi = mgs_env_info(env);
2926 struct lustre_cfg *lcfg;
2927 struct llog_cfg_rec *lcr;
2929 int rc, cmd, convert = 1;
2931 if (class_match_param(ptr, PARAM_TIMEOUT, &tmp) == 0) {
2932 cmd = LCFG_SET_TIMEOUT;
2933 } else if (class_match_param(ptr, PARAM_LDLM_TIMEOUT, &tmp) == 0) {
2934 cmd = LCFG_SET_LDLM_TIMEOUT;
2935 /* Check for known params here so we can return error to lctl */
2936 } else if ((class_match_param(ptr, PARAM_AT_MIN, &tmp) == 0) ||
2937 (class_match_param(ptr, PARAM_AT_MAX, &tmp) == 0) ||
2938 (class_match_param(ptr, PARAM_AT_EXTRA, &tmp) == 0) ||
2939 (class_match_param(ptr, PARAM_AT_EARLY_MARGIN, &tmp) == 0) ||
2940 (class_match_param(ptr, PARAM_AT_HISTORY, &tmp) == 0)) {
2942 } else if (class_match_param(ptr, PARAM_JOBID_VAR, &tmp) == 0) {
2943 convert = 0; /* Don't convert string value to integer */
2949 if (mgs_param_empty(ptr))
2950 CDEBUG(D_MGS, "global '%s' removed\n", sys);
2952 CDEBUG(D_MGS, "global '%s' val=%s\n", sys, tmp);
2954 lustre_cfg_bufs_reset(&mgi->mgi_bufs, NULL);
2955 lustre_cfg_bufs_set_string(&mgi->mgi_bufs, 1, sys);
2956 if (!convert && *tmp != '\0')
2957 lustre_cfg_bufs_set_string(&mgi->mgi_bufs, 2, tmp);
2958 lcr = lustre_cfg_rec_new(cmd, &mgi->mgi_bufs);
2962 lcfg = &lcr->lcr_cfg;
2963 lcfg->lcfg_num = convert ? simple_strtoul(tmp, NULL, 0) : 0;
2964 /* truncate the comment to the parameter name */
2968 /* modify all servers and clients */
2969 rc = mgs_write_log_direct_all(env, mgs, fsdb, mti,
2970 *tmp == '\0' ? NULL : lcr,
2971 mti->mti_fsname, sys, 0);
2972 if (rc == 0 && *tmp != '\0') {
2974 case LCFG_SET_TIMEOUT:
2975 if (!obd_timeout_set || lcfg->lcfg_num > obd_timeout)
2976 class_process_config(lcfg);
2978 case LCFG_SET_LDLM_TIMEOUT:
2979 if (!ldlm_timeout_set || lcfg->lcfg_num > ldlm_timeout)
2980 class_process_config(lcfg);
2987 lustre_cfg_rec_free(lcr);
2991 /* write quota settings into log */
2992 static int mgs_write_log_quota(const struct lu_env *env, struct mgs_device *mgs,
2993 struct fs_db *fsdb, struct mgs_target_info *mti,
2994 char *quota, char *ptr)
2996 struct mgs_thread_info *mgi = mgs_env_info(env);
2997 struct llog_cfg_rec *lcr;
3000 int rc, cmd = LCFG_PARAM;
3002 /* support only 'meta' and 'data' pools so far */
3003 if (class_match_param(ptr, QUOTA_METAPOOL_NAME, &tmp) != 0 &&
3004 class_match_param(ptr, QUOTA_DATAPOOL_NAME, &tmp) != 0) {
3005 CERROR("parameter quota.%s isn't supported (only quota.mdt "
3006 "& quota.ost are)\n", ptr);
3011 CDEBUG(D_MGS, "global '%s' removed\n", quota);
3013 CDEBUG(D_MGS, "global '%s'\n", quota);
3015 if (strchr(tmp, 'u') == NULL && strchr(tmp, 'g') == NULL &&
3016 strcmp(tmp, "none") != 0) {
3017 CERROR("enable option(%s) isn't supported\n", tmp);
3022 lustre_cfg_bufs_reset(&mgi->mgi_bufs, mti->mti_fsname);
3023 lustre_cfg_bufs_set_string(&mgi->mgi_bufs, 1, quota);
3024 lcr = lustre_cfg_rec_new(cmd, &mgi->mgi_bufs);
3028 /* truncate the comment to the parameter name */
3033 /* XXX we duplicated quota enable information in all server
3034 * config logs, it should be moved to a separate config
3035 * log once we cleanup the config log for global param. */
3036 /* modify all servers */
3037 rc = mgs_write_log_direct_all(env, mgs, fsdb, mti,
3038 *tmp == '\0' ? NULL : lcr,
3039 mti->mti_fsname, quota, 1);
3041 lustre_cfg_rec_free(lcr);
3042 return rc < 0 ? rc : 0;
3045 static int mgs_srpc_set_param_disk(const struct lu_env *env,
3046 struct mgs_device *mgs,
3048 struct mgs_target_info *mti,
3051 struct mgs_thread_info *mgi = mgs_env_info(env);
3052 struct llog_cfg_rec *lcr;
3053 struct llog_handle *llh = NULL;
3055 char *comment, *ptr;
3061 ptr = strchr(param, '=');
3062 LASSERT(ptr != NULL);
3065 OBD_ALLOC(comment, len + 1);
3066 if (comment == NULL)
3068 strncpy(comment, param, len);
3069 comment[len] = '\0';
3072 lustre_cfg_bufs_reset(&mgi->mgi_bufs, mti->mti_svname);
3073 lustre_cfg_bufs_set_string(&mgi->mgi_bufs, 1, param);
3074 lcr = lustre_cfg_rec_new(LCFG_SPTLRPC_CONF, &mgi->mgi_bufs);
3076 GOTO(out_comment, rc = -ENOMEM);
3078 /* construct log name */
3079 rc = name_create(&logname, mti->mti_fsname, "-sptlrpc");
3083 if (mgs_log_is_empty(env, mgs, logname)) {
3084 rc = record_start_log(env, mgs, &llh, logname);
3087 record_end_log(env, &llh);
3090 /* obsolete old one */
3091 rc = mgs_modify(env, mgs, fsdb, mti, logname, mti->mti_svname,
3095 /* write the new one */
3096 rc = mgs_write_log_direct(env, mgs, fsdb, logname, lcr,
3097 mti->mti_svname, comment);
3099 CERROR("%s: error writing log %s: rc = %d\n",
3100 mgs->mgs_obd->obd_name, logname, rc);
3102 name_destroy(&logname);
3104 lustre_cfg_rec_free(lcr);
3106 OBD_FREE(comment, len + 1);
3110 static int mgs_srpc_set_param_udesc_mem(struct fs_db *fsdb,
3115 /* disable the adjustable udesc parameter for now, i.e. use default
3116 * setting that client always ship udesc to MDT if possible. to enable
3117 * it simply remove the following line */
3120 ptr = strchr(param, '=');
3125 if (strcmp(param, PARAM_SRPC_UDESC))
3128 if (strcmp(ptr, "yes") == 0) {
3129 set_bit(FSDB_UDESC, &fsdb->fsdb_flags);
3130 CWARN("Enable user descriptor shipping from client to MDT\n");
3131 } else if (strcmp(ptr, "no") == 0) {
3132 clear_bit(FSDB_UDESC, &fsdb->fsdb_flags);
3133 CWARN("Disable user descriptor shipping from client to MDT\n");
3141 CERROR("Invalid param: %s\n", param);
3145 static int mgs_srpc_set_param_mem(struct fs_db *fsdb,
3149 struct sptlrpc_rule rule;
3150 struct sptlrpc_rule_set *rset;
3154 if (strncmp(param, PARAM_SRPC, sizeof(PARAM_SRPC) - 1) != 0) {
3155 CERROR("Invalid sptlrpc parameter: %s\n", param);
3159 if (strncmp(param, PARAM_SRPC_UDESC,
3160 sizeof(PARAM_SRPC_UDESC) - 1) == 0) {
3161 RETURN(mgs_srpc_set_param_udesc_mem(fsdb, param));
3164 if (strncmp(param, PARAM_SRPC_FLVR, sizeof(PARAM_SRPC_FLVR) - 1) != 0) {
3165 CERROR("Invalid sptlrpc flavor parameter: %s\n", param);
3169 param += sizeof(PARAM_SRPC_FLVR) - 1;
3171 rc = sptlrpc_parse_rule(param, &rule);
3175 /* mgs rules implies must be mgc->mgs */
3176 if (test_bit(FSDB_MGS_SELF, &fsdb->fsdb_flags)) {
3177 if ((rule.sr_from != LUSTRE_SP_MGC &&
3178 rule.sr_from != LUSTRE_SP_ANY) ||
3179 (rule.sr_to != LUSTRE_SP_MGS &&
3180 rule.sr_to != LUSTRE_SP_ANY))
3184 /* preapre room for this coming rule. svcname format should be:
3185 * - fsname: general rule
3186 * - fsname-tgtname: target-specific rule
3188 if (strchr(svname, '-')) {
3189 struct mgs_tgt_srpc_conf *tgtconf;
3192 for (tgtconf = fsdb->fsdb_srpc_tgt; tgtconf != NULL;
3193 tgtconf = tgtconf->mtsc_next) {
3194 if (!strcmp(tgtconf->mtsc_tgt, svname)) {
3203 OBD_ALLOC_PTR(tgtconf);
3204 if (tgtconf == NULL)
3207 name_len = strlen(svname);
3209 OBD_ALLOC(tgtconf->mtsc_tgt, name_len + 1);
3210 if (tgtconf->mtsc_tgt == NULL) {
3211 OBD_FREE_PTR(tgtconf);
3214 memcpy(tgtconf->mtsc_tgt, svname, name_len);
3216 tgtconf->mtsc_next = fsdb->fsdb_srpc_tgt;
3217 fsdb->fsdb_srpc_tgt = tgtconf;
3220 rset = &tgtconf->mtsc_rset;
3221 } else if (strcmp(svname, MGSSELF_NAME) == 0) {
3222 /* put _mgs related srpc rule directly in mgs ruleset */
3223 rset = &fsdb->fsdb_mgs->mgs_lut.lut_sptlrpc_rset;
3225 rset = &fsdb->fsdb_srpc_gen;
3228 rc = sptlrpc_rule_set_merge(rset, &rule);
3233 static int mgs_srpc_set_param(const struct lu_env *env,
3234 struct mgs_device *mgs,
3236 struct mgs_target_info *mti,
3246 /* keep a copy of original param, which could be destroied
3248 copy_size = strlen(param) + 1;
3249 OBD_ALLOC(copy, copy_size);
3252 memcpy(copy, param, copy_size);
3254 rc = mgs_srpc_set_param_mem(fsdb, mti->mti_svname, param);
3258 /* previous steps guaranteed the syntax is correct */
3259 rc = mgs_srpc_set_param_disk(env, mgs, fsdb, mti, copy);
3263 if (test_bit(FSDB_MGS_SELF, &fsdb->fsdb_flags)) {
3265 * for mgs rules, make them effective immediately.
3267 LASSERT(fsdb->fsdb_srpc_tgt == NULL);
3268 sptlrpc_target_update_exp_flavor(mgs->mgs_obd,
3269 &fsdb->fsdb_srpc_gen);
3273 OBD_FREE(copy, copy_size);
3277 struct mgs_srpc_read_data {
3278 struct fs_db *msrd_fsdb;
3282 static int mgs_srpc_read_handler(const struct lu_env *env,
3283 struct llog_handle *llh,
3284 struct llog_rec_hdr *rec, void *data)
3286 struct mgs_srpc_read_data *msrd = data;
3287 struct cfg_marker *marker;
3288 struct lustre_cfg *lcfg = REC_DATA(rec);
3289 char *svname, *param;
3293 if (rec->lrh_type != OBD_CFG_REC) {
3294 CERROR("unhandled lrh_type: %#x\n", rec->lrh_type);
3298 cfg_len = REC_DATA_LEN(rec);
3300 rc = lustre_cfg_sanity_check(lcfg, cfg_len);
3302 CERROR("Insane cfg\n");
3306 if (lcfg->lcfg_command == LCFG_MARKER) {
3307 marker = lustre_cfg_buf(lcfg, 1);
3309 if (marker->cm_flags & CM_START &&
3310 marker->cm_flags & CM_SKIP)
3311 msrd->msrd_skip = 1;
3312 if (marker->cm_flags & CM_END)
3313 msrd->msrd_skip = 0;
3318 if (msrd->msrd_skip)
3321 if (lcfg->lcfg_command != LCFG_SPTLRPC_CONF) {
3322 CERROR("invalid command (%x)\n", lcfg->lcfg_command);
3326 svname = lustre_cfg_string(lcfg, 0);
3327 if (svname == NULL) {
3328 CERROR("svname is empty\n");
3332 param = lustre_cfg_string(lcfg, 1);
3333 if (param == NULL) {
3334 CERROR("param is empty\n");
3338 rc = mgs_srpc_set_param_mem(msrd->msrd_fsdb, svname, param);
3340 CERROR("read sptlrpc record error (%d): %s\n", rc, param);
3345 int mgs_get_fsdb_srpc_from_llog(const struct lu_env *env,
3346 struct mgs_device *mgs,
3349 struct llog_handle *llh = NULL;
3350 struct llog_ctxt *ctxt;
3352 struct mgs_srpc_read_data msrd;
3356 /* construct log name */
3357 rc = name_create(&logname, fsdb->fsdb_name, "-sptlrpc");
3361 ctxt = llog_get_context(mgs->mgs_obd, LLOG_CONFIG_ORIG_CTXT);
3362 LASSERT(ctxt != NULL);
3364 if (mgs_log_is_empty(env, mgs, logname))
3367 rc = llog_open(env, ctxt, &llh, NULL, logname,
3375 rc = llog_init_handle(env, llh, LLOG_F_IS_PLAIN, NULL);
3377 GOTO(out_close, rc);
3379 if (llog_get_size(llh) <= 1)
3380 GOTO(out_close, rc = 0);
3382 msrd.msrd_fsdb = fsdb;
3385 rc = llog_process(env, llh, mgs_srpc_read_handler, (void *)&msrd,
3389 llog_close(env, llh);
3391 llog_ctxt_put(ctxt);
3392 name_destroy(&logname);
3395 CERROR("failed to read sptlrpc config database: %d\n", rc);
3399 /* Permanent settings of all parameters by writing into the appropriate
3400 * configuration logs.
3401 * A parameter with null value ("<param>='\0'") means to erase it out of
3404 static int mgs_write_log_param(const struct lu_env *env,
3405 struct mgs_device *mgs, struct fs_db *fsdb,
3406 struct mgs_target_info *mti, char *ptr)
3408 struct mgs_thread_info *mgi = mgs_env_info(env);
3414 /* For various parameter settings, we have to figure out which logs
3415 care about them (e.g. both mdt and client for lov settings) */
3416 CDEBUG(D_MGS, "next param '%s'\n", ptr);
3418 /* The params are stored in MOUNT_DATA_FILE and modified via
3419 tunefs.lustre, or set using lctl conf_param */
3421 /* Processed in lustre_start_mgc */
3422 if (class_match_param(ptr, PARAM_MGSNODE, NULL) == 0)
3425 /* Processed in ost/mdt */
3426 if (class_match_param(ptr, PARAM_NETWORK, NULL) == 0)
3429 /* Processed in mgs_write_log_ost */
3430 if (class_match_param(ptr, PARAM_FAILMODE, NULL) == 0) {
3431 if (mti->mti_flags & LDD_F_PARAM) {
3432 LCONSOLE_ERROR_MSG(0x169, "%s can only be "
3433 "changed with tunefs.lustre"
3434 "and --writeconf\n", ptr);
3440 if (class_match_param(ptr, PARAM_SRPC, NULL) == 0) {
3441 rc = mgs_srpc_set_param(env, mgs, fsdb, mti, ptr);
3445 if (class_match_param(ptr, PARAM_FAILNODE, NULL) == 0) {
3446 /* Add a failover nidlist */
3448 /* We already processed failovers params for new
3449 targets in mgs_write_log_target */
3450 if (mti->mti_flags & LDD_F_PARAM) {
3451 CDEBUG(D_MGS, "Adding failnode\n");
3452 rc = mgs_write_log_add_failnid(env, mgs, fsdb, mti);
3457 if (class_match_param(ptr, PARAM_SYS, &tmp) == 0) {
3458 rc = mgs_write_log_sys(env, mgs, fsdb, mti, ptr, tmp);
3462 if (class_match_param(ptr, PARAM_QUOTA, &tmp) == 0) {
3463 rc = mgs_write_log_quota(env, mgs, fsdb, mti, ptr, tmp);
3467 if (class_match_param(ptr, PARAM_OSC PARAM_ACTIVE, &tmp) == 0 ||
3468 class_match_param(ptr, PARAM_MDC PARAM_ACTIVE, &tmp) == 0) {
3469 /* active=0 means off, anything else means on */
3470 int flag = (*tmp == '0') ? CM_EXCLUDE : 0;
3471 bool deactive_osc = memcmp(ptr, PARAM_OSC PARAM_ACTIVE,
3472 strlen(PARAM_OSC PARAM_ACTIVE)) == 0;
3475 if (!deactive_osc) {
3478 rc = server_name2index(mti->mti_svname, &index, NULL);
3483 LCONSOLE_ERROR_MSG(0x144, "%s: MDC0 can not be"
3484 " (de)activated.\n",
3486 GOTO(end, rc = -EPERM);
3490 LCONSOLE_WARN("Permanently %sactivating %s\n",
3491 flag ? "de" : "re", mti->mti_svname);
3493 rc = name_create(&logname, mti->mti_fsname, "-client");
3496 rc = mgs_modify(env, mgs, fsdb, mti, logname,
3498 deactive_osc ? "add osc" : "add mdc", flag);
3499 name_destroy(&logname);
3504 /* Add to all MDT logs for DNE */
3505 for (i = 0; i < INDEX_MAP_SIZE * 8; i++) {
3506 if (!test_bit(i, fsdb->fsdb_mdt_index_map))
3508 rc = name_create_mdt(&logname, mti->mti_fsname, i);
3511 rc = mgs_modify(env, mgs, fsdb, mti, logname,
3513 deactive_osc ? "add osc" : "add osp",
3515 name_destroy(&logname);
3521 LCONSOLE_ERROR_MSG(0x145, "Couldn't find %s in"
3522 "log (%d). No permanent "
3523 "changes were made to the "
3525 mti->mti_svname, rc);
3526 if (test_bit(FSDB_OLDLOG14, &fsdb->fsdb_flags))
3527 LCONSOLE_ERROR_MSG(0x146, "This may be"
3532 "update the logs.\n");
3535 /* Fall through to osc/mdc proc for deactivating live
3536 OSC/OSP on running MDT / clients. */
3538 /* Below here, let obd's XXX_process_config methods handle it */
3540 /* All lov. in proc */
3541 if (class_match_param(ptr, PARAM_LOV, NULL) == 0) {
3544 CDEBUG(D_MGS, "lov param %s\n", ptr);
3545 if (!(mti->mti_flags & LDD_F_SV_TYPE_MDT)) {
3546 LCONSOLE_ERROR_MSG(0x147, "LOV params must be "
3547 "set on the MDT, not %s. "
3554 if (mgs_log_is_empty(env, mgs, mti->mti_svname))
3555 GOTO(end, rc = -ENODEV);
3557 rc = name_create_mdt_and_lov(&logname, &mdtlovname, fsdb,
3558 mti->mti_stripe_index);
3561 rc = mgs_wlp_lcfg(env, mgs, fsdb, mti, mti->mti_svname,
3562 &mgi->mgi_bufs, mdtlovname, ptr);
3563 name_destroy(&logname);
3564 name_destroy(&mdtlovname);
3569 rc = name_create(&logname, mti->mti_fsname, "-client");
3572 rc = mgs_wlp_lcfg(env, mgs, fsdb, mti, logname, &mgi->mgi_bufs,
3573 fsdb->fsdb_clilov, ptr);
3574 name_destroy(&logname);
3578 /* All osc., mdc., llite. params in proc */
3579 if ((class_match_param(ptr, PARAM_OSC, NULL) == 0) ||
3580 (class_match_param(ptr, PARAM_MDC, NULL) == 0) ||
3581 (class_match_param(ptr, PARAM_LLITE, NULL) == 0)) {
3584 if (test_bit(FSDB_OLDLOG14, &fsdb->fsdb_flags)) {
3585 LCONSOLE_ERROR_MSG(0x148, "Upgraded client logs for %s"
3586 " cannot be modified. Consider"
3587 " updating the configuration with"
3590 GOTO(end, rc = -EINVAL);
3592 if (memcmp(ptr, PARAM_LLITE, strlen(PARAM_LLITE)) == 0) {
3593 rc = name_create(&cname, mti->mti_fsname, "-client");
3594 /* Add the client type to match the obdname in
3595 class_config_llog_handler */
3596 } else if (mti->mti_flags & LDD_F_SV_TYPE_MDT) {
3597 rc = name_create(&cname, mti->mti_svname, "-mdc");
3598 } else if (mti->mti_flags & LDD_F_SV_TYPE_OST) {
3599 rc = name_create(&cname, mti->mti_svname, "-osc");
3601 GOTO(end, rc = -EINVAL);
3606 /* Forbid direct update of llite root squash parameters.
3607 * These parameters are indirectly set via the MDT settings.
3609 if ((class_match_param(ptr, PARAM_LLITE, &tmp) == 0) &&
3610 ((memcmp(tmp, "root_squash=", 12) == 0) ||
3611 (memcmp(tmp, "nosquash_nids=", 14) == 0))) {
3612 LCONSOLE_ERROR("%s: root squash parameters can only "
3613 "be updated through MDT component\n",
3615 name_destroy(&cname);
3616 GOTO(end, rc = -EINVAL);
3619 CDEBUG(D_MGS, "%.3s param %s\n", ptr, ptr + 4);
3622 rc = name_create(&logname, mti->mti_fsname, "-client");
3624 name_destroy(&cname);
3627 rc = mgs_wlp_lcfg(env, mgs, fsdb, mti, logname, &mgi->mgi_bufs,
3630 /* osc params affect the MDT as well */
3631 if (!rc && (mti->mti_flags & LDD_F_SV_TYPE_OST)) {
3634 for (i = 0; i < INDEX_MAP_SIZE * 8; i++){
3635 if (!test_bit(i, fsdb->fsdb_mdt_index_map))
3637 name_destroy(&cname);
3638 rc = name_create_mdt_osc(&cname, mti->mti_svname,
3640 name_destroy(&logname);
3643 rc = name_create_mdt(&logname,
3644 mti->mti_fsname, i);
3647 if (!mgs_log_is_empty(env, mgs, logname)) {
3648 rc = mgs_wlp_lcfg(env, mgs, fsdb,
3658 /* For mdc activate/deactivate, it affects OSP on MDT as well */
3659 if (class_match_param(ptr, PARAM_MDC PARAM_ACTIVE, &tmp) == 0 &&
3662 char *lodname = NULL;
3663 char *param_str = NULL;
3667 /* replace mdc with osp */
3668 memcpy(ptr, PARAM_OSP, strlen(PARAM_OSP));
3669 rc = server_name2index(mti->mti_svname, &index, NULL);
3671 memcpy(ptr, PARAM_MDC, strlen(PARAM_MDC));
3675 for (i = 0; i < INDEX_MAP_SIZE * 8; i++) {
3676 if (!test_bit(i, fsdb->fsdb_mdt_index_map))
3682 name_destroy(&logname);
3683 rc = name_create_mdt(&logname, mti->mti_fsname,
3688 if (mgs_log_is_empty(env, mgs, logname))
3691 snprintf(suffix, sizeof(suffix), "-osp-MDT%04x",
3693 name_destroy(&cname);
3694 rc = name_create(&cname, mti->mti_svname,
3699 rc = mgs_wlp_lcfg(env, mgs, fsdb, mti, logname,
3700 &mgi->mgi_bufs, cname, ptr);
3704 /* Add configuration log for noitfying LOD
3705 * to active/deactive the OSP. */
3706 name_destroy(¶m_str);
3707 rc = name_create(¶m_str, cname,
3708 (*tmp == '0') ? ".active=0" :
3713 name_destroy(&lodname);
3714 rc = name_create(&lodname, logname, "-mdtlov");
3718 rc = mgs_wlp_lcfg(env, mgs, fsdb, mti, logname,
3719 &mgi->mgi_bufs, lodname,
3724 memcpy(ptr, PARAM_MDC, strlen(PARAM_MDC));
3725 name_destroy(&lodname);
3726 name_destroy(¶m_str);
3729 name_destroy(&logname);
3730 name_destroy(&cname);
3734 /* All mdt. params in proc */
3735 if (class_match_param(ptr, PARAM_MDT, &tmp) == 0) {
3739 CDEBUG(D_MGS, "%.3s param %s\n", ptr, ptr + 4);
3740 if (strncmp(mti->mti_svname, mti->mti_fsname,
3741 MTI_NAME_MAXLEN) == 0)
3742 /* device is unspecified completely? */
3743 rc = LDD_F_SV_TYPE_MDT | LDD_F_SV_ALL;
3745 rc = server_name2index(mti->mti_svname, &idx, NULL);
3748 if ((rc & LDD_F_SV_TYPE_MDT) == 0)
3750 if (rc & LDD_F_SV_ALL) {
3751 for (i = 0; i < INDEX_MAP_SIZE * 8; i++) {
3753 fsdb->fsdb_mdt_index_map))
3755 rc = name_create_mdt(&logname,
3756 mti->mti_fsname, i);
3759 rc = mgs_wlp_lcfg(env, mgs, fsdb, mti,
3760 logname, &mgi->mgi_bufs,
3762 name_destroy(&logname);
3767 if ((memcmp(tmp, "root_squash=", 12) == 0) ||
3768 (memcmp(tmp, "nosquash_nids=", 14) == 0)) {
3769 LCONSOLE_ERROR("%s: root squash parameters "
3770 "cannot be applied to a single MDT\n",
3772 GOTO(end, rc = -EINVAL);
3774 rc = mgs_wlp_lcfg(env, mgs, fsdb, mti,
3775 mti->mti_svname, &mgi->mgi_bufs,
3776 mti->mti_svname, ptr);
3781 /* root squash settings are also applied to llite
3782 * config log (see LU-1778) */
3784 ((memcmp(tmp, "root_squash=", 12) == 0) ||
3785 (memcmp(tmp, "nosquash_nids=", 14) == 0))) {
3789 rc = name_create(&cname, mti->mti_fsname, "-client");
3792 rc = name_create(&logname, mti->mti_fsname, "-client");
3794 name_destroy(&cname);
3797 rc = name_create(&ptr2, PARAM_LLITE, tmp);
3799 name_destroy(&cname);
3800 name_destroy(&logname);
3803 rc = mgs_wlp_lcfg(env, mgs, fsdb, mti, logname,
3804 &mgi->mgi_bufs, cname, ptr2);
3805 name_destroy(&ptr2);
3806 name_destroy(&logname);
3807 name_destroy(&cname);
3812 /* All mdd., ost. and osd. params in proc */
3813 if ((class_match_param(ptr, PARAM_MDD, NULL) == 0) ||
3814 (class_match_param(ptr, PARAM_OST, NULL) == 0) ||
3815 (class_match_param(ptr, PARAM_OSD, NULL) == 0)) {
3816 CDEBUG(D_MGS, "%.3s param %s\n", ptr, ptr + 4);
3817 if (mgs_log_is_empty(env, mgs, mti->mti_svname))
3818 GOTO(end, rc = -ENODEV);
3820 rc = mgs_wlp_lcfg(env, mgs, fsdb, mti, mti->mti_svname,
3821 &mgi->mgi_bufs, mti->mti_svname, ptr);
3825 LCONSOLE_WARN("Ignoring unrecognized param '%s'\n", ptr);
3829 CERROR("err %d on param '%s'\n", rc, ptr);
3834 int mgs_write_log_target(const struct lu_env *env, struct mgs_device *mgs,
3835 struct mgs_target_info *mti, struct fs_db *fsdb)
3842 /* set/check the new target index */
3843 rc = mgs_set_index(env, mgs, mti);
3847 if (rc == EALREADY) {
3848 LCONSOLE_WARN("Found index %d for %s, updating log\n",
3849 mti->mti_stripe_index, mti->mti_svname);
3850 /* We would like to mark old log sections as invalid
3851 and add new log sections in the client and mdt logs.
3852 But if we add new sections, then live clients will
3853 get repeat setup instructions for already running
3854 osc's. So don't update the client/mdt logs. */
3855 mti->mti_flags &= ~LDD_F_UPDATE;
3859 OBD_FAIL_TIMEOUT(OBD_FAIL_MGS_WRITE_TARGET_DELAY, cfs_fail_val > 0 ?
3862 mutex_lock(&fsdb->fsdb_mutex);
3864 if (mti->mti_flags &
3865 (LDD_F_VIRGIN | LDD_F_UPGRADE14 | LDD_F_WRITECONF)) {
3866 /* Generate a log from scratch */
3867 if (mti->mti_flags & LDD_F_SV_TYPE_MDT) {
3868 rc = mgs_write_log_mdt(env, mgs, fsdb, mti);
3869 } else if (mti->mti_flags & LDD_F_SV_TYPE_OST) {
3870 rc = mgs_write_log_ost(env, mgs, fsdb, mti);
3872 CERROR("Unknown target type %#x, can't create log for "
3873 "%s\n", mti->mti_flags, mti->mti_svname);
3876 CERROR("Can't write logs for %s (%d)\n",
3877 mti->mti_svname, rc);
3881 /* Just update the params from tunefs in mgs_write_log_params */
3882 CDEBUG(D_MGS, "Update params for %s\n", mti->mti_svname);
3883 mti->mti_flags |= LDD_F_PARAM;
3886 /* allocate temporary buffer, where class_get_next_param will
3887 make copy of a current parameter */
3888 OBD_ALLOC(buf, strlen(mti->mti_params) + 1);
3890 GOTO(out_up, rc = -ENOMEM);
3891 params = mti->mti_params;
3892 while (params != NULL) {
3893 rc = class_get_next_param(¶ms, buf);
3896 /* there is no next parameter, that is
3901 CDEBUG(D_MGS, "remaining string: '%s', param: '%s'\n",
3903 rc = mgs_write_log_param(env, mgs, fsdb, mti, buf);
3908 OBD_FREE(buf, strlen(mti->mti_params) + 1);
3911 mutex_unlock(&fsdb->fsdb_mutex);
3915 int mgs_erase_log(const struct lu_env *env, struct mgs_device *mgs, char *name)
3917 struct llog_ctxt *ctxt;
3920 ctxt = llog_get_context(mgs->mgs_obd, LLOG_CONFIG_ORIG_CTXT);
3922 CERROR("%s: MGS config context doesn't exist\n",
3923 mgs->mgs_obd->obd_name);
3926 rc = llog_erase(env, ctxt, NULL, name);
3927 /* llog may not exist */
3930 llog_ctxt_put(ctxt);
3934 CERROR("%s: failed to clear log %s: %d\n",
3935 mgs->mgs_obd->obd_name, name, rc);
3940 /* erase all logs for the given fs */
3941 int mgs_erase_logs(const struct lu_env *env, struct mgs_device *mgs, char *fsname)
3944 struct list_head log_list;
3945 struct mgs_direntry *dirent, *n;
3946 int rc, len = strlen(fsname);
3950 /* Find all the logs in the CONFIGS directory */
3951 rc = class_dentry_readdir(env, mgs, &log_list);
3955 mutex_lock(&mgs->mgs_mutex);
3957 /* Delete the fs db */
3958 fsdb = mgs_find_fsdb(mgs, fsname);
3960 mgs_free_fsdb(mgs, fsdb);
3962 mutex_unlock(&mgs->mgs_mutex);
3964 list_for_each_entry_safe(dirent, n, &log_list, mde_list) {
3965 list_del_init(&dirent->mde_list);
3966 suffix = strrchr(dirent->mde_name, '-');
3967 if (suffix != NULL) {
3968 if ((len == suffix - dirent->mde_name) &&
3969 (strncmp(fsname, dirent->mde_name, len) == 0)) {
3970 CDEBUG(D_MGS, "Removing log %s\n",
3972 mgs_erase_log(env, mgs, dirent->mde_name);
3975 mgs_direntry_free(dirent);
3981 /* list all logs for the given fs */
3982 int mgs_list_logs(const struct lu_env *env, struct mgs_device *mgs,
3983 struct obd_ioctl_data *data)
3985 struct list_head log_list;
3986 struct mgs_direntry *dirent, *n;
3992 /* Find all the logs in the CONFIGS directory */
3993 rc = class_dentry_readdir(env, mgs, &log_list);
3997 out = data->ioc_bulk;
3998 remains = data->ioc_inllen1;
3999 list_for_each_entry_safe(dirent, n, &log_list, mde_list) {
4000 list_del_init(&dirent->mde_list);
4001 suffix = strrchr(dirent->mde_name, '-');
4002 if (suffix != NULL) {
4003 l = snprintf(out, remains, "config log: $%s\n",
4008 mgs_direntry_free(dirent);
4015 /* from llog_swab */
4016 static void print_lustre_cfg(struct lustre_cfg *lcfg)
4021 CDEBUG(D_MGS, "lustre_cfg: %p\n", lcfg);
4022 CDEBUG(D_MGS, "\tlcfg->lcfg_version: %#x\n", lcfg->lcfg_version);
4024 CDEBUG(D_MGS, "\tlcfg->lcfg_command: %#x\n", lcfg->lcfg_command);
4025 CDEBUG(D_MGS, "\tlcfg->lcfg_num: %#x\n", lcfg->lcfg_num);
4026 CDEBUG(D_MGS, "\tlcfg->lcfg_flags: %#x\n", lcfg->lcfg_flags);
4027 CDEBUG(D_MGS, "\tlcfg->lcfg_nid: %s\n", libcfs_nid2str(lcfg->lcfg_nid));
4029 CDEBUG(D_MGS, "\tlcfg->lcfg_bufcount: %d\n", lcfg->lcfg_bufcount);
4030 if (lcfg->lcfg_bufcount < LUSTRE_CFG_MAX_BUFCOUNT)
4031 for (i = 0; i < lcfg->lcfg_bufcount; i++) {
4032 CDEBUG(D_MGS, "\tlcfg->lcfg_buflens[%d]: %d %s\n",
4033 i, lcfg->lcfg_buflens[i],
4034 lustre_cfg_string(lcfg, i));
4039 /* Setup _mgs fsdb and log
4041 int mgs__mgs_fsdb_setup(const struct lu_env *env, struct mgs_device *mgs,
4047 rc = mgs_find_or_make_fsdb(env, mgs, MGSSELF_NAME, &fsdb);
4052 /* Setup params fsdb and log
4054 int mgs_params_fsdb_setup(const struct lu_env *env, struct mgs_device *mgs,
4057 struct llog_handle *params_llh = NULL;
4061 rc = mgs_find_or_make_fsdb(env, mgs, PARAMS_FILENAME, &fsdb);
4063 mutex_lock(&fsdb->fsdb_mutex);
4064 rc = record_start_log(env, mgs, ¶ms_llh, PARAMS_FILENAME);
4066 rc = record_end_log(env, ¶ms_llh);
4067 mutex_unlock(&fsdb->fsdb_mutex);
4073 /* Cleanup params fsdb and log
4075 int mgs_params_fsdb_cleanup(const struct lu_env *env, struct mgs_device *mgs)
4077 return mgs_erase_logs(env, mgs, PARAMS_FILENAME);
4080 /* Set a permanent (config log) param for a target or fs
4081 * \param lcfg buf0 may contain the device (testfs-MDT0000) name
4082 * buf1 contains the single parameter
4084 int mgs_setparam(const struct lu_env *env, struct mgs_device *mgs,
4085 struct lustre_cfg *lcfg, char *fsname)
4088 struct mgs_target_info *mti;
4089 char *devname, *param;
4096 print_lustre_cfg(lcfg);
4098 /* lustre, lustre-mdtlov, lustre-client, lustre-MDT0000 */
4099 devname = lustre_cfg_string(lcfg, 0);
4100 param = lustre_cfg_string(lcfg, 1);
4102 /* Assume device name embedded in param:
4103 lustre-OST0000.osc.max_dirty_mb=32 */
4104 ptr = strchr(param, '.');
4112 LCONSOLE_ERROR_MSG(0x14d, "No target specified: %s\n", param);
4116 rc = mgs_parse_devname(devname, fsname, NULL);
4117 if (rc == 0 && !mgs_parse_devname(devname, NULL, &index)) {
4118 /* param related to llite isn't allowed to set by OST or MDT */
4119 if (rc == 0 && strncmp(param, PARAM_LLITE,
4120 sizeof(PARAM_LLITE) - 1) == 0)
4123 /* assume devname is the fsname */
4124 strlcpy(fsname, devname, MTI_NAME_MAXLEN);
4126 CDEBUG(D_MGS, "setparam fs='%s' device='%s'\n", fsname, devname);
4128 rc = mgs_find_or_make_fsdb(env, mgs,
4129 lcfg->lcfg_command == LCFG_SET_PARAM ?
4130 PARAMS_FILENAME : fsname, &fsdb);
4134 if (lcfg->lcfg_command != LCFG_SET_PARAM &&
4135 !test_bit(FSDB_MGS_SELF, &fsdb->fsdb_flags) &&
4136 test_bit(FSDB_LOG_EMPTY, &fsdb->fsdb_flags)) {
4137 CERROR("No filesystem targets for %s. cfg_device from lctl "
4138 "is '%s'\n", fsname, devname);
4139 mgs_free_fsdb(mgs, fsdb);
4143 /* Create a fake mti to hold everything */
4146 GOTO(out, rc = -ENOMEM);
4147 if (strlcpy(mti->mti_fsname, fsname, sizeof(mti->mti_fsname))
4148 >= sizeof(mti->mti_fsname))
4149 GOTO(out, rc = -E2BIG);
4150 if (strlcpy(mti->mti_svname, devname, sizeof(mti->mti_svname))
4151 >= sizeof(mti->mti_svname))
4152 GOTO(out, rc = -E2BIG);
4153 if (strlcpy(mti->mti_params, param, sizeof(mti->mti_params))
4154 >= sizeof(mti->mti_params))
4155 GOTO(out, rc = -E2BIG);
4156 rc = server_name2index(mti->mti_svname, &mti->mti_stripe_index, &tmp);
4158 /* Not a valid server; may be only fsname */
4161 /* Strip -osc or -mdc suffix from svname */
4162 if (server_make_name(rc, mti->mti_stripe_index, mti->mti_fsname,
4164 GOTO(out, rc = -EINVAL);
4166 * Revoke lock so everyone updates. Should be alright if
4167 * someone was already reading while we were updating the logs,
4168 * so we don't really need to hold the lock while we're
4171 if (lcfg->lcfg_command == LCFG_SET_PARAM) {
4172 mti->mti_flags = rc | LDD_F_PARAM2;
4173 mutex_lock(&fsdb->fsdb_mutex);
4174 rc = mgs_write_log_param2(env, mgs, fsdb, mti, mti->mti_params);
4175 mutex_unlock(&fsdb->fsdb_mutex);
4176 mgs_revoke_lock(mgs, fsdb, CONFIG_T_PARAMS);
4178 mti->mti_flags = rc | LDD_F_PARAM;
4179 mutex_lock(&fsdb->fsdb_mutex);
4180 rc = mgs_write_log_param(env, mgs, fsdb, mti, mti->mti_params);
4181 mutex_unlock(&fsdb->fsdb_mutex);
4182 mgs_revoke_lock(mgs, fsdb, CONFIG_T_CONFIG);
4190 static int mgs_write_log_pool(const struct lu_env *env,
4191 struct mgs_device *mgs, char *logname,
4192 struct fs_db *fsdb, char *tgtname,
4193 enum lcfg_command_type cmd,
4194 char *fsname, char *poolname,
4195 char *ostname, char *comment)
4197 struct llog_handle *llh = NULL;
4200 rc = record_start_log(env, mgs, &llh, logname);
4203 rc = record_marker(env, llh, fsdb, CM_START, tgtname, comment);
4206 rc = record_base(env, llh, tgtname, 0, cmd,
4207 fsname, poolname, ostname, NULL);
4210 rc = record_marker(env, llh, fsdb, CM_END, tgtname, comment);
4212 record_end_log(env, &llh);
4216 int mgs_nodemap_cmd(const struct lu_env *env, struct mgs_device *mgs,
4217 enum lcfg_command_type cmd, const char *nodemap_name,
4228 case LCFG_NODEMAP_ADD:
4229 rc = nodemap_add(nodemap_name);
4231 case LCFG_NODEMAP_DEL:
4232 rc = nodemap_del(nodemap_name);
4234 case LCFG_NODEMAP_ADD_RANGE:
4235 rc = nodemap_parse_range(param, nid);
4238 rc = nodemap_add_range(nodemap_name, nid);
4240 case LCFG_NODEMAP_DEL_RANGE:
4241 rc = nodemap_parse_range(param, nid);
4244 rc = nodemap_del_range(nodemap_name, nid);
4246 case LCFG_NODEMAP_ADMIN:
4247 bool_switch = simple_strtoul(param, NULL, 10);
4248 rc = nodemap_set_allow_root(nodemap_name, bool_switch);
4250 case LCFG_NODEMAP_DENY_UNKNOWN:
4251 bool_switch = simple_strtoul(param, NULL, 10);
4252 rc = nodemap_set_deny_unknown(nodemap_name, bool_switch);
4254 case LCFG_NODEMAP_TRUSTED:
4255 bool_switch = simple_strtoul(param, NULL, 10);
4256 rc = nodemap_set_trust_client_ids(nodemap_name, bool_switch);
4258 case LCFG_NODEMAP_SQUASH_UID:
4259 int_id = simple_strtoul(param, NULL, 10);
4260 rc = nodemap_set_squash_uid(nodemap_name, int_id);
4262 case LCFG_NODEMAP_SQUASH_GID:
4263 int_id = simple_strtoul(param, NULL, 10);
4264 rc = nodemap_set_squash_gid(nodemap_name, int_id);
4266 case LCFG_NODEMAP_ADD_UIDMAP:
4267 case LCFG_NODEMAP_ADD_GIDMAP:
4268 rc = nodemap_parse_idmap(param, idmap);
4271 if (cmd == LCFG_NODEMAP_ADD_UIDMAP)
4272 rc = nodemap_add_idmap(nodemap_name, NODEMAP_UID,
4275 rc = nodemap_add_idmap(nodemap_name, NODEMAP_GID,
4278 case LCFG_NODEMAP_DEL_UIDMAP:
4279 case LCFG_NODEMAP_DEL_GIDMAP:
4280 rc = nodemap_parse_idmap(param, idmap);
4283 if (cmd == LCFG_NODEMAP_DEL_UIDMAP)
4284 rc = nodemap_del_idmap(nodemap_name, NODEMAP_UID,
4287 rc = nodemap_del_idmap(nodemap_name, NODEMAP_GID,
4290 case LCFG_NODEMAP_SET_FILESET:
4291 rc = nodemap_set_fileset(nodemap_name, param);
4300 int mgs_pool_cmd(const struct lu_env *env, struct mgs_device *mgs,
4301 enum lcfg_command_type cmd, char *fsname,
4302 char *poolname, char *ostname)
4307 char *label = NULL, *canceled_label = NULL;
4309 struct mgs_target_info *mti = NULL;
4310 bool checked = false;
4314 rc = mgs_find_or_make_fsdb(env, mgs, fsname, &fsdb);
4316 CERROR("Can't get db for %s\n", fsname);
4319 if (test_bit(FSDB_LOG_EMPTY, &fsdb->fsdb_flags)) {
4320 CERROR("%s is not defined\n", fsname);
4321 mgs_free_fsdb(mgs, fsdb);
4325 label_sz = 10 + strlen(fsname) + strlen(poolname);
4327 /* check if ostname match fsname */
4328 if (ostname != NULL) {
4331 ptr = strrchr(ostname, '-');
4332 if ((ptr == NULL) ||
4333 (strncmp(fsname, ostname, ptr-ostname) != 0))
4335 label_sz += strlen(ostname);
4338 OBD_ALLOC(label, label_sz);
4345 "new %s.%s", fsname, poolname);
4349 "add %s.%s.%s", fsname, poolname, ostname);
4352 OBD_ALLOC(canceled_label, label_sz);
4353 if (canceled_label == NULL)
4354 GOTO(out_label, rc = -ENOMEM);
4356 "rem %s.%s.%s", fsname, poolname, ostname);
4357 sprintf(canceled_label,
4358 "add %s.%s.%s", fsname, poolname, ostname);
4361 OBD_ALLOC(canceled_label, label_sz);
4362 if (canceled_label == NULL)
4363 GOTO(out_label, rc = -ENOMEM);
4365 "del %s.%s", fsname, poolname);
4366 sprintf(canceled_label,
4367 "new %s.%s", fsname, poolname);
4375 GOTO(out_cancel, rc = -ENOMEM);
4376 strncpy(mti->mti_svname, "lov pool", sizeof(mti->mti_svname));
4378 mutex_lock(&fsdb->fsdb_mutex);
4379 /* write pool def to all MDT logs */
4380 for (i = 0; i < INDEX_MAP_SIZE * 8; i++) {
4381 if (test_bit(i, fsdb->fsdb_mdt_index_map)) {
4382 rc = name_create_mdt_and_lov(&logname, &lovname,
4385 mutex_unlock(&fsdb->fsdb_mutex);
4389 if (!checked && (canceled_label == NULL)) {
4390 rc = mgs_check_marker(env, mgs, fsdb, mti,
4391 logname, lovname, label);
4393 name_destroy(&logname);
4394 name_destroy(&lovname);
4395 mutex_unlock(&fsdb->fsdb_mutex);
4397 rc = (rc == LLOG_PROC_BREAK ?
4402 if (canceled_label != NULL)
4403 rc = mgs_modify(env, mgs, fsdb, mti, logname,
4404 lovname, canceled_label,
4408 rc = mgs_write_log_pool(env, mgs, logname,
4412 name_destroy(&logname);
4413 name_destroy(&lovname);
4415 mutex_unlock(&fsdb->fsdb_mutex);
4421 rc = name_create(&logname, fsname, "-client");
4423 mutex_unlock(&fsdb->fsdb_mutex);
4427 if (!checked && (canceled_label == NULL)) {
4428 rc = mgs_check_marker(env, mgs, fsdb, mti, logname,
4429 fsdb->fsdb_clilov, label);
4431 name_destroy(&logname);
4432 mutex_unlock(&fsdb->fsdb_mutex);
4433 GOTO(out_mti, rc = (rc == LLOG_PROC_BREAK ?
4437 if (canceled_label != NULL) {
4438 rc = mgs_modify(env, mgs, fsdb, mti, logname,
4439 fsdb->fsdb_clilov, canceled_label, CM_SKIP);
4441 mutex_unlock(&fsdb->fsdb_mutex);
4442 name_destroy(&logname);
4447 rc = mgs_write_log_pool(env, mgs, logname, fsdb, fsdb->fsdb_clilov,
4448 cmd, fsname, poolname, ostname, label);
4449 mutex_unlock(&fsdb->fsdb_mutex);
4450 name_destroy(&logname);
4451 /* request for update */
4452 mgs_revoke_lock(mgs, fsdb, CONFIG_T_CONFIG);
4459 if (canceled_label != NULL)
4460 OBD_FREE(canceled_label, label_sz);
4462 OBD_FREE(label, label_sz);