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);
124 CERROR("%s: key failed when listing %s: rc = %d\n",
125 mgs->mgs_obd->obd_name, MOUNT_CONFIGS_DIR, rc);
129 /******************** DB functions *********************/
131 static inline int name_create(char **newname, char *prefix, char *suffix)
134 OBD_ALLOC(*newname, strlen(prefix) + strlen(suffix) + 1);
137 sprintf(*newname, "%s%s", prefix, suffix);
141 static inline void name_destroy(char **name)
144 OBD_FREE(*name, strlen(*name) + 1);
148 struct mgs_fsdb_handler_data
154 /* from the (client) config log, figure out:
155 1. which ost's/mdt's are configured (by index)
156 2. what the last config step is
157 3. COMPAT_18 osc name
159 /* It might be better to have a separate db file, instead of parsing the info
160 out of the client log. This is slow and potentially error-prone. */
161 static int mgs_fsdb_handler(const struct lu_env *env, struct llog_handle *llh,
162 struct llog_rec_hdr *rec, void *data)
164 struct mgs_fsdb_handler_data *d = data;
165 struct fs_db *fsdb = d->fsdb;
166 int cfg_len = rec->lrh_len;
167 char *cfg_buf = (char*) (rec + 1);
168 struct lustre_cfg *lcfg;
173 if (rec->lrh_type != OBD_CFG_REC) {
174 CERROR("unhandled lrh_type: %#x\n", rec->lrh_type);
178 rc = lustre_cfg_sanity_check(cfg_buf, cfg_len);
180 CERROR("Insane cfg\n");
184 lcfg = (struct lustre_cfg *)cfg_buf;
186 CDEBUG(D_INFO, "cmd %x %s %s\n", lcfg->lcfg_command,
187 lustre_cfg_string(lcfg, 0), lustre_cfg_string(lcfg, 1));
189 /* Figure out ost indicies */
190 /* lov_modify_tgts add 0:lov1 1:ost1_UUID 2(index):0 3(gen):1 */
191 if (lcfg->lcfg_command == LCFG_LOV_ADD_OBD ||
192 lcfg->lcfg_command == LCFG_LOV_DEL_OBD) {
193 index = simple_strtoul(lustre_cfg_string(lcfg, 2),
195 CDEBUG(D_MGS, "OST index for %s is %u (%s)\n",
196 lustre_cfg_string(lcfg, 1), index,
197 lustre_cfg_string(lcfg, 2));
198 set_bit(index, fsdb->fsdb_ost_index_map);
201 /* Figure out mdt indicies */
202 /* attach 0:MDC_uml1_mdsA_MNT_client 1:mdc 2:1d834_MNT_client_03f */
203 if ((lcfg->lcfg_command == LCFG_ATTACH) &&
204 (strcmp(lustre_cfg_string(lcfg, 1), LUSTRE_MDC_NAME) == 0)) {
205 rc = server_name2index(lustre_cfg_string(lcfg, 0),
207 if (rc != LDD_F_SV_TYPE_MDT) {
208 CWARN("Unparsable MDC name %s, assuming index 0\n",
209 lustre_cfg_string(lcfg, 0));
213 CDEBUG(D_MGS, "MDT index is %u\n", index);
214 set_bit(index, fsdb->fsdb_mdt_index_map);
215 fsdb->fsdb_mdt_count ++;
219 * figure out the old config. fsdb_gen = 0 means old log
220 * It is obsoleted and not supported anymore
222 if (fsdb->fsdb_gen == 0) {
223 CERROR("Old config format is not supported\n");
228 * compat to 1.8, check osc name used by MDT0 to OSTs, bz18548.
230 if (!test_bit(FSDB_OSCNAME18, &fsdb->fsdb_flags) &&
231 lcfg->lcfg_command == LCFG_ATTACH &&
232 strcmp(lustre_cfg_string(lcfg, 1), LUSTRE_OSC_NAME) == 0) {
233 if (OBD_OCD_VERSION_MAJOR(d->ver) == 1 &&
234 OBD_OCD_VERSION_MINOR(d->ver) <= 8) {
235 CWARN("MDT using 1.8 OSC name scheme\n");
236 set_bit(FSDB_OSCNAME18, &fsdb->fsdb_flags);
240 if (lcfg->lcfg_command == LCFG_MARKER) {
241 struct cfg_marker *marker;
242 marker = lustre_cfg_buf(lcfg, 1);
244 d->ver = marker->cm_vers;
246 /* Keep track of the latest marker step */
247 fsdb->fsdb_gen = max(fsdb->fsdb_gen, marker->cm_step);
253 /* fsdb->fsdb_mutex is already held in mgs_find_or_make_fsdb*/
254 static int mgs_get_fsdb_from_llog(const struct lu_env *env,
255 struct mgs_device *mgs,
259 struct llog_handle *loghandle;
260 struct llog_ctxt *ctxt;
261 struct mgs_fsdb_handler_data d = { fsdb, 0 };
266 ctxt = llog_get_context(mgs->mgs_obd, LLOG_CONFIG_ORIG_CTXT);
267 LASSERT(ctxt != NULL);
268 rc = name_create(&logname, fsdb->fsdb_name, "-client");
271 rc = llog_open_create(env, ctxt, &loghandle, NULL, logname);
275 rc = llog_init_handle(env, loghandle, LLOG_F_IS_PLAIN, NULL);
279 if (llog_get_size(loghandle) <= 1)
280 set_bit(FSDB_LOG_EMPTY, &fsdb->fsdb_flags);
282 rc = llog_process(env, loghandle, mgs_fsdb_handler, (void *)&d, NULL);
283 CDEBUG(D_INFO, "get_db = %d\n", rc);
285 llog_close(env, loghandle);
287 name_destroy(&logname);
294 static void mgs_free_fsdb_srpc(struct fs_db *fsdb)
296 struct mgs_tgt_srpc_conf *tgtconf;
298 /* free target-specific rules */
299 while (fsdb->fsdb_srpc_tgt) {
300 tgtconf = fsdb->fsdb_srpc_tgt;
301 fsdb->fsdb_srpc_tgt = tgtconf->mtsc_next;
303 LASSERT(tgtconf->mtsc_tgt);
305 sptlrpc_rule_set_free(&tgtconf->mtsc_rset);
306 OBD_FREE(tgtconf->mtsc_tgt, strlen(tgtconf->mtsc_tgt) + 1);
307 OBD_FREE_PTR(tgtconf);
310 /* free general rules */
311 sptlrpc_rule_set_free(&fsdb->fsdb_srpc_gen);
314 struct fs_db *mgs_find_fsdb(struct mgs_device *mgs, char *fsname)
317 struct list_head *tmp;
319 list_for_each(tmp, &mgs->mgs_fs_db_list) {
320 fsdb = list_entry(tmp, struct fs_db, fsdb_list);
321 if (strcmp(fsdb->fsdb_name, fsname) == 0)
327 /* caller must hold the mgs->mgs_fs_db_lock */
328 static struct fs_db *mgs_new_fsdb(const struct lu_env *env,
329 struct mgs_device *mgs, char *fsname)
335 if (strlen(fsname) >= sizeof(fsdb->fsdb_name)) {
336 CERROR("fsname %s is too long\n", fsname);
337 RETURN(ERR_PTR(-EINVAL));
342 RETURN(ERR_PTR(-ENOMEM));
344 strcpy(fsdb->fsdb_name, fsname);
345 mutex_init(&fsdb->fsdb_mutex);
346 set_bit(FSDB_UDESC, &fsdb->fsdb_flags);
349 if (strcmp(fsname, MGSSELF_NAME) == 0) {
350 set_bit(FSDB_MGS_SELF, &fsdb->fsdb_flags);
351 fsdb->fsdb_mgs = mgs;
353 OBD_ALLOC(fsdb->fsdb_ost_index_map, INDEX_MAP_SIZE);
354 OBD_ALLOC(fsdb->fsdb_mdt_index_map, INDEX_MAP_SIZE);
355 if (!fsdb->fsdb_ost_index_map || !fsdb->fsdb_mdt_index_map) {
356 CERROR("No memory for index maps\n");
357 GOTO(err, rc = -ENOMEM);
360 rc = name_create(&fsdb->fsdb_clilov, fsname, "-clilov");
363 rc = name_create(&fsdb->fsdb_clilmv, fsname, "-clilmv");
367 /* initialise data for NID table */
368 mgs_ir_init_fs(env, mgs, fsdb);
370 lproc_mgs_add_live(mgs, fsdb);
373 list_add(&fsdb->fsdb_list, &mgs->mgs_fs_db_list);
377 if (fsdb->fsdb_ost_index_map)
378 OBD_FREE(fsdb->fsdb_ost_index_map, INDEX_MAP_SIZE);
379 if (fsdb->fsdb_mdt_index_map)
380 OBD_FREE(fsdb->fsdb_mdt_index_map, INDEX_MAP_SIZE);
381 name_destroy(&fsdb->fsdb_clilov);
382 name_destroy(&fsdb->fsdb_clilmv);
387 static void mgs_free_fsdb(struct mgs_device *mgs, struct fs_db *fsdb)
389 /* wait for anyone with the sem */
390 mutex_lock(&fsdb->fsdb_mutex);
391 lproc_mgs_del_live(mgs, fsdb);
392 list_del(&fsdb->fsdb_list);
394 /* deinitialize fsr */
395 mgs_ir_fini_fs(mgs, fsdb);
397 if (fsdb->fsdb_ost_index_map)
398 OBD_FREE(fsdb->fsdb_ost_index_map, INDEX_MAP_SIZE);
399 if (fsdb->fsdb_mdt_index_map)
400 OBD_FREE(fsdb->fsdb_mdt_index_map, INDEX_MAP_SIZE);
401 name_destroy(&fsdb->fsdb_clilov);
402 name_destroy(&fsdb->fsdb_clilmv);
403 mgs_free_fsdb_srpc(fsdb);
404 mutex_unlock(&fsdb->fsdb_mutex);
408 int mgs_init_fsdb_list(struct mgs_device *mgs)
410 INIT_LIST_HEAD(&mgs->mgs_fs_db_list);
414 int mgs_cleanup_fsdb_list(struct mgs_device *mgs)
417 struct list_head *tmp, *tmp2;
419 mutex_lock(&mgs->mgs_mutex);
420 list_for_each_safe(tmp, tmp2, &mgs->mgs_fs_db_list) {
421 fsdb = list_entry(tmp, struct fs_db, fsdb_list);
422 mgs_free_fsdb(mgs, fsdb);
424 mutex_unlock(&mgs->mgs_mutex);
428 int mgs_find_or_make_fsdb(const struct lu_env *env,
429 struct mgs_device *mgs, char *name,
436 mutex_lock(&mgs->mgs_mutex);
437 fsdb = mgs_find_fsdb(mgs, name);
439 mutex_unlock(&mgs->mgs_mutex);
444 CDEBUG(D_MGS, "Creating new db\n");
445 fsdb = mgs_new_fsdb(env, mgs, name);
446 /* lock fsdb_mutex until the db is loaded from llogs */
448 mutex_lock(&fsdb->fsdb_mutex);
449 mutex_unlock(&mgs->mgs_mutex);
451 RETURN(PTR_ERR(fsdb));
453 if (!test_bit(FSDB_MGS_SELF, &fsdb->fsdb_flags)) {
454 /* populate the db from the client llog */
455 rc = mgs_get_fsdb_from_llog(env, mgs, fsdb);
457 CERROR("Can't get db from client log %d\n", rc);
462 /* populate srpc rules from params llog */
463 rc = mgs_get_fsdb_srpc_from_llog(env, mgs, fsdb);
465 CERROR("Can't get db from params log %d\n", rc);
469 mutex_unlock(&fsdb->fsdb_mutex);
475 mutex_unlock(&fsdb->fsdb_mutex);
476 mgs_free_fsdb(mgs, fsdb);
482 -1= empty client log */
483 int mgs_check_index(const struct lu_env *env,
484 struct mgs_device *mgs,
485 struct mgs_target_info *mti)
492 LASSERT(!(mti->mti_flags & LDD_F_NEED_INDEX));
494 rc = mgs_find_or_make_fsdb(env, mgs, mti->mti_fsname, &fsdb);
496 CERROR("Can't get db for %s\n", mti->mti_fsname);
500 if (test_bit(FSDB_LOG_EMPTY, &fsdb->fsdb_flags))
503 if (mti->mti_flags & LDD_F_SV_TYPE_OST)
504 imap = fsdb->fsdb_ost_index_map;
505 else if (mti->mti_flags & LDD_F_SV_TYPE_MDT)
506 imap = fsdb->fsdb_mdt_index_map;
510 if (test_bit(mti->mti_stripe_index, imap))
515 static __inline__ int next_index(void *index_map, int map_len)
518 for (i = 0; i < map_len * 8; i++)
519 if (!test_bit(i, index_map)) {
522 CERROR("max index %d exceeded.\n", i);
527 0 newly marked as in use
529 +EALREADY for update of an old index */
530 static int mgs_set_index(const struct lu_env *env,
531 struct mgs_device *mgs,
532 struct mgs_target_info *mti)
539 rc = mgs_find_or_make_fsdb(env, mgs, mti->mti_fsname, &fsdb);
541 CERROR("Can't get db for %s\n", mti->mti_fsname);
545 mutex_lock(&fsdb->fsdb_mutex);
546 if (mti->mti_flags & LDD_F_SV_TYPE_OST) {
547 imap = fsdb->fsdb_ost_index_map;
548 } else if (mti->mti_flags & LDD_F_SV_TYPE_MDT) {
549 imap = fsdb->fsdb_mdt_index_map;
551 GOTO(out_up, rc = -EINVAL);
554 if (mti->mti_flags & LDD_F_NEED_INDEX) {
555 rc = next_index(imap, INDEX_MAP_SIZE);
557 GOTO(out_up, rc = -ERANGE);
558 mti->mti_stripe_index = rc;
559 if (mti->mti_flags & LDD_F_SV_TYPE_MDT)
560 fsdb->fsdb_mdt_count ++;
563 /* the last index(0xffff) is reserved for default value. */
564 if (mti->mti_stripe_index >= INDEX_MAP_SIZE * 8 - 1) {
565 LCONSOLE_ERROR_MSG(0x13f, "Server %s requested index %u, "
566 "but index must be less than %u.\n",
567 mti->mti_svname, mti->mti_stripe_index,
568 INDEX_MAP_SIZE * 8 - 1);
569 GOTO(out_up, rc = -ERANGE);
572 if (test_bit(mti->mti_stripe_index, imap)) {
573 if ((mti->mti_flags & LDD_F_VIRGIN) &&
574 !(mti->mti_flags & LDD_F_WRITECONF)) {
575 LCONSOLE_ERROR_MSG(0x140, "Server %s requested index "
576 "%d, but that index is already in "
577 "use. Use --writeconf to force\n",
579 mti->mti_stripe_index);
580 GOTO(out_up, rc = -EADDRINUSE);
582 CDEBUG(D_MGS, "Server %s updating index %d\n",
583 mti->mti_svname, mti->mti_stripe_index);
584 GOTO(out_up, rc = EALREADY);
588 set_bit(mti->mti_stripe_index, imap);
589 clear_bit(FSDB_LOG_EMPTY, &fsdb->fsdb_flags);
590 mutex_unlock(&fsdb->fsdb_mutex);
591 server_make_name(mti->mti_flags & ~(LDD_F_VIRGIN | LDD_F_WRITECONF),
592 mti->mti_stripe_index, mti->mti_fsname, mti->mti_svname);
594 CDEBUG(D_MGS, "Set index for %s to %d\n", mti->mti_svname,
595 mti->mti_stripe_index);
599 mutex_unlock(&fsdb->fsdb_mutex);
603 struct mgs_modify_lookup {
604 struct cfg_marker mml_marker;
608 static int mgs_modify_handler(const struct lu_env *env,
609 struct llog_handle *llh,
610 struct llog_rec_hdr *rec, void *data)
612 struct mgs_modify_lookup *mml = data;
613 struct cfg_marker *marker;
614 struct lustre_cfg *lcfg = REC_DATA(rec);
615 int cfg_len = REC_DATA_LEN(rec);
619 if (rec->lrh_type != OBD_CFG_REC) {
620 CERROR("unhandled lrh_type: %#x\n", rec->lrh_type);
624 rc = lustre_cfg_sanity_check(lcfg, cfg_len);
626 CERROR("Insane cfg\n");
630 /* We only care about markers */
631 if (lcfg->lcfg_command != LCFG_MARKER)
634 marker = lustre_cfg_buf(lcfg, 1);
635 if ((strcmp(mml->mml_marker.cm_comment, marker->cm_comment) == 0) &&
636 (strcmp(mml->mml_marker.cm_tgtname, marker->cm_tgtname) == 0) &&
637 !(marker->cm_flags & CM_SKIP)) {
638 /* Found a non-skipped marker match */
639 CDEBUG(D_MGS, "Changing rec %u marker %d %x->%x: %s %s\n",
640 rec->lrh_index, marker->cm_step,
641 marker->cm_flags, mml->mml_marker.cm_flags,
642 marker->cm_tgtname, marker->cm_comment);
643 /* Overwrite the old marker llog entry */
644 marker->cm_flags &= ~CM_EXCLUDE; /* in case we're unexcluding */
645 marker->cm_flags |= mml->mml_marker.cm_flags;
646 marker->cm_canceltime = mml->mml_marker.cm_canceltime;
647 rc = llog_write(env, llh, rec, rec->lrh_index);
656 * Modify an existing config log record (for CM_SKIP or CM_EXCLUDE)
658 * 0 - modified successfully,
659 * 1 - no modification was done
662 static int mgs_modify(const struct lu_env *env, struct mgs_device *mgs,
663 struct fs_db *fsdb, struct mgs_target_info *mti,
664 char *logname, char *devname, char *comment, int flags)
666 struct llog_handle *loghandle;
667 struct llog_ctxt *ctxt;
668 struct mgs_modify_lookup *mml;
673 LASSERT(mutex_is_locked(&fsdb->fsdb_mutex));
674 CDEBUG(D_MGS, "modify %s/%s/%s fl=%x\n", logname, devname, comment,
677 ctxt = llog_get_context(mgs->mgs_obd, LLOG_CONFIG_ORIG_CTXT);
678 LASSERT(ctxt != NULL);
679 rc = llog_open(env, ctxt, &loghandle, NULL, logname, LLOG_OPEN_EXISTS);
686 rc = llog_init_handle(env, loghandle, LLOG_F_IS_PLAIN, NULL);
690 if (llog_get_size(loghandle) <= 1)
691 GOTO(out_close, rc = 0);
695 GOTO(out_close, rc = -ENOMEM);
696 if (strlcpy(mml->mml_marker.cm_comment, comment,
697 sizeof(mml->mml_marker.cm_comment)) >=
698 sizeof(mml->mml_marker.cm_comment))
699 GOTO(out_free, rc = -E2BIG);
700 if (strlcpy(mml->mml_marker.cm_tgtname, devname,
701 sizeof(mml->mml_marker.cm_tgtname)) >=
702 sizeof(mml->mml_marker.cm_tgtname))
703 GOTO(out_free, rc = -E2BIG);
704 /* Modify mostly means cancel */
705 mml->mml_marker.cm_flags = flags;
706 mml->mml_marker.cm_canceltime = flags ? cfs_time_current_sec() : 0;
707 mml->mml_modified = 0;
708 rc = llog_process(env, loghandle, mgs_modify_handler, (void *)mml,
710 if (!rc && !mml->mml_modified)
717 llog_close(env, loghandle);
720 CERROR("%s: modify %s/%s failed: rc = %d\n",
721 mgs->mgs_obd->obd_name, mti->mti_svname, comment, rc);
726 /** This structure is passed to mgs_replace_handler */
727 struct mgs_replace_uuid_lookup {
728 /* Nids are replaced for this target device */
729 struct mgs_target_info target;
730 /* Temporary modified llog */
731 struct llog_handle *temp_llh;
732 /* Flag is set if in target block*/
733 int in_target_device;
734 /* Nids already added. Just skip (multiple nids) */
735 int device_nids_added;
736 /* Flag is set if this block should not be copied */
741 * Check: a) if block should be skipped
742 * b) is it target block
747 * \retval 0 should not to be skipped
748 * \retval 1 should to be skipped
750 static int check_markers(struct lustre_cfg *lcfg,
751 struct mgs_replace_uuid_lookup *mrul)
753 struct cfg_marker *marker;
755 /* Track markers. Find given device */
756 if (lcfg->lcfg_command == LCFG_MARKER) {
757 marker = lustre_cfg_buf(lcfg, 1);
758 /* Clean llog from records marked as CM_EXCLUDE.
759 CM_SKIP records are used for "active" command
760 and can be restored if needed */
761 if ((marker->cm_flags & (CM_EXCLUDE | CM_START)) ==
762 (CM_EXCLUDE | CM_START)) {
767 if ((marker->cm_flags & (CM_EXCLUDE | CM_END)) ==
768 (CM_EXCLUDE | CM_END)) {
773 if (strcmp(mrul->target.mti_svname, marker->cm_tgtname) == 0) {
774 LASSERT(!(marker->cm_flags & CM_START) ||
775 !(marker->cm_flags & CM_END));
776 if (marker->cm_flags & CM_START) {
777 mrul->in_target_device = 1;
778 mrul->device_nids_added = 0;
779 } else if (marker->cm_flags & CM_END)
780 mrul->in_target_device = 0;
787 static int record_base(const struct lu_env *env, struct llog_handle *llh,
788 char *cfgname, lnet_nid_t nid, int cmd,
789 char *s1, char *s2, char *s3, char *s4)
791 struct mgs_thread_info *mgi = mgs_env_info(env);
792 struct llog_cfg_rec *lcr;
795 CDEBUG(D_MGS, "lcfg %s %#x %s %s %s %s\n", cfgname,
796 cmd, s1, s2, s3, s4);
798 lustre_cfg_bufs_reset(&mgi->mgi_bufs, cfgname);
800 lustre_cfg_bufs_set_string(&mgi->mgi_bufs, 1, s1);
802 lustre_cfg_bufs_set_string(&mgi->mgi_bufs, 2, s2);
804 lustre_cfg_bufs_set_string(&mgi->mgi_bufs, 3, s3);
806 lustre_cfg_bufs_set_string(&mgi->mgi_bufs, 4, s4);
808 lcr = lustre_cfg_rec_new(cmd, &mgi->mgi_bufs);
812 lcr->lcr_cfg.lcfg_nid = nid;
813 rc = llog_write(env, llh, &lcr->lcr_hdr, LLOG_NEXT_IDX);
815 lustre_cfg_rec_free(lcr);
819 "failed to write lcfg %s %#x %s %s %s %s: rc = %d\n",
820 cfgname, cmd, s1, s2, s3, s4, rc);
824 static inline int record_add_uuid(const struct lu_env *env,
825 struct llog_handle *llh,
826 uint64_t nid, char *uuid)
828 return record_base(env, llh, NULL, nid, LCFG_ADD_UUID, uuid,
832 static inline int record_add_conn(const struct lu_env *env,
833 struct llog_handle *llh,
834 char *devname, char *uuid)
836 return record_base(env, llh, devname, 0, LCFG_ADD_CONN, uuid,
840 static inline int record_attach(const struct lu_env *env,
841 struct llog_handle *llh, char *devname,
842 char *type, char *uuid)
844 return record_base(env, llh, devname, 0, LCFG_ATTACH, type, uuid,
848 static inline int record_setup(const struct lu_env *env,
849 struct llog_handle *llh, char *devname,
850 char *s1, char *s2, char *s3, char *s4)
852 return record_base(env, llh, devname, 0, LCFG_SETUP, s1, s2, s3, s4);
856 * \retval <0 record processing error
857 * \retval n record is processed. No need copy original one.
858 * \retval 0 record is not processed.
860 static int process_command(const struct lu_env *env, struct lustre_cfg *lcfg,
861 struct mgs_replace_uuid_lookup *mrul)
868 if (lcfg->lcfg_command == LCFG_ADD_UUID) {
869 /* LCFG_ADD_UUID command found. Let's skip original command
870 and add passed nids */
871 ptr = mrul->target.mti_params;
872 while (class_parse_nid(ptr, &nid, &ptr) == 0) {
873 CDEBUG(D_MGS, "add nid %s with uuid %s, "
874 "device %s\n", libcfs_nid2str(nid),
875 mrul->target.mti_params,
876 mrul->target.mti_svname);
877 rc = record_add_uuid(env,
879 mrul->target.mti_params);
884 if (nids_added == 0) {
885 CERROR("No new nids were added, nid %s with uuid %s, "
886 "device %s\n", libcfs_nid2str(nid),
887 mrul->target.mti_params,
888 mrul->target.mti_svname);
891 mrul->device_nids_added = 1;
897 if (mrul->device_nids_added && lcfg->lcfg_command == LCFG_SETUP) {
898 /* LCFG_SETUP command found. UUID should be changed */
899 rc = record_setup(env,
901 /* devname the same */
902 lustre_cfg_string(lcfg, 0),
903 /* s1 is not changed */
904 lustre_cfg_string(lcfg, 1),
905 /* new uuid should be
907 mrul->target.mti_params,
908 /* s3 is not changed */
909 lustre_cfg_string(lcfg, 3),
910 /* s4 is not changed */
911 lustre_cfg_string(lcfg, 4));
915 /* Another commands in target device block */
920 * Handler that called for every record in llog.
921 * Records are processed in order they placed in llog.
923 * \param[in] llh log to be processed
924 * \param[in] rec current record
925 * \param[in] data mgs_replace_uuid_lookup structure
929 static int mgs_replace_handler(const struct lu_env *env,
930 struct llog_handle *llh,
931 struct llog_rec_hdr *rec,
934 struct mgs_replace_uuid_lookup *mrul;
935 struct lustre_cfg *lcfg = REC_DATA(rec);
936 int cfg_len = REC_DATA_LEN(rec);
940 mrul = (struct mgs_replace_uuid_lookup *)data;
942 if (rec->lrh_type != OBD_CFG_REC) {
943 CERROR("unhandled lrh_type: %#x, cmd %x %s %s\n",
944 rec->lrh_type, lcfg->lcfg_command,
945 lustre_cfg_string(lcfg, 0),
946 lustre_cfg_string(lcfg, 1));
950 rc = lustre_cfg_sanity_check(lcfg, cfg_len);
952 /* Do not copy any invalidated records */
953 GOTO(skip_out, rc = 0);
956 rc = check_markers(lcfg, mrul);
957 if (rc || mrul->skip_it)
958 GOTO(skip_out, rc = 0);
960 /* Write to new log all commands outside target device block */
961 if (!mrul->in_target_device)
962 GOTO(copy_out, rc = 0);
964 /* Skip all other LCFG_ADD_UUID and LCFG_ADD_CONN records
965 (failover nids) for this target, assuming that if then
966 primary is changing then so is the failover */
967 if (mrul->device_nids_added &&
968 (lcfg->lcfg_command == LCFG_ADD_UUID ||
969 lcfg->lcfg_command == LCFG_ADD_CONN))
970 GOTO(skip_out, rc = 0);
972 rc = process_command(env, lcfg, mrul);
979 /* Record is placed in temporary llog as is */
980 rc = llog_write(env, mrul->temp_llh, rec, LLOG_NEXT_IDX);
982 CDEBUG(D_MGS, "Copied idx=%d, rc=%d, len=%d, cmd %x %s %s\n",
983 rec->lrh_index, rc, rec->lrh_len, lcfg->lcfg_command,
984 lustre_cfg_string(lcfg, 0), lustre_cfg_string(lcfg, 1));
988 CDEBUG(D_MGS, "Skipped idx=%d, rc=%d, len=%d, cmd %x %s %s\n",
989 rec->lrh_index, rc, rec->lrh_len, lcfg->lcfg_command,
990 lustre_cfg_string(lcfg, 0), lustre_cfg_string(lcfg, 1));
994 static int mgs_log_is_empty(const struct lu_env *env,
995 struct mgs_device *mgs, char *name)
997 struct llog_ctxt *ctxt;
1000 ctxt = llog_get_context(mgs->mgs_obd, LLOG_CONFIG_ORIG_CTXT);
1001 LASSERT(ctxt != NULL);
1003 rc = llog_is_empty(env, ctxt, name);
1004 llog_ctxt_put(ctxt);
1008 static int mgs_replace_nids_log(const struct lu_env *env,
1009 struct obd_device *mgs, struct fs_db *fsdb,
1010 char *logname, char *devname, char *nids)
1012 struct llog_handle *orig_llh, *backup_llh;
1013 struct llog_ctxt *ctxt;
1014 struct mgs_replace_uuid_lookup *mrul;
1015 struct mgs_device *mgs_dev = lu2mgs_dev(mgs->obd_lu_dev);
1016 static struct obd_uuid cfg_uuid = { .uuid = "config_uuid" };
1021 CDEBUG(D_MGS, "Replace nids for %s in %s\n", devname, logname);
1023 ctxt = llog_get_context(mgs, LLOG_CONFIG_ORIG_CTXT);
1024 LASSERT(ctxt != NULL);
1026 if (mgs_log_is_empty(env, mgs_dev, logname)) {
1027 /* Log is empty. Nothing to replace */
1028 GOTO(out_put, rc = 0);
1031 OBD_ALLOC(backup, strlen(logname) + strlen(".bak") + 1);
1033 GOTO(out_put, rc = -ENOMEM);
1035 sprintf(backup, "%s.bak", logname);
1037 rc = llog_backup(env, mgs, ctxt, ctxt, logname, backup);
1039 /* Now erase original log file. Connections are not allowed.
1040 Backup is already saved */
1041 rc = llog_erase(env, ctxt, NULL, logname);
1044 } else if (rc != -ENOENT) {
1045 CERROR("%s: can't make backup for %s: rc = %d\n",
1046 mgs->obd_name, logname, rc);
1050 /* open local log */
1051 rc = llog_open_create(env, ctxt, &orig_llh, NULL, logname);
1053 GOTO(out_restore, rc);
1055 rc = llog_init_handle(env, orig_llh, LLOG_F_IS_PLAIN, &cfg_uuid);
1057 GOTO(out_closel, rc);
1059 /* open backup llog */
1060 rc = llog_open(env, ctxt, &backup_llh, NULL, backup,
1063 GOTO(out_closel, rc);
1065 rc = llog_init_handle(env, backup_llh, LLOG_F_IS_PLAIN, NULL);
1067 GOTO(out_close, rc);
1069 if (llog_get_size(backup_llh) <= 1)
1070 GOTO(out_close, rc = 0);
1072 OBD_ALLOC_PTR(mrul);
1074 GOTO(out_close, rc = -ENOMEM);
1075 /* devname is only needed information to replace UUID records */
1076 strlcpy(mrul->target.mti_svname, devname,
1077 sizeof(mrul->target.mti_svname));
1078 /* parse nids later */
1079 strlcpy(mrul->target.mti_params, nids, sizeof(mrul->target.mti_params));
1080 /* Copy records to this temporary llog */
1081 mrul->temp_llh = orig_llh;
1083 rc = llog_process(env, backup_llh, mgs_replace_handler,
1084 (void *)mrul, NULL);
1087 rc2 = llog_close(NULL, backup_llh);
1091 rc2 = llog_close(NULL, orig_llh);
1097 CERROR("%s: llog should be restored: rc = %d\n",
1099 rc2 = llog_backup(env, mgs, ctxt, ctxt, backup,
1102 CERROR("%s: can't restore backup %s: rc = %d\n",
1103 mgs->obd_name, logname, rc2);
1107 OBD_FREE(backup, strlen(backup) + 1);
1110 llog_ctxt_put(ctxt);
1113 CERROR("%s: failed to replace nids in log %s: rc = %d\n",
1114 mgs->obd_name, logname, rc);
1120 * Parse device name and get file system name and/or device index
1122 * \param[in] devname device name (ex. lustre-MDT0000)
1123 * \param[out] fsname file system name(optional)
1124 * \param[out] index device index(optional)
1128 static int mgs_parse_devname(char *devname, char *fsname, __u32 *index)
1133 /* Extract fsname */
1135 rc = server_name2fsname(devname, fsname, NULL);
1137 CDEBUG(D_MGS, "Device name %s without fsname\n",
1144 rc = server_name2index(devname, index, NULL);
1146 CDEBUG(D_MGS, "Device name %s with wrong index\n",
1155 /* This is only called during replace_nids */
1156 static int only_mgs_is_running(struct obd_device *mgs_obd)
1158 /* TDB: Is global variable with devices count exists? */
1159 int num_devices = get_devices_count();
1160 int num_exports = 0;
1161 struct obd_export *exp;
1163 spin_lock(&mgs_obd->obd_dev_lock);
1164 list_for_each_entry(exp, &mgs_obd->obd_exports, exp_obd_chain) {
1165 /* skip self export */
1166 if (exp == mgs_obd->obd_self_export)
1168 if (exp_connect_flags(exp) & OBD_CONNECT_MDS_MDS)
1173 CERROR("%s: node %s still connected during replace_nids "
1174 "connect_flags:%llx\n",
1176 libcfs_nid2str(exp->exp_nid_stats->nid),
1177 exp_connect_flags(exp));
1180 spin_unlock(&mgs_obd->obd_dev_lock);
1182 /* osd, MGS and MGC + self_export
1183 (wc -l /proc/fs/lustre/devices <= 2) && (non self exports == 0) */
1184 return (num_devices <= 3) && (num_exports == 0);
1187 static int name_create_mdt(char **logname, char *fsname, int i)
1191 sprintf(mdt_index, "-MDT%04x", i);
1192 return name_create(logname, fsname, mdt_index);
1196 * Replace nids for \a device to \a nids values
1198 * \param obd MGS obd device
1199 * \param devname nids need to be replaced for this device
1200 * (ex. lustre-OST0000)
1201 * \param nids nids list (ex. nid1,nid2,nid3)
1205 int mgs_replace_nids(const struct lu_env *env,
1206 struct mgs_device *mgs,
1207 char *devname, char *nids)
1209 /* Assume fsname is part of device name */
1210 char fsname[MTI_NAME_MAXLEN];
1217 struct obd_device *mgs_obd = mgs->mgs_obd;
1220 /* We can only change NIDs if no other nodes are connected */
1221 spin_lock(&mgs_obd->obd_dev_lock);
1222 conn_state = mgs_obd->obd_no_conn;
1223 mgs_obd->obd_no_conn = 1;
1224 spin_unlock(&mgs_obd->obd_dev_lock);
1226 /* We can not change nids if not only MGS is started */
1227 if (!only_mgs_is_running(mgs_obd)) {
1228 CERROR("Only MGS is allowed to be started\n");
1229 GOTO(out, rc = -EINPROGRESS);
1232 /* Get fsname and index*/
1233 rc = mgs_parse_devname(devname, fsname, &index);
1237 rc = mgs_find_or_make_fsdb(env, mgs, fsname, &fsdb);
1239 CERROR("%s: can't find fsdb: rc = %d\n", fsname, rc);
1243 /* Process client llogs */
1244 name_create(&logname, fsname, "-client");
1245 rc = mgs_replace_nids_log(env, mgs_obd, fsdb, logname, devname, nids);
1246 name_destroy(&logname);
1248 CERROR("%s: error while replacing NIDs for %s: rc = %d\n",
1249 fsname, devname, rc);
1253 /* Process MDT llogs */
1254 for (i = 0; i < INDEX_MAP_SIZE * 8; i++) {
1255 if (!test_bit(i, fsdb->fsdb_mdt_index_map))
1257 name_create_mdt(&logname, fsname, i);
1258 rc = mgs_replace_nids_log(env, mgs_obd, fsdb, logname, devname, nids);
1259 name_destroy(&logname);
1265 spin_lock(&mgs_obd->obd_dev_lock);
1266 mgs_obd->obd_no_conn = conn_state;
1267 spin_unlock(&mgs_obd->obd_dev_lock);
1272 static int record_lov_setup(const struct lu_env *env, struct llog_handle *llh,
1273 char *devname, struct lov_desc *desc)
1275 struct mgs_thread_info *mgi = mgs_env_info(env);
1276 struct llog_cfg_rec *lcr;
1279 lustre_cfg_bufs_reset(&mgi->mgi_bufs, devname);
1280 lustre_cfg_bufs_set(&mgi->mgi_bufs, 1, desc, sizeof(*desc));
1281 lcr = lustre_cfg_rec_new(LCFG_SETUP, &mgi->mgi_bufs);
1285 rc = llog_write(env, llh, &lcr->lcr_hdr, LLOG_NEXT_IDX);
1286 lustre_cfg_rec_free(lcr);
1290 static int record_lmv_setup(const struct lu_env *env, struct llog_handle *llh,
1291 char *devname, struct lmv_desc *desc)
1293 struct mgs_thread_info *mgi = mgs_env_info(env);
1294 struct llog_cfg_rec *lcr;
1297 lustre_cfg_bufs_reset(&mgi->mgi_bufs, devname);
1298 lustre_cfg_bufs_set(&mgi->mgi_bufs, 1, desc, sizeof(*desc));
1299 lcr = lustre_cfg_rec_new(LCFG_SETUP, &mgi->mgi_bufs);
1303 rc = llog_write(env, llh, &lcr->lcr_hdr, LLOG_NEXT_IDX);
1304 lustre_cfg_rec_free(lcr);
1308 static inline int record_mdc_add(const struct lu_env *env,
1309 struct llog_handle *llh,
1310 char *logname, char *mdcuuid,
1311 char *mdtuuid, char *index,
1314 return record_base(env,llh,logname,0,LCFG_ADD_MDC,
1315 mdtuuid,index,gen,mdcuuid);
1318 static inline int record_lov_add(const struct lu_env *env,
1319 struct llog_handle *llh,
1320 char *lov_name, char *ost_uuid,
1321 char *index, char *gen)
1323 return record_base(env, llh, lov_name, 0, LCFG_LOV_ADD_OBD,
1324 ost_uuid, index, gen, NULL);
1327 static inline int record_mount_opt(const struct lu_env *env,
1328 struct llog_handle *llh,
1329 char *profile, char *lov_name,
1332 return record_base(env, llh, NULL, 0, LCFG_MOUNTOPT,
1333 profile, lov_name, mdc_name, NULL);
1336 static int record_marker(const struct lu_env *env,
1337 struct llog_handle *llh,
1338 struct fs_db *fsdb, __u32 flags,
1339 char *tgtname, char *comment)
1341 struct mgs_thread_info *mgi = mgs_env_info(env);
1342 struct llog_cfg_rec *lcr;
1346 if (flags & CM_START)
1348 mgi->mgi_marker.cm_step = fsdb->fsdb_gen;
1349 mgi->mgi_marker.cm_flags = flags;
1350 mgi->mgi_marker.cm_vers = LUSTRE_VERSION_CODE;
1351 cplen = strlcpy(mgi->mgi_marker.cm_tgtname, tgtname,
1352 sizeof(mgi->mgi_marker.cm_tgtname));
1353 if (cplen >= sizeof(mgi->mgi_marker.cm_tgtname))
1355 cplen = strlcpy(mgi->mgi_marker.cm_comment, comment,
1356 sizeof(mgi->mgi_marker.cm_comment));
1357 if (cplen >= sizeof(mgi->mgi_marker.cm_comment))
1359 mgi->mgi_marker.cm_createtime = cfs_time_current_sec();
1360 mgi->mgi_marker.cm_canceltime = 0;
1361 lustre_cfg_bufs_reset(&mgi->mgi_bufs, NULL);
1362 lustre_cfg_bufs_set(&mgi->mgi_bufs, 1, &mgi->mgi_marker,
1363 sizeof(mgi->mgi_marker));
1364 lcr = lustre_cfg_rec_new(LCFG_MARKER, &mgi->mgi_bufs);
1368 rc = llog_write(env, llh, &lcr->lcr_hdr, LLOG_NEXT_IDX);
1369 lustre_cfg_rec_free(lcr);
1373 static int record_start_log(const struct lu_env *env, struct mgs_device *mgs,
1374 struct llog_handle **llh, char *name)
1376 static struct obd_uuid cfg_uuid = { .uuid = "config_uuid" };
1377 struct llog_ctxt *ctxt;
1382 GOTO(out, rc = -EBUSY);
1384 ctxt = llog_get_context(mgs->mgs_obd, LLOG_CONFIG_ORIG_CTXT);
1386 GOTO(out, rc = -ENODEV);
1387 LASSERT(ctxt->loc_obd == mgs->mgs_obd);
1389 rc = llog_open_create(env, ctxt, llh, NULL, name);
1392 rc = llog_init_handle(env, *llh, LLOG_F_IS_PLAIN, &cfg_uuid);
1394 llog_close(env, *llh);
1396 llog_ctxt_put(ctxt);
1399 CERROR("%s: can't start log %s: rc = %d\n",
1400 mgs->mgs_obd->obd_name, name, rc);
1406 static int record_end_log(const struct lu_env *env, struct llog_handle **llh)
1410 rc = llog_close(env, *llh);
1416 /******************** config "macros" *********************/
1418 /* write an lcfg directly into a log (with markers) */
1419 static int mgs_write_log_direct(const struct lu_env *env,
1420 struct mgs_device *mgs, struct fs_db *fsdb,
1421 char *logname, struct llog_cfg_rec *lcr,
1422 char *devname, char *comment)
1424 struct llog_handle *llh = NULL;
1429 rc = record_start_log(env, mgs, &llh, logname);
1433 /* FIXME These should be a single journal transaction */
1434 rc = record_marker(env, llh, fsdb, CM_START, devname, comment);
1437 rc = llog_write(env, llh, &lcr->lcr_hdr, LLOG_NEXT_IDX);
1440 rc = record_marker(env, llh, fsdb, CM_END, devname, comment);
1444 record_end_log(env, &llh);
1448 /* write the lcfg in all logs for the given fs */
1449 static int mgs_write_log_direct_all(const struct lu_env *env,
1450 struct mgs_device *mgs,
1452 struct mgs_target_info *mti,
1453 struct llog_cfg_rec *lcr, char *devname,
1454 char *comment, int server_only)
1456 struct list_head log_list;
1457 struct mgs_direntry *dirent, *n;
1458 char *fsname = mti->mti_fsname;
1459 int rc = 0, len = strlen(fsname);
1462 /* Find all the logs in the CONFIGS directory */
1463 rc = class_dentry_readdir(env, mgs, &log_list);
1467 /* Could use fsdb index maps instead of directory listing */
1468 list_for_each_entry_safe(dirent, n, &log_list, mde_list) {
1469 list_del_init(&dirent->mde_list);
1470 /* don't write to sptlrpc rule log */
1471 if (strstr(dirent->mde_name, "-sptlrpc") != NULL)
1474 /* caller wants write server logs only */
1475 if (server_only && strstr(dirent->mde_name, "-client") != NULL)
1478 if (strlen(dirent->mde_name) <= len ||
1479 strncmp(fsname, dirent->mde_name, len) != 0 ||
1480 dirent->mde_name[len] != '-')
1483 CDEBUG(D_MGS, "Changing log %s\n", dirent->mde_name);
1484 /* Erase any old settings of this same parameter */
1485 rc = mgs_modify(env, mgs, fsdb, mti, dirent->mde_name,
1486 devname, comment, CM_SKIP);
1488 CERROR("%s: Can't modify llog %s: rc = %d\n",
1489 mgs->mgs_obd->obd_name, dirent->mde_name, rc);
1492 /* Write the new one */
1493 rc = mgs_write_log_direct(env, mgs, fsdb, dirent->mde_name,
1494 lcr, devname, comment);
1496 CERROR("%s: writing log %s: rc = %d\n",
1497 mgs->mgs_obd->obd_name, dirent->mde_name, rc);
1499 mgs_direntry_free(dirent);
1505 static int mgs_write_log_osp_to_mdt(const struct lu_env *env,
1506 struct mgs_device *mgs,
1508 struct mgs_target_info *mti,
1509 int index, char *logname);
1510 static int mgs_write_log_osc_to_lov(const struct lu_env *env,
1511 struct mgs_device *mgs,
1513 struct mgs_target_info *mti,
1514 char *logname, char *suffix, char *lovname,
1515 enum lustre_sec_part sec_part, int flags);
1516 static int name_create_mdt_and_lov(char **logname, char **lovname,
1517 struct fs_db *fsdb, int i);
1519 static int add_param(char *params, char *key, char *val)
1521 char *start = params + strlen(params);
1522 char *end = params + sizeof(((struct mgs_target_info *)0)->mti_params);
1526 keylen = strlen(key);
1527 if (start + 1 + keylen + strlen(val) >= end) {
1528 CERROR("params are too long: %s %s%s\n",
1529 params, key != NULL ? key : "", val);
1533 sprintf(start, " %s%s", key != NULL ? key : "", val);
1538 * Walk through client config log record and convert the related records
1541 static int mgs_steal_client_llog_handler(const struct lu_env *env,
1542 struct llog_handle *llh,
1543 struct llog_rec_hdr *rec, void *data)
1545 struct mgs_device *mgs;
1546 struct obd_device *obd;
1547 struct mgs_target_info *mti, *tmti;
1549 int cfg_len = rec->lrh_len;
1550 char *cfg_buf = (char*) (rec + 1);
1551 struct lustre_cfg *lcfg;
1553 struct llog_handle *mdt_llh = NULL;
1554 static int got_an_osc_or_mdc = 0;
1555 /* 0: not found any osc/mdc;
1559 static int last_step = -1;
1564 mti = ((struct temp_comp*)data)->comp_mti;
1565 tmti = ((struct temp_comp*)data)->comp_tmti;
1566 fsdb = ((struct temp_comp*)data)->comp_fsdb;
1567 obd = ((struct temp_comp *)data)->comp_obd;
1568 mgs = lu2mgs_dev(obd->obd_lu_dev);
1571 if (rec->lrh_type != OBD_CFG_REC) {
1572 CERROR("unhandled lrh_type: %#x\n", rec->lrh_type);
1576 rc = lustre_cfg_sanity_check(cfg_buf, cfg_len);
1578 CERROR("Insane cfg\n");
1582 lcfg = (struct lustre_cfg *)cfg_buf;
1584 if (lcfg->lcfg_command == LCFG_MARKER) {
1585 struct cfg_marker *marker;
1586 marker = lustre_cfg_buf(lcfg, 1);
1587 if (!strncmp(marker->cm_comment, "add osc", 7) &&
1588 (marker->cm_flags & CM_START) &&
1589 !(marker->cm_flags & CM_SKIP)) {
1590 got_an_osc_or_mdc = 1;
1591 cplen = strlcpy(tmti->mti_svname, marker->cm_tgtname,
1592 sizeof(tmti->mti_svname));
1593 if (cplen >= sizeof(tmti->mti_svname))
1595 rc = record_start_log(env, mgs, &mdt_llh,
1599 rc = record_marker(env, mdt_llh, fsdb, CM_START,
1600 mti->mti_svname, "add osc(copied)");
1601 record_end_log(env, &mdt_llh);
1602 last_step = marker->cm_step;
1605 if (!strncmp(marker->cm_comment, "add osc", 7) &&
1606 (marker->cm_flags & CM_END) &&
1607 !(marker->cm_flags & CM_SKIP)) {
1608 LASSERT(last_step == marker->cm_step);
1610 got_an_osc_or_mdc = 0;
1611 memset(tmti, 0, sizeof(*tmti));
1612 rc = record_start_log(env, mgs, &mdt_llh,
1616 rc = record_marker(env, mdt_llh, fsdb, CM_END,
1617 mti->mti_svname, "add osc(copied)");
1618 record_end_log(env, &mdt_llh);
1621 if (!strncmp(marker->cm_comment, "add mdc", 7) &&
1622 (marker->cm_flags & CM_START) &&
1623 !(marker->cm_flags & CM_SKIP)) {
1624 got_an_osc_or_mdc = 2;
1625 last_step = marker->cm_step;
1626 memcpy(tmti->mti_svname, marker->cm_tgtname,
1627 strlen(marker->cm_tgtname));
1631 if (!strncmp(marker->cm_comment, "add mdc", 7) &&
1632 (marker->cm_flags & CM_END) &&
1633 !(marker->cm_flags & CM_SKIP)) {
1634 LASSERT(last_step == marker->cm_step);
1636 got_an_osc_or_mdc = 0;
1637 memset(tmti, 0, sizeof(*tmti));
1642 if (got_an_osc_or_mdc == 0 || last_step < 0)
1645 if (lcfg->lcfg_command == LCFG_ADD_UUID) {
1646 __u64 nodenid = lcfg->lcfg_nid;
1648 if (strlen(tmti->mti_uuid) == 0) {
1649 /* target uuid not set, this config record is before
1650 * LCFG_SETUP, this nid is one of target node nid.
1652 tmti->mti_nids[tmti->mti_nid_count] = nodenid;
1653 tmti->mti_nid_count++;
1655 char nidstr[LNET_NIDSTR_SIZE];
1657 /* failover node nid */
1658 libcfs_nid2str_r(nodenid, nidstr, sizeof(nidstr));
1659 rc = add_param(tmti->mti_params, PARAM_FAILNODE,
1666 if (lcfg->lcfg_command == LCFG_SETUP) {
1669 target = lustre_cfg_string(lcfg, 1);
1670 memcpy(tmti->mti_uuid, target, strlen(target));
1674 /* ignore client side sptlrpc_conf_log */
1675 if (lcfg->lcfg_command == LCFG_SPTLRPC_CONF)
1678 if (lcfg->lcfg_command == LCFG_ADD_MDC) {
1681 if (sscanf(lustre_cfg_buf(lcfg, 2), "%d", &index) != 1)
1684 memcpy(tmti->mti_fsname, mti->mti_fsname,
1685 strlen(mti->mti_fsname));
1686 tmti->mti_stripe_index = index;
1688 rc = mgs_write_log_osp_to_mdt(env, mgs, fsdb, tmti,
1689 mti->mti_stripe_index,
1691 memset(tmti, 0, sizeof(*tmti));
1695 if (lcfg->lcfg_command == LCFG_LOV_ADD_OBD) {
1698 char *logname, *lovname;
1700 rc = name_create_mdt_and_lov(&logname, &lovname, fsdb,
1701 mti->mti_stripe_index);
1704 sprintf(mdt_index, "-MDT%04x", mti->mti_stripe_index);
1706 if (sscanf(lustre_cfg_buf(lcfg, 2), "%d", &index) != 1) {
1707 name_destroy(&logname);
1708 name_destroy(&lovname);
1712 tmti->mti_stripe_index = index;
1713 rc = mgs_write_log_osc_to_lov(env, mgs, fsdb, tmti, logname,
1716 name_destroy(&logname);
1717 name_destroy(&lovname);
1723 /* fsdb->fsdb_mutex is already held in mgs_write_log_target*/
1724 /* stealed from mgs_get_fsdb_from_llog*/
1725 static int mgs_steal_llog_for_mdt_from_client(const struct lu_env *env,
1726 struct mgs_device *mgs,
1728 struct temp_comp* comp)
1730 struct llog_handle *loghandle;
1731 struct mgs_target_info *tmti;
1732 struct llog_ctxt *ctxt;
1737 ctxt = llog_get_context(mgs->mgs_obd, LLOG_CONFIG_ORIG_CTXT);
1738 LASSERT(ctxt != NULL);
1740 OBD_ALLOC_PTR(tmti);
1742 GOTO(out_ctxt, rc = -ENOMEM);
1744 comp->comp_tmti = tmti;
1745 comp->comp_obd = mgs->mgs_obd;
1747 rc = llog_open(env, ctxt, &loghandle, NULL, client_name,
1755 rc = llog_init_handle(env, loghandle, LLOG_F_IS_PLAIN, NULL);
1757 GOTO(out_close, rc);
1759 rc = llog_process_or_fork(env, loghandle, mgs_steal_client_llog_handler,
1760 (void *)comp, NULL, false);
1761 CDEBUG(D_MGS, "steal llog re = %d\n", rc);
1763 llog_close(env, loghandle);
1767 llog_ctxt_put(ctxt);
1771 /* lmv is the second thing for client logs */
1772 /* copied from mgs_write_log_lov. Please refer to that. */
1773 static int mgs_write_log_lmv(const struct lu_env *env,
1774 struct mgs_device *mgs,
1776 struct mgs_target_info *mti,
1777 char *logname, char *lmvname)
1779 struct llog_handle *llh = NULL;
1780 struct lmv_desc *lmvdesc;
1785 CDEBUG(D_MGS, "Writing lmv(%s) log for %s\n", lmvname,logname);
1787 OBD_ALLOC_PTR(lmvdesc);
1788 if (lmvdesc == NULL)
1790 lmvdesc->ld_active_tgt_count = 0;
1791 lmvdesc->ld_tgt_count = 0;
1792 sprintf((char*)lmvdesc->ld_uuid.uuid, "%s_UUID", lmvname);
1793 uuid = (char *)lmvdesc->ld_uuid.uuid;
1795 rc = record_start_log(env, mgs, &llh, logname);
1798 rc = record_marker(env, llh, fsdb, CM_START, lmvname, "lmv setup");
1801 rc = record_attach(env, llh, lmvname, "lmv", uuid);
1804 rc = record_lmv_setup(env, llh, lmvname, lmvdesc);
1807 rc = record_marker(env, llh, fsdb, CM_END, lmvname, "lmv setup");
1811 record_end_log(env, &llh);
1813 OBD_FREE_PTR(lmvdesc);
1817 /* lov is the first thing in the mdt and client logs */
1818 static int mgs_write_log_lov(const struct lu_env *env, struct mgs_device *mgs,
1819 struct fs_db *fsdb, struct mgs_target_info *mti,
1820 char *logname, char *lovname)
1822 struct llog_handle *llh = NULL;
1823 struct lov_desc *lovdesc;
1828 CDEBUG(D_MGS, "Writing lov(%s) log for %s\n", lovname, logname);
1831 #01 L attach 0:lov_mdsA 1:lov 2:71ccb_lov_mdsA_19f961a9e1
1832 #02 L lov_setup 0:lov_mdsA 1:(struct lov_desc)
1833 uuid=lov1_UUID, stripe count=1, size=1048576, offset=0, pattern=0
1836 /* FIXME just make lov_setup accept empty desc (put uuid in buf 2) */
1837 OBD_ALLOC_PTR(lovdesc);
1838 if (lovdesc == NULL)
1840 lovdesc->ld_magic = LOV_DESC_MAGIC;
1841 lovdesc->ld_tgt_count = 0;
1842 /* Defaults. Can be changed later by lcfg config_param */
1843 lovdesc->ld_default_stripe_count = 1;
1844 lovdesc->ld_pattern = LOV_PATTERN_RAID0;
1845 lovdesc->ld_default_stripe_size = LOV_DESC_STRIPE_SIZE_DEFAULT;
1846 lovdesc->ld_default_stripe_offset = -1;
1847 lovdesc->ld_qos_maxage = LOV_DESC_QOS_MAXAGE_DEFAULT;
1848 sprintf((char*)lovdesc->ld_uuid.uuid, "%s_UUID", lovname);
1849 /* can these be the same? */
1850 uuid = (char *)lovdesc->ld_uuid.uuid;
1852 /* This should always be the first entry in a log.
1853 rc = mgs_clear_log(obd, logname); */
1854 rc = record_start_log(env, mgs, &llh, logname);
1857 /* FIXME these should be a single journal transaction */
1858 rc = record_marker(env, llh, fsdb, CM_START, lovname, "lov setup");
1861 rc = record_attach(env, llh, lovname, "lov", uuid);
1864 rc = record_lov_setup(env, llh, lovname, lovdesc);
1867 rc = record_marker(env, llh, fsdb, CM_END, lovname, "lov setup");
1872 record_end_log(env, &llh);
1874 OBD_FREE_PTR(lovdesc);
1878 /* add failnids to open log */
1879 static int mgs_write_log_failnids(const struct lu_env *env,
1880 struct mgs_target_info *mti,
1881 struct llog_handle *llh,
1884 char *failnodeuuid = NULL;
1885 char *ptr = mti->mti_params;
1890 #03 L add_uuid nid=uml1@tcp(0x20000c0a80201) nal=90 0: 1:uml1_UUID
1891 #04 L add_uuid nid=1@elan(0x1000000000001) nal=90 0: 1:uml1_UUID
1892 #05 L setup 0:OSC_uml1_ost1_mdsA 1:ost1_UUID 2:uml1_UUID
1893 #06 L add_uuid nid=uml2@tcp(0x20000c0a80202) nal=90 0: 1:uml2_UUID
1894 #0x L add_uuid nid=2@elan(0x1000000000002) nal=90 0: 1:uml2_UUID
1895 #07 L add_conn 0:OSC_uml1_ost1_mdsA 1:uml2_UUID
1899 * Pull failnid info out of params string, which may contain something
1900 * like "<nid1>,<nid2>:<nid3>,<nid4>". class_parse_nid() does not
1901 * complain about abnormal inputs like ",:<nid1>", "<nid1>:,<nid2>",
1902 * etc. However, convert_hostnames() should have caught those.
1904 while (class_find_param(ptr, PARAM_FAILNODE, &ptr) == 0) {
1905 while (class_parse_nid(ptr, &nid, &ptr) == 0) {
1906 char nidstr[LNET_NIDSTR_SIZE];
1908 if (failnodeuuid == NULL) {
1909 /* We don't know the failover node name,
1910 * so just use the first nid as the uuid */
1911 libcfs_nid2str_r(nid, nidstr, sizeof(nidstr));
1912 rc = name_create(&failnodeuuid, nidstr, "");
1916 CDEBUG(D_MGS, "add nid %s for failover uuid %s, "
1918 libcfs_nid2str_r(nid, nidstr, sizeof(nidstr)),
1919 failnodeuuid, cliname);
1920 rc = record_add_uuid(env, llh, nid, failnodeuuid);
1922 * If *ptr is ':', we have added all NIDs for
1926 rc = record_add_conn(env, llh, cliname,
1928 name_destroy(&failnodeuuid);
1929 failnodeuuid = NULL;
1933 rc = record_add_conn(env, llh, cliname, failnodeuuid);
1934 name_destroy(&failnodeuuid);
1935 failnodeuuid = NULL;
1942 static int mgs_write_log_mdc_to_lmv(const struct lu_env *env,
1943 struct mgs_device *mgs,
1945 struct mgs_target_info *mti,
1946 char *logname, char *lmvname)
1948 struct llog_handle *llh = NULL;
1949 char *mdcname = NULL;
1950 char *nodeuuid = NULL;
1951 char *mdcuuid = NULL;
1952 char *lmvuuid = NULL;
1954 char nidstr[LNET_NIDSTR_SIZE];
1958 if (mgs_log_is_empty(env, mgs, logname)) {
1959 CERROR("log is empty! Logical error\n");
1963 CDEBUG(D_MGS, "adding mdc for %s to log %s:lmv(%s)\n",
1964 mti->mti_svname, logname, lmvname);
1966 libcfs_nid2str_r(mti->mti_nids[0], nidstr, sizeof(nidstr));
1967 rc = name_create(&nodeuuid, nidstr, "");
1970 rc = name_create(&mdcname, mti->mti_svname, "-mdc");
1973 rc = name_create(&mdcuuid, mdcname, "_UUID");
1976 rc = name_create(&lmvuuid, lmvname, "_UUID");
1980 rc = record_start_log(env, mgs, &llh, logname);
1983 rc = record_marker(env, llh, fsdb, CM_START, mti->mti_svname,
1987 for (i = 0; i < mti->mti_nid_count; i++) {
1988 CDEBUG(D_MGS, "add nid %s for mdt\n",
1989 libcfs_nid2str_r(mti->mti_nids[i],
1990 nidstr, sizeof(nidstr)));
1992 rc = record_add_uuid(env, llh, mti->mti_nids[i], nodeuuid);
1997 rc = record_attach(env, llh, mdcname, LUSTRE_MDC_NAME, lmvuuid);
2000 rc = record_setup(env, llh, mdcname, mti->mti_uuid, nodeuuid,
2004 rc = mgs_write_log_failnids(env, mti, llh, mdcname);
2007 snprintf(index, sizeof(index), "%d", mti->mti_stripe_index);
2008 rc = record_mdc_add(env, llh, lmvname, mdcuuid, mti->mti_uuid,
2012 rc = record_marker(env, llh, fsdb, CM_END, mti->mti_svname,
2017 record_end_log(env, &llh);
2019 name_destroy(&lmvuuid);
2020 name_destroy(&mdcuuid);
2021 name_destroy(&mdcname);
2022 name_destroy(&nodeuuid);
2026 static inline int name_create_lov(char **lovname, char *mdtname,
2027 struct fs_db *fsdb, int index)
2030 if (index == 0 && test_bit(FSDB_OSCNAME18, &fsdb->fsdb_flags))
2031 return name_create(lovname, fsdb->fsdb_name, "-mdtlov");
2033 return name_create(lovname, mdtname, "-mdtlov");
2036 static int name_create_mdt_and_lov(char **logname, char **lovname,
2037 struct fs_db *fsdb, int i)
2041 rc = name_create_mdt(logname, fsdb->fsdb_name, i);
2045 if (i == 0 && test_bit(FSDB_OSCNAME18, &fsdb->fsdb_flags))
2046 rc = name_create(lovname, fsdb->fsdb_name, "-mdtlov");
2048 rc = name_create(lovname, *logname, "-mdtlov");
2050 name_destroy(logname);
2056 static inline int name_create_mdt_osc(char **oscname, char *ostname,
2057 struct fs_db *fsdb, int i)
2061 if (i == 0 && test_bit(FSDB_OSCNAME18, &fsdb->fsdb_flags))
2062 sprintf(suffix, "-osc");
2064 sprintf(suffix, "-osc-MDT%04x", i);
2065 return name_create(oscname, ostname, suffix);
2068 /* add new mdc to already existent MDS */
2069 static int mgs_write_log_osp_to_mdt(const struct lu_env *env,
2070 struct mgs_device *mgs,
2072 struct mgs_target_info *mti,
2073 int mdt_index, char *logname)
2075 struct llog_handle *llh = NULL;
2076 char *nodeuuid = NULL;
2077 char *ospname = NULL;
2078 char *lovuuid = NULL;
2079 char *mdtuuid = NULL;
2080 char *svname = NULL;
2081 char *mdtname = NULL;
2082 char *lovname = NULL;
2084 char nidstr[LNET_NIDSTR_SIZE];
2088 if (mgs_log_is_empty(env, mgs, mti->mti_svname)) {
2089 CERROR("log is empty! Logical error\n");
2093 CDEBUG(D_MGS, "adding osp index %d to %s\n", mti->mti_stripe_index,
2096 rc = name_create_mdt(&mdtname, fsdb->fsdb_name, mti->mti_stripe_index);
2100 libcfs_nid2str_r(mti->mti_nids[0], nidstr, sizeof(nidstr));
2101 rc = name_create(&nodeuuid, nidstr, "");
2103 GOTO(out_destory, rc);
2105 rc = name_create(&svname, mdtname, "-osp");
2107 GOTO(out_destory, rc);
2109 sprintf(index_str, "-MDT%04x", mdt_index);
2110 rc = name_create(&ospname, svname, index_str);
2112 GOTO(out_destory, rc);
2114 rc = name_create_lov(&lovname, logname, fsdb, mdt_index);
2116 GOTO(out_destory, rc);
2118 rc = name_create(&lovuuid, lovname, "_UUID");
2120 GOTO(out_destory, rc);
2122 rc = name_create(&mdtuuid, mdtname, "_UUID");
2124 GOTO(out_destory, rc);
2126 rc = record_start_log(env, mgs, &llh, logname);
2128 GOTO(out_destory, rc);
2130 rc = record_marker(env, llh, fsdb, CM_START, mti->mti_svname,
2133 GOTO(out_destory, rc);
2135 for (i = 0; i < mti->mti_nid_count; i++) {
2136 CDEBUG(D_MGS, "add nid %s for mdt\n",
2137 libcfs_nid2str_r(mti->mti_nids[i],
2138 nidstr, sizeof(nidstr)));
2139 rc = record_add_uuid(env, llh, mti->mti_nids[i], nodeuuid);
2144 rc = record_attach(env, llh, ospname, LUSTRE_OSP_NAME, lovuuid);
2148 rc = record_setup(env, llh, ospname, mti->mti_uuid, nodeuuid,
2153 rc = mgs_write_log_failnids(env, mti, llh, ospname);
2157 /* Add mdc(osp) to lod */
2158 snprintf(index_str, sizeof(index_str), "%d", mti->mti_stripe_index);
2159 rc = record_base(env, llh, lovname, 0, LCFG_ADD_MDC, mti->mti_uuid,
2160 index_str, "1", NULL);
2164 rc = record_marker(env, llh, fsdb, CM_END, mti->mti_svname, "add osp");
2169 record_end_log(env, &llh);
2172 name_destroy(&mdtuuid);
2173 name_destroy(&lovuuid);
2174 name_destroy(&lovname);
2175 name_destroy(&ospname);
2176 name_destroy(&svname);
2177 name_destroy(&nodeuuid);
2178 name_destroy(&mdtname);
2182 static int mgs_write_log_mdt0(const struct lu_env *env,
2183 struct mgs_device *mgs,
2185 struct mgs_target_info *mti)
2187 char *log = mti->mti_svname;
2188 struct llog_handle *llh = NULL;
2189 char *uuid, *lovname;
2191 char *ptr = mti->mti_params;
2192 int rc = 0, failout = 0;
2195 OBD_ALLOC(uuid, sizeof(struct obd_uuid));
2199 if (class_find_param(ptr, PARAM_FAILMODE, &ptr) == 0)
2200 failout = (strncmp(ptr, "failout", 7) == 0);
2202 rc = name_create(&lovname, log, "-mdtlov");
2205 if (mgs_log_is_empty(env, mgs, log)) {
2206 rc = mgs_write_log_lov(env, mgs, fsdb, mti, log, lovname);
2211 sprintf(mdt_index, "%d", mti->mti_stripe_index);
2213 rc = record_start_log(env, mgs, &llh, log);
2217 /* add MDT itself */
2219 /* FIXME this whole fn should be a single journal transaction */
2220 sprintf(uuid, "%s_UUID", log);
2221 rc = record_marker(env, llh, fsdb, CM_START, log, "add mdt");
2224 rc = record_attach(env, llh, log, LUSTRE_MDT_NAME, uuid);
2227 rc = record_mount_opt(env, llh, log, lovname, NULL);
2230 rc = record_setup(env, llh, log, uuid, mdt_index, lovname,
2231 failout ? "n" : "f");
2234 rc = record_marker(env, llh, fsdb, CM_END, log, "add mdt");
2238 record_end_log(env, &llh);
2240 name_destroy(&lovname);
2242 OBD_FREE(uuid, sizeof(struct obd_uuid));
2246 /* envelope method for all layers log */
2247 static int mgs_write_log_mdt(const struct lu_env *env,
2248 struct mgs_device *mgs,
2250 struct mgs_target_info *mti)
2252 struct mgs_thread_info *mgi = mgs_env_info(env);
2253 struct llog_handle *llh = NULL;
2258 CDEBUG(D_MGS, "writing new mdt %s\n", mti->mti_svname);
2260 if (mti->mti_uuid[0] == '\0') {
2261 /* Make up our own uuid */
2262 snprintf(mti->mti_uuid, sizeof(mti->mti_uuid),
2263 "%s_UUID", mti->mti_svname);
2267 rc = mgs_write_log_mdt0(env, mgs, fsdb, mti);
2270 /* Append the mdt info to the client log */
2271 rc = name_create(&cliname, mti->mti_fsname, "-client");
2275 if (mgs_log_is_empty(env, mgs, cliname)) {
2276 /* Start client log */
2277 rc = mgs_write_log_lov(env, mgs, fsdb, mti, cliname,
2281 rc = mgs_write_log_lmv(env, mgs, fsdb, mti, cliname,
2288 #09 L add_uuid nid=uml1@tcp(0x20000c0a80201) 0: 1:uml1_UUID
2289 #10 L attach 0:MDC_uml1_mdsA_MNT_client 1:mdc 2:1d834_MNT_client_03f
2290 #11 L setup 0:MDC_uml1_mdsA_MNT_client 1:mdsA_UUID 2:uml1_UUID
2291 #12 L add_uuid nid=uml2@tcp(0x20000c0a80202) 0: 1:uml2_UUID
2292 #13 L add_conn 0:MDC_uml1_mdsA_MNT_client 1:uml2_UUID
2293 #14 L mount_option 0: 1:client 2:lov1 3:MDC_uml1_mdsA_MNT_client
2296 /* copy client info about lov/lmv */
2297 mgi->mgi_comp.comp_mti = mti;
2298 mgi->mgi_comp.comp_fsdb = fsdb;
2300 rc = mgs_steal_llog_for_mdt_from_client(env, mgs, cliname,
2304 rc = mgs_write_log_mdc_to_lmv(env, mgs, fsdb, mti, cliname,
2310 rc = record_start_log(env, mgs, &llh, cliname);
2314 rc = record_marker(env, llh, fsdb, CM_START, cliname,
2318 rc = record_mount_opt(env, llh, cliname, fsdb->fsdb_clilov,
2322 rc = record_marker(env, llh, fsdb, CM_END, cliname,
2328 /* for_all_existing_mdt except current one */
2329 for (i = 0; i < INDEX_MAP_SIZE * 8; i++) {
2330 if (i != mti->mti_stripe_index &&
2331 test_bit(i, fsdb->fsdb_mdt_index_map)) {
2334 rc = name_create_mdt(&logname, fsdb->fsdb_name, i);
2338 /* NB: If the log for the MDT is empty, it means
2339 * the MDT is only added to the index
2340 * map, and not being process yet, i.e. this
2341 * is an unregistered MDT, see mgs_write_log_target().
2342 * so we should skip it. Otherwise
2344 * 1. MGS get register request for MDT1 and MDT2.
2346 * 2. Then both MDT1 and MDT2 are added into
2347 * fsdb_mdt_index_map. (see mgs_set_index()).
2349 * 3. Then MDT1 get the lock of fsdb_mutex, then
2350 * generate the config log, here, it will regard MDT2
2351 * as an existent MDT, and generate "add osp" for
2352 * lustre-MDT0001-osp-MDT0002. Note: at the moment
2353 * MDT0002 config log is still empty, so it will
2354 * add "add osp" even before "lov setup", which
2355 * will definitly cause trouble.
2357 * 4. MDT1 registeration finished, fsdb_mutex is
2358 * released, then MDT2 get in, then in above
2359 * mgs_steal_llog_for_mdt_from_client(), it will
2360 * add another osp log for lustre-MDT0001-osp-MDT0002,
2361 * which will cause another trouble.*/
2362 if (!mgs_log_is_empty(env, mgs, logname))
2363 rc = mgs_write_log_osp_to_mdt(env, mgs, fsdb,
2366 name_destroy(&logname);
2372 record_end_log(env, &llh);
2374 name_destroy(&cliname);
2378 /* Add the ost info to the client/mdt lov */
2379 static int mgs_write_log_osc_to_lov(const struct lu_env *env,
2380 struct mgs_device *mgs, struct fs_db *fsdb,
2381 struct mgs_target_info *mti,
2382 char *logname, char *suffix, char *lovname,
2383 enum lustre_sec_part sec_part, int flags)
2385 struct llog_handle *llh = NULL;
2386 char *nodeuuid = NULL;
2387 char *oscname = NULL;
2388 char *oscuuid = NULL;
2389 char *lovuuid = NULL;
2390 char *svname = NULL;
2392 char nidstr[LNET_NIDSTR_SIZE];
2396 CDEBUG(D_INFO, "adding osc for %s to log %s\n",
2397 mti->mti_svname, logname);
2399 if (mgs_log_is_empty(env, mgs, logname)) {
2400 CERROR("log is empty! Logical error\n");
2404 libcfs_nid2str_r(mti->mti_nids[0], nidstr, sizeof(nidstr));
2405 rc = name_create(&nodeuuid, nidstr, "");
2408 rc = name_create(&svname, mti->mti_svname, "-osc");
2412 /* for the system upgraded from old 1.8, keep using the old osc naming
2413 * style for mdt, see name_create_mdt_osc(). LU-1257 */
2414 if (test_bit(FSDB_OSCNAME18, &fsdb->fsdb_flags))
2415 rc = name_create(&oscname, svname, "");
2417 rc = name_create(&oscname, svname, suffix);
2421 rc = name_create(&oscuuid, oscname, "_UUID");
2424 rc = name_create(&lovuuid, lovname, "_UUID");
2430 #03 L add_uuid nid=uml1@tcp(0x20000c0a80201) 0: 1:uml1_UUID
2432 #04 L add_uuid nid=1@elan(0x1000000000001) nal=90 0: 1:uml1_UUID
2433 #04 L attach 0:OSC_uml1_ost1_MNT_client 1:osc 2:89070_lov1_a41dff51a
2434 #05 L setup 0:OSC_uml1_ost1_MNT_client 1:ost1_UUID 2:uml1_UUID
2436 #06 L add_uuid nid=uml2@tcp(0x20000c0a80202) 0: 1:uml2_UUID
2437 #07 L add_conn 0:OSC_uml1_ost1_MNT_client 1:uml2_UUID
2438 #08 L lov_modify_tgts add 0:lov1 1:ost1_UUID 2(index):0 3(gen):1
2441 rc = record_start_log(env, mgs, &llh, logname);
2445 /* FIXME these should be a single journal transaction */
2446 rc = record_marker(env, llh, fsdb, CM_START | flags, mti->mti_svname,
2451 /* NB: don't change record order, because upon MDT steal OSC config
2452 * from client, it treats all nids before LCFG_SETUP as target nids
2453 * (multiple interfaces), while nids after as failover node nids.
2454 * See mgs_steal_client_llog_handler() LCFG_ADD_UUID.
2456 for (i = 0; i < mti->mti_nid_count; i++) {
2457 CDEBUG(D_MGS, "add nid %s\n",
2458 libcfs_nid2str_r(mti->mti_nids[i],
2459 nidstr, sizeof(nidstr)));
2460 rc = record_add_uuid(env, llh, mti->mti_nids[i], nodeuuid);
2464 rc = record_attach(env, llh, oscname, LUSTRE_OSC_NAME, lovuuid);
2467 rc = record_setup(env, llh, oscname, mti->mti_uuid, nodeuuid,
2471 rc = mgs_write_log_failnids(env, mti, llh, oscname);
2475 snprintf(index, sizeof(index), "%d", mti->mti_stripe_index);
2477 rc = record_lov_add(env, llh, lovname, mti->mti_uuid, index, "1");
2480 rc = record_marker(env, llh, fsdb, CM_END | flags, mti->mti_svname,
2485 record_end_log(env, &llh);
2487 name_destroy(&lovuuid);
2488 name_destroy(&oscuuid);
2489 name_destroy(&oscname);
2490 name_destroy(&svname);
2491 name_destroy(&nodeuuid);
2495 static int mgs_write_log_ost(const struct lu_env *env,
2496 struct mgs_device *mgs, struct fs_db *fsdb,
2497 struct mgs_target_info *mti)
2499 struct llog_handle *llh = NULL;
2500 char *logname, *lovname;
2501 char *ptr = mti->mti_params;
2502 int rc, flags = 0, failout = 0, i;
2505 CDEBUG(D_MGS, "writing new ost %s\n", mti->mti_svname);
2507 /* The ost startup log */
2509 /* If the ost log already exists, that means that someone reformatted
2510 the ost and it called target_add again. */
2511 if (!mgs_log_is_empty(env, mgs, mti->mti_svname)) {
2512 LCONSOLE_ERROR_MSG(0x141, "The config log for %s already "
2513 "exists, yet the server claims it never "
2514 "registered. It may have been reformatted, "
2515 "or the index changed. writeconf the MDT to "
2516 "regenerate all logs.\n", mti->mti_svname);
2521 attach obdfilter ost1 ost1_UUID
2522 setup /dev/loop2 ldiskfs f|n errors=remount-ro,user_xattr
2524 if (class_find_param(ptr, PARAM_FAILMODE, &ptr) == 0)
2525 failout = (strncmp(ptr, "failout", 7) == 0);
2526 rc = record_start_log(env, mgs, &llh, mti->mti_svname);
2529 /* FIXME these should be a single journal transaction */
2530 rc = record_marker(env, llh, fsdb, CM_START, mti->mti_svname,"add ost");
2533 if (*mti->mti_uuid == '\0')
2534 snprintf(mti->mti_uuid, sizeof(mti->mti_uuid),
2535 "%s_UUID", mti->mti_svname);
2536 rc = record_attach(env, llh, mti->mti_svname,
2537 "obdfilter"/*LUSTRE_OST_NAME*/, mti->mti_uuid);
2540 rc = record_setup(env, llh, mti->mti_svname,
2541 "dev"/*ignored*/, "type"/*ignored*/,
2542 failout ? "n" : "f", NULL/*options*/);
2545 rc = record_marker(env, llh, fsdb, CM_END, mti->mti_svname, "add ost");
2549 record_end_log(env, &llh);
2552 /* We also have to update the other logs where this osc is part of
2555 if (test_bit(FSDB_OLDLOG14, &fsdb->fsdb_flags)) {
2556 /* If we're upgrading, the old mdt log already has our
2557 entry. Let's do a fake one for fun. */
2558 /* Note that we can't add any new failnids, since we don't
2559 know the old osc names. */
2560 flags = CM_SKIP | CM_UPGRADE146;
2562 } else if ((mti->mti_flags & LDD_F_UPDATE) != LDD_F_UPDATE) {
2563 /* If the update flag isn't set, don't update client/mdt
2566 LCONSOLE_WARN("Client log for %s was not updated; writeconf "
2567 "the MDT first to regenerate it.\n",
2571 /* Add ost to all MDT lov defs */
2572 for (i = 0; i < INDEX_MAP_SIZE * 8; i++){
2573 if (test_bit(i, fsdb->fsdb_mdt_index_map)) {
2576 rc = name_create_mdt_and_lov(&logname, &lovname, fsdb,
2580 sprintf(mdt_index, "-MDT%04x", i);
2581 rc = mgs_write_log_osc_to_lov(env, mgs, fsdb, mti,
2583 lovname, LUSTRE_SP_MDT,
2585 name_destroy(&logname);
2586 name_destroy(&lovname);
2592 /* Append ost info to the client log */
2593 rc = name_create(&logname, mti->mti_fsname, "-client");
2596 if (mgs_log_is_empty(env, mgs, logname)) {
2597 /* Start client log */
2598 rc = mgs_write_log_lov(env, mgs, fsdb, mti, logname,
2602 rc = mgs_write_log_lmv(env, mgs, fsdb, mti, logname,
2607 rc = mgs_write_log_osc_to_lov(env, mgs, fsdb, mti, logname, "",
2608 fsdb->fsdb_clilov, LUSTRE_SP_CLI, flags);
2610 name_destroy(&logname);
2614 static __inline__ int mgs_param_empty(char *ptr)
2618 if ((tmp = strchr(ptr, '=')) && (*(++tmp) == '\0'))
2623 static int mgs_write_log_failnid_internal(const struct lu_env *env,
2624 struct mgs_device *mgs,
2626 struct mgs_target_info *mti,
2627 char *logname, char *cliname)
2630 struct llog_handle *llh = NULL;
2632 if (mgs_param_empty(mti->mti_params)) {
2633 /* Remove _all_ failnids */
2634 rc = mgs_modify(env, mgs, fsdb, mti, logname,
2635 mti->mti_svname, "add failnid", CM_SKIP);
2636 return rc < 0 ? rc : 0;
2639 /* Otherwise failover nids are additive */
2640 rc = record_start_log(env, mgs, &llh, logname);
2643 /* FIXME this should be a single journal transaction */
2644 rc = record_marker(env, llh, fsdb, CM_START, mti->mti_svname,
2648 rc = mgs_write_log_failnids(env, mti, llh, cliname);
2651 rc = record_marker(env, llh, fsdb, CM_END,
2652 mti->mti_svname, "add failnid");
2654 record_end_log(env, &llh);
2659 /* Add additional failnids to an existing log.
2660 The mdc/osc must have been added to logs first */
2661 /* tcp nids must be in dotted-quad ascii -
2662 we can't resolve hostnames from the kernel. */
2663 static int mgs_write_log_add_failnid(const struct lu_env *env,
2664 struct mgs_device *mgs,
2666 struct mgs_target_info *mti)
2668 char *logname, *cliname;
2672 /* FIXME we currently can't erase the failnids
2673 * given when a target first registers, since they aren't part of
2674 * an "add uuid" stanza */
2676 /* Verify that we know about this target */
2677 if (mgs_log_is_empty(env, mgs, mti->mti_svname)) {
2678 LCONSOLE_ERROR_MSG(0x142, "The target %s has not registered "
2679 "yet. It must be started before failnids "
2680 "can be added.\n", mti->mti_svname);
2684 /* Create mdc/osc client name (e.g. lustre-OST0001-osc) */
2685 if (mti->mti_flags & LDD_F_SV_TYPE_MDT) {
2686 rc = name_create(&cliname, mti->mti_svname, "-mdc");
2687 } else if (mti->mti_flags & LDD_F_SV_TYPE_OST) {
2688 rc = name_create(&cliname, mti->mti_svname, "-osc");
2694 /* Add failover nids to the client log */
2695 rc = name_create(&logname, mti->mti_fsname, "-client");
2697 name_destroy(&cliname);
2700 rc = mgs_write_log_failnid_internal(env, mgs, fsdb,mti,logname,cliname);
2701 name_destroy(&logname);
2702 name_destroy(&cliname);
2706 if (mti->mti_flags & LDD_F_SV_TYPE_OST) {
2707 /* Add OST failover nids to the MDT logs as well */
2710 for (i = 0; i < INDEX_MAP_SIZE * 8; i++) {
2711 if (!test_bit(i, fsdb->fsdb_mdt_index_map))
2713 rc = name_create_mdt(&logname, mti->mti_fsname, i);
2716 rc = name_create_mdt_osc(&cliname, mti->mti_svname,
2719 name_destroy(&logname);
2722 rc = mgs_write_log_failnid_internal(env, mgs, fsdb,
2725 name_destroy(&cliname);
2726 name_destroy(&logname);
2735 static int mgs_wlp_lcfg(const struct lu_env *env,
2736 struct mgs_device *mgs, struct fs_db *fsdb,
2737 struct mgs_target_info *mti,
2738 char *logname, struct lustre_cfg_bufs *bufs,
2739 char *tgtname, char *ptr)
2741 char comment[MTI_NAME_MAXLEN];
2743 struct llog_cfg_rec *lcr;
2746 /* Erase any old settings of this same parameter */
2747 memcpy(comment, ptr, MTI_NAME_MAXLEN);
2748 comment[MTI_NAME_MAXLEN - 1] = 0;
2749 /* But don't try to match the value. */
2750 tmp = strchr(comment, '=');
2753 /* FIXME we should skip settings that are the same as old values */
2754 rc = mgs_modify(env, mgs, fsdb, mti, logname, tgtname, comment,CM_SKIP);
2757 del = mgs_param_empty(ptr);
2759 LCONSOLE_INFO("%s parameter %s.%s in log %s\n", del ? "Disabling" : rc ?
2760 "Setting" : "Modifying", tgtname, comment, logname);
2762 /* mgs_modify() will return 1 if nothing had to be done */
2768 lustre_cfg_bufs_reset(bufs, tgtname);
2769 lustre_cfg_bufs_set_string(bufs, 1, ptr);
2770 if (mti->mti_flags & LDD_F_PARAM2)
2771 lustre_cfg_bufs_set_string(bufs, 2, LCTL_UPCALL);
2773 lcr = lustre_cfg_rec_new((mti->mti_flags & LDD_F_PARAM2) ?
2774 LCFG_SET_PARAM : LCFG_PARAM, bufs);
2778 rc = mgs_write_log_direct(env, mgs, fsdb, logname, lcr, tgtname,
2780 lustre_cfg_rec_free(lcr);
2784 static int mgs_write_log_param2(const struct lu_env *env,
2785 struct mgs_device *mgs,
2787 struct mgs_target_info *mti, char *ptr)
2789 struct lustre_cfg_bufs bufs;
2793 CDEBUG(D_MGS, "next param '%s'\n", ptr);
2794 rc = mgs_wlp_lcfg(env, mgs, fsdb, mti, PARAMS_FILENAME, &bufs,
2795 mti->mti_svname, ptr);
2800 /* write global variable settings into log */
2801 static int mgs_write_log_sys(const struct lu_env *env,
2802 struct mgs_device *mgs, struct fs_db *fsdb,
2803 struct mgs_target_info *mti, char *sys, char *ptr)
2805 struct mgs_thread_info *mgi = mgs_env_info(env);
2806 struct lustre_cfg *lcfg;
2807 struct llog_cfg_rec *lcr;
2809 int rc, cmd, convert = 1;
2811 if (class_match_param(ptr, PARAM_TIMEOUT, &tmp) == 0) {
2812 cmd = LCFG_SET_TIMEOUT;
2813 } else if (class_match_param(ptr, PARAM_LDLM_TIMEOUT, &tmp) == 0) {
2814 cmd = LCFG_SET_LDLM_TIMEOUT;
2815 /* Check for known params here so we can return error to lctl */
2816 } else if ((class_match_param(ptr, PARAM_AT_MIN, &tmp) == 0) ||
2817 (class_match_param(ptr, PARAM_AT_MAX, &tmp) == 0) ||
2818 (class_match_param(ptr, PARAM_AT_EXTRA, &tmp) == 0) ||
2819 (class_match_param(ptr, PARAM_AT_EARLY_MARGIN, &tmp) == 0) ||
2820 (class_match_param(ptr, PARAM_AT_HISTORY, &tmp) == 0)) {
2822 } else if (class_match_param(ptr, PARAM_JOBID_VAR, &tmp) == 0) {
2823 convert = 0; /* Don't convert string value to integer */
2829 if (mgs_param_empty(ptr))
2830 CDEBUG(D_MGS, "global '%s' removed\n", sys);
2832 CDEBUG(D_MGS, "global '%s' val=%s\n", sys, tmp);
2834 lustre_cfg_bufs_reset(&mgi->mgi_bufs, NULL);
2835 lustre_cfg_bufs_set_string(&mgi->mgi_bufs, 1, sys);
2836 if (!convert && *tmp != '\0')
2837 lustre_cfg_bufs_set_string(&mgi->mgi_bufs, 2, tmp);
2838 lcr = lustre_cfg_rec_new(cmd, &mgi->mgi_bufs);
2842 lcfg = &lcr->lcr_cfg;
2843 lcfg->lcfg_num = convert ? simple_strtoul(tmp, NULL, 0) : 0;
2844 /* truncate the comment to the parameter name */
2848 /* modify all servers and clients */
2849 rc = mgs_write_log_direct_all(env, mgs, fsdb, mti,
2850 *tmp == '\0' ? NULL : lcr,
2851 mti->mti_fsname, sys, 0);
2852 if (rc == 0 && *tmp != '\0') {
2854 case LCFG_SET_TIMEOUT:
2855 if (!obd_timeout_set || lcfg->lcfg_num > obd_timeout)
2856 class_process_config(lcfg);
2858 case LCFG_SET_LDLM_TIMEOUT:
2859 if (!ldlm_timeout_set || lcfg->lcfg_num > ldlm_timeout)
2860 class_process_config(lcfg);
2867 lustre_cfg_rec_free(lcr);
2871 /* write quota settings into log */
2872 static int mgs_write_log_quota(const struct lu_env *env, struct mgs_device *mgs,
2873 struct fs_db *fsdb, struct mgs_target_info *mti,
2874 char *quota, char *ptr)
2876 struct mgs_thread_info *mgi = mgs_env_info(env);
2877 struct llog_cfg_rec *lcr;
2880 int rc, cmd = LCFG_PARAM;
2882 /* support only 'meta' and 'data' pools so far */
2883 if (class_match_param(ptr, QUOTA_METAPOOL_NAME, &tmp) != 0 &&
2884 class_match_param(ptr, QUOTA_DATAPOOL_NAME, &tmp) != 0) {
2885 CERROR("parameter quota.%s isn't supported (only quota.mdt "
2886 "& quota.ost are)\n", ptr);
2891 CDEBUG(D_MGS, "global '%s' removed\n", quota);
2893 CDEBUG(D_MGS, "global '%s'\n", quota);
2895 if (strchr(tmp, 'u') == NULL && strchr(tmp, 'g') == NULL &&
2896 strcmp(tmp, "none") != 0) {
2897 CERROR("enable option(%s) isn't supported\n", tmp);
2902 lustre_cfg_bufs_reset(&mgi->mgi_bufs, mti->mti_fsname);
2903 lustre_cfg_bufs_set_string(&mgi->mgi_bufs, 1, quota);
2904 lcr = lustre_cfg_rec_new(cmd, &mgi->mgi_bufs);
2908 /* truncate the comment to the parameter name */
2913 /* XXX we duplicated quota enable information in all server
2914 * config logs, it should be moved to a separate config
2915 * log once we cleanup the config log for global param. */
2916 /* modify all servers */
2917 rc = mgs_write_log_direct_all(env, mgs, fsdb, mti,
2918 *tmp == '\0' ? NULL : lcr,
2919 mti->mti_fsname, quota, 1);
2921 lustre_cfg_rec_free(lcr);
2922 return rc < 0 ? rc : 0;
2925 static int mgs_srpc_set_param_disk(const struct lu_env *env,
2926 struct mgs_device *mgs,
2928 struct mgs_target_info *mti,
2931 struct mgs_thread_info *mgi = mgs_env_info(env);
2932 struct llog_cfg_rec *lcr;
2933 struct llog_handle *llh = NULL;
2935 char *comment, *ptr;
2941 ptr = strchr(param, '=');
2942 LASSERT(ptr != NULL);
2945 OBD_ALLOC(comment, len + 1);
2946 if (comment == NULL)
2948 strncpy(comment, param, len);
2949 comment[len] = '\0';
2952 lustre_cfg_bufs_reset(&mgi->mgi_bufs, mti->mti_svname);
2953 lustre_cfg_bufs_set_string(&mgi->mgi_bufs, 1, param);
2954 lcr = lustre_cfg_rec_new(LCFG_SPTLRPC_CONF, &mgi->mgi_bufs);
2956 GOTO(out_comment, rc = -ENOMEM);
2958 /* construct log name */
2959 rc = name_create(&logname, mti->mti_fsname, "-sptlrpc");
2963 if (mgs_log_is_empty(env, mgs, logname)) {
2964 rc = record_start_log(env, mgs, &llh, logname);
2967 record_end_log(env, &llh);
2970 /* obsolete old one */
2971 rc = mgs_modify(env, mgs, fsdb, mti, logname, mti->mti_svname,
2975 /* write the new one */
2976 rc = mgs_write_log_direct(env, mgs, fsdb, logname, lcr,
2977 mti->mti_svname, comment);
2979 CERROR("%s: error writing log %s: rc = %d\n",
2980 mgs->mgs_obd->obd_name, logname, rc);
2982 name_destroy(&logname);
2984 lustre_cfg_rec_free(lcr);
2986 OBD_FREE(comment, len + 1);
2990 static int mgs_srpc_set_param_udesc_mem(struct fs_db *fsdb,
2995 /* disable the adjustable udesc parameter for now, i.e. use default
2996 * setting that client always ship udesc to MDT if possible. to enable
2997 * it simply remove the following line */
3000 ptr = strchr(param, '=');
3005 if (strcmp(param, PARAM_SRPC_UDESC))
3008 if (strcmp(ptr, "yes") == 0) {
3009 set_bit(FSDB_UDESC, &fsdb->fsdb_flags);
3010 CWARN("Enable user descriptor shipping from client to MDT\n");
3011 } else if (strcmp(ptr, "no") == 0) {
3012 clear_bit(FSDB_UDESC, &fsdb->fsdb_flags);
3013 CWARN("Disable user descriptor shipping from client to MDT\n");
3021 CERROR("Invalid param: %s\n", param);
3025 static int mgs_srpc_set_param_mem(struct fs_db *fsdb,
3029 struct sptlrpc_rule rule;
3030 struct sptlrpc_rule_set *rset;
3034 if (strncmp(param, PARAM_SRPC, sizeof(PARAM_SRPC) - 1) != 0) {
3035 CERROR("Invalid sptlrpc parameter: %s\n", param);
3039 if (strncmp(param, PARAM_SRPC_UDESC,
3040 sizeof(PARAM_SRPC_UDESC) - 1) == 0) {
3041 RETURN(mgs_srpc_set_param_udesc_mem(fsdb, param));
3044 if (strncmp(param, PARAM_SRPC_FLVR, sizeof(PARAM_SRPC_FLVR) - 1) != 0) {
3045 CERROR("Invalid sptlrpc flavor parameter: %s\n", param);
3049 param += sizeof(PARAM_SRPC_FLVR) - 1;
3051 rc = sptlrpc_parse_rule(param, &rule);
3055 /* mgs rules implies must be mgc->mgs */
3056 if (test_bit(FSDB_MGS_SELF, &fsdb->fsdb_flags)) {
3057 if ((rule.sr_from != LUSTRE_SP_MGC &&
3058 rule.sr_from != LUSTRE_SP_ANY) ||
3059 (rule.sr_to != LUSTRE_SP_MGS &&
3060 rule.sr_to != LUSTRE_SP_ANY))
3064 /* preapre room for this coming rule. svcname format should be:
3065 * - fsname: general rule
3066 * - fsname-tgtname: target-specific rule
3068 if (strchr(svname, '-')) {
3069 struct mgs_tgt_srpc_conf *tgtconf;
3072 for (tgtconf = fsdb->fsdb_srpc_tgt; tgtconf != NULL;
3073 tgtconf = tgtconf->mtsc_next) {
3074 if (!strcmp(tgtconf->mtsc_tgt, svname)) {
3083 OBD_ALLOC_PTR(tgtconf);
3084 if (tgtconf == NULL)
3087 name_len = strlen(svname);
3089 OBD_ALLOC(tgtconf->mtsc_tgt, name_len + 1);
3090 if (tgtconf->mtsc_tgt == NULL) {
3091 OBD_FREE_PTR(tgtconf);
3094 memcpy(tgtconf->mtsc_tgt, svname, name_len);
3096 tgtconf->mtsc_next = fsdb->fsdb_srpc_tgt;
3097 fsdb->fsdb_srpc_tgt = tgtconf;
3100 rset = &tgtconf->mtsc_rset;
3101 } else if (strcmp(svname, MGSSELF_NAME) == 0) {
3102 /* put _mgs related srpc rule directly in mgs ruleset */
3103 rset = &fsdb->fsdb_mgs->mgs_lut.lut_sptlrpc_rset;
3105 rset = &fsdb->fsdb_srpc_gen;
3108 rc = sptlrpc_rule_set_merge(rset, &rule);
3113 static int mgs_srpc_set_param(const struct lu_env *env,
3114 struct mgs_device *mgs,
3116 struct mgs_target_info *mti,
3126 /* keep a copy of original param, which could be destroied
3128 copy_size = strlen(param) + 1;
3129 OBD_ALLOC(copy, copy_size);
3132 memcpy(copy, param, copy_size);
3134 rc = mgs_srpc_set_param_mem(fsdb, mti->mti_svname, param);
3138 /* previous steps guaranteed the syntax is correct */
3139 rc = mgs_srpc_set_param_disk(env, mgs, fsdb, mti, copy);
3143 if (test_bit(FSDB_MGS_SELF, &fsdb->fsdb_flags)) {
3145 * for mgs rules, make them effective immediately.
3147 LASSERT(fsdb->fsdb_srpc_tgt == NULL);
3148 sptlrpc_target_update_exp_flavor(mgs->mgs_obd,
3149 &fsdb->fsdb_srpc_gen);
3153 OBD_FREE(copy, copy_size);
3157 struct mgs_srpc_read_data {
3158 struct fs_db *msrd_fsdb;
3162 static int mgs_srpc_read_handler(const struct lu_env *env,
3163 struct llog_handle *llh,
3164 struct llog_rec_hdr *rec, void *data)
3166 struct mgs_srpc_read_data *msrd = data;
3167 struct cfg_marker *marker;
3168 struct lustre_cfg *lcfg = REC_DATA(rec);
3169 char *svname, *param;
3173 if (rec->lrh_type != OBD_CFG_REC) {
3174 CERROR("unhandled lrh_type: %#x\n", rec->lrh_type);
3178 cfg_len = REC_DATA_LEN(rec);
3180 rc = lustre_cfg_sanity_check(lcfg, cfg_len);
3182 CERROR("Insane cfg\n");
3186 if (lcfg->lcfg_command == LCFG_MARKER) {
3187 marker = lustre_cfg_buf(lcfg, 1);
3189 if (marker->cm_flags & CM_START &&
3190 marker->cm_flags & CM_SKIP)
3191 msrd->msrd_skip = 1;
3192 if (marker->cm_flags & CM_END)
3193 msrd->msrd_skip = 0;
3198 if (msrd->msrd_skip)
3201 if (lcfg->lcfg_command != LCFG_SPTLRPC_CONF) {
3202 CERROR("invalid command (%x)\n", lcfg->lcfg_command);
3206 svname = lustre_cfg_string(lcfg, 0);
3207 if (svname == NULL) {
3208 CERROR("svname is empty\n");
3212 param = lustre_cfg_string(lcfg, 1);
3213 if (param == NULL) {
3214 CERROR("param is empty\n");
3218 rc = mgs_srpc_set_param_mem(msrd->msrd_fsdb, svname, param);
3220 CERROR("read sptlrpc record error (%d): %s\n", rc, param);
3225 int mgs_get_fsdb_srpc_from_llog(const struct lu_env *env,
3226 struct mgs_device *mgs,
3229 struct llog_handle *llh = NULL;
3230 struct llog_ctxt *ctxt;
3232 struct mgs_srpc_read_data msrd;
3236 /* construct log name */
3237 rc = name_create(&logname, fsdb->fsdb_name, "-sptlrpc");
3241 ctxt = llog_get_context(mgs->mgs_obd, LLOG_CONFIG_ORIG_CTXT);
3242 LASSERT(ctxt != NULL);
3244 if (mgs_log_is_empty(env, mgs, logname))
3247 rc = llog_open(env, ctxt, &llh, NULL, logname,
3255 rc = llog_init_handle(env, llh, LLOG_F_IS_PLAIN, NULL);
3257 GOTO(out_close, rc);
3259 if (llog_get_size(llh) <= 1)
3260 GOTO(out_close, rc = 0);
3262 msrd.msrd_fsdb = fsdb;
3265 rc = llog_process(env, llh, mgs_srpc_read_handler, (void *)&msrd,
3269 llog_close(env, llh);
3271 llog_ctxt_put(ctxt);
3272 name_destroy(&logname);
3275 CERROR("failed to read sptlrpc config database: %d\n", rc);
3279 /* Permanent settings of all parameters by writing into the appropriate
3280 * configuration logs.
3281 * A parameter with null value ("<param>='\0'") means to erase it out of
3284 static int mgs_write_log_param(const struct lu_env *env,
3285 struct mgs_device *mgs, struct fs_db *fsdb,
3286 struct mgs_target_info *mti, char *ptr)
3288 struct mgs_thread_info *mgi = mgs_env_info(env);
3291 int rc = 0, rc2 = 0;
3294 /* For various parameter settings, we have to figure out which logs
3295 care about them (e.g. both mdt and client for lov settings) */
3296 CDEBUG(D_MGS, "next param '%s'\n", ptr);
3298 /* The params are stored in MOUNT_DATA_FILE and modified via
3299 tunefs.lustre, or set using lctl conf_param */
3301 /* Processed in lustre_start_mgc */
3302 if (class_match_param(ptr, PARAM_MGSNODE, NULL) == 0)
3305 /* Processed in ost/mdt */
3306 if (class_match_param(ptr, PARAM_NETWORK, NULL) == 0)
3309 /* Processed in mgs_write_log_ost */
3310 if (class_match_param(ptr, PARAM_FAILMODE, NULL) == 0) {
3311 if (mti->mti_flags & LDD_F_PARAM) {
3312 LCONSOLE_ERROR_MSG(0x169, "%s can only be "
3313 "changed with tunefs.lustre"
3314 "and --writeconf\n", ptr);
3320 if (class_match_param(ptr, PARAM_SRPC, NULL) == 0) {
3321 rc = mgs_srpc_set_param(env, mgs, fsdb, mti, ptr);
3325 if (class_match_param(ptr, PARAM_FAILNODE, NULL) == 0) {
3326 /* Add a failover nidlist */
3328 /* We already processed failovers params for new
3329 targets in mgs_write_log_target */
3330 if (mti->mti_flags & LDD_F_PARAM) {
3331 CDEBUG(D_MGS, "Adding failnode\n");
3332 rc = mgs_write_log_add_failnid(env, mgs, fsdb, mti);
3337 if (class_match_param(ptr, PARAM_SYS, &tmp) == 0) {
3338 rc = mgs_write_log_sys(env, mgs, fsdb, mti, ptr, tmp);
3342 if (class_match_param(ptr, PARAM_QUOTA, &tmp) == 0) {
3343 rc = mgs_write_log_quota(env, mgs, fsdb, mti, ptr, tmp);
3347 if (class_match_param(ptr, PARAM_OSC PARAM_ACTIVE, &tmp) == 0 ||
3348 class_match_param(ptr, PARAM_MDC PARAM_ACTIVE, &tmp) == 0) {
3349 /* active=0 means off, anything else means on */
3350 int flag = (*tmp == '0') ? CM_EXCLUDE : 0;
3351 bool deactive_osc = memcmp(ptr, PARAM_OSC PARAM_ACTIVE,
3352 strlen(PARAM_OSC PARAM_ACTIVE)) == 0;
3355 if (!deactive_osc) {
3358 rc = server_name2index(mti->mti_svname, &index, NULL);
3363 LCONSOLE_ERROR_MSG(0x144, "%s: MDC0 can not be"
3364 " (de)activated.\n",
3366 GOTO(end, rc = -EINVAL);
3370 LCONSOLE_WARN("Permanently %sactivating %s\n",
3371 flag ? "de" : "re", mti->mti_svname);
3373 rc = name_create(&logname, mti->mti_fsname, "-client");
3376 rc = mgs_modify(env, mgs, fsdb, mti, logname,
3378 deactive_osc ? "add osc" : "add mdc", flag);
3379 name_destroy(&logname);
3384 /* Add to all MDT logs for DNE */
3385 for (i = 0; i < INDEX_MAP_SIZE * 8; i++) {
3386 if (!test_bit(i, fsdb->fsdb_mdt_index_map))
3388 rc = name_create_mdt(&logname, mti->mti_fsname, i);
3391 rc = mgs_modify(env, mgs, fsdb, mti, logname,
3393 deactive_osc ? "add osc" : "add osp",
3395 name_destroy(&logname);
3401 LCONSOLE_ERROR_MSG(0x145, "Couldn't find %s in"
3402 "log (%d). No permanent "
3403 "changes were made to the "
3405 mti->mti_svname, rc);
3406 if (test_bit(FSDB_OLDLOG14, &fsdb->fsdb_flags))
3407 LCONSOLE_ERROR_MSG(0x146, "This may be"
3412 "update the logs.\n");
3415 /* Fall through to osc/mdc proc for deactivating live
3416 OSC/OSP on running MDT / clients. */
3418 /* Below here, let obd's XXX_process_config methods handle it */
3420 /* All lov. in proc */
3421 if (class_match_param(ptr, PARAM_LOV, NULL) == 0) {
3424 CDEBUG(D_MGS, "lov param %s\n", ptr);
3425 if (!(mti->mti_flags & LDD_F_SV_TYPE_MDT)) {
3426 LCONSOLE_ERROR_MSG(0x147, "LOV params must be "
3427 "set on the MDT, not %s. "
3434 if (mgs_log_is_empty(env, mgs, mti->mti_svname))
3435 GOTO(end, rc = -ENODEV);
3437 rc = name_create_mdt_and_lov(&logname, &mdtlovname, fsdb,
3438 mti->mti_stripe_index);
3441 rc = mgs_wlp_lcfg(env, mgs, fsdb, mti, mti->mti_svname,
3442 &mgi->mgi_bufs, mdtlovname, ptr);
3443 name_destroy(&logname);
3444 name_destroy(&mdtlovname);
3449 rc = name_create(&logname, mti->mti_fsname, "-client");
3452 rc = mgs_wlp_lcfg(env, mgs, fsdb, mti, logname, &mgi->mgi_bufs,
3453 fsdb->fsdb_clilov, ptr);
3454 name_destroy(&logname);
3458 /* All osc., mdc., llite. params in proc */
3459 if ((class_match_param(ptr, PARAM_OSC, NULL) == 0) ||
3460 (class_match_param(ptr, PARAM_MDC, NULL) == 0) ||
3461 (class_match_param(ptr, PARAM_LLITE, NULL) == 0)) {
3464 if (test_bit(FSDB_OLDLOG14, &fsdb->fsdb_flags)) {
3465 LCONSOLE_ERROR_MSG(0x148, "Upgraded client logs for %s"
3466 " cannot be modified. Consider"
3467 " updating the configuration with"
3470 GOTO(end, rc = -EINVAL);
3472 if (memcmp(ptr, PARAM_LLITE, strlen(PARAM_LLITE)) == 0) {
3473 rc = name_create(&cname, mti->mti_fsname, "-client");
3474 /* Add the client type to match the obdname in
3475 class_config_llog_handler */
3476 } else if (mti->mti_flags & LDD_F_SV_TYPE_MDT) {
3477 rc = name_create(&cname, mti->mti_svname, "-mdc");
3478 } else if (mti->mti_flags & LDD_F_SV_TYPE_OST) {
3479 rc = name_create(&cname, mti->mti_svname, "-osc");
3481 GOTO(end, rc = -EINVAL);
3486 /* Forbid direct update of llite root squash parameters.
3487 * These parameters are indirectly set via the MDT settings.
3489 if ((class_match_param(ptr, PARAM_LLITE, &tmp) == 0) &&
3490 ((memcmp(tmp, "root_squash=", 12) == 0) ||
3491 (memcmp(tmp, "nosquash_nids=", 14) == 0))) {
3492 LCONSOLE_ERROR("%s: root squash parameters can only "
3493 "be updated through MDT component\n",
3495 name_destroy(&cname);
3496 GOTO(end, rc = -EINVAL);
3499 CDEBUG(D_MGS, "%.3s param %s\n", ptr, ptr + 4);
3502 rc = name_create(&logname, mti->mti_fsname, "-client");
3504 name_destroy(&cname);
3507 rc = mgs_wlp_lcfg(env, mgs, fsdb, mti, logname, &mgi->mgi_bufs,
3510 /* osc params affect the MDT as well */
3511 if (!rc && (mti->mti_flags & LDD_F_SV_TYPE_OST)) {
3514 for (i = 0; i < INDEX_MAP_SIZE * 8; i++){
3515 if (!test_bit(i, fsdb->fsdb_mdt_index_map))
3517 name_destroy(&cname);
3518 rc = name_create_mdt_osc(&cname, mti->mti_svname,
3520 name_destroy(&logname);
3523 rc = name_create_mdt(&logname,
3524 mti->mti_fsname, i);
3527 if (!mgs_log_is_empty(env, mgs, logname)) {
3528 rc = mgs_wlp_lcfg(env, mgs, fsdb,
3538 /* For mdc activate/deactivate, it affects OSP on MDT as well */
3539 if (class_match_param(ptr, PARAM_MDC PARAM_ACTIVE, &tmp) == 0 &&
3542 char *lodname = NULL;
3543 char *param_str = NULL;
3547 /* replace mdc with osp */
3548 memcpy(ptr, PARAM_OSP, strlen(PARAM_OSP));
3549 rc = server_name2index(mti->mti_svname, &index, NULL);
3551 memcpy(ptr, PARAM_MDC, strlen(PARAM_MDC));
3555 for (i = 0; i < INDEX_MAP_SIZE * 8; i++) {
3556 if (!test_bit(i, fsdb->fsdb_mdt_index_map))
3562 name_destroy(&logname);
3563 rc = name_create_mdt(&logname, mti->mti_fsname,
3568 if (mgs_log_is_empty(env, mgs, logname))
3571 snprintf(suffix, sizeof(suffix), "-osp-MDT%04x",
3573 name_destroy(&cname);
3574 rc = name_create(&cname, mti->mti_svname,
3579 rc = mgs_wlp_lcfg(env, mgs, fsdb, mti, logname,
3580 &mgi->mgi_bufs, cname, ptr);
3584 /* Add configuration log for noitfying LOD
3585 * to active/deactive the OSP. */
3586 name_destroy(¶m_str);
3587 rc = name_create(¶m_str, cname,
3588 (*tmp == '0') ? ".active=0" :
3593 name_destroy(&lodname);
3594 rc = name_create(&lodname, logname, "-mdtlov");
3598 rc = mgs_wlp_lcfg(env, mgs, fsdb, mti, logname,
3599 &mgi->mgi_bufs, lodname,
3604 memcpy(ptr, PARAM_MDC, strlen(PARAM_MDC));
3605 name_destroy(&lodname);
3606 name_destroy(¶m_str);
3609 name_destroy(&logname);
3610 name_destroy(&cname);
3614 /* All mdt. params in proc */
3615 if (class_match_param(ptr, PARAM_MDT, &tmp) == 0) {
3619 CDEBUG(D_MGS, "%.3s param %s\n", ptr, ptr + 4);
3620 if (strncmp(mti->mti_svname, mti->mti_fsname,
3621 MTI_NAME_MAXLEN) == 0)
3622 /* device is unspecified completely? */
3623 rc = LDD_F_SV_TYPE_MDT | LDD_F_SV_ALL;
3625 rc = server_name2index(mti->mti_svname, &idx, NULL);
3628 if ((rc & LDD_F_SV_TYPE_MDT) == 0)
3630 if (rc & LDD_F_SV_ALL) {
3631 for (i = 0; i < INDEX_MAP_SIZE * 8; i++) {
3633 fsdb->fsdb_mdt_index_map))
3635 rc = name_create_mdt(&logname,
3636 mti->mti_fsname, i);
3639 rc = mgs_wlp_lcfg(env, mgs, fsdb, mti,
3640 logname, &mgi->mgi_bufs,
3642 name_destroy(&logname);
3647 if ((memcmp(tmp, "root_squash=", 12) == 0) ||
3648 (memcmp(tmp, "nosquash_nids=", 14) == 0)) {
3649 LCONSOLE_ERROR("%s: root squash parameters "
3650 "cannot be applied to a single MDT\n",
3652 GOTO(end, rc = -EINVAL);
3654 rc = mgs_wlp_lcfg(env, mgs, fsdb, mti,
3655 mti->mti_svname, &mgi->mgi_bufs,
3656 mti->mti_svname, ptr);
3661 /* root squash settings are also applied to llite
3662 * config log (see LU-1778) */
3664 ((memcmp(tmp, "root_squash=", 12) == 0) ||
3665 (memcmp(tmp, "nosquash_nids=", 14) == 0))) {
3669 rc = name_create(&cname, mti->mti_fsname, "-client");
3672 rc = name_create(&logname, mti->mti_fsname, "-client");
3674 name_destroy(&cname);
3677 rc = name_create(&ptr2, PARAM_LLITE, tmp);
3679 name_destroy(&cname);
3680 name_destroy(&logname);
3683 rc = mgs_wlp_lcfg(env, mgs, fsdb, mti, logname,
3684 &mgi->mgi_bufs, cname, ptr2);
3685 name_destroy(&ptr2);
3686 name_destroy(&logname);
3687 name_destroy(&cname);
3692 /* All mdd., ost. and osd. params in proc */
3693 if ((class_match_param(ptr, PARAM_MDD, NULL) == 0) ||
3694 (class_match_param(ptr, PARAM_OST, NULL) == 0) ||
3695 (class_match_param(ptr, PARAM_OSD, NULL) == 0)) {
3696 CDEBUG(D_MGS, "%.3s param %s\n", ptr, ptr + 4);
3697 if (mgs_log_is_empty(env, mgs, mti->mti_svname))
3698 GOTO(end, rc = -ENODEV);
3700 rc = mgs_wlp_lcfg(env, mgs, fsdb, mti, mti->mti_svname,
3701 &mgi->mgi_bufs, mti->mti_svname, ptr);
3705 LCONSOLE_WARN("Ignoring unrecognized param '%s'\n", ptr);
3710 CERROR("err %d on param '%s'\n", rc, ptr);
3715 /* Not implementing automatic failover nid addition at this time. */
3716 int mgs_check_failnid(const struct lu_env *env, struct mgs_device *mgs,
3717 struct mgs_target_info *mti)
3724 rc = mgs_find_or_make_fsdb(obd, fsname, &fsdb);
3728 if (mgs_log_is_empty(obd, mti->mti_svname))
3729 /* should never happen */
3732 CDEBUG(D_MGS, "Checking for new failnids for %s\n", mti->mti_svname);
3734 /* FIXME We can just check mti->params to see if we're already in
3735 the failover list. Modify mti->params for rewriting back at
3736 server_register_target(). */
3738 mutex_lock(&fsdb->fsdb_mutex);
3739 rc = mgs_write_log_add_failnid(obd, fsdb, mti);
3740 mutex_unlock(&fsdb->fsdb_mutex);
3749 int mgs_write_log_target(const struct lu_env *env, struct mgs_device *mgs,
3750 struct mgs_target_info *mti, struct fs_db *fsdb)
3757 /* set/check the new target index */
3758 rc = mgs_set_index(env, mgs, mti);
3762 if (rc == EALREADY) {
3763 LCONSOLE_WARN("Found index %d for %s, updating log\n",
3764 mti->mti_stripe_index, mti->mti_svname);
3765 /* We would like to mark old log sections as invalid
3766 and add new log sections in the client and mdt logs.
3767 But if we add new sections, then live clients will
3768 get repeat setup instructions for already running
3769 osc's. So don't update the client/mdt logs. */
3770 mti->mti_flags &= ~LDD_F_UPDATE;
3774 OBD_FAIL_TIMEOUT(OBD_FAIL_MGS_WRITE_TARGET_DELAY, cfs_fail_val > 0 ?
3777 mutex_lock(&fsdb->fsdb_mutex);
3779 if (mti->mti_flags &
3780 (LDD_F_VIRGIN | LDD_F_UPGRADE14 | LDD_F_WRITECONF)) {
3781 /* Generate a log from scratch */
3782 if (mti->mti_flags & LDD_F_SV_TYPE_MDT) {
3783 rc = mgs_write_log_mdt(env, mgs, fsdb, mti);
3784 } else if (mti->mti_flags & LDD_F_SV_TYPE_OST) {
3785 rc = mgs_write_log_ost(env, mgs, fsdb, mti);
3787 CERROR("Unknown target type %#x, can't create log for "
3788 "%s\n", mti->mti_flags, mti->mti_svname);
3791 CERROR("Can't write logs for %s (%d)\n",
3792 mti->mti_svname, rc);
3796 /* Just update the params from tunefs in mgs_write_log_params */
3797 CDEBUG(D_MGS, "Update params for %s\n", mti->mti_svname);
3798 mti->mti_flags |= LDD_F_PARAM;
3801 /* allocate temporary buffer, where class_get_next_param will
3802 make copy of a current parameter */
3803 OBD_ALLOC(buf, strlen(mti->mti_params) + 1);
3805 GOTO(out_up, rc = -ENOMEM);
3806 params = mti->mti_params;
3807 while (params != NULL) {
3808 rc = class_get_next_param(¶ms, buf);
3811 /* there is no next parameter, that is
3816 CDEBUG(D_MGS, "remaining string: '%s', param: '%s'\n",
3818 rc = mgs_write_log_param(env, mgs, fsdb, mti, buf);
3823 OBD_FREE(buf, strlen(mti->mti_params) + 1);
3826 mutex_unlock(&fsdb->fsdb_mutex);
3830 int mgs_erase_log(const struct lu_env *env, struct mgs_device *mgs, char *name)
3832 struct llog_ctxt *ctxt;
3835 ctxt = llog_get_context(mgs->mgs_obd, LLOG_CONFIG_ORIG_CTXT);
3837 CERROR("%s: MGS config context doesn't exist\n",
3838 mgs->mgs_obd->obd_name);
3841 rc = llog_erase(env, ctxt, NULL, name);
3842 /* llog may not exist */
3845 llog_ctxt_put(ctxt);
3849 CERROR("%s: failed to clear log %s: %d\n",
3850 mgs->mgs_obd->obd_name, name, rc);
3855 /* erase all logs for the given fs */
3856 int mgs_erase_logs(const struct lu_env *env, struct mgs_device *mgs, char *fsname)
3859 struct list_head log_list;
3860 struct mgs_direntry *dirent, *n;
3861 int rc, len = strlen(fsname);
3865 /* Find all the logs in the CONFIGS directory */
3866 rc = class_dentry_readdir(env, mgs, &log_list);
3870 mutex_lock(&mgs->mgs_mutex);
3872 /* Delete the fs db */
3873 fsdb = mgs_find_fsdb(mgs, fsname);
3875 mgs_free_fsdb(mgs, fsdb);
3877 mutex_unlock(&mgs->mgs_mutex);
3879 list_for_each_entry_safe(dirent, n, &log_list, mde_list) {
3880 list_del_init(&dirent->mde_list);
3881 suffix = strrchr(dirent->mde_name, '-');
3882 if (suffix != NULL) {
3883 if ((len == suffix - dirent->mde_name) &&
3884 (strncmp(fsname, dirent->mde_name, len) == 0)) {
3885 CDEBUG(D_MGS, "Removing log %s\n",
3887 mgs_erase_log(env, mgs, dirent->mde_name);
3890 mgs_direntry_free(dirent);
3896 /* list all logs for the given fs */
3897 int mgs_list_logs(const struct lu_env *env, struct mgs_device *mgs,
3898 struct obd_ioctl_data *data)
3900 struct list_head log_list;
3901 struct mgs_direntry *dirent, *n;
3907 /* Find all the logs in the CONFIGS directory */
3908 rc = class_dentry_readdir(env, mgs, &log_list);
3912 out = data->ioc_bulk;
3913 remains = data->ioc_inllen1;
3914 list_for_each_entry_safe(dirent, n, &log_list, mde_list) {
3915 list_del_init(&dirent->mde_list);
3916 suffix = strrchr(dirent->mde_name, '-');
3917 if (suffix != NULL) {
3918 l = snprintf(out, remains, "config log: $%s\n",
3923 mgs_direntry_free(dirent);
3930 /* from llog_swab */
3931 static void print_lustre_cfg(struct lustre_cfg *lcfg)
3936 CDEBUG(D_MGS, "lustre_cfg: %p\n", lcfg);
3937 CDEBUG(D_MGS, "\tlcfg->lcfg_version: %#x\n", lcfg->lcfg_version);
3939 CDEBUG(D_MGS, "\tlcfg->lcfg_command: %#x\n", lcfg->lcfg_command);
3940 CDEBUG(D_MGS, "\tlcfg->lcfg_num: %#x\n", lcfg->lcfg_num);
3941 CDEBUG(D_MGS, "\tlcfg->lcfg_flags: %#x\n", lcfg->lcfg_flags);
3942 CDEBUG(D_MGS, "\tlcfg->lcfg_nid: %s\n", libcfs_nid2str(lcfg->lcfg_nid));
3944 CDEBUG(D_MGS, "\tlcfg->lcfg_bufcount: %d\n", lcfg->lcfg_bufcount);
3945 if (lcfg->lcfg_bufcount < LUSTRE_CFG_MAX_BUFCOUNT)
3946 for (i = 0; i < lcfg->lcfg_bufcount; i++) {
3947 CDEBUG(D_MGS, "\tlcfg->lcfg_buflens[%d]: %d %s\n",
3948 i, lcfg->lcfg_buflens[i],
3949 lustre_cfg_string(lcfg, i));
3954 /* Setup _mgs fsdb and log
3956 int mgs__mgs_fsdb_setup(const struct lu_env *env, struct mgs_device *mgs,
3962 rc = mgs_find_or_make_fsdb(env, mgs, MGSSELF_NAME, &fsdb);
3967 /* Setup params fsdb and log
3969 int mgs_params_fsdb_setup(const struct lu_env *env, struct mgs_device *mgs,
3972 struct llog_handle *params_llh = NULL;
3976 rc = mgs_find_or_make_fsdb(env, mgs, PARAMS_FILENAME, &fsdb);
3978 mutex_lock(&fsdb->fsdb_mutex);
3979 rc = record_start_log(env, mgs, ¶ms_llh, PARAMS_FILENAME);
3981 rc = record_end_log(env, ¶ms_llh);
3982 mutex_unlock(&fsdb->fsdb_mutex);
3988 /* Cleanup params fsdb and log
3990 int mgs_params_fsdb_cleanup(const struct lu_env *env, struct mgs_device *mgs)
3992 return mgs_erase_logs(env, mgs, PARAMS_FILENAME);
3995 /* Set a permanent (config log) param for a target or fs
3996 * \param lcfg buf0 may contain the device (testfs-MDT0000) name
3997 * buf1 contains the single parameter
3999 int mgs_setparam(const struct lu_env *env, struct mgs_device *mgs,
4000 struct lustre_cfg *lcfg, char *fsname)
4003 struct mgs_target_info *mti;
4004 char *devname, *param;
4011 print_lustre_cfg(lcfg);
4013 /* lustre, lustre-mdtlov, lustre-client, lustre-MDT0000 */
4014 devname = lustre_cfg_string(lcfg, 0);
4015 param = lustre_cfg_string(lcfg, 1);
4017 /* Assume device name embedded in param:
4018 lustre-OST0000.osc.max_dirty_mb=32 */
4019 ptr = strchr(param, '.');
4027 LCONSOLE_ERROR_MSG(0x14d, "No target specified: %s\n", param);
4031 rc = mgs_parse_devname(devname, fsname, NULL);
4032 if (rc == 0 && !mgs_parse_devname(devname, NULL, &index)) {
4033 /* param related to llite isn't allowed to set by OST or MDT */
4034 if (rc == 0 && strncmp(param, PARAM_LLITE,
4035 sizeof(PARAM_LLITE) - 1) == 0)
4038 /* assume devname is the fsname */
4039 strlcpy(fsname, devname, MTI_NAME_MAXLEN);
4041 CDEBUG(D_MGS, "setparam fs='%s' device='%s'\n", fsname, devname);
4043 rc = mgs_find_or_make_fsdb(env, mgs,
4044 lcfg->lcfg_command == LCFG_SET_PARAM ?
4045 PARAMS_FILENAME : fsname, &fsdb);
4049 if (lcfg->lcfg_command != LCFG_SET_PARAM &&
4050 !test_bit(FSDB_MGS_SELF, &fsdb->fsdb_flags) &&
4051 test_bit(FSDB_LOG_EMPTY, &fsdb->fsdb_flags)) {
4052 CERROR("No filesystem targets for %s. cfg_device from lctl "
4053 "is '%s'\n", fsname, devname);
4054 mgs_free_fsdb(mgs, fsdb);
4058 /* Create a fake mti to hold everything */
4061 GOTO(out, rc = -ENOMEM);
4062 if (strlcpy(mti->mti_fsname, fsname, sizeof(mti->mti_fsname))
4063 >= sizeof(mti->mti_fsname))
4064 GOTO(out, rc = -E2BIG);
4065 if (strlcpy(mti->mti_svname, devname, sizeof(mti->mti_svname))
4066 >= sizeof(mti->mti_svname))
4067 GOTO(out, rc = -E2BIG);
4068 if (strlcpy(mti->mti_params, param, sizeof(mti->mti_params))
4069 >= sizeof(mti->mti_params))
4070 GOTO(out, rc = -E2BIG);
4071 rc = server_name2index(mti->mti_svname, &mti->mti_stripe_index, &tmp);
4073 /* Not a valid server; may be only fsname */
4076 /* Strip -osc or -mdc suffix from svname */
4077 if (server_make_name(rc, mti->mti_stripe_index, mti->mti_fsname,
4079 GOTO(out, rc = -EINVAL);
4081 * Revoke lock so everyone updates. Should be alright if
4082 * someone was already reading while we were updating the logs,
4083 * so we don't really need to hold the lock while we're
4086 if (lcfg->lcfg_command == LCFG_SET_PARAM) {
4087 mti->mti_flags = rc | LDD_F_PARAM2;
4088 mutex_lock(&fsdb->fsdb_mutex);
4089 rc = mgs_write_log_param2(env, mgs, fsdb, mti, mti->mti_params);
4090 mutex_unlock(&fsdb->fsdb_mutex);
4091 mgs_revoke_lock(mgs, fsdb, CONFIG_T_PARAMS);
4093 mti->mti_flags = rc | LDD_F_PARAM;
4094 mutex_lock(&fsdb->fsdb_mutex);
4095 rc = mgs_write_log_param(env, mgs, fsdb, mti, mti->mti_params);
4096 mutex_unlock(&fsdb->fsdb_mutex);
4097 mgs_revoke_lock(mgs, fsdb, CONFIG_T_CONFIG);
4105 static int mgs_write_log_pool(const struct lu_env *env,
4106 struct mgs_device *mgs, char *logname,
4107 struct fs_db *fsdb, char *tgtname,
4108 enum lcfg_command_type cmd,
4109 char *fsname, char *poolname,
4110 char *ostname, char *comment)
4112 struct llog_handle *llh = NULL;
4115 rc = record_start_log(env, mgs, &llh, logname);
4118 rc = record_marker(env, llh, fsdb, CM_START, tgtname, comment);
4121 rc = record_base(env, llh, tgtname, 0, cmd,
4122 fsname, poolname, ostname, NULL);
4125 rc = record_marker(env, llh, fsdb, CM_END, tgtname, comment);
4127 record_end_log(env, &llh);
4131 int mgs_nodemap_cmd(const struct lu_env *env, struct mgs_device *mgs,
4132 enum lcfg_command_type cmd, const char *nodemap_name,
4143 case LCFG_NODEMAP_ADD:
4144 rc = nodemap_add(nodemap_name);
4146 case LCFG_NODEMAP_DEL:
4147 rc = nodemap_del(nodemap_name);
4149 case LCFG_NODEMAP_ADD_RANGE:
4150 rc = nodemap_parse_range(param, nid);
4153 rc = nodemap_add_range(nodemap_name, nid);
4155 case LCFG_NODEMAP_DEL_RANGE:
4156 rc = nodemap_parse_range(param, nid);
4159 rc = nodemap_del_range(nodemap_name, nid);
4161 case LCFG_NODEMAP_ADMIN:
4162 bool_switch = simple_strtoul(param, NULL, 10);
4163 rc = nodemap_set_allow_root(nodemap_name, bool_switch);
4165 case LCFG_NODEMAP_TRUSTED:
4166 bool_switch = simple_strtoul(param, NULL, 10);
4167 rc = nodemap_set_trust_client_ids(nodemap_name, bool_switch);
4169 case LCFG_NODEMAP_SQUASH_UID:
4170 int_id = simple_strtoul(param, NULL, 10);
4171 rc = nodemap_set_squash_uid(nodemap_name, int_id);
4173 case LCFG_NODEMAP_SQUASH_GID:
4174 int_id = simple_strtoul(param, NULL, 10);
4175 rc = nodemap_set_squash_gid(nodemap_name, int_id);
4177 case LCFG_NODEMAP_ADD_UIDMAP:
4178 case LCFG_NODEMAP_ADD_GIDMAP:
4179 rc = nodemap_parse_idmap(param, idmap);
4182 if (cmd == LCFG_NODEMAP_ADD_UIDMAP)
4183 rc = nodemap_add_idmap(nodemap_name, NODEMAP_UID,
4186 rc = nodemap_add_idmap(nodemap_name, NODEMAP_GID,
4189 case LCFG_NODEMAP_DEL_UIDMAP:
4190 case LCFG_NODEMAP_DEL_GIDMAP:
4191 rc = nodemap_parse_idmap(param, idmap);
4194 if (cmd == LCFG_NODEMAP_DEL_UIDMAP)
4195 rc = nodemap_del_idmap(nodemap_name, NODEMAP_UID,
4198 rc = nodemap_del_idmap(nodemap_name, NODEMAP_GID,
4201 case LCFG_NODEMAP_SET_FILESET:
4202 rc = nodemap_set_fileset(nodemap_name, param);
4211 int mgs_pool_cmd(const struct lu_env *env, struct mgs_device *mgs,
4212 enum lcfg_command_type cmd, char *fsname,
4213 char *poolname, char *ostname)
4218 char *label = NULL, *canceled_label = NULL;
4220 struct mgs_target_info *mti = NULL;
4224 rc = mgs_find_or_make_fsdb(env, mgs, fsname, &fsdb);
4226 CERROR("Can't get db for %s\n", fsname);
4229 if (test_bit(FSDB_LOG_EMPTY, &fsdb->fsdb_flags)) {
4230 CERROR("%s is not defined\n", fsname);
4231 mgs_free_fsdb(mgs, fsdb);
4235 label_sz = 10 + strlen(fsname) + strlen(poolname);
4237 /* check if ostname match fsname */
4238 if (ostname != NULL) {
4241 ptr = strrchr(ostname, '-');
4242 if ((ptr == NULL) ||
4243 (strncmp(fsname, ostname, ptr-ostname) != 0))
4245 label_sz += strlen(ostname);
4248 OBD_ALLOC(label, label_sz);
4255 "new %s.%s", fsname, poolname);
4259 "add %s.%s.%s", fsname, poolname, ostname);
4262 OBD_ALLOC(canceled_label, label_sz);
4263 if (canceled_label == NULL)
4264 GOTO(out_label, rc = -ENOMEM);
4266 "rem %s.%s.%s", fsname, poolname, ostname);
4267 sprintf(canceled_label,
4268 "add %s.%s.%s", fsname, poolname, ostname);
4271 OBD_ALLOC(canceled_label, label_sz);
4272 if (canceled_label == NULL)
4273 GOTO(out_label, rc = -ENOMEM);
4275 "del %s.%s", fsname, poolname);
4276 sprintf(canceled_label,
4277 "new %s.%s", fsname, poolname);
4283 if (canceled_label != NULL) {
4286 GOTO(out_cancel, rc = -ENOMEM);
4289 mutex_lock(&fsdb->fsdb_mutex);
4290 /* write pool def to all MDT logs */
4291 for (i = 0; i < INDEX_MAP_SIZE * 8; i++) {
4292 if (test_bit(i, fsdb->fsdb_mdt_index_map)) {
4293 rc = name_create_mdt_and_lov(&logname, &lovname,
4296 mutex_unlock(&fsdb->fsdb_mutex);
4299 if (canceled_label != NULL) {
4300 strcpy(mti->mti_svname, "lov pool");
4301 rc = mgs_modify(env, mgs, fsdb, mti, logname,
4302 lovname, canceled_label,
4307 rc = mgs_write_log_pool(env, mgs, logname,
4311 name_destroy(&logname);
4312 name_destroy(&lovname);
4314 mutex_unlock(&fsdb->fsdb_mutex);
4320 rc = name_create(&logname, fsname, "-client");
4322 mutex_unlock(&fsdb->fsdb_mutex);
4325 if (canceled_label != NULL) {
4326 rc = mgs_modify(env, mgs, fsdb, mti, logname,
4327 fsdb->fsdb_clilov, canceled_label, CM_SKIP);
4329 mutex_unlock(&fsdb->fsdb_mutex);
4330 name_destroy(&logname);
4335 rc = mgs_write_log_pool(env, mgs, logname, fsdb, fsdb->fsdb_clilov,
4336 cmd, fsname, poolname, ostname, label);
4337 mutex_unlock(&fsdb->fsdb_mutex);
4338 name_destroy(&logname);
4339 /* request for update */
4340 mgs_revoke_lock(mgs, fsdb, CONFIG_T_CONFIG);
4347 if (canceled_label != NULL)
4348 OBD_FREE(canceled_label, label_sz);
4350 OBD_FREE(label, label_sz);