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, 2014, 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(mti->mti_stripe_index), "%d",
2159 mti->mti_stripe_index);
2160 rc = record_base(env, llh, lovname, 0, LCFG_ADD_MDC, mti->mti_uuid,
2161 index_str, "1", NULL);
2165 rc = record_marker(env, llh, fsdb, CM_END, mti->mti_svname, "add osp");
2170 record_end_log(env, &llh);
2173 name_destroy(&mdtuuid);
2174 name_destroy(&lovuuid);
2175 name_destroy(&lovname);
2176 name_destroy(&ospname);
2177 name_destroy(&svname);
2178 name_destroy(&nodeuuid);
2179 name_destroy(&mdtname);
2183 static int mgs_write_log_mdt0(const struct lu_env *env,
2184 struct mgs_device *mgs,
2186 struct mgs_target_info *mti)
2188 char *log = mti->mti_svname;
2189 struct llog_handle *llh = NULL;
2190 char *uuid, *lovname;
2192 char *ptr = mti->mti_params;
2193 int rc = 0, failout = 0;
2196 OBD_ALLOC(uuid, sizeof(struct obd_uuid));
2200 if (class_find_param(ptr, PARAM_FAILMODE, &ptr) == 0)
2201 failout = (strncmp(ptr, "failout", 7) == 0);
2203 rc = name_create(&lovname, log, "-mdtlov");
2206 if (mgs_log_is_empty(env, mgs, log)) {
2207 rc = mgs_write_log_lov(env, mgs, fsdb, mti, log, lovname);
2212 sprintf(mdt_index, "%d", mti->mti_stripe_index);
2214 rc = record_start_log(env, mgs, &llh, log);
2218 /* add MDT itself */
2220 /* FIXME this whole fn should be a single journal transaction */
2221 sprintf(uuid, "%s_UUID", log);
2222 rc = record_marker(env, llh, fsdb, CM_START, log, "add mdt");
2225 rc = record_attach(env, llh, log, LUSTRE_MDT_NAME, uuid);
2228 rc = record_mount_opt(env, llh, log, lovname, NULL);
2231 rc = record_setup(env, llh, log, uuid, mdt_index, lovname,
2232 failout ? "n" : "f");
2235 rc = record_marker(env, llh, fsdb, CM_END, log, "add mdt");
2239 record_end_log(env, &llh);
2241 name_destroy(&lovname);
2243 OBD_FREE(uuid, sizeof(struct obd_uuid));
2247 /* envelope method for all layers log */
2248 static int mgs_write_log_mdt(const struct lu_env *env,
2249 struct mgs_device *mgs,
2251 struct mgs_target_info *mti)
2253 struct mgs_thread_info *mgi = mgs_env_info(env);
2254 struct llog_handle *llh = NULL;
2259 CDEBUG(D_MGS, "writing new mdt %s\n", mti->mti_svname);
2261 if (mti->mti_uuid[0] == '\0') {
2262 /* Make up our own uuid */
2263 snprintf(mti->mti_uuid, sizeof(mti->mti_uuid),
2264 "%s_UUID", mti->mti_svname);
2268 rc = mgs_write_log_mdt0(env, mgs, fsdb, mti);
2271 /* Append the mdt info to the client log */
2272 rc = name_create(&cliname, mti->mti_fsname, "-client");
2276 if (mgs_log_is_empty(env, mgs, cliname)) {
2277 /* Start client log */
2278 rc = mgs_write_log_lov(env, mgs, fsdb, mti, cliname,
2282 rc = mgs_write_log_lmv(env, mgs, fsdb, mti, cliname,
2289 #09 L add_uuid nid=uml1@tcp(0x20000c0a80201) 0: 1:uml1_UUID
2290 #10 L attach 0:MDC_uml1_mdsA_MNT_client 1:mdc 2:1d834_MNT_client_03f
2291 #11 L setup 0:MDC_uml1_mdsA_MNT_client 1:mdsA_UUID 2:uml1_UUID
2292 #12 L add_uuid nid=uml2@tcp(0x20000c0a80202) 0: 1:uml2_UUID
2293 #13 L add_conn 0:MDC_uml1_mdsA_MNT_client 1:uml2_UUID
2294 #14 L mount_option 0: 1:client 2:lov1 3:MDC_uml1_mdsA_MNT_client
2297 /* copy client info about lov/lmv */
2298 mgi->mgi_comp.comp_mti = mti;
2299 mgi->mgi_comp.comp_fsdb = fsdb;
2301 rc = mgs_steal_llog_for_mdt_from_client(env, mgs, cliname,
2305 rc = mgs_write_log_mdc_to_lmv(env, mgs, fsdb, mti, cliname,
2311 rc = record_start_log(env, mgs, &llh, cliname);
2315 rc = record_marker(env, llh, fsdb, CM_START, cliname,
2319 rc = record_mount_opt(env, llh, cliname, fsdb->fsdb_clilov,
2323 rc = record_marker(env, llh, fsdb, CM_END, cliname,
2329 /* for_all_existing_mdt except current one */
2330 for (i = 0; i < INDEX_MAP_SIZE * 8; i++) {
2331 if (i != mti->mti_stripe_index &&
2332 test_bit(i, fsdb->fsdb_mdt_index_map)) {
2335 rc = name_create_mdt(&logname, fsdb->fsdb_name, i);
2339 rc = mgs_write_log_osp_to_mdt(env, mgs, fsdb, mti,
2341 name_destroy(&logname);
2347 record_end_log(env, &llh);
2349 name_destroy(&cliname);
2353 /* Add the ost info to the client/mdt lov */
2354 static int mgs_write_log_osc_to_lov(const struct lu_env *env,
2355 struct mgs_device *mgs, struct fs_db *fsdb,
2356 struct mgs_target_info *mti,
2357 char *logname, char *suffix, char *lovname,
2358 enum lustre_sec_part sec_part, int flags)
2360 struct llog_handle *llh = NULL;
2361 char *nodeuuid = NULL;
2362 char *oscname = NULL;
2363 char *oscuuid = NULL;
2364 char *lovuuid = NULL;
2365 char *svname = NULL;
2367 char nidstr[LNET_NIDSTR_SIZE];
2371 CDEBUG(D_INFO, "adding osc for %s to log %s\n",
2372 mti->mti_svname, logname);
2374 if (mgs_log_is_empty(env, mgs, logname)) {
2375 CERROR("log is empty! Logical error\n");
2379 libcfs_nid2str_r(mti->mti_nids[0], nidstr, sizeof(nidstr));
2380 rc = name_create(&nodeuuid, nidstr, "");
2383 rc = name_create(&svname, mti->mti_svname, "-osc");
2387 /* for the system upgraded from old 1.8, keep using the old osc naming
2388 * style for mdt, see name_create_mdt_osc(). LU-1257 */
2389 if (test_bit(FSDB_OSCNAME18, &fsdb->fsdb_flags))
2390 rc = name_create(&oscname, svname, "");
2392 rc = name_create(&oscname, svname, suffix);
2396 rc = name_create(&oscuuid, oscname, "_UUID");
2399 rc = name_create(&lovuuid, lovname, "_UUID");
2405 #03 L add_uuid nid=uml1@tcp(0x20000c0a80201) 0: 1:uml1_UUID
2407 #04 L add_uuid nid=1@elan(0x1000000000001) nal=90 0: 1:uml1_UUID
2408 #04 L attach 0:OSC_uml1_ost1_MNT_client 1:osc 2:89070_lov1_a41dff51a
2409 #05 L setup 0:OSC_uml1_ost1_MNT_client 1:ost1_UUID 2:uml1_UUID
2411 #06 L add_uuid nid=uml2@tcp(0x20000c0a80202) 0: 1:uml2_UUID
2412 #07 L add_conn 0:OSC_uml1_ost1_MNT_client 1:uml2_UUID
2413 #08 L lov_modify_tgts add 0:lov1 1:ost1_UUID 2(index):0 3(gen):1
2416 rc = record_start_log(env, mgs, &llh, logname);
2420 /* FIXME these should be a single journal transaction */
2421 rc = record_marker(env, llh, fsdb, CM_START | flags, mti->mti_svname,
2426 /* NB: don't change record order, because upon MDT steal OSC config
2427 * from client, it treats all nids before LCFG_SETUP as target nids
2428 * (multiple interfaces), while nids after as failover node nids.
2429 * See mgs_steal_client_llog_handler() LCFG_ADD_UUID.
2431 for (i = 0; i < mti->mti_nid_count; i++) {
2432 CDEBUG(D_MGS, "add nid %s\n",
2433 libcfs_nid2str_r(mti->mti_nids[i],
2434 nidstr, sizeof(nidstr)));
2435 rc = record_add_uuid(env, llh, mti->mti_nids[i], nodeuuid);
2439 rc = record_attach(env, llh, oscname, LUSTRE_OSC_NAME, lovuuid);
2442 rc = record_setup(env, llh, oscname, mti->mti_uuid, nodeuuid,
2446 rc = mgs_write_log_failnids(env, mti, llh, oscname);
2450 snprintf(index, sizeof(index), "%d", mti->mti_stripe_index);
2452 rc = record_lov_add(env, llh, lovname, mti->mti_uuid, index, "1");
2455 rc = record_marker(env, llh, fsdb, CM_END | flags, mti->mti_svname,
2460 record_end_log(env, &llh);
2462 name_destroy(&lovuuid);
2463 name_destroy(&oscuuid);
2464 name_destroy(&oscname);
2465 name_destroy(&svname);
2466 name_destroy(&nodeuuid);
2470 static int mgs_write_log_ost(const struct lu_env *env,
2471 struct mgs_device *mgs, struct fs_db *fsdb,
2472 struct mgs_target_info *mti)
2474 struct llog_handle *llh = NULL;
2475 char *logname, *lovname;
2476 char *ptr = mti->mti_params;
2477 int rc, flags = 0, failout = 0, i;
2480 CDEBUG(D_MGS, "writing new ost %s\n", mti->mti_svname);
2482 /* The ost startup log */
2484 /* If the ost log already exists, that means that someone reformatted
2485 the ost and it called target_add again. */
2486 if (!mgs_log_is_empty(env, mgs, mti->mti_svname)) {
2487 LCONSOLE_ERROR_MSG(0x141, "The config log for %s already "
2488 "exists, yet the server claims it never "
2489 "registered. It may have been reformatted, "
2490 "or the index changed. writeconf the MDT to "
2491 "regenerate all logs.\n", mti->mti_svname);
2496 attach obdfilter ost1 ost1_UUID
2497 setup /dev/loop2 ldiskfs f|n errors=remount-ro,user_xattr
2499 if (class_find_param(ptr, PARAM_FAILMODE, &ptr) == 0)
2500 failout = (strncmp(ptr, "failout", 7) == 0);
2501 rc = record_start_log(env, mgs, &llh, mti->mti_svname);
2504 /* FIXME these should be a single journal transaction */
2505 rc = record_marker(env, llh, fsdb, CM_START, mti->mti_svname,"add ost");
2508 if (*mti->mti_uuid == '\0')
2509 snprintf(mti->mti_uuid, sizeof(mti->mti_uuid),
2510 "%s_UUID", mti->mti_svname);
2511 rc = record_attach(env, llh, mti->mti_svname,
2512 "obdfilter"/*LUSTRE_OST_NAME*/, mti->mti_uuid);
2515 rc = record_setup(env, llh, mti->mti_svname,
2516 "dev"/*ignored*/, "type"/*ignored*/,
2517 failout ? "n" : "f", NULL/*options*/);
2520 rc = record_marker(env, llh, fsdb, CM_END, mti->mti_svname, "add ost");
2524 record_end_log(env, &llh);
2527 /* We also have to update the other logs where this osc is part of
2530 if (test_bit(FSDB_OLDLOG14, &fsdb->fsdb_flags)) {
2531 /* If we're upgrading, the old mdt log already has our
2532 entry. Let's do a fake one for fun. */
2533 /* Note that we can't add any new failnids, since we don't
2534 know the old osc names. */
2535 flags = CM_SKIP | CM_UPGRADE146;
2537 } else if ((mti->mti_flags & LDD_F_UPDATE) != LDD_F_UPDATE) {
2538 /* If the update flag isn't set, don't update client/mdt
2541 LCONSOLE_WARN("Client log for %s was not updated; writeconf "
2542 "the MDT first to regenerate it.\n",
2546 /* Add ost to all MDT lov defs */
2547 for (i = 0; i < INDEX_MAP_SIZE * 8; i++){
2548 if (test_bit(i, fsdb->fsdb_mdt_index_map)) {
2551 rc = name_create_mdt_and_lov(&logname, &lovname, fsdb,
2555 sprintf(mdt_index, "-MDT%04x", i);
2556 rc = mgs_write_log_osc_to_lov(env, mgs, fsdb, mti,
2558 lovname, LUSTRE_SP_MDT,
2560 name_destroy(&logname);
2561 name_destroy(&lovname);
2567 /* Append ost info to the client log */
2568 rc = name_create(&logname, mti->mti_fsname, "-client");
2571 if (mgs_log_is_empty(env, mgs, logname)) {
2572 /* Start client log */
2573 rc = mgs_write_log_lov(env, mgs, fsdb, mti, logname,
2577 rc = mgs_write_log_lmv(env, mgs, fsdb, mti, logname,
2582 rc = mgs_write_log_osc_to_lov(env, mgs, fsdb, mti, logname, "",
2583 fsdb->fsdb_clilov, LUSTRE_SP_CLI, 0);
2585 name_destroy(&logname);
2589 static __inline__ int mgs_param_empty(char *ptr)
2593 if ((tmp = strchr(ptr, '=')) && (*(++tmp) == '\0'))
2598 static int mgs_write_log_failnid_internal(const struct lu_env *env,
2599 struct mgs_device *mgs,
2601 struct mgs_target_info *mti,
2602 char *logname, char *cliname)
2605 struct llog_handle *llh = NULL;
2607 if (mgs_param_empty(mti->mti_params)) {
2608 /* Remove _all_ failnids */
2609 rc = mgs_modify(env, mgs, fsdb, mti, logname,
2610 mti->mti_svname, "add failnid", CM_SKIP);
2611 return rc < 0 ? rc : 0;
2614 /* Otherwise failover nids are additive */
2615 rc = record_start_log(env, mgs, &llh, logname);
2618 /* FIXME this should be a single journal transaction */
2619 rc = record_marker(env, llh, fsdb, CM_START, mti->mti_svname,
2623 rc = mgs_write_log_failnids(env, mti, llh, cliname);
2626 rc = record_marker(env, llh, fsdb, CM_END,
2627 mti->mti_svname, "add failnid");
2629 record_end_log(env, &llh);
2634 /* Add additional failnids to an existing log.
2635 The mdc/osc must have been added to logs first */
2636 /* tcp nids must be in dotted-quad ascii -
2637 we can't resolve hostnames from the kernel. */
2638 static int mgs_write_log_add_failnid(const struct lu_env *env,
2639 struct mgs_device *mgs,
2641 struct mgs_target_info *mti)
2643 char *logname, *cliname;
2647 /* FIXME we currently can't erase the failnids
2648 * given when a target first registers, since they aren't part of
2649 * an "add uuid" stanza */
2651 /* Verify that we know about this target */
2652 if (mgs_log_is_empty(env, mgs, mti->mti_svname)) {
2653 LCONSOLE_ERROR_MSG(0x142, "The target %s has not registered "
2654 "yet. It must be started before failnids "
2655 "can be added.\n", mti->mti_svname);
2659 /* Create mdc/osc client name (e.g. lustre-OST0001-osc) */
2660 if (mti->mti_flags & LDD_F_SV_TYPE_MDT) {
2661 rc = name_create(&cliname, mti->mti_svname, "-mdc");
2662 } else if (mti->mti_flags & LDD_F_SV_TYPE_OST) {
2663 rc = name_create(&cliname, mti->mti_svname, "-osc");
2669 /* Add failover nids to the client log */
2670 rc = name_create(&logname, mti->mti_fsname, "-client");
2672 name_destroy(&cliname);
2675 rc = mgs_write_log_failnid_internal(env, mgs, fsdb,mti,logname,cliname);
2676 name_destroy(&logname);
2677 name_destroy(&cliname);
2681 if (mti->mti_flags & LDD_F_SV_TYPE_OST) {
2682 /* Add OST failover nids to the MDT logs as well */
2685 for (i = 0; i < INDEX_MAP_SIZE * 8; i++) {
2686 if (!test_bit(i, fsdb->fsdb_mdt_index_map))
2688 rc = name_create_mdt(&logname, mti->mti_fsname, i);
2691 rc = name_create_mdt_osc(&cliname, mti->mti_svname,
2694 name_destroy(&logname);
2697 rc = mgs_write_log_failnid_internal(env, mgs, fsdb,
2700 name_destroy(&cliname);
2701 name_destroy(&logname);
2710 static int mgs_wlp_lcfg(const struct lu_env *env,
2711 struct mgs_device *mgs, struct fs_db *fsdb,
2712 struct mgs_target_info *mti,
2713 char *logname, struct lustre_cfg_bufs *bufs,
2714 char *tgtname, char *ptr)
2716 char comment[MTI_NAME_MAXLEN];
2718 struct llog_cfg_rec *lcr;
2721 /* Erase any old settings of this same parameter */
2722 memcpy(comment, ptr, MTI_NAME_MAXLEN);
2723 comment[MTI_NAME_MAXLEN - 1] = 0;
2724 /* But don't try to match the value. */
2725 tmp = strchr(comment, '=');
2728 /* FIXME we should skip settings that are the same as old values */
2729 rc = mgs_modify(env, mgs, fsdb, mti, logname, tgtname, comment,CM_SKIP);
2732 del = mgs_param_empty(ptr);
2734 LCONSOLE_INFO("%s parameter %s.%s in log %s\n", del ? "Disabling" : rc ?
2735 "Setting" : "Modifying", tgtname, comment, logname);
2737 /* mgs_modify() will return 1 if nothing had to be done */
2743 lustre_cfg_bufs_reset(bufs, tgtname);
2744 lustre_cfg_bufs_set_string(bufs, 1, ptr);
2745 if (mti->mti_flags & LDD_F_PARAM2)
2746 lustre_cfg_bufs_set_string(bufs, 2, LCTL_UPCALL);
2748 lcr = lustre_cfg_rec_new((mti->mti_flags & LDD_F_PARAM2) ?
2749 LCFG_SET_PARAM : LCFG_PARAM, bufs);
2753 rc = mgs_write_log_direct(env, mgs, fsdb, logname, lcr, tgtname,
2755 lustre_cfg_rec_free(lcr);
2759 static int mgs_write_log_param2(const struct lu_env *env,
2760 struct mgs_device *mgs,
2762 struct mgs_target_info *mti, char *ptr)
2764 struct lustre_cfg_bufs bufs;
2768 CDEBUG(D_MGS, "next param '%s'\n", ptr);
2769 rc = mgs_wlp_lcfg(env, mgs, fsdb, mti, PARAMS_FILENAME, &bufs,
2770 mti->mti_svname, ptr);
2775 /* write global variable settings into log */
2776 static int mgs_write_log_sys(const struct lu_env *env,
2777 struct mgs_device *mgs, struct fs_db *fsdb,
2778 struct mgs_target_info *mti, char *sys, char *ptr)
2780 struct mgs_thread_info *mgi = mgs_env_info(env);
2781 struct lustre_cfg *lcfg;
2782 struct llog_cfg_rec *lcr;
2784 int rc, cmd, convert = 1;
2786 if (class_match_param(ptr, PARAM_TIMEOUT, &tmp) == 0) {
2787 cmd = LCFG_SET_TIMEOUT;
2788 } else if (class_match_param(ptr, PARAM_LDLM_TIMEOUT, &tmp) == 0) {
2789 cmd = LCFG_SET_LDLM_TIMEOUT;
2790 /* Check for known params here so we can return error to lctl */
2791 } else if ((class_match_param(ptr, PARAM_AT_MIN, &tmp) == 0) ||
2792 (class_match_param(ptr, PARAM_AT_MAX, &tmp) == 0) ||
2793 (class_match_param(ptr, PARAM_AT_EXTRA, &tmp) == 0) ||
2794 (class_match_param(ptr, PARAM_AT_EARLY_MARGIN, &tmp) == 0) ||
2795 (class_match_param(ptr, PARAM_AT_HISTORY, &tmp) == 0)) {
2797 } else if (class_match_param(ptr, PARAM_JOBID_VAR, &tmp) == 0) {
2798 convert = 0; /* Don't convert string value to integer */
2804 if (mgs_param_empty(ptr))
2805 CDEBUG(D_MGS, "global '%s' removed\n", sys);
2807 CDEBUG(D_MGS, "global '%s' val=%s\n", sys, tmp);
2809 lustre_cfg_bufs_reset(&mgi->mgi_bufs, NULL);
2810 lustre_cfg_bufs_set_string(&mgi->mgi_bufs, 1, sys);
2811 if (!convert && *tmp != '\0')
2812 lustre_cfg_bufs_set_string(&mgi->mgi_bufs, 2, tmp);
2813 lcr = lustre_cfg_rec_new(cmd, &mgi->mgi_bufs);
2817 lcfg = &lcr->lcr_cfg;
2818 lcfg->lcfg_num = convert ? simple_strtoul(tmp, NULL, 0) : 0;
2819 /* truncate the comment to the parameter name */
2823 /* modify all servers and clients */
2824 rc = mgs_write_log_direct_all(env, mgs, fsdb, mti,
2825 *tmp == '\0' ? NULL : lcr,
2826 mti->mti_fsname, sys, 0);
2827 if (rc == 0 && *tmp != '\0') {
2829 case LCFG_SET_TIMEOUT:
2830 if (!obd_timeout_set || lcfg->lcfg_num > obd_timeout)
2831 class_process_config(lcfg);
2833 case LCFG_SET_LDLM_TIMEOUT:
2834 if (!ldlm_timeout_set || lcfg->lcfg_num > ldlm_timeout)
2835 class_process_config(lcfg);
2842 lustre_cfg_rec_free(lcr);
2846 /* write quota settings into log */
2847 static int mgs_write_log_quota(const struct lu_env *env, struct mgs_device *mgs,
2848 struct fs_db *fsdb, struct mgs_target_info *mti,
2849 char *quota, char *ptr)
2851 struct mgs_thread_info *mgi = mgs_env_info(env);
2852 struct llog_cfg_rec *lcr;
2855 int rc, cmd = LCFG_PARAM;
2857 /* support only 'meta' and 'data' pools so far */
2858 if (class_match_param(ptr, QUOTA_METAPOOL_NAME, &tmp) != 0 &&
2859 class_match_param(ptr, QUOTA_DATAPOOL_NAME, &tmp) != 0) {
2860 CERROR("parameter quota.%s isn't supported (only quota.mdt "
2861 "& quota.ost are)\n", ptr);
2866 CDEBUG(D_MGS, "global '%s' removed\n", quota);
2868 CDEBUG(D_MGS, "global '%s'\n", quota);
2870 if (strchr(tmp, 'u') == NULL && strchr(tmp, 'g') == NULL &&
2871 strcmp(tmp, "none") != 0) {
2872 CERROR("enable option(%s) isn't supported\n", tmp);
2877 lustre_cfg_bufs_reset(&mgi->mgi_bufs, mti->mti_fsname);
2878 lustre_cfg_bufs_set_string(&mgi->mgi_bufs, 1, quota);
2879 lcr = lustre_cfg_rec_new(cmd, &mgi->mgi_bufs);
2883 /* truncate the comment to the parameter name */
2888 /* XXX we duplicated quota enable information in all server
2889 * config logs, it should be moved to a separate config
2890 * log once we cleanup the config log for global param. */
2891 /* modify all servers */
2892 rc = mgs_write_log_direct_all(env, mgs, fsdb, mti,
2893 *tmp == '\0' ? NULL : lcr,
2894 mti->mti_fsname, quota, 1);
2896 lustre_cfg_rec_free(lcr);
2897 return rc < 0 ? rc : 0;
2900 static int mgs_srpc_set_param_disk(const struct lu_env *env,
2901 struct mgs_device *mgs,
2903 struct mgs_target_info *mti,
2906 struct mgs_thread_info *mgi = mgs_env_info(env);
2907 struct llog_cfg_rec *lcr;
2908 struct llog_handle *llh = NULL;
2910 char *comment, *ptr;
2916 ptr = strchr(param, '=');
2917 LASSERT(ptr != NULL);
2920 OBD_ALLOC(comment, len + 1);
2921 if (comment == NULL)
2923 strncpy(comment, param, len);
2924 comment[len] = '\0';
2927 lustre_cfg_bufs_reset(&mgi->mgi_bufs, mti->mti_svname);
2928 lustre_cfg_bufs_set_string(&mgi->mgi_bufs, 1, param);
2929 lcr = lustre_cfg_rec_new(LCFG_SPTLRPC_CONF, &mgi->mgi_bufs);
2931 GOTO(out_comment, rc = -ENOMEM);
2933 /* construct log name */
2934 rc = name_create(&logname, mti->mti_fsname, "-sptlrpc");
2938 if (mgs_log_is_empty(env, mgs, logname)) {
2939 rc = record_start_log(env, mgs, &llh, logname);
2942 record_end_log(env, &llh);
2945 /* obsolete old one */
2946 rc = mgs_modify(env, mgs, fsdb, mti, logname, mti->mti_svname,
2950 /* write the new one */
2951 rc = mgs_write_log_direct(env, mgs, fsdb, logname, lcr,
2952 mti->mti_svname, comment);
2954 CERROR("%s: error writing log %s: rc = %d\n",
2955 mgs->mgs_obd->obd_name, logname, rc);
2957 name_destroy(&logname);
2959 lustre_cfg_rec_free(lcr);
2961 OBD_FREE(comment, len + 1);
2965 static int mgs_srpc_set_param_udesc_mem(struct fs_db *fsdb,
2970 /* disable the adjustable udesc parameter for now, i.e. use default
2971 * setting that client always ship udesc to MDT if possible. to enable
2972 * it simply remove the following line */
2975 ptr = strchr(param, '=');
2980 if (strcmp(param, PARAM_SRPC_UDESC))
2983 if (strcmp(ptr, "yes") == 0) {
2984 set_bit(FSDB_UDESC, &fsdb->fsdb_flags);
2985 CWARN("Enable user descriptor shipping from client to MDT\n");
2986 } else if (strcmp(ptr, "no") == 0) {
2987 clear_bit(FSDB_UDESC, &fsdb->fsdb_flags);
2988 CWARN("Disable user descriptor shipping from client to MDT\n");
2996 CERROR("Invalid param: %s\n", param);
3000 static int mgs_srpc_set_param_mem(struct fs_db *fsdb,
3004 struct sptlrpc_rule rule;
3005 struct sptlrpc_rule_set *rset;
3009 if (strncmp(param, PARAM_SRPC, sizeof(PARAM_SRPC) - 1) != 0) {
3010 CERROR("Invalid sptlrpc parameter: %s\n", param);
3014 if (strncmp(param, PARAM_SRPC_UDESC,
3015 sizeof(PARAM_SRPC_UDESC) - 1) == 0) {
3016 RETURN(mgs_srpc_set_param_udesc_mem(fsdb, param));
3019 if (strncmp(param, PARAM_SRPC_FLVR, sizeof(PARAM_SRPC_FLVR) - 1) != 0) {
3020 CERROR("Invalid sptlrpc flavor parameter: %s\n", param);
3024 param += sizeof(PARAM_SRPC_FLVR) - 1;
3026 rc = sptlrpc_parse_rule(param, &rule);
3030 /* mgs rules implies must be mgc->mgs */
3031 if (test_bit(FSDB_MGS_SELF, &fsdb->fsdb_flags)) {
3032 if ((rule.sr_from != LUSTRE_SP_MGC &&
3033 rule.sr_from != LUSTRE_SP_ANY) ||
3034 (rule.sr_to != LUSTRE_SP_MGS &&
3035 rule.sr_to != LUSTRE_SP_ANY))
3039 /* preapre room for this coming rule. svcname format should be:
3040 * - fsname: general rule
3041 * - fsname-tgtname: target-specific rule
3043 if (strchr(svname, '-')) {
3044 struct mgs_tgt_srpc_conf *tgtconf;
3047 for (tgtconf = fsdb->fsdb_srpc_tgt; tgtconf != NULL;
3048 tgtconf = tgtconf->mtsc_next) {
3049 if (!strcmp(tgtconf->mtsc_tgt, svname)) {
3058 OBD_ALLOC_PTR(tgtconf);
3059 if (tgtconf == NULL)
3062 name_len = strlen(svname);
3064 OBD_ALLOC(tgtconf->mtsc_tgt, name_len + 1);
3065 if (tgtconf->mtsc_tgt == NULL) {
3066 OBD_FREE_PTR(tgtconf);
3069 memcpy(tgtconf->mtsc_tgt, svname, name_len);
3071 tgtconf->mtsc_next = fsdb->fsdb_srpc_tgt;
3072 fsdb->fsdb_srpc_tgt = tgtconf;
3075 rset = &tgtconf->mtsc_rset;
3076 } else if (strcmp(svname, MGSSELF_NAME) == 0) {
3077 /* put _mgs related srpc rule directly in mgs ruleset */
3078 rset = &fsdb->fsdb_mgs->mgs_lut.lut_sptlrpc_rset;
3080 rset = &fsdb->fsdb_srpc_gen;
3083 rc = sptlrpc_rule_set_merge(rset, &rule);
3088 static int mgs_srpc_set_param(const struct lu_env *env,
3089 struct mgs_device *mgs,
3091 struct mgs_target_info *mti,
3101 /* keep a copy of original param, which could be destroied
3103 copy_size = strlen(param) + 1;
3104 OBD_ALLOC(copy, copy_size);
3107 memcpy(copy, param, copy_size);
3109 rc = mgs_srpc_set_param_mem(fsdb, mti->mti_svname, param);
3113 /* previous steps guaranteed the syntax is correct */
3114 rc = mgs_srpc_set_param_disk(env, mgs, fsdb, mti, copy);
3118 if (test_bit(FSDB_MGS_SELF, &fsdb->fsdb_flags)) {
3120 * for mgs rules, make them effective immediately.
3122 LASSERT(fsdb->fsdb_srpc_tgt == NULL);
3123 sptlrpc_target_update_exp_flavor(mgs->mgs_obd,
3124 &fsdb->fsdb_srpc_gen);
3128 OBD_FREE(copy, copy_size);
3132 struct mgs_srpc_read_data {
3133 struct fs_db *msrd_fsdb;
3137 static int mgs_srpc_read_handler(const struct lu_env *env,
3138 struct llog_handle *llh,
3139 struct llog_rec_hdr *rec, void *data)
3141 struct mgs_srpc_read_data *msrd = data;
3142 struct cfg_marker *marker;
3143 struct lustre_cfg *lcfg = REC_DATA(rec);
3144 char *svname, *param;
3148 if (rec->lrh_type != OBD_CFG_REC) {
3149 CERROR("unhandled lrh_type: %#x\n", rec->lrh_type);
3153 cfg_len = REC_DATA_LEN(rec);
3155 rc = lustre_cfg_sanity_check(lcfg, cfg_len);
3157 CERROR("Insane cfg\n");
3161 if (lcfg->lcfg_command == LCFG_MARKER) {
3162 marker = lustre_cfg_buf(lcfg, 1);
3164 if (marker->cm_flags & CM_START &&
3165 marker->cm_flags & CM_SKIP)
3166 msrd->msrd_skip = 1;
3167 if (marker->cm_flags & CM_END)
3168 msrd->msrd_skip = 0;
3173 if (msrd->msrd_skip)
3176 if (lcfg->lcfg_command != LCFG_SPTLRPC_CONF) {
3177 CERROR("invalid command (%x)\n", lcfg->lcfg_command);
3181 svname = lustre_cfg_string(lcfg, 0);
3182 if (svname == NULL) {
3183 CERROR("svname is empty\n");
3187 param = lustre_cfg_string(lcfg, 1);
3188 if (param == NULL) {
3189 CERROR("param is empty\n");
3193 rc = mgs_srpc_set_param_mem(msrd->msrd_fsdb, svname, param);
3195 CERROR("read sptlrpc record error (%d): %s\n", rc, param);
3200 int mgs_get_fsdb_srpc_from_llog(const struct lu_env *env,
3201 struct mgs_device *mgs,
3204 struct llog_handle *llh = NULL;
3205 struct llog_ctxt *ctxt;
3207 struct mgs_srpc_read_data msrd;
3211 /* construct log name */
3212 rc = name_create(&logname, fsdb->fsdb_name, "-sptlrpc");
3216 ctxt = llog_get_context(mgs->mgs_obd, LLOG_CONFIG_ORIG_CTXT);
3217 LASSERT(ctxt != NULL);
3219 if (mgs_log_is_empty(env, mgs, logname))
3222 rc = llog_open(env, ctxt, &llh, NULL, logname,
3230 rc = llog_init_handle(env, llh, LLOG_F_IS_PLAIN, NULL);
3232 GOTO(out_close, rc);
3234 if (llog_get_size(llh) <= 1)
3235 GOTO(out_close, rc = 0);
3237 msrd.msrd_fsdb = fsdb;
3240 rc = llog_process(env, llh, mgs_srpc_read_handler, (void *)&msrd,
3244 llog_close(env, llh);
3246 llog_ctxt_put(ctxt);
3247 name_destroy(&logname);
3250 CERROR("failed to read sptlrpc config database: %d\n", rc);
3254 /* Permanent settings of all parameters by writing into the appropriate
3255 * configuration logs.
3256 * A parameter with null value ("<param>='\0'") means to erase it out of
3259 static int mgs_write_log_param(const struct lu_env *env,
3260 struct mgs_device *mgs, struct fs_db *fsdb,
3261 struct mgs_target_info *mti, char *ptr)
3263 struct mgs_thread_info *mgi = mgs_env_info(env);
3266 int rc = 0, rc2 = 0;
3269 /* For various parameter settings, we have to figure out which logs
3270 care about them (e.g. both mdt and client for lov settings) */
3271 CDEBUG(D_MGS, "next param '%s'\n", ptr);
3273 /* The params are stored in MOUNT_DATA_FILE and modified via
3274 tunefs.lustre, or set using lctl conf_param */
3276 /* Processed in lustre_start_mgc */
3277 if (class_match_param(ptr, PARAM_MGSNODE, NULL) == 0)
3280 /* Processed in ost/mdt */
3281 if (class_match_param(ptr, PARAM_NETWORK, NULL) == 0)
3284 /* Processed in mgs_write_log_ost */
3285 if (class_match_param(ptr, PARAM_FAILMODE, NULL) == 0) {
3286 if (mti->mti_flags & LDD_F_PARAM) {
3287 LCONSOLE_ERROR_MSG(0x169, "%s can only be "
3288 "changed with tunefs.lustre"
3289 "and --writeconf\n", ptr);
3295 if (class_match_param(ptr, PARAM_SRPC, NULL) == 0) {
3296 rc = mgs_srpc_set_param(env, mgs, fsdb, mti, ptr);
3300 if (class_match_param(ptr, PARAM_FAILNODE, NULL) == 0) {
3301 /* Add a failover nidlist */
3303 /* We already processed failovers params for new
3304 targets in mgs_write_log_target */
3305 if (mti->mti_flags & LDD_F_PARAM) {
3306 CDEBUG(D_MGS, "Adding failnode\n");
3307 rc = mgs_write_log_add_failnid(env, mgs, fsdb, mti);
3312 if (class_match_param(ptr, PARAM_SYS, &tmp) == 0) {
3313 rc = mgs_write_log_sys(env, mgs, fsdb, mti, ptr, tmp);
3317 if (class_match_param(ptr, PARAM_QUOTA, &tmp) == 0) {
3318 rc = mgs_write_log_quota(env, mgs, fsdb, mti, ptr, tmp);
3322 if (class_match_param(ptr, PARAM_OSC PARAM_ACTIVE, &tmp) == 0 ||
3323 class_match_param(ptr, PARAM_MDC PARAM_ACTIVE, &tmp) == 0) {
3324 /* active=0 means off, anything else means on */
3325 int flag = (*tmp == '0') ? CM_EXCLUDE : 0;
3326 bool deactive_osc = memcmp(ptr, PARAM_OSC PARAM_ACTIVE,
3327 strlen(PARAM_OSC PARAM_ACTIVE)) == 0;
3330 if (!deactive_osc) {
3333 rc = server_name2index(mti->mti_svname, &index, NULL);
3338 LCONSOLE_ERROR_MSG(0x144, "%s: MDC0 can not be"
3339 " (de)activated.\n",
3341 GOTO(end, rc = -EINVAL);
3345 LCONSOLE_WARN("Permanently %sactivating %s\n",
3346 flag ? "de" : "re", mti->mti_svname);
3348 rc = name_create(&logname, mti->mti_fsname, "-client");
3351 rc = mgs_modify(env, mgs, fsdb, mti, logname,
3353 deactive_osc ? "add osc" : "add mdc", flag);
3354 name_destroy(&logname);
3359 /* Add to all MDT logs for DNE */
3360 for (i = 0; i < INDEX_MAP_SIZE * 8; i++) {
3361 if (!test_bit(i, fsdb->fsdb_mdt_index_map))
3363 rc = name_create_mdt(&logname, mti->mti_fsname, i);
3366 rc = mgs_modify(env, mgs, fsdb, mti, logname,
3368 deactive_osc ? "add osc" : "add osp",
3370 name_destroy(&logname);
3376 LCONSOLE_ERROR_MSG(0x145, "Couldn't find %s in"
3377 "log (%d). No permanent "
3378 "changes were made to the "
3380 mti->mti_svname, rc);
3381 if (test_bit(FSDB_OLDLOG14, &fsdb->fsdb_flags))
3382 LCONSOLE_ERROR_MSG(0x146, "This may be"
3387 "update the logs.\n");
3390 /* Fall through to osc/mdc proc for deactivating live
3391 OSC/OSP on running MDT / clients. */
3393 /* Below here, let obd's XXX_process_config methods handle it */
3395 /* All lov. in proc */
3396 if (class_match_param(ptr, PARAM_LOV, NULL) == 0) {
3399 CDEBUG(D_MGS, "lov param %s\n", ptr);
3400 if (!(mti->mti_flags & LDD_F_SV_TYPE_MDT)) {
3401 LCONSOLE_ERROR_MSG(0x147, "LOV params must be "
3402 "set on the MDT, not %s. "
3409 if (mgs_log_is_empty(env, mgs, mti->mti_svname))
3410 GOTO(end, rc = -ENODEV);
3412 rc = name_create_mdt_and_lov(&logname, &mdtlovname, fsdb,
3413 mti->mti_stripe_index);
3416 rc = mgs_wlp_lcfg(env, mgs, fsdb, mti, mti->mti_svname,
3417 &mgi->mgi_bufs, mdtlovname, ptr);
3418 name_destroy(&logname);
3419 name_destroy(&mdtlovname);
3424 rc = name_create(&logname, mti->mti_fsname, "-client");
3427 rc = mgs_wlp_lcfg(env, mgs, fsdb, mti, logname, &mgi->mgi_bufs,
3428 fsdb->fsdb_clilov, ptr);
3429 name_destroy(&logname);
3433 /* All osc., mdc., llite. params in proc */
3434 if ((class_match_param(ptr, PARAM_OSC, NULL) == 0) ||
3435 (class_match_param(ptr, PARAM_MDC, NULL) == 0) ||
3436 (class_match_param(ptr, PARAM_LLITE, NULL) == 0)) {
3439 if (test_bit(FSDB_OLDLOG14, &fsdb->fsdb_flags)) {
3440 LCONSOLE_ERROR_MSG(0x148, "Upgraded client logs for %s"
3441 " cannot be modified. Consider"
3442 " updating the configuration with"
3445 GOTO(end, rc = -EINVAL);
3447 if (memcmp(ptr, PARAM_LLITE, strlen(PARAM_LLITE)) == 0) {
3448 rc = name_create(&cname, mti->mti_fsname, "-client");
3449 /* Add the client type to match the obdname in
3450 class_config_llog_handler */
3451 } else if (mti->mti_flags & LDD_F_SV_TYPE_MDT) {
3452 rc = name_create(&cname, mti->mti_svname, "-mdc");
3453 } else if (mti->mti_flags & LDD_F_SV_TYPE_OST) {
3454 rc = name_create(&cname, mti->mti_svname, "-osc");
3456 GOTO(end, rc = -EINVAL);
3461 /* Forbid direct update of llite root squash parameters.
3462 * These parameters are indirectly set via the MDT settings.
3464 if ((class_match_param(ptr, PARAM_LLITE, &tmp) == 0) &&
3465 ((memcmp(tmp, "root_squash=", 12) == 0) ||
3466 (memcmp(tmp, "nosquash_nids=", 14) == 0))) {
3467 LCONSOLE_ERROR("%s: root squash parameters can only "
3468 "be updated through MDT component\n",
3470 name_destroy(&cname);
3471 GOTO(end, rc = -EINVAL);
3474 CDEBUG(D_MGS, "%.3s param %s\n", ptr, ptr + 4);
3477 rc = name_create(&logname, mti->mti_fsname, "-client");
3479 name_destroy(&cname);
3482 rc = mgs_wlp_lcfg(env, mgs, fsdb, mti, logname, &mgi->mgi_bufs,
3485 /* osc params affect the MDT as well */
3486 if (!rc && (mti->mti_flags & LDD_F_SV_TYPE_OST)) {
3489 for (i = 0; i < INDEX_MAP_SIZE * 8; i++){
3490 if (!test_bit(i, fsdb->fsdb_mdt_index_map))
3492 name_destroy(&cname);
3493 rc = name_create_mdt_osc(&cname, mti->mti_svname,
3495 name_destroy(&logname);
3498 rc = name_create_mdt(&logname,
3499 mti->mti_fsname, i);
3502 if (!mgs_log_is_empty(env, mgs, logname)) {
3503 rc = mgs_wlp_lcfg(env, mgs, fsdb,
3513 /* For mdc activate/deactivate, it affects OSP on MDT as well */
3514 if (class_match_param(ptr, PARAM_MDC PARAM_ACTIVE, &tmp) == 0 &&
3517 char *lodname = NULL;
3518 char *param_str = NULL;
3522 /* replace mdc with osp */
3523 memcpy(ptr, PARAM_OSP, strlen(PARAM_OSP));
3524 rc = server_name2index(mti->mti_svname, &index, NULL);
3526 memcpy(ptr, PARAM_MDC, strlen(PARAM_MDC));
3530 for (i = 0; i < INDEX_MAP_SIZE * 8; i++) {
3531 if (!test_bit(i, fsdb->fsdb_mdt_index_map))
3537 name_destroy(&logname);
3538 rc = name_create_mdt(&logname, mti->mti_fsname,
3543 if (mgs_log_is_empty(env, mgs, logname))
3546 snprintf(suffix, sizeof(suffix), "-osp-MDT%04x",
3548 name_destroy(&cname);
3549 rc = name_create(&cname, mti->mti_svname,
3554 rc = mgs_wlp_lcfg(env, mgs, fsdb, mti, logname,
3555 &mgi->mgi_bufs, cname, ptr);
3559 /* Add configuration log for noitfying LOD
3560 * to active/deactive the OSP. */
3561 name_destroy(¶m_str);
3562 rc = name_create(¶m_str, cname,
3563 (*tmp == '0') ? ".active=0" :
3568 name_destroy(&lodname);
3569 rc = name_create(&lodname, logname, "-mdtlov");
3573 rc = mgs_wlp_lcfg(env, mgs, fsdb, mti, logname,
3574 &mgi->mgi_bufs, lodname,
3579 memcpy(ptr, PARAM_MDC, strlen(PARAM_MDC));
3580 name_destroy(&lodname);
3581 name_destroy(¶m_str);
3584 name_destroy(&logname);
3585 name_destroy(&cname);
3589 /* All mdt. params in proc */
3590 if (class_match_param(ptr, PARAM_MDT, &tmp) == 0) {
3594 CDEBUG(D_MGS, "%.3s param %s\n", ptr, ptr + 4);
3595 if (strncmp(mti->mti_svname, mti->mti_fsname,
3596 MTI_NAME_MAXLEN) == 0)
3597 /* device is unspecified completely? */
3598 rc = LDD_F_SV_TYPE_MDT | LDD_F_SV_ALL;
3600 rc = server_name2index(mti->mti_svname, &idx, NULL);
3603 if ((rc & LDD_F_SV_TYPE_MDT) == 0)
3605 if (rc & LDD_F_SV_ALL) {
3606 for (i = 0; i < INDEX_MAP_SIZE * 8; i++) {
3608 fsdb->fsdb_mdt_index_map))
3610 rc = name_create_mdt(&logname,
3611 mti->mti_fsname, i);
3614 rc = mgs_wlp_lcfg(env, mgs, fsdb, mti,
3615 logname, &mgi->mgi_bufs,
3617 name_destroy(&logname);
3622 if ((memcmp(tmp, "root_squash=", 12) == 0) ||
3623 (memcmp(tmp, "nosquash_nids=", 14) == 0)) {
3624 LCONSOLE_ERROR("%s: root squash parameters "
3625 "cannot be applied to a single MDT\n",
3627 GOTO(end, rc = -EINVAL);
3629 rc = mgs_wlp_lcfg(env, mgs, fsdb, mti,
3630 mti->mti_svname, &mgi->mgi_bufs,
3631 mti->mti_svname, ptr);
3636 /* root squash settings are also applied to llite
3637 * config log (see LU-1778) */
3639 ((memcmp(tmp, "root_squash=", 12) == 0) ||
3640 (memcmp(tmp, "nosquash_nids=", 14) == 0))) {
3644 rc = name_create(&cname, mti->mti_fsname, "-client");
3647 rc = name_create(&logname, mti->mti_fsname, "-client");
3649 name_destroy(&cname);
3652 rc = name_create(&ptr2, PARAM_LLITE, tmp);
3654 name_destroy(&cname);
3655 name_destroy(&logname);
3658 rc = mgs_wlp_lcfg(env, mgs, fsdb, mti, logname,
3659 &mgi->mgi_bufs, cname, ptr2);
3660 name_destroy(&ptr2);
3661 name_destroy(&logname);
3662 name_destroy(&cname);
3667 /* All mdd., ost. and osd. params in proc */
3668 if ((class_match_param(ptr, PARAM_MDD, NULL) == 0) ||
3669 (class_match_param(ptr, PARAM_OST, NULL) == 0) ||
3670 (class_match_param(ptr, PARAM_OSD, NULL) == 0)) {
3671 CDEBUG(D_MGS, "%.3s param %s\n", ptr, ptr + 4);
3672 if (mgs_log_is_empty(env, mgs, mti->mti_svname))
3673 GOTO(end, rc = -ENODEV);
3675 rc = mgs_wlp_lcfg(env, mgs, fsdb, mti, mti->mti_svname,
3676 &mgi->mgi_bufs, mti->mti_svname, ptr);
3680 LCONSOLE_WARN("Ignoring unrecognized param '%s'\n", ptr);
3685 CERROR("err %d on param '%s'\n", rc, ptr);
3690 /* Not implementing automatic failover nid addition at this time. */
3691 int mgs_check_failnid(const struct lu_env *env, struct mgs_device *mgs,
3692 struct mgs_target_info *mti)
3699 rc = mgs_find_or_make_fsdb(obd, fsname, &fsdb);
3703 if (mgs_log_is_empty(obd, mti->mti_svname))
3704 /* should never happen */
3707 CDEBUG(D_MGS, "Checking for new failnids for %s\n", mti->mti_svname);
3709 /* FIXME We can just check mti->params to see if we're already in
3710 the failover list. Modify mti->params for rewriting back at
3711 server_register_target(). */
3713 mutex_lock(&fsdb->fsdb_mutex);
3714 rc = mgs_write_log_add_failnid(obd, fsdb, mti);
3715 mutex_unlock(&fsdb->fsdb_mutex);
3724 int mgs_write_log_target(const struct lu_env *env, struct mgs_device *mgs,
3725 struct mgs_target_info *mti, struct fs_db *fsdb)
3732 /* set/check the new target index */
3733 rc = mgs_set_index(env, mgs, mti);
3737 if (rc == EALREADY) {
3738 LCONSOLE_WARN("Found index %d for %s, updating log\n",
3739 mti->mti_stripe_index, mti->mti_svname);
3740 /* We would like to mark old log sections as invalid
3741 and add new log sections in the client and mdt logs.
3742 But if we add new sections, then live clients will
3743 get repeat setup instructions for already running
3744 osc's. So don't update the client/mdt logs. */
3745 mti->mti_flags &= ~LDD_F_UPDATE;
3749 mutex_lock(&fsdb->fsdb_mutex);
3751 if (mti->mti_flags &
3752 (LDD_F_VIRGIN | LDD_F_UPGRADE14 | LDD_F_WRITECONF)) {
3753 /* Generate a log from scratch */
3754 if (mti->mti_flags & LDD_F_SV_TYPE_MDT) {
3755 rc = mgs_write_log_mdt(env, mgs, fsdb, mti);
3756 } else if (mti->mti_flags & LDD_F_SV_TYPE_OST) {
3757 rc = mgs_write_log_ost(env, mgs, fsdb, mti);
3759 CERROR("Unknown target type %#x, can't create log for "
3760 "%s\n", mti->mti_flags, mti->mti_svname);
3763 CERROR("Can't write logs for %s (%d)\n",
3764 mti->mti_svname, rc);
3768 /* Just update the params from tunefs in mgs_write_log_params */
3769 CDEBUG(D_MGS, "Update params for %s\n", mti->mti_svname);
3770 mti->mti_flags |= LDD_F_PARAM;
3773 /* allocate temporary buffer, where class_get_next_param will
3774 make copy of a current parameter */
3775 OBD_ALLOC(buf, strlen(mti->mti_params) + 1);
3777 GOTO(out_up, rc = -ENOMEM);
3778 params = mti->mti_params;
3779 while (params != NULL) {
3780 rc = class_get_next_param(¶ms, buf);
3783 /* there is no next parameter, that is
3788 CDEBUG(D_MGS, "remaining string: '%s', param: '%s'\n",
3790 rc = mgs_write_log_param(env, mgs, fsdb, mti, buf);
3795 OBD_FREE(buf, strlen(mti->mti_params) + 1);
3798 mutex_unlock(&fsdb->fsdb_mutex);
3802 int mgs_erase_log(const struct lu_env *env, struct mgs_device *mgs, char *name)
3804 struct llog_ctxt *ctxt;
3807 ctxt = llog_get_context(mgs->mgs_obd, LLOG_CONFIG_ORIG_CTXT);
3809 CERROR("%s: MGS config context doesn't exist\n",
3810 mgs->mgs_obd->obd_name);
3813 rc = llog_erase(env, ctxt, NULL, name);
3814 /* llog may not exist */
3817 llog_ctxt_put(ctxt);
3821 CERROR("%s: failed to clear log %s: %d\n",
3822 mgs->mgs_obd->obd_name, name, rc);
3827 /* erase all logs for the given fs */
3828 int mgs_erase_logs(const struct lu_env *env, struct mgs_device *mgs, char *fsname)
3831 struct list_head log_list;
3832 struct mgs_direntry *dirent, *n;
3833 int rc, len = strlen(fsname);
3837 /* Find all the logs in the CONFIGS directory */
3838 rc = class_dentry_readdir(env, mgs, &log_list);
3842 mutex_lock(&mgs->mgs_mutex);
3844 /* Delete the fs db */
3845 fsdb = mgs_find_fsdb(mgs, fsname);
3847 mgs_free_fsdb(mgs, fsdb);
3849 mutex_unlock(&mgs->mgs_mutex);
3851 list_for_each_entry_safe(dirent, n, &log_list, mde_list) {
3852 list_del_init(&dirent->mde_list);
3853 suffix = strrchr(dirent->mde_name, '-');
3854 if (suffix != NULL) {
3855 if ((len == suffix - dirent->mde_name) &&
3856 (strncmp(fsname, dirent->mde_name, len) == 0)) {
3857 CDEBUG(D_MGS, "Removing log %s\n",
3859 mgs_erase_log(env, mgs, dirent->mde_name);
3862 mgs_direntry_free(dirent);
3868 /* list all logs for the given fs */
3869 int mgs_list_logs(const struct lu_env *env, struct mgs_device *mgs,
3870 struct obd_ioctl_data *data)
3872 struct list_head log_list;
3873 struct mgs_direntry *dirent, *n;
3879 /* Find all the logs in the CONFIGS directory */
3880 rc = class_dentry_readdir(env, mgs, &log_list);
3884 out = data->ioc_bulk;
3885 remains = data->ioc_inllen1;
3886 list_for_each_entry_safe(dirent, n, &log_list, mde_list) {
3887 list_del_init(&dirent->mde_list);
3888 suffix = strrchr(dirent->mde_name, '-');
3889 if (suffix != NULL) {
3890 l = snprintf(out, remains, "config log: $%s\n",
3895 mgs_direntry_free(dirent);
3902 /* from llog_swab */
3903 static void print_lustre_cfg(struct lustre_cfg *lcfg)
3908 CDEBUG(D_MGS, "lustre_cfg: %p\n", lcfg);
3909 CDEBUG(D_MGS, "\tlcfg->lcfg_version: %#x\n", lcfg->lcfg_version);
3911 CDEBUG(D_MGS, "\tlcfg->lcfg_command: %#x\n", lcfg->lcfg_command);
3912 CDEBUG(D_MGS, "\tlcfg->lcfg_num: %#x\n", lcfg->lcfg_num);
3913 CDEBUG(D_MGS, "\tlcfg->lcfg_flags: %#x\n", lcfg->lcfg_flags);
3914 CDEBUG(D_MGS, "\tlcfg->lcfg_nid: %s\n", libcfs_nid2str(lcfg->lcfg_nid));
3916 CDEBUG(D_MGS, "\tlcfg->lcfg_bufcount: %d\n", lcfg->lcfg_bufcount);
3917 if (lcfg->lcfg_bufcount < LUSTRE_CFG_MAX_BUFCOUNT)
3918 for (i = 0; i < lcfg->lcfg_bufcount; i++) {
3919 CDEBUG(D_MGS, "\tlcfg->lcfg_buflens[%d]: %d %s\n",
3920 i, lcfg->lcfg_buflens[i],
3921 lustre_cfg_string(lcfg, i));
3926 /* Setup _mgs fsdb and log
3928 int mgs__mgs_fsdb_setup(const struct lu_env *env, struct mgs_device *mgs,
3934 rc = mgs_find_or_make_fsdb(env, mgs, MGSSELF_NAME, &fsdb);
3939 /* Setup params fsdb and log
3941 int mgs_params_fsdb_setup(const struct lu_env *env, struct mgs_device *mgs,
3944 struct llog_handle *params_llh = NULL;
3948 rc = mgs_find_or_make_fsdb(env, mgs, PARAMS_FILENAME, &fsdb);
3950 mutex_lock(&fsdb->fsdb_mutex);
3951 rc = record_start_log(env, mgs, ¶ms_llh, PARAMS_FILENAME);
3953 rc = record_end_log(env, ¶ms_llh);
3954 mutex_unlock(&fsdb->fsdb_mutex);
3960 /* Cleanup params fsdb and log
3962 int mgs_params_fsdb_cleanup(const struct lu_env *env, struct mgs_device *mgs)
3964 return mgs_erase_logs(env, mgs, PARAMS_FILENAME);
3967 /* Set a permanent (config log) param for a target or fs
3968 * \param lcfg buf0 may contain the device (testfs-MDT0000) name
3969 * buf1 contains the single parameter
3971 int mgs_setparam(const struct lu_env *env, struct mgs_device *mgs,
3972 struct lustre_cfg *lcfg, char *fsname)
3975 struct mgs_target_info *mti;
3976 char *devname, *param;
3983 print_lustre_cfg(lcfg);
3985 /* lustre, lustre-mdtlov, lustre-client, lustre-MDT0000 */
3986 devname = lustre_cfg_string(lcfg, 0);
3987 param = lustre_cfg_string(lcfg, 1);
3989 /* Assume device name embedded in param:
3990 lustre-OST0000.osc.max_dirty_mb=32 */
3991 ptr = strchr(param, '.');
3999 LCONSOLE_ERROR_MSG(0x14d, "No target specified: %s\n", param);
4003 rc = mgs_parse_devname(devname, fsname, NULL);
4004 if (rc == 0 && !mgs_parse_devname(devname, NULL, &index)) {
4005 /* param related to llite isn't allowed to set by OST or MDT */
4006 if (rc == 0 && strncmp(param, PARAM_LLITE,
4007 sizeof(PARAM_LLITE) - 1) == 0)
4010 /* assume devname is the fsname */
4011 strlcpy(fsname, devname, MTI_NAME_MAXLEN);
4013 CDEBUG(D_MGS, "setparam fs='%s' device='%s'\n", fsname, devname);
4015 rc = mgs_find_or_make_fsdb(env, mgs,
4016 lcfg->lcfg_command == LCFG_SET_PARAM ?
4017 PARAMS_FILENAME : fsname, &fsdb);
4021 if (lcfg->lcfg_command != LCFG_SET_PARAM &&
4022 !test_bit(FSDB_MGS_SELF, &fsdb->fsdb_flags) &&
4023 test_bit(FSDB_LOG_EMPTY, &fsdb->fsdb_flags)) {
4024 CERROR("No filesystem targets for %s. cfg_device from lctl "
4025 "is '%s'\n", fsname, devname);
4026 mgs_free_fsdb(mgs, fsdb);
4030 /* Create a fake mti to hold everything */
4033 GOTO(out, rc = -ENOMEM);
4034 if (strlcpy(mti->mti_fsname, fsname, sizeof(mti->mti_fsname))
4035 >= sizeof(mti->mti_fsname))
4036 GOTO(out, rc = -E2BIG);
4037 if (strlcpy(mti->mti_svname, devname, sizeof(mti->mti_svname))
4038 >= sizeof(mti->mti_svname))
4039 GOTO(out, rc = -E2BIG);
4040 if (strlcpy(mti->mti_params, param, sizeof(mti->mti_params))
4041 >= sizeof(mti->mti_params))
4042 GOTO(out, rc = -E2BIG);
4043 rc = server_name2index(mti->mti_svname, &mti->mti_stripe_index, &tmp);
4045 /* Not a valid server; may be only fsname */
4048 /* Strip -osc or -mdc suffix from svname */
4049 if (server_make_name(rc, mti->mti_stripe_index, mti->mti_fsname,
4051 GOTO(out, rc = -EINVAL);
4053 * Revoke lock so everyone updates. Should be alright if
4054 * someone was already reading while we were updating the logs,
4055 * so we don't really need to hold the lock while we're
4058 if (lcfg->lcfg_command == LCFG_SET_PARAM) {
4059 mti->mti_flags = rc | LDD_F_PARAM2;
4060 mutex_lock(&fsdb->fsdb_mutex);
4061 rc = mgs_write_log_param2(env, mgs, fsdb, mti, mti->mti_params);
4062 mutex_unlock(&fsdb->fsdb_mutex);
4063 mgs_revoke_lock(mgs, fsdb, CONFIG_T_PARAMS);
4065 mti->mti_flags = rc | LDD_F_PARAM;
4066 mutex_lock(&fsdb->fsdb_mutex);
4067 rc = mgs_write_log_param(env, mgs, fsdb, mti, mti->mti_params);
4068 mutex_unlock(&fsdb->fsdb_mutex);
4069 mgs_revoke_lock(mgs, fsdb, CONFIG_T_CONFIG);
4077 static int mgs_write_log_pool(const struct lu_env *env,
4078 struct mgs_device *mgs, char *logname,
4079 struct fs_db *fsdb, char *tgtname,
4080 enum lcfg_command_type cmd,
4081 char *fsname, char *poolname,
4082 char *ostname, char *comment)
4084 struct llog_handle *llh = NULL;
4087 rc = record_start_log(env, mgs, &llh, logname);
4090 rc = record_marker(env, llh, fsdb, CM_START, tgtname, comment);
4093 rc = record_base(env, llh, tgtname, 0, cmd,
4094 fsname, poolname, ostname, NULL);
4097 rc = record_marker(env, llh, fsdb, CM_END, tgtname, comment);
4099 record_end_log(env, &llh);
4103 int mgs_nodemap_cmd(const struct lu_env *env, struct mgs_device *mgs,
4104 enum lcfg_command_type cmd, const char *nodemap_name,
4115 case LCFG_NODEMAP_ADD:
4116 rc = nodemap_add(nodemap_name);
4118 case LCFG_NODEMAP_DEL:
4119 rc = nodemap_del(nodemap_name);
4121 case LCFG_NODEMAP_ADD_RANGE:
4122 rc = nodemap_parse_range(param, nid);
4125 rc = nodemap_add_range(nodemap_name, nid);
4127 case LCFG_NODEMAP_DEL_RANGE:
4128 rc = nodemap_parse_range(param, nid);
4131 rc = nodemap_del_range(nodemap_name, nid);
4133 case LCFG_NODEMAP_ADMIN:
4134 bool_switch = simple_strtoul(param, NULL, 10);
4135 rc = nodemap_set_allow_root(nodemap_name, bool_switch);
4137 case LCFG_NODEMAP_TRUSTED:
4138 bool_switch = simple_strtoul(param, NULL, 10);
4139 rc = nodemap_set_trust_client_ids(nodemap_name, bool_switch);
4141 case LCFG_NODEMAP_SQUASH_UID:
4142 int_id = simple_strtoul(param, NULL, 10);
4143 rc = nodemap_set_squash_uid(nodemap_name, int_id);
4145 case LCFG_NODEMAP_SQUASH_GID:
4146 int_id = simple_strtoul(param, NULL, 10);
4147 rc = nodemap_set_squash_gid(nodemap_name, int_id);
4149 case LCFG_NODEMAP_ADD_UIDMAP:
4150 case LCFG_NODEMAP_ADD_GIDMAP:
4151 rc = nodemap_parse_idmap(param, idmap);
4154 if (cmd == LCFG_NODEMAP_ADD_UIDMAP)
4155 rc = nodemap_add_idmap(nodemap_name, NODEMAP_UID,
4158 rc = nodemap_add_idmap(nodemap_name, NODEMAP_GID,
4161 case LCFG_NODEMAP_DEL_UIDMAP:
4162 case LCFG_NODEMAP_DEL_GIDMAP:
4163 rc = nodemap_parse_idmap(param, idmap);
4166 if (cmd == LCFG_NODEMAP_DEL_UIDMAP)
4167 rc = nodemap_del_idmap(nodemap_name, NODEMAP_UID,
4170 rc = nodemap_del_idmap(nodemap_name, NODEMAP_GID,
4180 int mgs_pool_cmd(const struct lu_env *env, struct mgs_device *mgs,
4181 enum lcfg_command_type cmd, char *fsname,
4182 char *poolname, char *ostname)
4187 char *label = NULL, *canceled_label = NULL;
4189 struct mgs_target_info *mti = NULL;
4193 rc = mgs_find_or_make_fsdb(env, mgs, fsname, &fsdb);
4195 CERROR("Can't get db for %s\n", fsname);
4198 if (test_bit(FSDB_LOG_EMPTY, &fsdb->fsdb_flags)) {
4199 CERROR("%s is not defined\n", fsname);
4200 mgs_free_fsdb(mgs, fsdb);
4204 label_sz = 10 + strlen(fsname) + strlen(poolname);
4206 /* check if ostname match fsname */
4207 if (ostname != NULL) {
4210 ptr = strrchr(ostname, '-');
4211 if ((ptr == NULL) ||
4212 (strncmp(fsname, ostname, ptr-ostname) != 0))
4214 label_sz += strlen(ostname);
4217 OBD_ALLOC(label, label_sz);
4224 "new %s.%s", fsname, poolname);
4228 "add %s.%s.%s", fsname, poolname, ostname);
4231 OBD_ALLOC(canceled_label, label_sz);
4232 if (canceled_label == NULL)
4233 GOTO(out_label, rc = -ENOMEM);
4235 "rem %s.%s.%s", fsname, poolname, ostname);
4236 sprintf(canceled_label,
4237 "add %s.%s.%s", fsname, poolname, ostname);
4240 OBD_ALLOC(canceled_label, label_sz);
4241 if (canceled_label == NULL)
4242 GOTO(out_label, rc = -ENOMEM);
4244 "del %s.%s", fsname, poolname);
4245 sprintf(canceled_label,
4246 "new %s.%s", fsname, poolname);
4252 if (canceled_label != NULL) {
4255 GOTO(out_cancel, rc = -ENOMEM);
4258 mutex_lock(&fsdb->fsdb_mutex);
4259 /* write pool def to all MDT logs */
4260 for (i = 0; i < INDEX_MAP_SIZE * 8; i++) {
4261 if (test_bit(i, fsdb->fsdb_mdt_index_map)) {
4262 rc = name_create_mdt_and_lov(&logname, &lovname,
4265 mutex_unlock(&fsdb->fsdb_mutex);
4268 if (canceled_label != NULL) {
4269 strcpy(mti->mti_svname, "lov pool");
4270 rc = mgs_modify(env, mgs, fsdb, mti, logname,
4271 lovname, canceled_label,
4276 rc = mgs_write_log_pool(env, mgs, logname,
4280 name_destroy(&logname);
4281 name_destroy(&lovname);
4283 mutex_unlock(&fsdb->fsdb_mutex);
4289 rc = name_create(&logname, fsname, "-client");
4291 mutex_unlock(&fsdb->fsdb_mutex);
4294 if (canceled_label != NULL) {
4295 rc = mgs_modify(env, mgs, fsdb, mti, logname,
4296 fsdb->fsdb_clilov, canceled_label, CM_SKIP);
4298 mutex_unlock(&fsdb->fsdb_mutex);
4299 name_destroy(&logname);
4304 rc = mgs_write_log_pool(env, mgs, logname, fsdb, fsdb->fsdb_clilov,
4305 cmd, fsname, poolname, ostname, label);
4306 mutex_unlock(&fsdb->fsdb_mutex);
4307 name_destroy(&logname);
4308 /* request for update */
4309 mgs_revoke_lock(mgs, fsdb, CONFIG_T_CONFIG);
4316 if (canceled_label != NULL)
4317 OBD_FREE(canceled_label, label_sz);
4319 OBD_FREE(label, label_sz);