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.sun.com/software/products/lustre/docs/GPLv2.pdf
20 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
21 * CA 95054 USA or visit www.sun.com if you need additional information or
27 * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved.
28 * Use is subject to license terms.
30 * Copyright (c) 2011, 2015, Intel Corporation.
33 * This file is part of Lustre, http://www.lustre.org/
34 * Lustre is a trademark of Sun Microsystems, Inc.
36 * lustre/mgs/mgs_llog.c
38 * Lustre Management Server (mgs) config llog creation
40 * Author: Nathan Rutman <nathan@clusterfs.com>
41 * Author: Alex Zhuravlev <bzzz@whamcloud.com>
42 * Author: Mikhail Pershin <tappro@whamcloud.com>
45 #define DEBUG_SUBSYSTEM S_MGS
46 #define D_MGS D_CONFIG
49 #include <lustre_ioctl.h>
50 #include <lustre_param.h>
51 #include <lustre_sec.h>
52 #include <lustre_quota.h>
54 #include "mgs_internal.h"
56 /********************** Class functions ********************/
58 /* Find all logs in CONFIG directory and link then into list */
59 int class_dentry_readdir(const struct lu_env *env,
60 struct mgs_device *mgs, struct list_head *log_list)
62 struct dt_object *dir = mgs->mgs_configs_dir;
63 const struct dt_it_ops *iops;
65 struct mgs_direntry *de;
69 INIT_LIST_HEAD(log_list);
72 LASSERT(dir->do_index_ops);
74 iops = &dir->do_index_ops->dio_it;
75 it = iops->init(env, dir, LUDA_64BITHASH);
79 rc = iops->load(env, it, 0);
85 key = (void *)iops->key(env, it);
87 CERROR("%s: key failed when listing %s: rc = %d\n",
88 mgs->mgs_obd->obd_name, MOUNT_CONFIGS_DIR,
92 key_sz = iops->key_size(env, it);
95 /* filter out "." and ".." entries */
99 if (key_sz == 2 && key[1] == '.')
103 de = mgs_direntry_alloc(key_sz + 1);
109 memcpy(de->mde_name, key, key_sz);
110 de->mde_name[key_sz] = 0;
112 list_add(&de->mde_list, log_list);
115 rc = iops->next(env, it);
125 CERROR("%s: key failed when listing %s: rc = %d\n",
126 mgs->mgs_obd->obd_name, MOUNT_CONFIGS_DIR, rc);
130 /******************** DB functions *********************/
132 static inline int name_create(char **newname, char *prefix, char *suffix)
135 OBD_ALLOC(*newname, strlen(prefix) + strlen(suffix) + 1);
138 sprintf(*newname, "%s%s", prefix, suffix);
142 static inline void name_destroy(char **name)
145 OBD_FREE(*name, strlen(*name) + 1);
149 struct mgs_fsdb_handler_data
155 /* from the (client) config log, figure out:
156 1. which ost's/mdt's are configured (by index)
157 2. what the last config step is
158 3. COMPAT_18 osc name
160 /* It might be better to have a separate db file, instead of parsing the info
161 out of the client log. This is slow and potentially error-prone. */
162 static int mgs_fsdb_handler(const struct lu_env *env, struct llog_handle *llh,
163 struct llog_rec_hdr *rec, void *data)
165 struct mgs_fsdb_handler_data *d = data;
166 struct fs_db *fsdb = d->fsdb;
167 int cfg_len = rec->lrh_len;
168 char *cfg_buf = (char*) (rec + 1);
169 struct lustre_cfg *lcfg;
174 if (rec->lrh_type != OBD_CFG_REC) {
175 CERROR("unhandled lrh_type: %#x\n", rec->lrh_type);
179 rc = lustre_cfg_sanity_check(cfg_buf, cfg_len);
181 CERROR("Insane cfg\n");
185 lcfg = (struct lustre_cfg *)cfg_buf;
187 CDEBUG(D_INFO, "cmd %x %s %s\n", lcfg->lcfg_command,
188 lustre_cfg_string(lcfg, 0), lustre_cfg_string(lcfg, 1));
190 /* Figure out ost indicies */
191 /* lov_modify_tgts add 0:lov1 1:ost1_UUID 2(index):0 3(gen):1 */
192 if (lcfg->lcfg_command == LCFG_LOV_ADD_OBD ||
193 lcfg->lcfg_command == LCFG_LOV_DEL_OBD) {
194 index = simple_strtoul(lustre_cfg_string(lcfg, 2),
196 CDEBUG(D_MGS, "OST index for %s is %u (%s)\n",
197 lustre_cfg_string(lcfg, 1), index,
198 lustre_cfg_string(lcfg, 2));
199 set_bit(index, fsdb->fsdb_ost_index_map);
202 /* Figure out mdt indicies */
203 /* attach 0:MDC_uml1_mdsA_MNT_client 1:mdc 2:1d834_MNT_client_03f */
204 if ((lcfg->lcfg_command == LCFG_ATTACH) &&
205 (strcmp(lustre_cfg_string(lcfg, 1), LUSTRE_MDC_NAME) == 0)) {
206 rc = server_name2index(lustre_cfg_string(lcfg, 0),
208 if (rc != LDD_F_SV_TYPE_MDT) {
209 CWARN("Unparsable MDC name %s, assuming index 0\n",
210 lustre_cfg_string(lcfg, 0));
214 CDEBUG(D_MGS, "MDT index is %u\n", index);
215 set_bit(index, fsdb->fsdb_mdt_index_map);
216 fsdb->fsdb_mdt_count ++;
220 * figure out the old config. fsdb_gen = 0 means old log
221 * It is obsoleted and not supported anymore
223 if (fsdb->fsdb_gen == 0) {
224 CERROR("Old config format is not supported\n");
229 * compat to 1.8, check osc name used by MDT0 to OSTs, bz18548.
231 if (!test_bit(FSDB_OSCNAME18, &fsdb->fsdb_flags) &&
232 lcfg->lcfg_command == LCFG_ATTACH &&
233 strcmp(lustre_cfg_string(lcfg, 1), LUSTRE_OSC_NAME) == 0) {
234 if (OBD_OCD_VERSION_MAJOR(d->ver) == 1 &&
235 OBD_OCD_VERSION_MINOR(d->ver) <= 8) {
236 CWARN("MDT using 1.8 OSC name scheme\n");
237 set_bit(FSDB_OSCNAME18, &fsdb->fsdb_flags);
241 if (lcfg->lcfg_command == LCFG_MARKER) {
242 struct cfg_marker *marker;
243 marker = lustre_cfg_buf(lcfg, 1);
245 d->ver = marker->cm_vers;
247 /* Keep track of the latest marker step */
248 fsdb->fsdb_gen = max(fsdb->fsdb_gen, marker->cm_step);
254 /* fsdb->fsdb_mutex is already held in mgs_find_or_make_fsdb*/
255 static int mgs_get_fsdb_from_llog(const struct lu_env *env,
256 struct mgs_device *mgs,
260 struct llog_handle *loghandle;
261 struct llog_ctxt *ctxt;
262 struct mgs_fsdb_handler_data d = { fsdb, 0 };
267 ctxt = llog_get_context(mgs->mgs_obd, LLOG_CONFIG_ORIG_CTXT);
268 LASSERT(ctxt != NULL);
269 rc = name_create(&logname, fsdb->fsdb_name, "-client");
272 rc = llog_open_create(env, ctxt, &loghandle, NULL, logname);
276 rc = llog_init_handle(env, loghandle, LLOG_F_IS_PLAIN, NULL);
280 if (llog_get_size(loghandle) <= 1)
281 set_bit(FSDB_LOG_EMPTY, &fsdb->fsdb_flags);
283 rc = llog_process(env, loghandle, mgs_fsdb_handler, (void *)&d, NULL);
284 CDEBUG(D_INFO, "get_db = %d\n", rc);
286 llog_close(env, loghandle);
288 name_destroy(&logname);
295 static void mgs_free_fsdb_srpc(struct fs_db *fsdb)
297 struct mgs_tgt_srpc_conf *tgtconf;
299 /* free target-specific rules */
300 while (fsdb->fsdb_srpc_tgt) {
301 tgtconf = fsdb->fsdb_srpc_tgt;
302 fsdb->fsdb_srpc_tgt = tgtconf->mtsc_next;
304 LASSERT(tgtconf->mtsc_tgt);
306 sptlrpc_rule_set_free(&tgtconf->mtsc_rset);
307 OBD_FREE(tgtconf->mtsc_tgt, strlen(tgtconf->mtsc_tgt) + 1);
308 OBD_FREE_PTR(tgtconf);
311 /* free general rules */
312 sptlrpc_rule_set_free(&fsdb->fsdb_srpc_gen);
315 struct fs_db *mgs_find_fsdb(struct mgs_device *mgs, char *fsname)
318 struct list_head *tmp;
320 list_for_each(tmp, &mgs->mgs_fs_db_list) {
321 fsdb = list_entry(tmp, struct fs_db, fsdb_list);
322 if (strcmp(fsdb->fsdb_name, fsname) == 0)
328 /* caller must hold the mgs->mgs_fs_db_lock */
329 static struct fs_db *mgs_new_fsdb(const struct lu_env *env,
330 struct mgs_device *mgs, char *fsname)
336 if (strlen(fsname) >= sizeof(fsdb->fsdb_name)) {
337 CERROR("fsname %s is too long\n", fsname);
338 RETURN(ERR_PTR(-EINVAL));
343 RETURN(ERR_PTR(-ENOMEM));
345 strcpy(fsdb->fsdb_name, fsname);
346 mutex_init(&fsdb->fsdb_mutex);
347 set_bit(FSDB_UDESC, &fsdb->fsdb_flags);
350 if (strcmp(fsname, MGSSELF_NAME) == 0) {
351 set_bit(FSDB_MGS_SELF, &fsdb->fsdb_flags);
352 fsdb->fsdb_mgs = mgs;
354 OBD_ALLOC(fsdb->fsdb_ost_index_map, INDEX_MAP_SIZE);
355 OBD_ALLOC(fsdb->fsdb_mdt_index_map, INDEX_MAP_SIZE);
356 if (!fsdb->fsdb_ost_index_map || !fsdb->fsdb_mdt_index_map) {
357 CERROR("No memory for index maps\n");
358 GOTO(err, rc = -ENOMEM);
361 rc = name_create(&fsdb->fsdb_clilov, fsname, "-clilov");
364 rc = name_create(&fsdb->fsdb_clilmv, fsname, "-clilmv");
368 /* initialise data for NID table */
369 mgs_ir_init_fs(env, mgs, fsdb);
371 lproc_mgs_add_live(mgs, fsdb);
374 list_add(&fsdb->fsdb_list, &mgs->mgs_fs_db_list);
378 if (fsdb->fsdb_ost_index_map)
379 OBD_FREE(fsdb->fsdb_ost_index_map, INDEX_MAP_SIZE);
380 if (fsdb->fsdb_mdt_index_map)
381 OBD_FREE(fsdb->fsdb_mdt_index_map, INDEX_MAP_SIZE);
382 name_destroy(&fsdb->fsdb_clilov);
383 name_destroy(&fsdb->fsdb_clilmv);
388 static void mgs_free_fsdb(struct mgs_device *mgs, struct fs_db *fsdb)
390 /* wait for anyone with the sem */
391 mutex_lock(&fsdb->fsdb_mutex);
392 lproc_mgs_del_live(mgs, fsdb);
393 list_del(&fsdb->fsdb_list);
395 /* deinitialize fsr */
396 mgs_ir_fini_fs(mgs, fsdb);
398 if (fsdb->fsdb_ost_index_map)
399 OBD_FREE(fsdb->fsdb_ost_index_map, INDEX_MAP_SIZE);
400 if (fsdb->fsdb_mdt_index_map)
401 OBD_FREE(fsdb->fsdb_mdt_index_map, INDEX_MAP_SIZE);
402 name_destroy(&fsdb->fsdb_clilov);
403 name_destroy(&fsdb->fsdb_clilmv);
404 mgs_free_fsdb_srpc(fsdb);
405 mutex_unlock(&fsdb->fsdb_mutex);
409 int mgs_init_fsdb_list(struct mgs_device *mgs)
411 INIT_LIST_HEAD(&mgs->mgs_fs_db_list);
415 int mgs_cleanup_fsdb_list(struct mgs_device *mgs)
418 struct list_head *tmp, *tmp2;
420 mutex_lock(&mgs->mgs_mutex);
421 list_for_each_safe(tmp, tmp2, &mgs->mgs_fs_db_list) {
422 fsdb = list_entry(tmp, struct fs_db, fsdb_list);
423 mgs_free_fsdb(mgs, fsdb);
425 mutex_unlock(&mgs->mgs_mutex);
429 int mgs_find_or_make_fsdb(const struct lu_env *env,
430 struct mgs_device *mgs, char *name,
437 mutex_lock(&mgs->mgs_mutex);
438 fsdb = mgs_find_fsdb(mgs, name);
440 mutex_unlock(&mgs->mgs_mutex);
445 CDEBUG(D_MGS, "Creating new db\n");
446 fsdb = mgs_new_fsdb(env, mgs, name);
447 /* lock fsdb_mutex until the db is loaded from llogs */
449 mutex_lock(&fsdb->fsdb_mutex);
450 mutex_unlock(&mgs->mgs_mutex);
452 RETURN(PTR_ERR(fsdb));
454 if (!test_bit(FSDB_MGS_SELF, &fsdb->fsdb_flags)) {
455 /* populate the db from the client llog */
456 rc = mgs_get_fsdb_from_llog(env, mgs, fsdb);
458 CERROR("Can't get db from client log %d\n", rc);
463 /* populate srpc rules from params llog */
464 rc = mgs_get_fsdb_srpc_from_llog(env, mgs, fsdb);
466 CERROR("Can't get db from params log %d\n", rc);
470 mutex_unlock(&fsdb->fsdb_mutex);
476 mutex_unlock(&fsdb->fsdb_mutex);
477 mgs_free_fsdb(mgs, fsdb);
483 -1= empty client log */
484 int mgs_check_index(const struct lu_env *env,
485 struct mgs_device *mgs,
486 struct mgs_target_info *mti)
493 LASSERT(!(mti->mti_flags & LDD_F_NEED_INDEX));
495 rc = mgs_find_or_make_fsdb(env, mgs, mti->mti_fsname, &fsdb);
497 CERROR("Can't get db for %s\n", mti->mti_fsname);
501 if (test_bit(FSDB_LOG_EMPTY, &fsdb->fsdb_flags))
504 if (mti->mti_flags & LDD_F_SV_TYPE_OST)
505 imap = fsdb->fsdb_ost_index_map;
506 else if (mti->mti_flags & LDD_F_SV_TYPE_MDT)
507 imap = fsdb->fsdb_mdt_index_map;
511 if (test_bit(mti->mti_stripe_index, imap))
516 static __inline__ int next_index(void *index_map, int map_len)
519 for (i = 0; i < map_len * 8; i++)
520 if (!test_bit(i, index_map)) {
523 CERROR("max index %d exceeded.\n", i);
528 0 newly marked as in use
530 +EALREADY for update of an old index */
531 static int mgs_set_index(const struct lu_env *env,
532 struct mgs_device *mgs,
533 struct mgs_target_info *mti)
540 rc = mgs_find_or_make_fsdb(env, mgs, mti->mti_fsname, &fsdb);
542 CERROR("Can't get db for %s\n", mti->mti_fsname);
546 mutex_lock(&fsdb->fsdb_mutex);
547 if (mti->mti_flags & LDD_F_SV_TYPE_OST) {
548 imap = fsdb->fsdb_ost_index_map;
549 } else if (mti->mti_flags & LDD_F_SV_TYPE_MDT) {
550 imap = fsdb->fsdb_mdt_index_map;
552 GOTO(out_up, rc = -EINVAL);
555 if (mti->mti_flags & LDD_F_NEED_INDEX) {
556 rc = next_index(imap, INDEX_MAP_SIZE);
558 GOTO(out_up, rc = -ERANGE);
559 mti->mti_stripe_index = rc;
560 if (mti->mti_flags & LDD_F_SV_TYPE_MDT)
561 fsdb->fsdb_mdt_count ++;
564 /* the last index(0xffff) is reserved for default value. */
565 if (mti->mti_stripe_index >= INDEX_MAP_SIZE * 8 - 1) {
566 LCONSOLE_ERROR_MSG(0x13f, "Server %s requested index %u, "
567 "but index must be less than %u.\n",
568 mti->mti_svname, mti->mti_stripe_index,
569 INDEX_MAP_SIZE * 8 - 1);
570 GOTO(out_up, rc = -ERANGE);
573 if (test_bit(mti->mti_stripe_index, imap)) {
574 if ((mti->mti_flags & LDD_F_VIRGIN) &&
575 !(mti->mti_flags & LDD_F_WRITECONF)) {
576 LCONSOLE_ERROR_MSG(0x140, "Server %s requested index "
577 "%d, but that index is already in "
578 "use. Use --writeconf to force\n",
580 mti->mti_stripe_index);
581 GOTO(out_up, rc = -EADDRINUSE);
583 CDEBUG(D_MGS, "Server %s updating index %d\n",
584 mti->mti_svname, mti->mti_stripe_index);
585 GOTO(out_up, rc = EALREADY);
589 set_bit(mti->mti_stripe_index, imap);
590 clear_bit(FSDB_LOG_EMPTY, &fsdb->fsdb_flags);
591 mutex_unlock(&fsdb->fsdb_mutex);
592 server_make_name(mti->mti_flags & ~(LDD_F_VIRGIN | LDD_F_WRITECONF),
593 mti->mti_stripe_index, mti->mti_fsname, mti->mti_svname);
595 CDEBUG(D_MGS, "Set index for %s to %d\n", mti->mti_svname,
596 mti->mti_stripe_index);
600 mutex_unlock(&fsdb->fsdb_mutex);
604 struct mgs_modify_lookup {
605 struct cfg_marker mml_marker;
609 static int mgs_modify_handler(const struct lu_env *env,
610 struct llog_handle *llh,
611 struct llog_rec_hdr *rec, void *data)
613 struct mgs_modify_lookup *mml = data;
614 struct cfg_marker *marker;
615 struct lustre_cfg *lcfg = REC_DATA(rec);
616 int cfg_len = REC_DATA_LEN(rec);
620 if (rec->lrh_type != OBD_CFG_REC) {
621 CERROR("unhandled lrh_type: %#x\n", rec->lrh_type);
625 rc = lustre_cfg_sanity_check(lcfg, cfg_len);
627 CERROR("Insane cfg\n");
631 /* We only care about markers */
632 if (lcfg->lcfg_command != LCFG_MARKER)
635 marker = lustre_cfg_buf(lcfg, 1);
636 if ((strcmp(mml->mml_marker.cm_comment, marker->cm_comment) == 0) &&
637 (strcmp(mml->mml_marker.cm_tgtname, marker->cm_tgtname) == 0) &&
638 !(marker->cm_flags & CM_SKIP)) {
639 /* Found a non-skipped marker match */
640 CDEBUG(D_MGS, "Changing rec %u marker %d %x->%x: %s %s\n",
641 rec->lrh_index, marker->cm_step,
642 marker->cm_flags, mml->mml_marker.cm_flags,
643 marker->cm_tgtname, marker->cm_comment);
644 /* Overwrite the old marker llog entry */
645 marker->cm_flags &= ~CM_EXCLUDE; /* in case we're unexcluding */
646 marker->cm_flags |= mml->mml_marker.cm_flags;
647 marker->cm_canceltime = mml->mml_marker.cm_canceltime;
648 rc = llog_write(env, llh, rec, rec->lrh_index);
657 * Modify an existing config log record (for CM_SKIP or CM_EXCLUDE)
659 * 0 - modified successfully,
660 * 1 - no modification was done
663 static int mgs_modify(const struct lu_env *env, struct mgs_device *mgs,
664 struct fs_db *fsdb, struct mgs_target_info *mti,
665 char *logname, char *devname, char *comment, int flags)
667 struct llog_handle *loghandle;
668 struct llog_ctxt *ctxt;
669 struct mgs_modify_lookup *mml;
674 LASSERT(mutex_is_locked(&fsdb->fsdb_mutex));
675 CDEBUG(D_MGS, "modify %s/%s/%s fl=%x\n", logname, devname, comment,
678 ctxt = llog_get_context(mgs->mgs_obd, LLOG_CONFIG_ORIG_CTXT);
679 LASSERT(ctxt != NULL);
680 rc = llog_open(env, ctxt, &loghandle, NULL, logname, LLOG_OPEN_EXISTS);
687 rc = llog_init_handle(env, loghandle, LLOG_F_IS_PLAIN, NULL);
691 if (llog_get_size(loghandle) <= 1)
692 GOTO(out_close, rc = 0);
696 GOTO(out_close, rc = -ENOMEM);
697 if (strlcpy(mml->mml_marker.cm_comment, comment,
698 sizeof(mml->mml_marker.cm_comment)) >=
699 sizeof(mml->mml_marker.cm_comment))
700 GOTO(out_free, rc = -E2BIG);
701 if (strlcpy(mml->mml_marker.cm_tgtname, devname,
702 sizeof(mml->mml_marker.cm_tgtname)) >=
703 sizeof(mml->mml_marker.cm_tgtname))
704 GOTO(out_free, rc = -E2BIG);
705 /* Modify mostly means cancel */
706 mml->mml_marker.cm_flags = flags;
707 mml->mml_marker.cm_canceltime = flags ? cfs_time_current_sec() : 0;
708 mml->mml_modified = 0;
709 rc = llog_process(env, loghandle, mgs_modify_handler, (void *)mml,
711 if (!rc && !mml->mml_modified)
718 llog_close(env, loghandle);
721 CERROR("%s: modify %s/%s failed: rc = %d\n",
722 mgs->mgs_obd->obd_name, mti->mti_svname, comment, rc);
727 /** This structure is passed to mgs_replace_handler */
728 struct mgs_replace_uuid_lookup {
729 /* Nids are replaced for this target device */
730 struct mgs_target_info target;
731 /* Temporary modified llog */
732 struct llog_handle *temp_llh;
733 /* Flag is set if in target block*/
734 int in_target_device;
735 /* Nids already added. Just skip (multiple nids) */
736 int device_nids_added;
737 /* Flag is set if this block should not be copied */
742 * Check: a) if block should be skipped
743 * b) is it target block
748 * \retval 0 should not to be skipped
749 * \retval 1 should to be skipped
751 static int check_markers(struct lustre_cfg *lcfg,
752 struct mgs_replace_uuid_lookup *mrul)
754 struct cfg_marker *marker;
756 /* Track markers. Find given device */
757 if (lcfg->lcfg_command == LCFG_MARKER) {
758 marker = lustre_cfg_buf(lcfg, 1);
759 /* Clean llog from records marked as CM_EXCLUDE.
760 CM_SKIP records are used for "active" command
761 and can be restored if needed */
762 if ((marker->cm_flags & (CM_EXCLUDE | CM_START)) ==
763 (CM_EXCLUDE | CM_START)) {
768 if ((marker->cm_flags & (CM_EXCLUDE | CM_END)) ==
769 (CM_EXCLUDE | CM_END)) {
774 if (strcmp(mrul->target.mti_svname, marker->cm_tgtname) == 0) {
775 LASSERT(!(marker->cm_flags & CM_START) ||
776 !(marker->cm_flags & CM_END));
777 if (marker->cm_flags & CM_START) {
778 mrul->in_target_device = 1;
779 mrul->device_nids_added = 0;
780 } else if (marker->cm_flags & CM_END)
781 mrul->in_target_device = 0;
788 static int record_base(const struct lu_env *env, struct llog_handle *llh,
789 char *cfgname, lnet_nid_t nid, int cmd,
790 char *s1, char *s2, char *s3, char *s4)
792 struct mgs_thread_info *mgi = mgs_env_info(env);
793 struct llog_cfg_rec *lcr;
796 CDEBUG(D_MGS, "lcfg %s %#x %s %s %s %s\n", cfgname,
797 cmd, s1, s2, s3, s4);
799 lustre_cfg_bufs_reset(&mgi->mgi_bufs, cfgname);
801 lustre_cfg_bufs_set_string(&mgi->mgi_bufs, 1, s1);
803 lustre_cfg_bufs_set_string(&mgi->mgi_bufs, 2, s2);
805 lustre_cfg_bufs_set_string(&mgi->mgi_bufs, 3, s3);
807 lustre_cfg_bufs_set_string(&mgi->mgi_bufs, 4, s4);
809 lcr = lustre_cfg_rec_new(cmd, &mgi->mgi_bufs);
813 lcr->lcr_cfg.lcfg_nid = nid;
814 rc = llog_write(env, llh, &lcr->lcr_hdr, LLOG_NEXT_IDX);
816 lustre_cfg_rec_free(lcr);
820 "failed to write lcfg %s %#x %s %s %s %s: rc = %d\n",
821 cfgname, cmd, s1, s2, s3, s4, rc);
825 static inline int record_add_uuid(const struct lu_env *env,
826 struct llog_handle *llh,
827 uint64_t nid, char *uuid)
829 return record_base(env, llh, NULL, nid, LCFG_ADD_UUID, uuid,
833 static inline int record_add_conn(const struct lu_env *env,
834 struct llog_handle *llh,
835 char *devname, char *uuid)
837 return record_base(env, llh, devname, 0, LCFG_ADD_CONN, uuid,
841 static inline int record_attach(const struct lu_env *env,
842 struct llog_handle *llh, char *devname,
843 char *type, char *uuid)
845 return record_base(env, llh, devname, 0, LCFG_ATTACH, type, uuid,
849 static inline int record_setup(const struct lu_env *env,
850 struct llog_handle *llh, char *devname,
851 char *s1, char *s2, char *s3, char *s4)
853 return record_base(env, llh, devname, 0, LCFG_SETUP, s1, s2, s3, s4);
857 * \retval <0 record processing error
858 * \retval n record is processed. No need copy original one.
859 * \retval 0 record is not processed.
861 static int process_command(const struct lu_env *env, struct lustre_cfg *lcfg,
862 struct mgs_replace_uuid_lookup *mrul)
869 if (lcfg->lcfg_command == LCFG_ADD_UUID) {
870 /* LCFG_ADD_UUID command found. Let's skip original command
871 and add passed nids */
872 ptr = mrul->target.mti_params;
873 while (class_parse_nid(ptr, &nid, &ptr) == 0) {
874 CDEBUG(D_MGS, "add nid %s with uuid %s, "
875 "device %s\n", libcfs_nid2str(nid),
876 mrul->target.mti_params,
877 mrul->target.mti_svname);
878 rc = record_add_uuid(env,
880 mrul->target.mti_params);
885 if (nids_added == 0) {
886 CERROR("No new nids were added, nid %s with uuid %s, "
887 "device %s\n", libcfs_nid2str(nid),
888 mrul->target.mti_params,
889 mrul->target.mti_svname);
892 mrul->device_nids_added = 1;
898 if (mrul->device_nids_added && lcfg->lcfg_command == LCFG_SETUP) {
899 /* LCFG_SETUP command found. UUID should be changed */
900 rc = record_setup(env,
902 /* devname the same */
903 lustre_cfg_string(lcfg, 0),
904 /* s1 is not changed */
905 lustre_cfg_string(lcfg, 1),
906 /* new uuid should be
908 mrul->target.mti_params,
909 /* s3 is not changed */
910 lustre_cfg_string(lcfg, 3),
911 /* s4 is not changed */
912 lustre_cfg_string(lcfg, 4));
916 /* Another commands in target device block */
921 * Handler that called for every record in llog.
922 * Records are processed in order they placed in llog.
924 * \param[in] llh log to be processed
925 * \param[in] rec current record
926 * \param[in] data mgs_replace_uuid_lookup structure
930 static int mgs_replace_handler(const struct lu_env *env,
931 struct llog_handle *llh,
932 struct llog_rec_hdr *rec,
935 struct mgs_replace_uuid_lookup *mrul;
936 struct lustre_cfg *lcfg = REC_DATA(rec);
937 int cfg_len = REC_DATA_LEN(rec);
941 mrul = (struct mgs_replace_uuid_lookup *)data;
943 if (rec->lrh_type != OBD_CFG_REC) {
944 CERROR("unhandled lrh_type: %#x, cmd %x %s %s\n",
945 rec->lrh_type, lcfg->lcfg_command,
946 lustre_cfg_string(lcfg, 0),
947 lustre_cfg_string(lcfg, 1));
951 rc = lustre_cfg_sanity_check(lcfg, cfg_len);
953 /* Do not copy any invalidated records */
954 GOTO(skip_out, rc = 0);
957 rc = check_markers(lcfg, mrul);
958 if (rc || mrul->skip_it)
959 GOTO(skip_out, rc = 0);
961 /* Write to new log all commands outside target device block */
962 if (!mrul->in_target_device)
963 GOTO(copy_out, rc = 0);
965 /* Skip all other LCFG_ADD_UUID and LCFG_ADD_CONN records
966 (failover nids) for this target, assuming that if then
967 primary is changing then so is the failover */
968 if (mrul->device_nids_added &&
969 (lcfg->lcfg_command == LCFG_ADD_UUID ||
970 lcfg->lcfg_command == LCFG_ADD_CONN))
971 GOTO(skip_out, rc = 0);
973 rc = process_command(env, lcfg, mrul);
980 /* Record is placed in temporary llog as is */
981 rc = llog_write(env, mrul->temp_llh, rec, LLOG_NEXT_IDX);
983 CDEBUG(D_MGS, "Copied idx=%d, rc=%d, len=%d, cmd %x %s %s\n",
984 rec->lrh_index, rc, rec->lrh_len, lcfg->lcfg_command,
985 lustre_cfg_string(lcfg, 0), lustre_cfg_string(lcfg, 1));
989 CDEBUG(D_MGS, "Skipped idx=%d, rc=%d, len=%d, cmd %x %s %s\n",
990 rec->lrh_index, rc, rec->lrh_len, lcfg->lcfg_command,
991 lustre_cfg_string(lcfg, 0), lustre_cfg_string(lcfg, 1));
995 static int mgs_log_is_empty(const struct lu_env *env,
996 struct mgs_device *mgs, char *name)
998 struct llog_ctxt *ctxt;
1001 ctxt = llog_get_context(mgs->mgs_obd, LLOG_CONFIG_ORIG_CTXT);
1002 LASSERT(ctxt != NULL);
1004 rc = llog_is_empty(env, ctxt, name);
1005 llog_ctxt_put(ctxt);
1009 static int mgs_replace_nids_log(const struct lu_env *env,
1010 struct obd_device *mgs, struct fs_db *fsdb,
1011 char *logname, char *devname, char *nids)
1013 struct llog_handle *orig_llh, *backup_llh;
1014 struct llog_ctxt *ctxt;
1015 struct mgs_replace_uuid_lookup *mrul;
1016 struct mgs_device *mgs_dev = lu2mgs_dev(mgs->obd_lu_dev);
1017 static struct obd_uuid cfg_uuid = { .uuid = "config_uuid" };
1022 CDEBUG(D_MGS, "Replace nids for %s in %s\n", devname, logname);
1024 ctxt = llog_get_context(mgs, LLOG_CONFIG_ORIG_CTXT);
1025 LASSERT(ctxt != NULL);
1027 if (mgs_log_is_empty(env, mgs_dev, logname)) {
1028 /* Log is empty. Nothing to replace */
1029 GOTO(out_put, rc = 0);
1032 OBD_ALLOC(backup, strlen(logname) + strlen(".bak") + 1);
1034 GOTO(out_put, rc = -ENOMEM);
1036 sprintf(backup, "%s.bak", logname);
1038 rc = llog_backup(env, mgs, ctxt, ctxt, logname, backup);
1040 /* Now erase original log file. Connections are not allowed.
1041 Backup is already saved */
1042 rc = llog_erase(env, ctxt, NULL, logname);
1045 } else if (rc != -ENOENT) {
1046 CERROR("%s: can't make backup for %s: rc = %d\n",
1047 mgs->obd_name, logname, rc);
1051 /* open local log */
1052 rc = llog_open_create(env, ctxt, &orig_llh, NULL, logname);
1054 GOTO(out_restore, rc);
1056 rc = llog_init_handle(env, orig_llh, LLOG_F_IS_PLAIN, &cfg_uuid);
1058 GOTO(out_closel, rc);
1060 /* open backup llog */
1061 rc = llog_open(env, ctxt, &backup_llh, NULL, backup,
1064 GOTO(out_closel, rc);
1066 rc = llog_init_handle(env, backup_llh, LLOG_F_IS_PLAIN, NULL);
1068 GOTO(out_close, rc);
1070 if (llog_get_size(backup_llh) <= 1)
1071 GOTO(out_close, rc = 0);
1073 OBD_ALLOC_PTR(mrul);
1075 GOTO(out_close, rc = -ENOMEM);
1076 /* devname is only needed information to replace UUID records */
1077 strlcpy(mrul->target.mti_svname, devname,
1078 sizeof(mrul->target.mti_svname));
1079 /* parse nids later */
1080 strlcpy(mrul->target.mti_params, nids, sizeof(mrul->target.mti_params));
1081 /* Copy records to this temporary llog */
1082 mrul->temp_llh = orig_llh;
1084 rc = llog_process(env, backup_llh, mgs_replace_handler,
1085 (void *)mrul, NULL);
1088 rc2 = llog_close(NULL, backup_llh);
1092 rc2 = llog_close(NULL, orig_llh);
1098 CERROR("%s: llog should be restored: rc = %d\n",
1100 rc2 = llog_backup(env, mgs, ctxt, ctxt, backup,
1103 CERROR("%s: can't restore backup %s: rc = %d\n",
1104 mgs->obd_name, logname, rc2);
1108 OBD_FREE(backup, strlen(backup) + 1);
1111 llog_ctxt_put(ctxt);
1114 CERROR("%s: failed to replace nids in log %s: rc = %d\n",
1115 mgs->obd_name, logname, rc);
1121 * Parse device name and get file system name and/or device index
1123 * \param[in] devname device name (ex. lustre-MDT0000)
1124 * \param[out] fsname file system name(optional)
1125 * \param[out] index device index(optional)
1129 static int mgs_parse_devname(char *devname, char *fsname, __u32 *index)
1134 /* Extract fsname */
1136 rc = server_name2fsname(devname, fsname, NULL);
1138 CDEBUG(D_MGS, "Device name %s without fsname\n",
1145 rc = server_name2index(devname, index, NULL);
1147 CDEBUG(D_MGS, "Device name %s with wrong index\n",
1156 /* This is only called during replace_nids */
1157 static int only_mgs_is_running(struct obd_device *mgs_obd)
1159 /* TDB: Is global variable with devices count exists? */
1160 int num_devices = get_devices_count();
1161 int num_exports = 0;
1162 struct obd_export *exp;
1164 spin_lock(&mgs_obd->obd_dev_lock);
1165 list_for_each_entry(exp, &mgs_obd->obd_exports, exp_obd_chain) {
1166 /* skip self export */
1167 if (exp == mgs_obd->obd_self_export)
1169 if (exp_connect_flags(exp) & OBD_CONNECT_MDS_MDS)
1174 CERROR("%s: node %s still connected during replace_nids "
1175 "connect_flags:%llx\n",
1177 libcfs_nid2str(exp->exp_nid_stats->nid),
1178 exp_connect_flags(exp));
1181 spin_unlock(&mgs_obd->obd_dev_lock);
1183 /* osd, MGS and MGC + self_export
1184 (wc -l /proc/fs/lustre/devices <= 2) && (non self exports == 0) */
1185 return (num_devices <= 3) && (num_exports == 0);
1188 static int name_create_mdt(char **logname, char *fsname, int i)
1192 sprintf(mdt_index, "-MDT%04x", i);
1193 return name_create(logname, fsname, mdt_index);
1197 * Replace nids for \a device to \a nids values
1199 * \param obd MGS obd device
1200 * \param devname nids need to be replaced for this device
1201 * (ex. lustre-OST0000)
1202 * \param nids nids list (ex. nid1,nid2,nid3)
1206 int mgs_replace_nids(const struct lu_env *env,
1207 struct mgs_device *mgs,
1208 char *devname, char *nids)
1210 /* Assume fsname is part of device name */
1211 char fsname[MTI_NAME_MAXLEN];
1218 struct obd_device *mgs_obd = mgs->mgs_obd;
1221 /* We can only change NIDs if no other nodes are connected */
1222 spin_lock(&mgs_obd->obd_dev_lock);
1223 conn_state = mgs_obd->obd_no_conn;
1224 mgs_obd->obd_no_conn = 1;
1225 spin_unlock(&mgs_obd->obd_dev_lock);
1227 /* We can not change nids if not only MGS is started */
1228 if (!only_mgs_is_running(mgs_obd)) {
1229 CERROR("Only MGS is allowed to be started\n");
1230 GOTO(out, rc = -EINPROGRESS);
1233 /* Get fsname and index*/
1234 rc = mgs_parse_devname(devname, fsname, &index);
1238 rc = mgs_find_or_make_fsdb(env, mgs, fsname, &fsdb);
1240 CERROR("%s: can't find fsdb: rc = %d\n", fsname, rc);
1244 /* Process client llogs */
1245 name_create(&logname, fsname, "-client");
1246 rc = mgs_replace_nids_log(env, mgs_obd, fsdb, logname, devname, nids);
1247 name_destroy(&logname);
1249 CERROR("%s: error while replacing NIDs for %s: rc = %d\n",
1250 fsname, devname, rc);
1254 /* Process MDT llogs */
1255 for (i = 0; i < INDEX_MAP_SIZE * 8; i++) {
1256 if (!test_bit(i, fsdb->fsdb_mdt_index_map))
1258 name_create_mdt(&logname, fsname, i);
1259 rc = mgs_replace_nids_log(env, mgs_obd, fsdb, logname, devname, nids);
1260 name_destroy(&logname);
1266 spin_lock(&mgs_obd->obd_dev_lock);
1267 mgs_obd->obd_no_conn = conn_state;
1268 spin_unlock(&mgs_obd->obd_dev_lock);
1273 static int record_lov_setup(const struct lu_env *env, struct llog_handle *llh,
1274 char *devname, struct lov_desc *desc)
1276 struct mgs_thread_info *mgi = mgs_env_info(env);
1277 struct llog_cfg_rec *lcr;
1280 lustre_cfg_bufs_reset(&mgi->mgi_bufs, devname);
1281 lustre_cfg_bufs_set(&mgi->mgi_bufs, 1, desc, sizeof(*desc));
1282 lcr = lustre_cfg_rec_new(LCFG_SETUP, &mgi->mgi_bufs);
1286 rc = llog_write(env, llh, &lcr->lcr_hdr, LLOG_NEXT_IDX);
1287 lustre_cfg_rec_free(lcr);
1291 static int record_lmv_setup(const struct lu_env *env, struct llog_handle *llh,
1292 char *devname, struct lmv_desc *desc)
1294 struct mgs_thread_info *mgi = mgs_env_info(env);
1295 struct llog_cfg_rec *lcr;
1298 lustre_cfg_bufs_reset(&mgi->mgi_bufs, devname);
1299 lustre_cfg_bufs_set(&mgi->mgi_bufs, 1, desc, sizeof(*desc));
1300 lcr = lustre_cfg_rec_new(LCFG_SETUP, &mgi->mgi_bufs);
1304 rc = llog_write(env, llh, &lcr->lcr_hdr, LLOG_NEXT_IDX);
1305 lustre_cfg_rec_free(lcr);
1309 static inline int record_mdc_add(const struct lu_env *env,
1310 struct llog_handle *llh,
1311 char *logname, char *mdcuuid,
1312 char *mdtuuid, char *index,
1315 return record_base(env,llh,logname,0,LCFG_ADD_MDC,
1316 mdtuuid,index,gen,mdcuuid);
1319 static inline int record_lov_add(const struct lu_env *env,
1320 struct llog_handle *llh,
1321 char *lov_name, char *ost_uuid,
1322 char *index, char *gen)
1324 return record_base(env, llh, lov_name, 0, LCFG_LOV_ADD_OBD,
1325 ost_uuid, index, gen, NULL);
1328 static inline int record_mount_opt(const struct lu_env *env,
1329 struct llog_handle *llh,
1330 char *profile, char *lov_name,
1333 return record_base(env, llh, NULL, 0, LCFG_MOUNTOPT,
1334 profile, lov_name, mdc_name, NULL);
1337 static int record_marker(const struct lu_env *env,
1338 struct llog_handle *llh,
1339 struct fs_db *fsdb, __u32 flags,
1340 char *tgtname, char *comment)
1342 struct mgs_thread_info *mgi = mgs_env_info(env);
1343 struct llog_cfg_rec *lcr;
1347 if (flags & CM_START)
1349 mgi->mgi_marker.cm_step = fsdb->fsdb_gen;
1350 mgi->mgi_marker.cm_flags = flags;
1351 mgi->mgi_marker.cm_vers = LUSTRE_VERSION_CODE;
1352 cplen = strlcpy(mgi->mgi_marker.cm_tgtname, tgtname,
1353 sizeof(mgi->mgi_marker.cm_tgtname));
1354 if (cplen >= sizeof(mgi->mgi_marker.cm_tgtname))
1356 cplen = strlcpy(mgi->mgi_marker.cm_comment, comment,
1357 sizeof(mgi->mgi_marker.cm_comment));
1358 if (cplen >= sizeof(mgi->mgi_marker.cm_comment))
1360 mgi->mgi_marker.cm_createtime = cfs_time_current_sec();
1361 mgi->mgi_marker.cm_canceltime = 0;
1362 lustre_cfg_bufs_reset(&mgi->mgi_bufs, NULL);
1363 lustre_cfg_bufs_set(&mgi->mgi_bufs, 1, &mgi->mgi_marker,
1364 sizeof(mgi->mgi_marker));
1365 lcr = lustre_cfg_rec_new(LCFG_MARKER, &mgi->mgi_bufs);
1369 rc = llog_write(env, llh, &lcr->lcr_hdr, LLOG_NEXT_IDX);
1370 lustre_cfg_rec_free(lcr);
1374 static int record_start_log(const struct lu_env *env, struct mgs_device *mgs,
1375 struct llog_handle **llh, char *name)
1377 static struct obd_uuid cfg_uuid = { .uuid = "config_uuid" };
1378 struct llog_ctxt *ctxt;
1383 GOTO(out, rc = -EBUSY);
1385 ctxt = llog_get_context(mgs->mgs_obd, LLOG_CONFIG_ORIG_CTXT);
1387 GOTO(out, rc = -ENODEV);
1388 LASSERT(ctxt->loc_obd == mgs->mgs_obd);
1390 rc = llog_open_create(env, ctxt, llh, NULL, name);
1393 rc = llog_init_handle(env, *llh, LLOG_F_IS_PLAIN, &cfg_uuid);
1395 llog_close(env, *llh);
1397 llog_ctxt_put(ctxt);
1400 CERROR("%s: can't start log %s: rc = %d\n",
1401 mgs->mgs_obd->obd_name, name, rc);
1407 static int record_end_log(const struct lu_env *env, struct llog_handle **llh)
1411 rc = llog_close(env, *llh);
1417 /******************** config "macros" *********************/
1419 /* write an lcfg directly into a log (with markers) */
1420 static int mgs_write_log_direct(const struct lu_env *env,
1421 struct mgs_device *mgs, struct fs_db *fsdb,
1422 char *logname, struct llog_cfg_rec *lcr,
1423 char *devname, char *comment)
1425 struct llog_handle *llh = NULL;
1430 rc = record_start_log(env, mgs, &llh, logname);
1434 /* FIXME These should be a single journal transaction */
1435 rc = record_marker(env, llh, fsdb, CM_START, devname, comment);
1438 rc = llog_write(env, llh, &lcr->lcr_hdr, LLOG_NEXT_IDX);
1441 rc = record_marker(env, llh, fsdb, CM_END, devname, comment);
1445 record_end_log(env, &llh);
1449 /* write the lcfg in all logs for the given fs */
1450 static int mgs_write_log_direct_all(const struct lu_env *env,
1451 struct mgs_device *mgs,
1453 struct mgs_target_info *mti,
1454 struct llog_cfg_rec *lcr, char *devname,
1455 char *comment, int server_only)
1457 struct list_head log_list;
1458 struct mgs_direntry *dirent, *n;
1459 char *fsname = mti->mti_fsname;
1460 int rc = 0, len = strlen(fsname);
1463 /* Find all the logs in the CONFIGS directory */
1464 rc = class_dentry_readdir(env, mgs, &log_list);
1468 /* Could use fsdb index maps instead of directory listing */
1469 list_for_each_entry_safe(dirent, n, &log_list, mde_list) {
1470 list_del_init(&dirent->mde_list);
1471 /* don't write to sptlrpc rule log */
1472 if (strstr(dirent->mde_name, "-sptlrpc") != NULL)
1475 /* caller wants write server logs only */
1476 if (server_only && strstr(dirent->mde_name, "-client") != NULL)
1479 if (strlen(dirent->mde_name) <= len ||
1480 strncmp(fsname, dirent->mde_name, len) != 0 ||
1481 dirent->mde_name[len] != '-')
1484 CDEBUG(D_MGS, "Changing log %s\n", dirent->mde_name);
1485 /* Erase any old settings of this same parameter */
1486 rc = mgs_modify(env, mgs, fsdb, mti, dirent->mde_name,
1487 devname, comment, CM_SKIP);
1489 CERROR("%s: Can't modify llog %s: rc = %d\n",
1490 mgs->mgs_obd->obd_name, dirent->mde_name, rc);
1493 /* Write the new one */
1494 rc = mgs_write_log_direct(env, mgs, fsdb, dirent->mde_name,
1495 lcr, devname, comment);
1497 CERROR("%s: writing log %s: rc = %d\n",
1498 mgs->mgs_obd->obd_name, dirent->mde_name, rc);
1500 mgs_direntry_free(dirent);
1506 static int mgs_write_log_osp_to_mdt(const struct lu_env *env,
1507 struct mgs_device *mgs,
1509 struct mgs_target_info *mti,
1510 int index, char *logname);
1511 static int mgs_write_log_osc_to_lov(const struct lu_env *env,
1512 struct mgs_device *mgs,
1514 struct mgs_target_info *mti,
1515 char *logname, char *suffix, char *lovname,
1516 enum lustre_sec_part sec_part, int flags);
1517 static int name_create_mdt_and_lov(char **logname, char **lovname,
1518 struct fs_db *fsdb, int i);
1520 static int add_param(char *params, char *key, char *val)
1522 char *start = params + strlen(params);
1523 char *end = params + sizeof(((struct mgs_target_info *)0)->mti_params);
1527 keylen = strlen(key);
1528 if (start + 1 + keylen + strlen(val) >= end) {
1529 CERROR("params are too long: %s %s%s\n",
1530 params, key != NULL ? key : "", val);
1534 sprintf(start, " %s%s", key != NULL ? key : "", val);
1539 * Walk through client config log record and convert the related records
1542 static int mgs_steal_client_llog_handler(const struct lu_env *env,
1543 struct llog_handle *llh,
1544 struct llog_rec_hdr *rec, void *data)
1546 struct mgs_device *mgs;
1547 struct obd_device *obd;
1548 struct mgs_target_info *mti, *tmti;
1550 int cfg_len = rec->lrh_len;
1551 char *cfg_buf = (char*) (rec + 1);
1552 struct lustre_cfg *lcfg;
1554 struct llog_handle *mdt_llh = NULL;
1555 static int got_an_osc_or_mdc = 0;
1556 /* 0: not found any osc/mdc;
1560 static int last_step = -1;
1565 mti = ((struct temp_comp*)data)->comp_mti;
1566 tmti = ((struct temp_comp*)data)->comp_tmti;
1567 fsdb = ((struct temp_comp*)data)->comp_fsdb;
1568 obd = ((struct temp_comp *)data)->comp_obd;
1569 mgs = lu2mgs_dev(obd->obd_lu_dev);
1572 if (rec->lrh_type != OBD_CFG_REC) {
1573 CERROR("unhandled lrh_type: %#x\n", rec->lrh_type);
1577 rc = lustre_cfg_sanity_check(cfg_buf, cfg_len);
1579 CERROR("Insane cfg\n");
1583 lcfg = (struct lustre_cfg *)cfg_buf;
1585 if (lcfg->lcfg_command == LCFG_MARKER) {
1586 struct cfg_marker *marker;
1587 marker = lustre_cfg_buf(lcfg, 1);
1588 if (!strncmp(marker->cm_comment, "add osc", 7) &&
1589 (marker->cm_flags & CM_START) &&
1590 !(marker->cm_flags & CM_SKIP)) {
1591 got_an_osc_or_mdc = 1;
1592 cplen = strlcpy(tmti->mti_svname, marker->cm_tgtname,
1593 sizeof(tmti->mti_svname));
1594 if (cplen >= sizeof(tmti->mti_svname))
1596 rc = record_start_log(env, mgs, &mdt_llh,
1600 rc = record_marker(env, mdt_llh, fsdb, CM_START,
1601 mti->mti_svname, "add osc(copied)");
1602 record_end_log(env, &mdt_llh);
1603 last_step = marker->cm_step;
1606 if (!strncmp(marker->cm_comment, "add osc", 7) &&
1607 (marker->cm_flags & CM_END) &&
1608 !(marker->cm_flags & CM_SKIP)) {
1609 LASSERT(last_step == marker->cm_step);
1611 got_an_osc_or_mdc = 0;
1612 memset(tmti, 0, sizeof(*tmti));
1613 rc = record_start_log(env, mgs, &mdt_llh,
1617 rc = record_marker(env, mdt_llh, fsdb, CM_END,
1618 mti->mti_svname, "add osc(copied)");
1619 record_end_log(env, &mdt_llh);
1622 if (!strncmp(marker->cm_comment, "add mdc", 7) &&
1623 (marker->cm_flags & CM_START) &&
1624 !(marker->cm_flags & CM_SKIP)) {
1625 got_an_osc_or_mdc = 2;
1626 last_step = marker->cm_step;
1627 memcpy(tmti->mti_svname, marker->cm_tgtname,
1628 strlen(marker->cm_tgtname));
1632 if (!strncmp(marker->cm_comment, "add mdc", 7) &&
1633 (marker->cm_flags & CM_END) &&
1634 !(marker->cm_flags & CM_SKIP)) {
1635 LASSERT(last_step == marker->cm_step);
1637 got_an_osc_or_mdc = 0;
1638 memset(tmti, 0, sizeof(*tmti));
1643 if (got_an_osc_or_mdc == 0 || last_step < 0)
1646 if (lcfg->lcfg_command == LCFG_ADD_UUID) {
1647 __u64 nodenid = lcfg->lcfg_nid;
1649 if (strlen(tmti->mti_uuid) == 0) {
1650 /* target uuid not set, this config record is before
1651 * LCFG_SETUP, this nid is one of target node nid.
1653 tmti->mti_nids[tmti->mti_nid_count] = nodenid;
1654 tmti->mti_nid_count++;
1656 char nidstr[LNET_NIDSTR_SIZE];
1658 /* failover node nid */
1659 libcfs_nid2str_r(nodenid, nidstr, sizeof(nidstr));
1660 rc = add_param(tmti->mti_params, PARAM_FAILNODE,
1667 if (lcfg->lcfg_command == LCFG_SETUP) {
1670 target = lustre_cfg_string(lcfg, 1);
1671 memcpy(tmti->mti_uuid, target, strlen(target));
1675 /* ignore client side sptlrpc_conf_log */
1676 if (lcfg->lcfg_command == LCFG_SPTLRPC_CONF)
1679 if (lcfg->lcfg_command == LCFG_ADD_MDC) {
1682 if (sscanf(lustre_cfg_buf(lcfg, 2), "%d", &index) != 1)
1685 memcpy(tmti->mti_fsname, mti->mti_fsname,
1686 strlen(mti->mti_fsname));
1687 tmti->mti_stripe_index = index;
1689 rc = mgs_write_log_osp_to_mdt(env, mgs, fsdb, tmti,
1690 mti->mti_stripe_index,
1692 memset(tmti, 0, sizeof(*tmti));
1696 if (lcfg->lcfg_command == LCFG_LOV_ADD_OBD) {
1699 char *logname, *lovname;
1701 rc = name_create_mdt_and_lov(&logname, &lovname, fsdb,
1702 mti->mti_stripe_index);
1705 sprintf(mdt_index, "-MDT%04x", mti->mti_stripe_index);
1707 if (sscanf(lustre_cfg_buf(lcfg, 2), "%d", &index) != 1) {
1708 name_destroy(&logname);
1709 name_destroy(&lovname);
1713 tmti->mti_stripe_index = index;
1714 rc = mgs_write_log_osc_to_lov(env, mgs, fsdb, tmti, logname,
1717 name_destroy(&logname);
1718 name_destroy(&lovname);
1724 /* fsdb->fsdb_mutex is already held in mgs_write_log_target*/
1725 /* stealed from mgs_get_fsdb_from_llog*/
1726 static int mgs_steal_llog_for_mdt_from_client(const struct lu_env *env,
1727 struct mgs_device *mgs,
1729 struct temp_comp* comp)
1731 struct llog_handle *loghandle;
1732 struct mgs_target_info *tmti;
1733 struct llog_ctxt *ctxt;
1738 ctxt = llog_get_context(mgs->mgs_obd, LLOG_CONFIG_ORIG_CTXT);
1739 LASSERT(ctxt != NULL);
1741 OBD_ALLOC_PTR(tmti);
1743 GOTO(out_ctxt, rc = -ENOMEM);
1745 comp->comp_tmti = tmti;
1746 comp->comp_obd = mgs->mgs_obd;
1748 rc = llog_open(env, ctxt, &loghandle, NULL, client_name,
1756 rc = llog_init_handle(env, loghandle, LLOG_F_IS_PLAIN, NULL);
1758 GOTO(out_close, rc);
1760 rc = llog_process_or_fork(env, loghandle, mgs_steal_client_llog_handler,
1761 (void *)comp, NULL, false);
1762 CDEBUG(D_MGS, "steal llog re = %d\n", rc);
1764 llog_close(env, loghandle);
1768 llog_ctxt_put(ctxt);
1772 /* lmv is the second thing for client logs */
1773 /* copied from mgs_write_log_lov. Please refer to that. */
1774 static int mgs_write_log_lmv(const struct lu_env *env,
1775 struct mgs_device *mgs,
1777 struct mgs_target_info *mti,
1778 char *logname, char *lmvname)
1780 struct llog_handle *llh = NULL;
1781 struct lmv_desc *lmvdesc;
1786 CDEBUG(D_MGS, "Writing lmv(%s) log for %s\n", lmvname,logname);
1788 OBD_ALLOC_PTR(lmvdesc);
1789 if (lmvdesc == NULL)
1791 lmvdesc->ld_active_tgt_count = 0;
1792 lmvdesc->ld_tgt_count = 0;
1793 sprintf((char*)lmvdesc->ld_uuid.uuid, "%s_UUID", lmvname);
1794 uuid = (char *)lmvdesc->ld_uuid.uuid;
1796 rc = record_start_log(env, mgs, &llh, logname);
1799 rc = record_marker(env, llh, fsdb, CM_START, lmvname, "lmv setup");
1802 rc = record_attach(env, llh, lmvname, "lmv", uuid);
1805 rc = record_lmv_setup(env, llh, lmvname, lmvdesc);
1808 rc = record_marker(env, llh, fsdb, CM_END, lmvname, "lmv setup");
1812 record_end_log(env, &llh);
1814 OBD_FREE_PTR(lmvdesc);
1818 /* lov is the first thing in the mdt and client logs */
1819 static int mgs_write_log_lov(const struct lu_env *env, struct mgs_device *mgs,
1820 struct fs_db *fsdb, struct mgs_target_info *mti,
1821 char *logname, char *lovname)
1823 struct llog_handle *llh = NULL;
1824 struct lov_desc *lovdesc;
1829 CDEBUG(D_MGS, "Writing lov(%s) log for %s\n", lovname, logname);
1832 #01 L attach 0:lov_mdsA 1:lov 2:71ccb_lov_mdsA_19f961a9e1
1833 #02 L lov_setup 0:lov_mdsA 1:(struct lov_desc)
1834 uuid=lov1_UUID, stripe count=1, size=1048576, offset=0, pattern=0
1837 /* FIXME just make lov_setup accept empty desc (put uuid in buf 2) */
1838 OBD_ALLOC_PTR(lovdesc);
1839 if (lovdesc == NULL)
1841 lovdesc->ld_magic = LOV_DESC_MAGIC;
1842 lovdesc->ld_tgt_count = 0;
1843 /* Defaults. Can be changed later by lcfg config_param */
1844 lovdesc->ld_default_stripe_count = 1;
1845 lovdesc->ld_pattern = LOV_PATTERN_RAID0;
1846 lovdesc->ld_default_stripe_size = LOV_DESC_STRIPE_SIZE_DEFAULT;
1847 lovdesc->ld_default_stripe_offset = -1;
1848 lovdesc->ld_qos_maxage = LOV_DESC_QOS_MAXAGE_DEFAULT;
1849 sprintf((char*)lovdesc->ld_uuid.uuid, "%s_UUID", lovname);
1850 /* can these be the same? */
1851 uuid = (char *)lovdesc->ld_uuid.uuid;
1853 /* This should always be the first entry in a log.
1854 rc = mgs_clear_log(obd, logname); */
1855 rc = record_start_log(env, mgs, &llh, logname);
1858 /* FIXME these should be a single journal transaction */
1859 rc = record_marker(env, llh, fsdb, CM_START, lovname, "lov setup");
1862 rc = record_attach(env, llh, lovname, "lov", uuid);
1865 rc = record_lov_setup(env, llh, lovname, lovdesc);
1868 rc = record_marker(env, llh, fsdb, CM_END, lovname, "lov setup");
1873 record_end_log(env, &llh);
1875 OBD_FREE_PTR(lovdesc);
1879 /* add failnids to open log */
1880 static int mgs_write_log_failnids(const struct lu_env *env,
1881 struct mgs_target_info *mti,
1882 struct llog_handle *llh,
1885 char *failnodeuuid = NULL;
1886 char *ptr = mti->mti_params;
1891 #03 L add_uuid nid=uml1@tcp(0x20000c0a80201) nal=90 0: 1:uml1_UUID
1892 #04 L add_uuid nid=1@elan(0x1000000000001) nal=90 0: 1:uml1_UUID
1893 #05 L setup 0:OSC_uml1_ost1_mdsA 1:ost1_UUID 2:uml1_UUID
1894 #06 L add_uuid nid=uml2@tcp(0x20000c0a80202) nal=90 0: 1:uml2_UUID
1895 #0x L add_uuid nid=2@elan(0x1000000000002) nal=90 0: 1:uml2_UUID
1896 #07 L add_conn 0:OSC_uml1_ost1_mdsA 1:uml2_UUID
1900 * Pull failnid info out of params string, which may contain something
1901 * like "<nid1>,<nid2>:<nid3>,<nid4>". class_parse_nid() does not
1902 * complain about abnormal inputs like ",:<nid1>", "<nid1>:,<nid2>",
1903 * etc. However, convert_hostnames() should have caught those.
1905 while (class_find_param(ptr, PARAM_FAILNODE, &ptr) == 0) {
1906 while (class_parse_nid(ptr, &nid, &ptr) == 0) {
1907 char nidstr[LNET_NIDSTR_SIZE];
1909 if (failnodeuuid == NULL) {
1910 /* We don't know the failover node name,
1911 * so just use the first nid as the uuid */
1912 libcfs_nid2str_r(nid, nidstr, sizeof(nidstr));
1913 rc = name_create(&failnodeuuid, nidstr, "");
1917 CDEBUG(D_MGS, "add nid %s for failover uuid %s, "
1919 libcfs_nid2str_r(nid, nidstr, sizeof(nidstr)),
1920 failnodeuuid, cliname);
1921 rc = record_add_uuid(env, llh, nid, failnodeuuid);
1923 * If *ptr is ':', we have added all NIDs for
1927 rc = record_add_conn(env, llh, cliname,
1929 name_destroy(&failnodeuuid);
1930 failnodeuuid = NULL;
1934 rc = record_add_conn(env, llh, cliname, failnodeuuid);
1935 name_destroy(&failnodeuuid);
1936 failnodeuuid = NULL;
1943 static int mgs_write_log_mdc_to_lmv(const struct lu_env *env,
1944 struct mgs_device *mgs,
1946 struct mgs_target_info *mti,
1947 char *logname, char *lmvname)
1949 struct llog_handle *llh = NULL;
1950 char *mdcname = NULL;
1951 char *nodeuuid = NULL;
1952 char *mdcuuid = NULL;
1953 char *lmvuuid = NULL;
1955 char nidstr[LNET_NIDSTR_SIZE];
1959 if (mgs_log_is_empty(env, mgs, logname)) {
1960 CERROR("log is empty! Logical error\n");
1964 CDEBUG(D_MGS, "adding mdc for %s to log %s:lmv(%s)\n",
1965 mti->mti_svname, logname, lmvname);
1967 libcfs_nid2str_r(mti->mti_nids[0], nidstr, sizeof(nidstr));
1968 rc = name_create(&nodeuuid, nidstr, "");
1971 rc = name_create(&mdcname, mti->mti_svname, "-mdc");
1974 rc = name_create(&mdcuuid, mdcname, "_UUID");
1977 rc = name_create(&lmvuuid, lmvname, "_UUID");
1981 rc = record_start_log(env, mgs, &llh, logname);
1984 rc = record_marker(env, llh, fsdb, CM_START, mti->mti_svname,
1988 for (i = 0; i < mti->mti_nid_count; i++) {
1989 CDEBUG(D_MGS, "add nid %s for mdt\n",
1990 libcfs_nid2str_r(mti->mti_nids[i],
1991 nidstr, sizeof(nidstr)));
1993 rc = record_add_uuid(env, llh, mti->mti_nids[i], nodeuuid);
1998 rc = record_attach(env, llh, mdcname, LUSTRE_MDC_NAME, lmvuuid);
2001 rc = record_setup(env, llh, mdcname, mti->mti_uuid, nodeuuid,
2005 rc = mgs_write_log_failnids(env, mti, llh, mdcname);
2008 snprintf(index, sizeof(index), "%d", mti->mti_stripe_index);
2009 rc = record_mdc_add(env, llh, lmvname, mdcuuid, mti->mti_uuid,
2013 rc = record_marker(env, llh, fsdb, CM_END, mti->mti_svname,
2018 record_end_log(env, &llh);
2020 name_destroy(&lmvuuid);
2021 name_destroy(&mdcuuid);
2022 name_destroy(&mdcname);
2023 name_destroy(&nodeuuid);
2027 static inline int name_create_lov(char **lovname, char *mdtname,
2028 struct fs_db *fsdb, int index)
2031 if (index == 0 && test_bit(FSDB_OSCNAME18, &fsdb->fsdb_flags))
2032 return name_create(lovname, fsdb->fsdb_name, "-mdtlov");
2034 return name_create(lovname, mdtname, "-mdtlov");
2037 static int name_create_mdt_and_lov(char **logname, char **lovname,
2038 struct fs_db *fsdb, int i)
2042 rc = name_create_mdt(logname, fsdb->fsdb_name, i);
2046 if (i == 0 && test_bit(FSDB_OSCNAME18, &fsdb->fsdb_flags))
2047 rc = name_create(lovname, fsdb->fsdb_name, "-mdtlov");
2049 rc = name_create(lovname, *logname, "-mdtlov");
2051 name_destroy(logname);
2057 static inline int name_create_mdt_osc(char **oscname, char *ostname,
2058 struct fs_db *fsdb, int i)
2062 if (i == 0 && test_bit(FSDB_OSCNAME18, &fsdb->fsdb_flags))
2063 sprintf(suffix, "-osc");
2065 sprintf(suffix, "-osc-MDT%04x", i);
2066 return name_create(oscname, ostname, suffix);
2069 /* add new mdc to already existent MDS */
2070 static int mgs_write_log_osp_to_mdt(const struct lu_env *env,
2071 struct mgs_device *mgs,
2073 struct mgs_target_info *mti,
2074 int mdt_index, char *logname)
2076 struct llog_handle *llh = NULL;
2077 char *nodeuuid = NULL;
2078 char *ospname = NULL;
2079 char *lovuuid = NULL;
2080 char *mdtuuid = NULL;
2081 char *svname = NULL;
2082 char *mdtname = NULL;
2083 char *lovname = NULL;
2085 char nidstr[LNET_NIDSTR_SIZE];
2089 if (mgs_log_is_empty(env, mgs, mti->mti_svname)) {
2090 CERROR("log is empty! Logical error\n");
2094 CDEBUG(D_MGS, "adding osp index %d to %s\n", mti->mti_stripe_index,
2097 rc = name_create_mdt(&mdtname, fsdb->fsdb_name, mti->mti_stripe_index);
2101 libcfs_nid2str_r(mti->mti_nids[0], nidstr, sizeof(nidstr));
2102 rc = name_create(&nodeuuid, nidstr, "");
2104 GOTO(out_destory, rc);
2106 rc = name_create(&svname, mdtname, "-osp");
2108 GOTO(out_destory, rc);
2110 sprintf(index_str, "-MDT%04x", mdt_index);
2111 rc = name_create(&ospname, svname, index_str);
2113 GOTO(out_destory, rc);
2115 rc = name_create_lov(&lovname, logname, fsdb, mdt_index);
2117 GOTO(out_destory, rc);
2119 rc = name_create(&lovuuid, lovname, "_UUID");
2121 GOTO(out_destory, rc);
2123 rc = name_create(&mdtuuid, mdtname, "_UUID");
2125 GOTO(out_destory, rc);
2127 rc = record_start_log(env, mgs, &llh, logname);
2129 GOTO(out_destory, rc);
2131 rc = record_marker(env, llh, fsdb, CM_START, mti->mti_svname,
2134 GOTO(out_destory, rc);
2136 for (i = 0; i < mti->mti_nid_count; i++) {
2137 CDEBUG(D_MGS, "add nid %s for mdt\n",
2138 libcfs_nid2str_r(mti->mti_nids[i],
2139 nidstr, sizeof(nidstr)));
2140 rc = record_add_uuid(env, llh, mti->mti_nids[i], nodeuuid);
2145 rc = record_attach(env, llh, ospname, LUSTRE_OSP_NAME, lovuuid);
2149 rc = record_setup(env, llh, ospname, mti->mti_uuid, nodeuuid,
2154 rc = mgs_write_log_failnids(env, mti, llh, ospname);
2158 /* Add mdc(osp) to lod */
2159 snprintf(index_str, sizeof(index_str), "%d", mti->mti_stripe_index);
2160 rc = record_base(env, llh, lovname, 0, LCFG_ADD_MDC, mti->mti_uuid,
2161 index_str, "1", NULL);
2165 rc = record_marker(env, llh, fsdb, CM_END, mti->mti_svname, "add osp");
2170 record_end_log(env, &llh);
2173 name_destroy(&mdtuuid);
2174 name_destroy(&lovuuid);
2175 name_destroy(&lovname);
2176 name_destroy(&ospname);
2177 name_destroy(&svname);
2178 name_destroy(&nodeuuid);
2179 name_destroy(&mdtname);
2183 static int mgs_write_log_mdt0(const struct lu_env *env,
2184 struct mgs_device *mgs,
2186 struct mgs_target_info *mti)
2188 char *log = mti->mti_svname;
2189 struct llog_handle *llh = NULL;
2190 char *uuid, *lovname;
2192 char *ptr = mti->mti_params;
2193 int rc = 0, failout = 0;
2196 OBD_ALLOC(uuid, sizeof(struct obd_uuid));
2200 if (class_find_param(ptr, PARAM_FAILMODE, &ptr) == 0)
2201 failout = (strncmp(ptr, "failout", 7) == 0);
2203 rc = name_create(&lovname, log, "-mdtlov");
2206 if (mgs_log_is_empty(env, mgs, log)) {
2207 rc = mgs_write_log_lov(env, mgs, fsdb, mti, log, lovname);
2212 sprintf(mdt_index, "%d", mti->mti_stripe_index);
2214 rc = record_start_log(env, mgs, &llh, log);
2218 /* add MDT itself */
2220 /* FIXME this whole fn should be a single journal transaction */
2221 sprintf(uuid, "%s_UUID", log);
2222 rc = record_marker(env, llh, fsdb, CM_START, log, "add mdt");
2225 rc = record_attach(env, llh, log, LUSTRE_MDT_NAME, uuid);
2228 rc = record_mount_opt(env, llh, log, lovname, NULL);
2231 rc = record_setup(env, llh, log, uuid, mdt_index, lovname,
2232 failout ? "n" : "f");
2235 rc = record_marker(env, llh, fsdb, CM_END, log, "add mdt");
2239 record_end_log(env, &llh);
2241 name_destroy(&lovname);
2243 OBD_FREE(uuid, sizeof(struct obd_uuid));
2247 /* envelope method for all layers log */
2248 static int mgs_write_log_mdt(const struct lu_env *env,
2249 struct mgs_device *mgs,
2251 struct mgs_target_info *mti)
2253 struct mgs_thread_info *mgi = mgs_env_info(env);
2254 struct llog_handle *llh = NULL;
2259 CDEBUG(D_MGS, "writing new mdt %s\n", mti->mti_svname);
2261 if (mti->mti_uuid[0] == '\0') {
2262 /* Make up our own uuid */
2263 snprintf(mti->mti_uuid, sizeof(mti->mti_uuid),
2264 "%s_UUID", mti->mti_svname);
2268 rc = mgs_write_log_mdt0(env, mgs, fsdb, mti);
2271 /* Append the mdt info to the client log */
2272 rc = name_create(&cliname, mti->mti_fsname, "-client");
2276 if (mgs_log_is_empty(env, mgs, cliname)) {
2277 /* Start client log */
2278 rc = mgs_write_log_lov(env, mgs, fsdb, mti, cliname,
2282 rc = mgs_write_log_lmv(env, mgs, fsdb, mti, cliname,
2289 #09 L add_uuid nid=uml1@tcp(0x20000c0a80201) 0: 1:uml1_UUID
2290 #10 L attach 0:MDC_uml1_mdsA_MNT_client 1:mdc 2:1d834_MNT_client_03f
2291 #11 L setup 0:MDC_uml1_mdsA_MNT_client 1:mdsA_UUID 2:uml1_UUID
2292 #12 L add_uuid nid=uml2@tcp(0x20000c0a80202) 0: 1:uml2_UUID
2293 #13 L add_conn 0:MDC_uml1_mdsA_MNT_client 1:uml2_UUID
2294 #14 L mount_option 0: 1:client 2:lov1 3:MDC_uml1_mdsA_MNT_client
2297 /* copy client info about lov/lmv */
2298 mgi->mgi_comp.comp_mti = mti;
2299 mgi->mgi_comp.comp_fsdb = fsdb;
2301 rc = mgs_steal_llog_for_mdt_from_client(env, mgs, cliname,
2305 rc = mgs_write_log_mdc_to_lmv(env, mgs, fsdb, mti, cliname,
2311 rc = record_start_log(env, mgs, &llh, cliname);
2315 rc = record_marker(env, llh, fsdb, CM_START, cliname,
2319 rc = record_mount_opt(env, llh, cliname, fsdb->fsdb_clilov,
2323 rc = record_marker(env, llh, fsdb, CM_END, cliname,
2329 /* for_all_existing_mdt except current one */
2330 for (i = 0; i < INDEX_MAP_SIZE * 8; i++) {
2331 if (i != mti->mti_stripe_index &&
2332 test_bit(i, fsdb->fsdb_mdt_index_map)) {
2335 rc = name_create_mdt(&logname, fsdb->fsdb_name, i);
2339 /* NB: If the log for the MDT is empty, it means
2340 * the MDT is only added to the index
2341 * map, and not being process yet, i.e. this
2342 * is an unregistered MDT, see mgs_write_log_target().
2343 * so we should skip it. Otherwise
2345 * 1. MGS get register request for MDT1 and MDT2.
2347 * 2. Then both MDT1 and MDT2 are added into
2348 * fsdb_mdt_index_map. (see mgs_set_index()).
2350 * 3. Then MDT1 get the lock of fsdb_mutex, then
2351 * generate the config log, here, it will regard MDT2
2352 * as an existent MDT, and generate "add osp" for
2353 * lustre-MDT0001-osp-MDT0002. Note: at the moment
2354 * MDT0002 config log is still empty, so it will
2355 * add "add osp" even before "lov setup", which
2356 * will definitly cause trouble.
2358 * 4. MDT1 registeration finished, fsdb_mutex is
2359 * released, then MDT2 get in, then in above
2360 * mgs_steal_llog_for_mdt_from_client(), it will
2361 * add another osp log for lustre-MDT0001-osp-MDT0002,
2362 * which will cause another trouble.*/
2363 if (!mgs_log_is_empty(env, mgs, logname))
2364 rc = mgs_write_log_osp_to_mdt(env, mgs, fsdb,
2367 name_destroy(&logname);
2373 record_end_log(env, &llh);
2375 name_destroy(&cliname);
2379 /* Add the ost info to the client/mdt lov */
2380 static int mgs_write_log_osc_to_lov(const struct lu_env *env,
2381 struct mgs_device *mgs, struct fs_db *fsdb,
2382 struct mgs_target_info *mti,
2383 char *logname, char *suffix, char *lovname,
2384 enum lustre_sec_part sec_part, int flags)
2386 struct llog_handle *llh = NULL;
2387 char *nodeuuid = NULL;
2388 char *oscname = NULL;
2389 char *oscuuid = NULL;
2390 char *lovuuid = NULL;
2391 char *svname = NULL;
2393 char nidstr[LNET_NIDSTR_SIZE];
2397 CDEBUG(D_INFO, "adding osc for %s to log %s\n",
2398 mti->mti_svname, logname);
2400 if (mgs_log_is_empty(env, mgs, logname)) {
2401 CERROR("log is empty! Logical error\n");
2405 libcfs_nid2str_r(mti->mti_nids[0], nidstr, sizeof(nidstr));
2406 rc = name_create(&nodeuuid, nidstr, "");
2409 rc = name_create(&svname, mti->mti_svname, "-osc");
2413 /* for the system upgraded from old 1.8, keep using the old osc naming
2414 * style for mdt, see name_create_mdt_osc(). LU-1257 */
2415 if (test_bit(FSDB_OSCNAME18, &fsdb->fsdb_flags))
2416 rc = name_create(&oscname, svname, "");
2418 rc = name_create(&oscname, svname, suffix);
2422 rc = name_create(&oscuuid, oscname, "_UUID");
2425 rc = name_create(&lovuuid, lovname, "_UUID");
2431 #03 L add_uuid nid=uml1@tcp(0x20000c0a80201) 0: 1:uml1_UUID
2433 #04 L add_uuid nid=1@elan(0x1000000000001) nal=90 0: 1:uml1_UUID
2434 #04 L attach 0:OSC_uml1_ost1_MNT_client 1:osc 2:89070_lov1_a41dff51a
2435 #05 L setup 0:OSC_uml1_ost1_MNT_client 1:ost1_UUID 2:uml1_UUID
2437 #06 L add_uuid nid=uml2@tcp(0x20000c0a80202) 0: 1:uml2_UUID
2438 #07 L add_conn 0:OSC_uml1_ost1_MNT_client 1:uml2_UUID
2439 #08 L lov_modify_tgts add 0:lov1 1:ost1_UUID 2(index):0 3(gen):1
2442 rc = record_start_log(env, mgs, &llh, logname);
2446 /* FIXME these should be a single journal transaction */
2447 rc = record_marker(env, llh, fsdb, CM_START | flags, mti->mti_svname,
2452 /* NB: don't change record order, because upon MDT steal OSC config
2453 * from client, it treats all nids before LCFG_SETUP as target nids
2454 * (multiple interfaces), while nids after as failover node nids.
2455 * See mgs_steal_client_llog_handler() LCFG_ADD_UUID.
2457 for (i = 0; i < mti->mti_nid_count; i++) {
2458 CDEBUG(D_MGS, "add nid %s\n",
2459 libcfs_nid2str_r(mti->mti_nids[i],
2460 nidstr, sizeof(nidstr)));
2461 rc = record_add_uuid(env, llh, mti->mti_nids[i], nodeuuid);
2465 rc = record_attach(env, llh, oscname, LUSTRE_OSC_NAME, lovuuid);
2468 rc = record_setup(env, llh, oscname, mti->mti_uuid, nodeuuid,
2472 rc = mgs_write_log_failnids(env, mti, llh, oscname);
2476 snprintf(index, sizeof(index), "%d", mti->mti_stripe_index);
2478 rc = record_lov_add(env, llh, lovname, mti->mti_uuid, index, "1");
2481 rc = record_marker(env, llh, fsdb, CM_END | flags, mti->mti_svname,
2486 record_end_log(env, &llh);
2488 name_destroy(&lovuuid);
2489 name_destroy(&oscuuid);
2490 name_destroy(&oscname);
2491 name_destroy(&svname);
2492 name_destroy(&nodeuuid);
2496 static int mgs_write_log_ost(const struct lu_env *env,
2497 struct mgs_device *mgs, struct fs_db *fsdb,
2498 struct mgs_target_info *mti)
2500 struct llog_handle *llh = NULL;
2501 char *logname, *lovname;
2502 char *ptr = mti->mti_params;
2503 int rc, flags = 0, failout = 0, i;
2506 CDEBUG(D_MGS, "writing new ost %s\n", mti->mti_svname);
2508 /* The ost startup log */
2510 /* If the ost log already exists, that means that someone reformatted
2511 the ost and it called target_add again. */
2512 if (!mgs_log_is_empty(env, mgs, mti->mti_svname)) {
2513 LCONSOLE_ERROR_MSG(0x141, "The config log for %s already "
2514 "exists, yet the server claims it never "
2515 "registered. It may have been reformatted, "
2516 "or the index changed. writeconf the MDT to "
2517 "regenerate all logs.\n", mti->mti_svname);
2522 attach obdfilter ost1 ost1_UUID
2523 setup /dev/loop2 ldiskfs f|n errors=remount-ro,user_xattr
2525 if (class_find_param(ptr, PARAM_FAILMODE, &ptr) == 0)
2526 failout = (strncmp(ptr, "failout", 7) == 0);
2527 rc = record_start_log(env, mgs, &llh, mti->mti_svname);
2530 /* FIXME these should be a single journal transaction */
2531 rc = record_marker(env, llh, fsdb, CM_START, mti->mti_svname,"add ost");
2534 if (*mti->mti_uuid == '\0')
2535 snprintf(mti->mti_uuid, sizeof(mti->mti_uuid),
2536 "%s_UUID", mti->mti_svname);
2537 rc = record_attach(env, llh, mti->mti_svname,
2538 "obdfilter"/*LUSTRE_OST_NAME*/, mti->mti_uuid);
2541 rc = record_setup(env, llh, mti->mti_svname,
2542 "dev"/*ignored*/, "type"/*ignored*/,
2543 failout ? "n" : "f", NULL/*options*/);
2546 rc = record_marker(env, llh, fsdb, CM_END, mti->mti_svname, "add ost");
2550 record_end_log(env, &llh);
2553 /* We also have to update the other logs where this osc is part of
2556 if (test_bit(FSDB_OLDLOG14, &fsdb->fsdb_flags)) {
2557 /* If we're upgrading, the old mdt log already has our
2558 entry. Let's do a fake one for fun. */
2559 /* Note that we can't add any new failnids, since we don't
2560 know the old osc names. */
2561 flags = CM_SKIP | CM_UPGRADE146;
2563 } else if ((mti->mti_flags & LDD_F_UPDATE) != LDD_F_UPDATE) {
2564 /* If the update flag isn't set, don't update client/mdt
2567 LCONSOLE_WARN("Client log for %s was not updated; writeconf "
2568 "the MDT first to regenerate it.\n",
2572 /* Add ost to all MDT lov defs */
2573 for (i = 0; i < INDEX_MAP_SIZE * 8; i++){
2574 if (test_bit(i, fsdb->fsdb_mdt_index_map)) {
2577 rc = name_create_mdt_and_lov(&logname, &lovname, fsdb,
2581 sprintf(mdt_index, "-MDT%04x", i);
2582 rc = mgs_write_log_osc_to_lov(env, mgs, fsdb, mti,
2584 lovname, LUSTRE_SP_MDT,
2586 name_destroy(&logname);
2587 name_destroy(&lovname);
2593 /* Append ost info to the client log */
2594 rc = name_create(&logname, mti->mti_fsname, "-client");
2597 if (mgs_log_is_empty(env, mgs, logname)) {
2598 /* Start client log */
2599 rc = mgs_write_log_lov(env, mgs, fsdb, mti, logname,
2603 rc = mgs_write_log_lmv(env, mgs, fsdb, mti, logname,
2608 rc = mgs_write_log_osc_to_lov(env, mgs, fsdb, mti, logname, "",
2609 fsdb->fsdb_clilov, LUSTRE_SP_CLI, flags);
2611 name_destroy(&logname);
2615 static __inline__ int mgs_param_empty(char *ptr)
2619 if ((tmp = strchr(ptr, '=')) && (*(++tmp) == '\0'))
2624 static int mgs_write_log_failnid_internal(const struct lu_env *env,
2625 struct mgs_device *mgs,
2627 struct mgs_target_info *mti,
2628 char *logname, char *cliname)
2631 struct llog_handle *llh = NULL;
2633 if (mgs_param_empty(mti->mti_params)) {
2634 /* Remove _all_ failnids */
2635 rc = mgs_modify(env, mgs, fsdb, mti, logname,
2636 mti->mti_svname, "add failnid", CM_SKIP);
2637 return rc < 0 ? rc : 0;
2640 /* Otherwise failover nids are additive */
2641 rc = record_start_log(env, mgs, &llh, logname);
2644 /* FIXME this should be a single journal transaction */
2645 rc = record_marker(env, llh, fsdb, CM_START, mti->mti_svname,
2649 rc = mgs_write_log_failnids(env, mti, llh, cliname);
2652 rc = record_marker(env, llh, fsdb, CM_END,
2653 mti->mti_svname, "add failnid");
2655 record_end_log(env, &llh);
2660 /* Add additional failnids to an existing log.
2661 The mdc/osc must have been added to logs first */
2662 /* tcp nids must be in dotted-quad ascii -
2663 we can't resolve hostnames from the kernel. */
2664 static int mgs_write_log_add_failnid(const struct lu_env *env,
2665 struct mgs_device *mgs,
2667 struct mgs_target_info *mti)
2669 char *logname, *cliname;
2673 /* FIXME we currently can't erase the failnids
2674 * given when a target first registers, since they aren't part of
2675 * an "add uuid" stanza */
2677 /* Verify that we know about this target */
2678 if (mgs_log_is_empty(env, mgs, mti->mti_svname)) {
2679 LCONSOLE_ERROR_MSG(0x142, "The target %s has not registered "
2680 "yet. It must be started before failnids "
2681 "can be added.\n", mti->mti_svname);
2685 /* Create mdc/osc client name (e.g. lustre-OST0001-osc) */
2686 if (mti->mti_flags & LDD_F_SV_TYPE_MDT) {
2687 rc = name_create(&cliname, mti->mti_svname, "-mdc");
2688 } else if (mti->mti_flags & LDD_F_SV_TYPE_OST) {
2689 rc = name_create(&cliname, mti->mti_svname, "-osc");
2695 /* Add failover nids to the client log */
2696 rc = name_create(&logname, mti->mti_fsname, "-client");
2698 name_destroy(&cliname);
2701 rc = mgs_write_log_failnid_internal(env, mgs, fsdb,mti,logname,cliname);
2702 name_destroy(&logname);
2703 name_destroy(&cliname);
2707 if (mti->mti_flags & LDD_F_SV_TYPE_OST) {
2708 /* Add OST failover nids to the MDT logs as well */
2711 for (i = 0; i < INDEX_MAP_SIZE * 8; i++) {
2712 if (!test_bit(i, fsdb->fsdb_mdt_index_map))
2714 rc = name_create_mdt(&logname, mti->mti_fsname, i);
2717 rc = name_create_mdt_osc(&cliname, mti->mti_svname,
2720 name_destroy(&logname);
2723 rc = mgs_write_log_failnid_internal(env, mgs, fsdb,
2726 name_destroy(&cliname);
2727 name_destroy(&logname);
2736 static int mgs_wlp_lcfg(const struct lu_env *env,
2737 struct mgs_device *mgs, struct fs_db *fsdb,
2738 struct mgs_target_info *mti,
2739 char *logname, struct lustre_cfg_bufs *bufs,
2740 char *tgtname, char *ptr)
2742 char comment[MTI_NAME_MAXLEN];
2744 struct llog_cfg_rec *lcr;
2747 /* Erase any old settings of this same parameter */
2748 memcpy(comment, ptr, MTI_NAME_MAXLEN);
2749 comment[MTI_NAME_MAXLEN - 1] = 0;
2750 /* But don't try to match the value. */
2751 tmp = strchr(comment, '=');
2754 /* FIXME we should skip settings that are the same as old values */
2755 rc = mgs_modify(env, mgs, fsdb, mti, logname, tgtname, comment,CM_SKIP);
2758 del = mgs_param_empty(ptr);
2760 LCONSOLE_INFO("%s parameter %s.%s in log %s\n", del ? "Disabling" : rc ?
2761 "Setting" : "Modifying", tgtname, comment, logname);
2763 /* mgs_modify() will return 1 if nothing had to be done */
2769 lustre_cfg_bufs_reset(bufs, tgtname);
2770 lustre_cfg_bufs_set_string(bufs, 1, ptr);
2771 if (mti->mti_flags & LDD_F_PARAM2)
2772 lustre_cfg_bufs_set_string(bufs, 2, LCTL_UPCALL);
2774 lcr = lustre_cfg_rec_new((mti->mti_flags & LDD_F_PARAM2) ?
2775 LCFG_SET_PARAM : LCFG_PARAM, bufs);
2779 rc = mgs_write_log_direct(env, mgs, fsdb, logname, lcr, tgtname,
2781 lustre_cfg_rec_free(lcr);
2785 static int mgs_write_log_param2(const struct lu_env *env,
2786 struct mgs_device *mgs,
2788 struct mgs_target_info *mti, char *ptr)
2790 struct lustre_cfg_bufs bufs;
2794 CDEBUG(D_MGS, "next param '%s'\n", ptr);
2795 rc = mgs_wlp_lcfg(env, mgs, fsdb, mti, PARAMS_FILENAME, &bufs,
2796 mti->mti_svname, ptr);
2801 /* write global variable settings into log */
2802 static int mgs_write_log_sys(const struct lu_env *env,
2803 struct mgs_device *mgs, struct fs_db *fsdb,
2804 struct mgs_target_info *mti, char *sys, char *ptr)
2806 struct mgs_thread_info *mgi = mgs_env_info(env);
2807 struct lustre_cfg *lcfg;
2808 struct llog_cfg_rec *lcr;
2810 int rc, cmd, convert = 1;
2812 if (class_match_param(ptr, PARAM_TIMEOUT, &tmp) == 0) {
2813 cmd = LCFG_SET_TIMEOUT;
2814 } else if (class_match_param(ptr, PARAM_LDLM_TIMEOUT, &tmp) == 0) {
2815 cmd = LCFG_SET_LDLM_TIMEOUT;
2816 /* Check for known params here so we can return error to lctl */
2817 } else if ((class_match_param(ptr, PARAM_AT_MIN, &tmp) == 0) ||
2818 (class_match_param(ptr, PARAM_AT_MAX, &tmp) == 0) ||
2819 (class_match_param(ptr, PARAM_AT_EXTRA, &tmp) == 0) ||
2820 (class_match_param(ptr, PARAM_AT_EARLY_MARGIN, &tmp) == 0) ||
2821 (class_match_param(ptr, PARAM_AT_HISTORY, &tmp) == 0)) {
2823 } else if (class_match_param(ptr, PARAM_JOBID_VAR, &tmp) == 0) {
2824 convert = 0; /* Don't convert string value to integer */
2830 if (mgs_param_empty(ptr))
2831 CDEBUG(D_MGS, "global '%s' removed\n", sys);
2833 CDEBUG(D_MGS, "global '%s' val=%s\n", sys, tmp);
2835 lustre_cfg_bufs_reset(&mgi->mgi_bufs, NULL);
2836 lustre_cfg_bufs_set_string(&mgi->mgi_bufs, 1, sys);
2837 if (!convert && *tmp != '\0')
2838 lustre_cfg_bufs_set_string(&mgi->mgi_bufs, 2, tmp);
2839 lcr = lustre_cfg_rec_new(cmd, &mgi->mgi_bufs);
2843 lcfg = &lcr->lcr_cfg;
2844 lcfg->lcfg_num = convert ? simple_strtoul(tmp, NULL, 0) : 0;
2845 /* truncate the comment to the parameter name */
2849 /* modify all servers and clients */
2850 rc = mgs_write_log_direct_all(env, mgs, fsdb, mti,
2851 *tmp == '\0' ? NULL : lcr,
2852 mti->mti_fsname, sys, 0);
2853 if (rc == 0 && *tmp != '\0') {
2855 case LCFG_SET_TIMEOUT:
2856 if (!obd_timeout_set || lcfg->lcfg_num > obd_timeout)
2857 class_process_config(lcfg);
2859 case LCFG_SET_LDLM_TIMEOUT:
2860 if (!ldlm_timeout_set || lcfg->lcfg_num > ldlm_timeout)
2861 class_process_config(lcfg);
2868 lustre_cfg_rec_free(lcr);
2872 /* write quota settings into log */
2873 static int mgs_write_log_quota(const struct lu_env *env, struct mgs_device *mgs,
2874 struct fs_db *fsdb, struct mgs_target_info *mti,
2875 char *quota, char *ptr)
2877 struct mgs_thread_info *mgi = mgs_env_info(env);
2878 struct llog_cfg_rec *lcr;
2881 int rc, cmd = LCFG_PARAM;
2883 /* support only 'meta' and 'data' pools so far */
2884 if (class_match_param(ptr, QUOTA_METAPOOL_NAME, &tmp) != 0 &&
2885 class_match_param(ptr, QUOTA_DATAPOOL_NAME, &tmp) != 0) {
2886 CERROR("parameter quota.%s isn't supported (only quota.mdt "
2887 "& quota.ost are)\n", ptr);
2892 CDEBUG(D_MGS, "global '%s' removed\n", quota);
2894 CDEBUG(D_MGS, "global '%s'\n", quota);
2896 if (strchr(tmp, 'u') == NULL && strchr(tmp, 'g') == NULL &&
2897 strcmp(tmp, "none") != 0) {
2898 CERROR("enable option(%s) isn't supported\n", tmp);
2903 lustre_cfg_bufs_reset(&mgi->mgi_bufs, mti->mti_fsname);
2904 lustre_cfg_bufs_set_string(&mgi->mgi_bufs, 1, quota);
2905 lcr = lustre_cfg_rec_new(cmd, &mgi->mgi_bufs);
2909 /* truncate the comment to the parameter name */
2914 /* XXX we duplicated quota enable information in all server
2915 * config logs, it should be moved to a separate config
2916 * log once we cleanup the config log for global param. */
2917 /* modify all servers */
2918 rc = mgs_write_log_direct_all(env, mgs, fsdb, mti,
2919 *tmp == '\0' ? NULL : lcr,
2920 mti->mti_fsname, quota, 1);
2922 lustre_cfg_rec_free(lcr);
2923 return rc < 0 ? rc : 0;
2926 static int mgs_srpc_set_param_disk(const struct lu_env *env,
2927 struct mgs_device *mgs,
2929 struct mgs_target_info *mti,
2932 struct mgs_thread_info *mgi = mgs_env_info(env);
2933 struct llog_cfg_rec *lcr;
2934 struct llog_handle *llh = NULL;
2936 char *comment, *ptr;
2942 ptr = strchr(param, '=');
2943 LASSERT(ptr != NULL);
2946 OBD_ALLOC(comment, len + 1);
2947 if (comment == NULL)
2949 strncpy(comment, param, len);
2950 comment[len] = '\0';
2953 lustre_cfg_bufs_reset(&mgi->mgi_bufs, mti->mti_svname);
2954 lustre_cfg_bufs_set_string(&mgi->mgi_bufs, 1, param);
2955 lcr = lustre_cfg_rec_new(LCFG_SPTLRPC_CONF, &mgi->mgi_bufs);
2957 GOTO(out_comment, rc = -ENOMEM);
2959 /* construct log name */
2960 rc = name_create(&logname, mti->mti_fsname, "-sptlrpc");
2964 if (mgs_log_is_empty(env, mgs, logname)) {
2965 rc = record_start_log(env, mgs, &llh, logname);
2968 record_end_log(env, &llh);
2971 /* obsolete old one */
2972 rc = mgs_modify(env, mgs, fsdb, mti, logname, mti->mti_svname,
2976 /* write the new one */
2977 rc = mgs_write_log_direct(env, mgs, fsdb, logname, lcr,
2978 mti->mti_svname, comment);
2980 CERROR("%s: error writing log %s: rc = %d\n",
2981 mgs->mgs_obd->obd_name, logname, rc);
2983 name_destroy(&logname);
2985 lustre_cfg_rec_free(lcr);
2987 OBD_FREE(comment, len + 1);
2991 static int mgs_srpc_set_param_udesc_mem(struct fs_db *fsdb,
2996 /* disable the adjustable udesc parameter for now, i.e. use default
2997 * setting that client always ship udesc to MDT if possible. to enable
2998 * it simply remove the following line */
3001 ptr = strchr(param, '=');
3006 if (strcmp(param, PARAM_SRPC_UDESC))
3009 if (strcmp(ptr, "yes") == 0) {
3010 set_bit(FSDB_UDESC, &fsdb->fsdb_flags);
3011 CWARN("Enable user descriptor shipping from client to MDT\n");
3012 } else if (strcmp(ptr, "no") == 0) {
3013 clear_bit(FSDB_UDESC, &fsdb->fsdb_flags);
3014 CWARN("Disable user descriptor shipping from client to MDT\n");
3022 CERROR("Invalid param: %s\n", param);
3026 static int mgs_srpc_set_param_mem(struct fs_db *fsdb,
3030 struct sptlrpc_rule rule;
3031 struct sptlrpc_rule_set *rset;
3035 if (strncmp(param, PARAM_SRPC, sizeof(PARAM_SRPC) - 1) != 0) {
3036 CERROR("Invalid sptlrpc parameter: %s\n", param);
3040 if (strncmp(param, PARAM_SRPC_UDESC,
3041 sizeof(PARAM_SRPC_UDESC) - 1) == 0) {
3042 RETURN(mgs_srpc_set_param_udesc_mem(fsdb, param));
3045 if (strncmp(param, PARAM_SRPC_FLVR, sizeof(PARAM_SRPC_FLVR) - 1) != 0) {
3046 CERROR("Invalid sptlrpc flavor parameter: %s\n", param);
3050 param += sizeof(PARAM_SRPC_FLVR) - 1;
3052 rc = sptlrpc_parse_rule(param, &rule);
3056 /* mgs rules implies must be mgc->mgs */
3057 if (test_bit(FSDB_MGS_SELF, &fsdb->fsdb_flags)) {
3058 if ((rule.sr_from != LUSTRE_SP_MGC &&
3059 rule.sr_from != LUSTRE_SP_ANY) ||
3060 (rule.sr_to != LUSTRE_SP_MGS &&
3061 rule.sr_to != LUSTRE_SP_ANY))
3065 /* preapre room for this coming rule. svcname format should be:
3066 * - fsname: general rule
3067 * - fsname-tgtname: target-specific rule
3069 if (strchr(svname, '-')) {
3070 struct mgs_tgt_srpc_conf *tgtconf;
3073 for (tgtconf = fsdb->fsdb_srpc_tgt; tgtconf != NULL;
3074 tgtconf = tgtconf->mtsc_next) {
3075 if (!strcmp(tgtconf->mtsc_tgt, svname)) {
3084 OBD_ALLOC_PTR(tgtconf);
3085 if (tgtconf == NULL)
3088 name_len = strlen(svname);
3090 OBD_ALLOC(tgtconf->mtsc_tgt, name_len + 1);
3091 if (tgtconf->mtsc_tgt == NULL) {
3092 OBD_FREE_PTR(tgtconf);
3095 memcpy(tgtconf->mtsc_tgt, svname, name_len);
3097 tgtconf->mtsc_next = fsdb->fsdb_srpc_tgt;
3098 fsdb->fsdb_srpc_tgt = tgtconf;
3101 rset = &tgtconf->mtsc_rset;
3102 } else if (strcmp(svname, MGSSELF_NAME) == 0) {
3103 /* put _mgs related srpc rule directly in mgs ruleset */
3104 rset = &fsdb->fsdb_mgs->mgs_lut.lut_sptlrpc_rset;
3106 rset = &fsdb->fsdb_srpc_gen;
3109 rc = sptlrpc_rule_set_merge(rset, &rule);
3114 static int mgs_srpc_set_param(const struct lu_env *env,
3115 struct mgs_device *mgs,
3117 struct mgs_target_info *mti,
3127 /* keep a copy of original param, which could be destroied
3129 copy_size = strlen(param) + 1;
3130 OBD_ALLOC(copy, copy_size);
3133 memcpy(copy, param, copy_size);
3135 rc = mgs_srpc_set_param_mem(fsdb, mti->mti_svname, param);
3139 /* previous steps guaranteed the syntax is correct */
3140 rc = mgs_srpc_set_param_disk(env, mgs, fsdb, mti, copy);
3144 if (test_bit(FSDB_MGS_SELF, &fsdb->fsdb_flags)) {
3146 * for mgs rules, make them effective immediately.
3148 LASSERT(fsdb->fsdb_srpc_tgt == NULL);
3149 sptlrpc_target_update_exp_flavor(mgs->mgs_obd,
3150 &fsdb->fsdb_srpc_gen);
3154 OBD_FREE(copy, copy_size);
3158 struct mgs_srpc_read_data {
3159 struct fs_db *msrd_fsdb;
3163 static int mgs_srpc_read_handler(const struct lu_env *env,
3164 struct llog_handle *llh,
3165 struct llog_rec_hdr *rec, void *data)
3167 struct mgs_srpc_read_data *msrd = data;
3168 struct cfg_marker *marker;
3169 struct lustre_cfg *lcfg = REC_DATA(rec);
3170 char *svname, *param;
3174 if (rec->lrh_type != OBD_CFG_REC) {
3175 CERROR("unhandled lrh_type: %#x\n", rec->lrh_type);
3179 cfg_len = REC_DATA_LEN(rec);
3181 rc = lustre_cfg_sanity_check(lcfg, cfg_len);
3183 CERROR("Insane cfg\n");
3187 if (lcfg->lcfg_command == LCFG_MARKER) {
3188 marker = lustre_cfg_buf(lcfg, 1);
3190 if (marker->cm_flags & CM_START &&
3191 marker->cm_flags & CM_SKIP)
3192 msrd->msrd_skip = 1;
3193 if (marker->cm_flags & CM_END)
3194 msrd->msrd_skip = 0;
3199 if (msrd->msrd_skip)
3202 if (lcfg->lcfg_command != LCFG_SPTLRPC_CONF) {
3203 CERROR("invalid command (%x)\n", lcfg->lcfg_command);
3207 svname = lustre_cfg_string(lcfg, 0);
3208 if (svname == NULL) {
3209 CERROR("svname is empty\n");
3213 param = lustre_cfg_string(lcfg, 1);
3214 if (param == NULL) {
3215 CERROR("param is empty\n");
3219 rc = mgs_srpc_set_param_mem(msrd->msrd_fsdb, svname, param);
3221 CERROR("read sptlrpc record error (%d): %s\n", rc, param);
3226 int mgs_get_fsdb_srpc_from_llog(const struct lu_env *env,
3227 struct mgs_device *mgs,
3230 struct llog_handle *llh = NULL;
3231 struct llog_ctxt *ctxt;
3233 struct mgs_srpc_read_data msrd;
3237 /* construct log name */
3238 rc = name_create(&logname, fsdb->fsdb_name, "-sptlrpc");
3242 ctxt = llog_get_context(mgs->mgs_obd, LLOG_CONFIG_ORIG_CTXT);
3243 LASSERT(ctxt != NULL);
3245 if (mgs_log_is_empty(env, mgs, logname))
3248 rc = llog_open(env, ctxt, &llh, NULL, logname,
3256 rc = llog_init_handle(env, llh, LLOG_F_IS_PLAIN, NULL);
3258 GOTO(out_close, rc);
3260 if (llog_get_size(llh) <= 1)
3261 GOTO(out_close, rc = 0);
3263 msrd.msrd_fsdb = fsdb;
3266 rc = llog_process(env, llh, mgs_srpc_read_handler, (void *)&msrd,
3270 llog_close(env, llh);
3272 llog_ctxt_put(ctxt);
3273 name_destroy(&logname);
3276 CERROR("failed to read sptlrpc config database: %d\n", rc);
3280 /* Permanent settings of all parameters by writing into the appropriate
3281 * configuration logs.
3282 * A parameter with null value ("<param>='\0'") means to erase it out of
3285 static int mgs_write_log_param(const struct lu_env *env,
3286 struct mgs_device *mgs, struct fs_db *fsdb,
3287 struct mgs_target_info *mti, char *ptr)
3289 struct mgs_thread_info *mgi = mgs_env_info(env);
3292 int rc = 0, rc2 = 0;
3295 /* For various parameter settings, we have to figure out which logs
3296 care about them (e.g. both mdt and client for lov settings) */
3297 CDEBUG(D_MGS, "next param '%s'\n", ptr);
3299 /* The params are stored in MOUNT_DATA_FILE and modified via
3300 tunefs.lustre, or set using lctl conf_param */
3302 /* Processed in lustre_start_mgc */
3303 if (class_match_param(ptr, PARAM_MGSNODE, NULL) == 0)
3306 /* Processed in ost/mdt */
3307 if (class_match_param(ptr, PARAM_NETWORK, NULL) == 0)
3310 /* Processed in mgs_write_log_ost */
3311 if (class_match_param(ptr, PARAM_FAILMODE, NULL) == 0) {
3312 if (mti->mti_flags & LDD_F_PARAM) {
3313 LCONSOLE_ERROR_MSG(0x169, "%s can only be "
3314 "changed with tunefs.lustre"
3315 "and --writeconf\n", ptr);
3321 if (class_match_param(ptr, PARAM_SRPC, NULL) == 0) {
3322 rc = mgs_srpc_set_param(env, mgs, fsdb, mti, ptr);
3326 if (class_match_param(ptr, PARAM_FAILNODE, NULL) == 0) {
3327 /* Add a failover nidlist */
3329 /* We already processed failovers params for new
3330 targets in mgs_write_log_target */
3331 if (mti->mti_flags & LDD_F_PARAM) {
3332 CDEBUG(D_MGS, "Adding failnode\n");
3333 rc = mgs_write_log_add_failnid(env, mgs, fsdb, mti);
3338 if (class_match_param(ptr, PARAM_SYS, &tmp) == 0) {
3339 rc = mgs_write_log_sys(env, mgs, fsdb, mti, ptr, tmp);
3343 if (class_match_param(ptr, PARAM_QUOTA, &tmp) == 0) {
3344 rc = mgs_write_log_quota(env, mgs, fsdb, mti, ptr, tmp);
3348 if (class_match_param(ptr, PARAM_OSC PARAM_ACTIVE, &tmp) == 0 ||
3349 class_match_param(ptr, PARAM_MDC PARAM_ACTIVE, &tmp) == 0) {
3350 /* active=0 means off, anything else means on */
3351 int flag = (*tmp == '0') ? CM_EXCLUDE : 0;
3352 bool deactive_osc = memcmp(ptr, PARAM_OSC PARAM_ACTIVE,
3353 strlen(PARAM_OSC PARAM_ACTIVE)) == 0;
3356 if (!deactive_osc) {
3359 rc = server_name2index(mti->mti_svname, &index, NULL);
3364 LCONSOLE_ERROR_MSG(0x144, "%s: MDC0 can not be"
3365 " (de)activated.\n",
3367 GOTO(end, rc = -EINVAL);
3371 LCONSOLE_WARN("Permanently %sactivating %s\n",
3372 flag ? "de" : "re", mti->mti_svname);
3374 rc = name_create(&logname, mti->mti_fsname, "-client");
3377 rc = mgs_modify(env, mgs, fsdb, mti, logname,
3379 deactive_osc ? "add osc" : "add mdc", flag);
3380 name_destroy(&logname);
3385 /* Add to all MDT logs for DNE */
3386 for (i = 0; i < INDEX_MAP_SIZE * 8; i++) {
3387 if (!test_bit(i, fsdb->fsdb_mdt_index_map))
3389 rc = name_create_mdt(&logname, mti->mti_fsname, i);
3392 rc = mgs_modify(env, mgs, fsdb, mti, logname,
3394 deactive_osc ? "add osc" : "add osp",
3396 name_destroy(&logname);
3402 LCONSOLE_ERROR_MSG(0x145, "Couldn't find %s in"
3403 "log (%d). No permanent "
3404 "changes were made to the "
3406 mti->mti_svname, rc);
3407 if (test_bit(FSDB_OLDLOG14, &fsdb->fsdb_flags))
3408 LCONSOLE_ERROR_MSG(0x146, "This may be"
3413 "update the logs.\n");
3416 /* Fall through to osc/mdc proc for deactivating live
3417 OSC/OSP on running MDT / clients. */
3419 /* Below here, let obd's XXX_process_config methods handle it */
3421 /* All lov. in proc */
3422 if (class_match_param(ptr, PARAM_LOV, NULL) == 0) {
3425 CDEBUG(D_MGS, "lov param %s\n", ptr);
3426 if (!(mti->mti_flags & LDD_F_SV_TYPE_MDT)) {
3427 LCONSOLE_ERROR_MSG(0x147, "LOV params must be "
3428 "set on the MDT, not %s. "
3435 if (mgs_log_is_empty(env, mgs, mti->mti_svname))
3436 GOTO(end, rc = -ENODEV);
3438 rc = name_create_mdt_and_lov(&logname, &mdtlovname, fsdb,
3439 mti->mti_stripe_index);
3442 rc = mgs_wlp_lcfg(env, mgs, fsdb, mti, mti->mti_svname,
3443 &mgi->mgi_bufs, mdtlovname, ptr);
3444 name_destroy(&logname);
3445 name_destroy(&mdtlovname);
3450 rc = name_create(&logname, mti->mti_fsname, "-client");
3453 rc = mgs_wlp_lcfg(env, mgs, fsdb, mti, logname, &mgi->mgi_bufs,
3454 fsdb->fsdb_clilov, ptr);
3455 name_destroy(&logname);
3459 /* All osc., mdc., llite. params in proc */
3460 if ((class_match_param(ptr, PARAM_OSC, NULL) == 0) ||
3461 (class_match_param(ptr, PARAM_MDC, NULL) == 0) ||
3462 (class_match_param(ptr, PARAM_LLITE, NULL) == 0)) {
3465 if (test_bit(FSDB_OLDLOG14, &fsdb->fsdb_flags)) {
3466 LCONSOLE_ERROR_MSG(0x148, "Upgraded client logs for %s"
3467 " cannot be modified. Consider"
3468 " updating the configuration with"
3471 GOTO(end, rc = -EINVAL);
3473 if (memcmp(ptr, PARAM_LLITE, strlen(PARAM_LLITE)) == 0) {
3474 rc = name_create(&cname, mti->mti_fsname, "-client");
3475 /* Add the client type to match the obdname in
3476 class_config_llog_handler */
3477 } else if (mti->mti_flags & LDD_F_SV_TYPE_MDT) {
3478 rc = name_create(&cname, mti->mti_svname, "-mdc");
3479 } else if (mti->mti_flags & LDD_F_SV_TYPE_OST) {
3480 rc = name_create(&cname, mti->mti_svname, "-osc");
3482 GOTO(end, rc = -EINVAL);
3487 /* Forbid direct update of llite root squash parameters.
3488 * These parameters are indirectly set via the MDT settings.
3490 if ((class_match_param(ptr, PARAM_LLITE, &tmp) == 0) &&
3491 ((memcmp(tmp, "root_squash=", 12) == 0) ||
3492 (memcmp(tmp, "nosquash_nids=", 14) == 0))) {
3493 LCONSOLE_ERROR("%s: root squash parameters can only "
3494 "be updated through MDT component\n",
3496 name_destroy(&cname);
3497 GOTO(end, rc = -EINVAL);
3500 CDEBUG(D_MGS, "%.3s param %s\n", ptr, ptr + 4);
3503 rc = name_create(&logname, mti->mti_fsname, "-client");
3505 name_destroy(&cname);
3508 rc = mgs_wlp_lcfg(env, mgs, fsdb, mti, logname, &mgi->mgi_bufs,
3511 /* osc params affect the MDT as well */
3512 if (!rc && (mti->mti_flags & LDD_F_SV_TYPE_OST)) {
3515 for (i = 0; i < INDEX_MAP_SIZE * 8; i++){
3516 if (!test_bit(i, fsdb->fsdb_mdt_index_map))
3518 name_destroy(&cname);
3519 rc = name_create_mdt_osc(&cname, mti->mti_svname,
3521 name_destroy(&logname);
3524 rc = name_create_mdt(&logname,
3525 mti->mti_fsname, i);
3528 if (!mgs_log_is_empty(env, mgs, logname)) {
3529 rc = mgs_wlp_lcfg(env, mgs, fsdb,
3539 /* For mdc activate/deactivate, it affects OSP on MDT as well */
3540 if (class_match_param(ptr, PARAM_MDC PARAM_ACTIVE, &tmp) == 0 &&
3543 char *lodname = NULL;
3544 char *param_str = NULL;
3548 /* replace mdc with osp */
3549 memcpy(ptr, PARAM_OSP, strlen(PARAM_OSP));
3550 rc = server_name2index(mti->mti_svname, &index, NULL);
3552 memcpy(ptr, PARAM_MDC, strlen(PARAM_MDC));
3556 for (i = 0; i < INDEX_MAP_SIZE * 8; i++) {
3557 if (!test_bit(i, fsdb->fsdb_mdt_index_map))
3563 name_destroy(&logname);
3564 rc = name_create_mdt(&logname, mti->mti_fsname,
3569 if (mgs_log_is_empty(env, mgs, logname))
3572 snprintf(suffix, sizeof(suffix), "-osp-MDT%04x",
3574 name_destroy(&cname);
3575 rc = name_create(&cname, mti->mti_svname,
3580 rc = mgs_wlp_lcfg(env, mgs, fsdb, mti, logname,
3581 &mgi->mgi_bufs, cname, ptr);
3585 /* Add configuration log for noitfying LOD
3586 * to active/deactive the OSP. */
3587 name_destroy(¶m_str);
3588 rc = name_create(¶m_str, cname,
3589 (*tmp == '0') ? ".active=0" :
3594 name_destroy(&lodname);
3595 rc = name_create(&lodname, logname, "-mdtlov");
3599 rc = mgs_wlp_lcfg(env, mgs, fsdb, mti, logname,
3600 &mgi->mgi_bufs, lodname,
3605 memcpy(ptr, PARAM_MDC, strlen(PARAM_MDC));
3606 name_destroy(&lodname);
3607 name_destroy(¶m_str);
3610 name_destroy(&logname);
3611 name_destroy(&cname);
3615 /* All mdt. params in proc */
3616 if (class_match_param(ptr, PARAM_MDT, &tmp) == 0) {
3620 CDEBUG(D_MGS, "%.3s param %s\n", ptr, ptr + 4);
3621 if (strncmp(mti->mti_svname, mti->mti_fsname,
3622 MTI_NAME_MAXLEN) == 0)
3623 /* device is unspecified completely? */
3624 rc = LDD_F_SV_TYPE_MDT | LDD_F_SV_ALL;
3626 rc = server_name2index(mti->mti_svname, &idx, NULL);
3629 if ((rc & LDD_F_SV_TYPE_MDT) == 0)
3631 if (rc & LDD_F_SV_ALL) {
3632 for (i = 0; i < INDEX_MAP_SIZE * 8; i++) {
3634 fsdb->fsdb_mdt_index_map))
3636 rc = name_create_mdt(&logname,
3637 mti->mti_fsname, i);
3640 rc = mgs_wlp_lcfg(env, mgs, fsdb, mti,
3641 logname, &mgi->mgi_bufs,
3643 name_destroy(&logname);
3648 if ((memcmp(tmp, "root_squash=", 12) == 0) ||
3649 (memcmp(tmp, "nosquash_nids=", 14) == 0)) {
3650 LCONSOLE_ERROR("%s: root squash parameters "
3651 "cannot be applied to a single MDT\n",
3653 GOTO(end, rc = -EINVAL);
3655 rc = mgs_wlp_lcfg(env, mgs, fsdb, mti,
3656 mti->mti_svname, &mgi->mgi_bufs,
3657 mti->mti_svname, ptr);
3662 /* root squash settings are also applied to llite
3663 * config log (see LU-1778) */
3665 ((memcmp(tmp, "root_squash=", 12) == 0) ||
3666 (memcmp(tmp, "nosquash_nids=", 14) == 0))) {
3670 rc = name_create(&cname, mti->mti_fsname, "-client");
3673 rc = name_create(&logname, mti->mti_fsname, "-client");
3675 name_destroy(&cname);
3678 rc = name_create(&ptr2, PARAM_LLITE, tmp);
3680 name_destroy(&cname);
3681 name_destroy(&logname);
3684 rc = mgs_wlp_lcfg(env, mgs, fsdb, mti, logname,
3685 &mgi->mgi_bufs, cname, ptr2);
3686 name_destroy(&ptr2);
3687 name_destroy(&logname);
3688 name_destroy(&cname);
3693 /* All mdd., ost. and osd. params in proc */
3694 if ((class_match_param(ptr, PARAM_MDD, NULL) == 0) ||
3695 (class_match_param(ptr, PARAM_OST, NULL) == 0) ||
3696 (class_match_param(ptr, PARAM_OSD, NULL) == 0)) {
3697 CDEBUG(D_MGS, "%.3s param %s\n", ptr, ptr + 4);
3698 if (mgs_log_is_empty(env, mgs, mti->mti_svname))
3699 GOTO(end, rc = -ENODEV);
3701 rc = mgs_wlp_lcfg(env, mgs, fsdb, mti, mti->mti_svname,
3702 &mgi->mgi_bufs, mti->mti_svname, ptr);
3706 LCONSOLE_WARN("Ignoring unrecognized param '%s'\n", ptr);
3711 CERROR("err %d on param '%s'\n", rc, ptr);
3716 /* Not implementing automatic failover nid addition at this time. */
3717 int mgs_check_failnid(const struct lu_env *env, struct mgs_device *mgs,
3718 struct mgs_target_info *mti)
3725 rc = mgs_find_or_make_fsdb(obd, fsname, &fsdb);
3729 if (mgs_log_is_empty(obd, mti->mti_svname))
3730 /* should never happen */
3733 CDEBUG(D_MGS, "Checking for new failnids for %s\n", mti->mti_svname);
3735 /* FIXME We can just check mti->params to see if we're already in
3736 the failover list. Modify mti->params for rewriting back at
3737 server_register_target(). */
3739 mutex_lock(&fsdb->fsdb_mutex);
3740 rc = mgs_write_log_add_failnid(obd, fsdb, mti);
3741 mutex_unlock(&fsdb->fsdb_mutex);
3750 int mgs_write_log_target(const struct lu_env *env, struct mgs_device *mgs,
3751 struct mgs_target_info *mti, struct fs_db *fsdb)
3758 /* set/check the new target index */
3759 rc = mgs_set_index(env, mgs, mti);
3763 if (rc == EALREADY) {
3764 LCONSOLE_WARN("Found index %d for %s, updating log\n",
3765 mti->mti_stripe_index, mti->mti_svname);
3766 /* We would like to mark old log sections as invalid
3767 and add new log sections in the client and mdt logs.
3768 But if we add new sections, then live clients will
3769 get repeat setup instructions for already running
3770 osc's. So don't update the client/mdt logs. */
3771 mti->mti_flags &= ~LDD_F_UPDATE;
3775 OBD_FAIL_TIMEOUT(OBD_FAIL_MGS_WRITE_TARGET_DELAY, cfs_fail_val > 0 ?
3778 mutex_lock(&fsdb->fsdb_mutex);
3780 if (mti->mti_flags &
3781 (LDD_F_VIRGIN | LDD_F_UPGRADE14 | LDD_F_WRITECONF)) {
3782 /* Generate a log from scratch */
3783 if (mti->mti_flags & LDD_F_SV_TYPE_MDT) {
3784 rc = mgs_write_log_mdt(env, mgs, fsdb, mti);
3785 } else if (mti->mti_flags & LDD_F_SV_TYPE_OST) {
3786 rc = mgs_write_log_ost(env, mgs, fsdb, mti);
3788 CERROR("Unknown target type %#x, can't create log for "
3789 "%s\n", mti->mti_flags, mti->mti_svname);
3792 CERROR("Can't write logs for %s (%d)\n",
3793 mti->mti_svname, rc);
3797 /* Just update the params from tunefs in mgs_write_log_params */
3798 CDEBUG(D_MGS, "Update params for %s\n", mti->mti_svname);
3799 mti->mti_flags |= LDD_F_PARAM;
3802 /* allocate temporary buffer, where class_get_next_param will
3803 make copy of a current parameter */
3804 OBD_ALLOC(buf, strlen(mti->mti_params) + 1);
3806 GOTO(out_up, rc = -ENOMEM);
3807 params = mti->mti_params;
3808 while (params != NULL) {
3809 rc = class_get_next_param(¶ms, buf);
3812 /* there is no next parameter, that is
3817 CDEBUG(D_MGS, "remaining string: '%s', param: '%s'\n",
3819 rc = mgs_write_log_param(env, mgs, fsdb, mti, buf);
3824 OBD_FREE(buf, strlen(mti->mti_params) + 1);
3827 mutex_unlock(&fsdb->fsdb_mutex);
3831 int mgs_erase_log(const struct lu_env *env, struct mgs_device *mgs, char *name)
3833 struct llog_ctxt *ctxt;
3836 ctxt = llog_get_context(mgs->mgs_obd, LLOG_CONFIG_ORIG_CTXT);
3838 CERROR("%s: MGS config context doesn't exist\n",
3839 mgs->mgs_obd->obd_name);
3842 rc = llog_erase(env, ctxt, NULL, name);
3843 /* llog may not exist */
3846 llog_ctxt_put(ctxt);
3850 CERROR("%s: failed to clear log %s: %d\n",
3851 mgs->mgs_obd->obd_name, name, rc);
3856 /* erase all logs for the given fs */
3857 int mgs_erase_logs(const struct lu_env *env, struct mgs_device *mgs, char *fsname)
3860 struct list_head log_list;
3861 struct mgs_direntry *dirent, *n;
3862 int rc, len = strlen(fsname);
3866 /* Find all the logs in the CONFIGS directory */
3867 rc = class_dentry_readdir(env, mgs, &log_list);
3871 mutex_lock(&mgs->mgs_mutex);
3873 /* Delete the fs db */
3874 fsdb = mgs_find_fsdb(mgs, fsname);
3876 mgs_free_fsdb(mgs, fsdb);
3878 mutex_unlock(&mgs->mgs_mutex);
3880 list_for_each_entry_safe(dirent, n, &log_list, mde_list) {
3881 list_del_init(&dirent->mde_list);
3882 suffix = strrchr(dirent->mde_name, '-');
3883 if (suffix != NULL) {
3884 if ((len == suffix - dirent->mde_name) &&
3885 (strncmp(fsname, dirent->mde_name, len) == 0)) {
3886 CDEBUG(D_MGS, "Removing log %s\n",
3888 mgs_erase_log(env, mgs, dirent->mde_name);
3891 mgs_direntry_free(dirent);
3897 /* list all logs for the given fs */
3898 int mgs_list_logs(const struct lu_env *env, struct mgs_device *mgs,
3899 struct obd_ioctl_data *data)
3901 struct list_head log_list;
3902 struct mgs_direntry *dirent, *n;
3908 /* Find all the logs in the CONFIGS directory */
3909 rc = class_dentry_readdir(env, mgs, &log_list);
3913 out = data->ioc_bulk;
3914 remains = data->ioc_inllen1;
3915 list_for_each_entry_safe(dirent, n, &log_list, mde_list) {
3916 list_del_init(&dirent->mde_list);
3917 suffix = strrchr(dirent->mde_name, '-');
3918 if (suffix != NULL) {
3919 l = snprintf(out, remains, "config log: $%s\n",
3924 mgs_direntry_free(dirent);
3931 /* from llog_swab */
3932 static void print_lustre_cfg(struct lustre_cfg *lcfg)
3937 CDEBUG(D_MGS, "lustre_cfg: %p\n", lcfg);
3938 CDEBUG(D_MGS, "\tlcfg->lcfg_version: %#x\n", lcfg->lcfg_version);
3940 CDEBUG(D_MGS, "\tlcfg->lcfg_command: %#x\n", lcfg->lcfg_command);
3941 CDEBUG(D_MGS, "\tlcfg->lcfg_num: %#x\n", lcfg->lcfg_num);
3942 CDEBUG(D_MGS, "\tlcfg->lcfg_flags: %#x\n", lcfg->lcfg_flags);
3943 CDEBUG(D_MGS, "\tlcfg->lcfg_nid: %s\n", libcfs_nid2str(lcfg->lcfg_nid));
3945 CDEBUG(D_MGS, "\tlcfg->lcfg_bufcount: %d\n", lcfg->lcfg_bufcount);
3946 if (lcfg->lcfg_bufcount < LUSTRE_CFG_MAX_BUFCOUNT)
3947 for (i = 0; i < lcfg->lcfg_bufcount; i++) {
3948 CDEBUG(D_MGS, "\tlcfg->lcfg_buflens[%d]: %d %s\n",
3949 i, lcfg->lcfg_buflens[i],
3950 lustre_cfg_string(lcfg, i));
3955 /* Setup _mgs fsdb and log
3957 int mgs__mgs_fsdb_setup(const struct lu_env *env, struct mgs_device *mgs,
3963 rc = mgs_find_or_make_fsdb(env, mgs, MGSSELF_NAME, &fsdb);
3968 /* Setup params fsdb and log
3970 int mgs_params_fsdb_setup(const struct lu_env *env, struct mgs_device *mgs,
3973 struct llog_handle *params_llh = NULL;
3977 rc = mgs_find_or_make_fsdb(env, mgs, PARAMS_FILENAME, &fsdb);
3979 mutex_lock(&fsdb->fsdb_mutex);
3980 rc = record_start_log(env, mgs, ¶ms_llh, PARAMS_FILENAME);
3982 rc = record_end_log(env, ¶ms_llh);
3983 mutex_unlock(&fsdb->fsdb_mutex);
3989 /* Cleanup params fsdb and log
3991 int mgs_params_fsdb_cleanup(const struct lu_env *env, struct mgs_device *mgs)
3993 return mgs_erase_logs(env, mgs, PARAMS_FILENAME);
3996 /* Set a permanent (config log) param for a target or fs
3997 * \param lcfg buf0 may contain the device (testfs-MDT0000) name
3998 * buf1 contains the single parameter
4000 int mgs_setparam(const struct lu_env *env, struct mgs_device *mgs,
4001 struct lustre_cfg *lcfg, char *fsname)
4004 struct mgs_target_info *mti;
4005 char *devname, *param;
4012 print_lustre_cfg(lcfg);
4014 /* lustre, lustre-mdtlov, lustre-client, lustre-MDT0000 */
4015 devname = lustre_cfg_string(lcfg, 0);
4016 param = lustre_cfg_string(lcfg, 1);
4018 /* Assume device name embedded in param:
4019 lustre-OST0000.osc.max_dirty_mb=32 */
4020 ptr = strchr(param, '.');
4028 LCONSOLE_ERROR_MSG(0x14d, "No target specified: %s\n", param);
4032 rc = mgs_parse_devname(devname, fsname, NULL);
4033 if (rc == 0 && !mgs_parse_devname(devname, NULL, &index)) {
4034 /* param related to llite isn't allowed to set by OST or MDT */
4035 if (rc == 0 && strncmp(param, PARAM_LLITE,
4036 sizeof(PARAM_LLITE) - 1) == 0)
4039 /* assume devname is the fsname */
4040 strlcpy(fsname, devname, MTI_NAME_MAXLEN);
4042 CDEBUG(D_MGS, "setparam fs='%s' device='%s'\n", fsname, devname);
4044 rc = mgs_find_or_make_fsdb(env, mgs,
4045 lcfg->lcfg_command == LCFG_SET_PARAM ?
4046 PARAMS_FILENAME : fsname, &fsdb);
4050 if (lcfg->lcfg_command != LCFG_SET_PARAM &&
4051 !test_bit(FSDB_MGS_SELF, &fsdb->fsdb_flags) &&
4052 test_bit(FSDB_LOG_EMPTY, &fsdb->fsdb_flags)) {
4053 CERROR("No filesystem targets for %s. cfg_device from lctl "
4054 "is '%s'\n", fsname, devname);
4055 mgs_free_fsdb(mgs, fsdb);
4059 /* Create a fake mti to hold everything */
4062 GOTO(out, rc = -ENOMEM);
4063 if (strlcpy(mti->mti_fsname, fsname, sizeof(mti->mti_fsname))
4064 >= sizeof(mti->mti_fsname))
4065 GOTO(out, rc = -E2BIG);
4066 if (strlcpy(mti->mti_svname, devname, sizeof(mti->mti_svname))
4067 >= sizeof(mti->mti_svname))
4068 GOTO(out, rc = -E2BIG);
4069 if (strlcpy(mti->mti_params, param, sizeof(mti->mti_params))
4070 >= sizeof(mti->mti_params))
4071 GOTO(out, rc = -E2BIG);
4072 rc = server_name2index(mti->mti_svname, &mti->mti_stripe_index, &tmp);
4074 /* Not a valid server; may be only fsname */
4077 /* Strip -osc or -mdc suffix from svname */
4078 if (server_make_name(rc, mti->mti_stripe_index, mti->mti_fsname,
4080 GOTO(out, rc = -EINVAL);
4082 * Revoke lock so everyone updates. Should be alright if
4083 * someone was already reading while we were updating the logs,
4084 * so we don't really need to hold the lock while we're
4087 if (lcfg->lcfg_command == LCFG_SET_PARAM) {
4088 mti->mti_flags = rc | LDD_F_PARAM2;
4089 mutex_lock(&fsdb->fsdb_mutex);
4090 rc = mgs_write_log_param2(env, mgs, fsdb, mti, mti->mti_params);
4091 mutex_unlock(&fsdb->fsdb_mutex);
4092 mgs_revoke_lock(mgs, fsdb, CONFIG_T_PARAMS);
4094 mti->mti_flags = rc | LDD_F_PARAM;
4095 mutex_lock(&fsdb->fsdb_mutex);
4096 rc = mgs_write_log_param(env, mgs, fsdb, mti, mti->mti_params);
4097 mutex_unlock(&fsdb->fsdb_mutex);
4098 mgs_revoke_lock(mgs, fsdb, CONFIG_T_CONFIG);
4106 static int mgs_write_log_pool(const struct lu_env *env,
4107 struct mgs_device *mgs, char *logname,
4108 struct fs_db *fsdb, char *tgtname,
4109 enum lcfg_command_type cmd,
4110 char *fsname, char *poolname,
4111 char *ostname, char *comment)
4113 struct llog_handle *llh = NULL;
4116 rc = record_start_log(env, mgs, &llh, logname);
4119 rc = record_marker(env, llh, fsdb, CM_START, tgtname, comment);
4122 rc = record_base(env, llh, tgtname, 0, cmd,
4123 fsname, poolname, ostname, NULL);
4126 rc = record_marker(env, llh, fsdb, CM_END, tgtname, comment);
4128 record_end_log(env, &llh);
4132 int mgs_nodemap_cmd(const struct lu_env *env, struct mgs_device *mgs,
4133 enum lcfg_command_type cmd, const char *nodemap_name,
4144 case LCFG_NODEMAP_ADD:
4145 rc = nodemap_add(nodemap_name);
4147 case LCFG_NODEMAP_DEL:
4148 rc = nodemap_del(nodemap_name);
4150 case LCFG_NODEMAP_ADD_RANGE:
4151 rc = nodemap_parse_range(param, nid);
4154 rc = nodemap_add_range(nodemap_name, nid);
4156 case LCFG_NODEMAP_DEL_RANGE:
4157 rc = nodemap_parse_range(param, nid);
4160 rc = nodemap_del_range(nodemap_name, nid);
4162 case LCFG_NODEMAP_ADMIN:
4163 bool_switch = simple_strtoul(param, NULL, 10);
4164 rc = nodemap_set_allow_root(nodemap_name, bool_switch);
4166 case LCFG_NODEMAP_TRUSTED:
4167 bool_switch = simple_strtoul(param, NULL, 10);
4168 rc = nodemap_set_trust_client_ids(nodemap_name, bool_switch);
4170 case LCFG_NODEMAP_SQUASH_UID:
4171 int_id = simple_strtoul(param, NULL, 10);
4172 rc = nodemap_set_squash_uid(nodemap_name, int_id);
4174 case LCFG_NODEMAP_SQUASH_GID:
4175 int_id = simple_strtoul(param, NULL, 10);
4176 rc = nodemap_set_squash_gid(nodemap_name, int_id);
4178 case LCFG_NODEMAP_ADD_UIDMAP:
4179 case LCFG_NODEMAP_ADD_GIDMAP:
4180 rc = nodemap_parse_idmap(param, idmap);
4183 if (cmd == LCFG_NODEMAP_ADD_UIDMAP)
4184 rc = nodemap_add_idmap(nodemap_name, NODEMAP_UID,
4187 rc = nodemap_add_idmap(nodemap_name, NODEMAP_GID,
4190 case LCFG_NODEMAP_DEL_UIDMAP:
4191 case LCFG_NODEMAP_DEL_GIDMAP:
4192 rc = nodemap_parse_idmap(param, idmap);
4195 if (cmd == LCFG_NODEMAP_DEL_UIDMAP)
4196 rc = nodemap_del_idmap(nodemap_name, NODEMAP_UID,
4199 rc = nodemap_del_idmap(nodemap_name, NODEMAP_GID,
4202 case LCFG_NODEMAP_SET_FILESET:
4203 rc = nodemap_set_fileset(nodemap_name, param);
4212 int mgs_pool_cmd(const struct lu_env *env, struct mgs_device *mgs,
4213 enum lcfg_command_type cmd, char *fsname,
4214 char *poolname, char *ostname)
4219 char *label = NULL, *canceled_label = NULL;
4221 struct mgs_target_info *mti = NULL;
4225 rc = mgs_find_or_make_fsdb(env, mgs, fsname, &fsdb);
4227 CERROR("Can't get db for %s\n", fsname);
4230 if (test_bit(FSDB_LOG_EMPTY, &fsdb->fsdb_flags)) {
4231 CERROR("%s is not defined\n", fsname);
4232 mgs_free_fsdb(mgs, fsdb);
4236 label_sz = 10 + strlen(fsname) + strlen(poolname);
4238 /* check if ostname match fsname */
4239 if (ostname != NULL) {
4242 ptr = strrchr(ostname, '-');
4243 if ((ptr == NULL) ||
4244 (strncmp(fsname, ostname, ptr-ostname) != 0))
4246 label_sz += strlen(ostname);
4249 OBD_ALLOC(label, label_sz);
4256 "new %s.%s", fsname, poolname);
4260 "add %s.%s.%s", fsname, poolname, ostname);
4263 OBD_ALLOC(canceled_label, label_sz);
4264 if (canceled_label == NULL)
4265 GOTO(out_label, rc = -ENOMEM);
4267 "rem %s.%s.%s", fsname, poolname, ostname);
4268 sprintf(canceled_label,
4269 "add %s.%s.%s", fsname, poolname, ostname);
4272 OBD_ALLOC(canceled_label, label_sz);
4273 if (canceled_label == NULL)
4274 GOTO(out_label, rc = -ENOMEM);
4276 "del %s.%s", fsname, poolname);
4277 sprintf(canceled_label,
4278 "new %s.%s", fsname, poolname);
4284 if (canceled_label != NULL) {
4287 GOTO(out_cancel, rc = -ENOMEM);
4290 mutex_lock(&fsdb->fsdb_mutex);
4291 /* write pool def to all MDT logs */
4292 for (i = 0; i < INDEX_MAP_SIZE * 8; i++) {
4293 if (test_bit(i, fsdb->fsdb_mdt_index_map)) {
4294 rc = name_create_mdt_and_lov(&logname, &lovname,
4297 mutex_unlock(&fsdb->fsdb_mutex);
4300 if (canceled_label != NULL) {
4301 strcpy(mti->mti_svname, "lov pool");
4302 rc = mgs_modify(env, mgs, fsdb, mti, logname,
4303 lovname, canceled_label,
4308 rc = mgs_write_log_pool(env, mgs, logname,
4312 name_destroy(&logname);
4313 name_destroy(&lovname);
4315 mutex_unlock(&fsdb->fsdb_mutex);
4321 rc = name_create(&logname, fsname, "-client");
4323 mutex_unlock(&fsdb->fsdb_mutex);
4326 if (canceled_label != NULL) {
4327 rc = mgs_modify(env, mgs, fsdb, mti, logname,
4328 fsdb->fsdb_clilov, canceled_label, CM_SKIP);
4330 mutex_unlock(&fsdb->fsdb_mutex);
4331 name_destroy(&logname);
4336 rc = mgs_write_log_pool(env, mgs, logname, fsdb, fsdb->fsdb_clilov,
4337 cmd, fsname, poolname, ostname, label);
4338 mutex_unlock(&fsdb->fsdb_mutex);
4339 name_destroy(&logname);
4340 /* request for update */
4341 mgs_revoke_lock(mgs, fsdb, CONFIG_T_CONFIG);
4348 if (canceled_label != NULL)
4349 OBD_FREE(canceled_label, label_sz);
4351 OBD_FREE(label, label_sz);