4 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License version 2 only,
8 * as published by the Free Software Foundation.
10 * This program is distributed in the hope that it will be useful, but
11 * WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * General Public License version 2 for more details (a copy is included
14 * in the LICENSE file that accompanied this code).
16 * You should have received a copy of the GNU General Public License
17 * version 2 along with this program; If not, see
18 * http://www.sun.com/software/products/lustre/docs/GPLv2.pdf
20 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
21 * CA 95054 USA or visit www.sun.com if you need additional information or
27 * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved.
28 * Use is subject to license terms.
30 * Copyright (c) 2011, 2015, Intel Corporation.
33 * This file is part of Lustre, http://www.lustre.org/
34 * Lustre is a trademark of Sun Microsystems, Inc.
36 * lustre/mgs/mgs_llog.c
38 * Lustre Management Server (mgs) config llog creation
40 * Author: Nathan Rutman <nathan@clusterfs.com>
41 * Author: Alex Zhuravlev <bzzz@whamcloud.com>
42 * Author: Mikhail Pershin <tappro@whamcloud.com>
45 #define DEBUG_SUBSYSTEM S_MGS
46 #define D_MGS D_CONFIG
49 #include <lustre_ioctl.h>
50 #include <lustre_param.h>
51 #include <lustre_sec.h>
52 #include <lustre_quota.h>
54 #include "mgs_internal.h"
56 /********************** Class functions ********************/
58 /* Find all logs in CONFIG directory and link then into list */
59 int class_dentry_readdir(const struct lu_env *env,
60 struct mgs_device *mgs, struct list_head *log_list)
62 struct dt_object *dir = mgs->mgs_configs_dir;
63 const struct dt_it_ops *iops;
65 struct mgs_direntry *de;
69 INIT_LIST_HEAD(log_list);
72 LASSERT(dir->do_index_ops);
74 iops = &dir->do_index_ops->dio_it;
75 it = iops->init(env, dir, LUDA_64BITHASH);
79 rc = iops->load(env, it, 0);
85 key = (void *)iops->key(env, it);
87 CERROR("%s: key failed when listing %s: rc = %d\n",
88 mgs->mgs_obd->obd_name, MOUNT_CONFIGS_DIR,
92 key_sz = iops->key_size(env, it);
95 /* filter out "." and ".." entries */
99 if (key_sz == 2 && key[1] == '.')
103 de = mgs_direntry_alloc(key_sz + 1);
109 memcpy(de->mde_name, key, key_sz);
110 de->mde_name[key_sz] = 0;
112 list_add(&de->mde_list, log_list);
115 rc = iops->next(env, it);
124 CERROR("%s: key failed when listing %s: rc = %d\n",
125 mgs->mgs_obd->obd_name, MOUNT_CONFIGS_DIR, rc);
129 /******************** DB functions *********************/
131 static inline int name_create(char **newname, char *prefix, char *suffix)
134 OBD_ALLOC(*newname, strlen(prefix) + strlen(suffix) + 1);
137 sprintf(*newname, "%s%s", prefix, suffix);
141 static inline void name_destroy(char **name)
144 OBD_FREE(*name, strlen(*name) + 1);
148 struct mgs_fsdb_handler_data
154 /* from the (client) config log, figure out:
155 1. which ost's/mdt's are configured (by index)
156 2. what the last config step is
157 3. COMPAT_18 osc name
159 /* It might be better to have a separate db file, instead of parsing the info
160 out of the client log. This is slow and potentially error-prone. */
161 static int mgs_fsdb_handler(const struct lu_env *env, struct llog_handle *llh,
162 struct llog_rec_hdr *rec, void *data)
164 struct mgs_fsdb_handler_data *d = data;
165 struct fs_db *fsdb = d->fsdb;
166 int cfg_len = rec->lrh_len;
167 char *cfg_buf = (char*) (rec + 1);
168 struct lustre_cfg *lcfg;
173 if (rec->lrh_type != OBD_CFG_REC) {
174 CERROR("unhandled lrh_type: %#x\n", rec->lrh_type);
178 rc = lustre_cfg_sanity_check(cfg_buf, cfg_len);
180 CERROR("Insane cfg\n");
184 lcfg = (struct lustre_cfg *)cfg_buf;
186 CDEBUG(D_INFO, "cmd %x %s %s\n", lcfg->lcfg_command,
187 lustre_cfg_string(lcfg, 0), lustre_cfg_string(lcfg, 1));
189 /* Figure out ost indicies */
190 /* lov_modify_tgts add 0:lov1 1:ost1_UUID 2(index):0 3(gen):1 */
191 if (lcfg->lcfg_command == LCFG_LOV_ADD_OBD ||
192 lcfg->lcfg_command == LCFG_LOV_DEL_OBD) {
193 index = simple_strtoul(lustre_cfg_string(lcfg, 2),
195 CDEBUG(D_MGS, "OST index for %s is %u (%s)\n",
196 lustre_cfg_string(lcfg, 1), index,
197 lustre_cfg_string(lcfg, 2));
198 set_bit(index, fsdb->fsdb_ost_index_map);
201 /* Figure out mdt indicies */
202 /* attach 0:MDC_uml1_mdsA_MNT_client 1:mdc 2:1d834_MNT_client_03f */
203 if ((lcfg->lcfg_command == LCFG_ATTACH) &&
204 (strcmp(lustre_cfg_string(lcfg, 1), LUSTRE_MDC_NAME) == 0)) {
205 rc = server_name2index(lustre_cfg_string(lcfg, 0),
207 if (rc != LDD_F_SV_TYPE_MDT) {
208 CWARN("Unparsable MDC name %s, assuming index 0\n",
209 lustre_cfg_string(lcfg, 0));
213 CDEBUG(D_MGS, "MDT index is %u\n", index);
214 set_bit(index, fsdb->fsdb_mdt_index_map);
215 fsdb->fsdb_mdt_count ++;
219 * figure out the old config. fsdb_gen = 0 means old log
220 * It is obsoleted and not supported anymore
222 if (fsdb->fsdb_gen == 0) {
223 CERROR("Old config format is not supported\n");
228 * compat to 1.8, check osc name used by MDT0 to OSTs, bz18548.
230 if (!test_bit(FSDB_OSCNAME18, &fsdb->fsdb_flags) &&
231 lcfg->lcfg_command == LCFG_ATTACH &&
232 strcmp(lustre_cfg_string(lcfg, 1), LUSTRE_OSC_NAME) == 0) {
233 if (OBD_OCD_VERSION_MAJOR(d->ver) == 1 &&
234 OBD_OCD_VERSION_MINOR(d->ver) <= 8) {
235 CWARN("MDT using 1.8 OSC name scheme\n");
236 set_bit(FSDB_OSCNAME18, &fsdb->fsdb_flags);
240 if (lcfg->lcfg_command == LCFG_MARKER) {
241 struct cfg_marker *marker;
242 marker = lustre_cfg_buf(lcfg, 1);
244 d->ver = marker->cm_vers;
246 /* Keep track of the latest marker step */
247 fsdb->fsdb_gen = max(fsdb->fsdb_gen, marker->cm_step);
253 /* fsdb->fsdb_mutex is already held in mgs_find_or_make_fsdb*/
254 static int mgs_get_fsdb_from_llog(const struct lu_env *env,
255 struct mgs_device *mgs,
259 struct llog_handle *loghandle;
260 struct llog_ctxt *ctxt;
261 struct mgs_fsdb_handler_data d = { fsdb, 0 };
266 ctxt = llog_get_context(mgs->mgs_obd, LLOG_CONFIG_ORIG_CTXT);
267 LASSERT(ctxt != NULL);
268 rc = name_create(&logname, fsdb->fsdb_name, "-client");
271 rc = llog_open_create(env, ctxt, &loghandle, NULL, logname);
275 rc = llog_init_handle(env, loghandle, LLOG_F_IS_PLAIN, NULL);
279 if (llog_get_size(loghandle) <= 1)
280 set_bit(FSDB_LOG_EMPTY, &fsdb->fsdb_flags);
282 rc = llog_process(env, loghandle, mgs_fsdb_handler, (void *)&d, NULL);
283 CDEBUG(D_INFO, "get_db = %d\n", rc);
285 llog_close(env, loghandle);
287 name_destroy(&logname);
294 static void mgs_free_fsdb_srpc(struct fs_db *fsdb)
296 struct mgs_tgt_srpc_conf *tgtconf;
298 /* free target-specific rules */
299 while (fsdb->fsdb_srpc_tgt) {
300 tgtconf = fsdb->fsdb_srpc_tgt;
301 fsdb->fsdb_srpc_tgt = tgtconf->mtsc_next;
303 LASSERT(tgtconf->mtsc_tgt);
305 sptlrpc_rule_set_free(&tgtconf->mtsc_rset);
306 OBD_FREE(tgtconf->mtsc_tgt, strlen(tgtconf->mtsc_tgt) + 1);
307 OBD_FREE_PTR(tgtconf);
310 /* free general rules */
311 sptlrpc_rule_set_free(&fsdb->fsdb_srpc_gen);
314 struct fs_db *mgs_find_fsdb(struct mgs_device *mgs, char *fsname)
317 struct list_head *tmp;
319 list_for_each(tmp, &mgs->mgs_fs_db_list) {
320 fsdb = list_entry(tmp, struct fs_db, fsdb_list);
321 if (strcmp(fsdb->fsdb_name, fsname) == 0)
327 /* caller must hold the mgs->mgs_fs_db_lock */
328 static struct fs_db *mgs_new_fsdb(const struct lu_env *env,
329 struct mgs_device *mgs, char *fsname)
335 if (strlen(fsname) >= sizeof(fsdb->fsdb_name)) {
336 CERROR("fsname %s is too long\n", fsname);
337 RETURN(ERR_PTR(-EINVAL));
342 RETURN(ERR_PTR(-ENOMEM));
344 strcpy(fsdb->fsdb_name, fsname);
345 mutex_init(&fsdb->fsdb_mutex);
346 set_bit(FSDB_UDESC, &fsdb->fsdb_flags);
349 if (strcmp(fsname, MGSSELF_NAME) == 0) {
350 set_bit(FSDB_MGS_SELF, &fsdb->fsdb_flags);
351 fsdb->fsdb_mgs = mgs;
353 OBD_ALLOC(fsdb->fsdb_ost_index_map, INDEX_MAP_SIZE);
354 OBD_ALLOC(fsdb->fsdb_mdt_index_map, INDEX_MAP_SIZE);
355 if (!fsdb->fsdb_ost_index_map || !fsdb->fsdb_mdt_index_map) {
356 CERROR("No memory for index maps\n");
357 GOTO(err, rc = -ENOMEM);
360 rc = name_create(&fsdb->fsdb_clilov, fsname, "-clilov");
363 rc = name_create(&fsdb->fsdb_clilmv, fsname, "-clilmv");
367 /* initialise data for NID table */
368 mgs_ir_init_fs(env, mgs, fsdb);
370 lproc_mgs_add_live(mgs, fsdb);
373 list_add(&fsdb->fsdb_list, &mgs->mgs_fs_db_list);
377 if (fsdb->fsdb_ost_index_map)
378 OBD_FREE(fsdb->fsdb_ost_index_map, INDEX_MAP_SIZE);
379 if (fsdb->fsdb_mdt_index_map)
380 OBD_FREE(fsdb->fsdb_mdt_index_map, INDEX_MAP_SIZE);
381 name_destroy(&fsdb->fsdb_clilov);
382 name_destroy(&fsdb->fsdb_clilmv);
387 static void mgs_free_fsdb(struct mgs_device *mgs, struct fs_db *fsdb)
389 /* wait for anyone with the sem */
390 mutex_lock(&fsdb->fsdb_mutex);
391 lproc_mgs_del_live(mgs, fsdb);
392 list_del(&fsdb->fsdb_list);
394 /* deinitialize fsr */
395 mgs_ir_fini_fs(mgs, fsdb);
397 if (fsdb->fsdb_ost_index_map)
398 OBD_FREE(fsdb->fsdb_ost_index_map, INDEX_MAP_SIZE);
399 if (fsdb->fsdb_mdt_index_map)
400 OBD_FREE(fsdb->fsdb_mdt_index_map, INDEX_MAP_SIZE);
401 name_destroy(&fsdb->fsdb_clilov);
402 name_destroy(&fsdb->fsdb_clilmv);
403 mgs_free_fsdb_srpc(fsdb);
404 mutex_unlock(&fsdb->fsdb_mutex);
408 int mgs_init_fsdb_list(struct mgs_device *mgs)
410 INIT_LIST_HEAD(&mgs->mgs_fs_db_list);
414 int mgs_cleanup_fsdb_list(struct mgs_device *mgs)
417 struct list_head *tmp, *tmp2;
419 mutex_lock(&mgs->mgs_mutex);
420 list_for_each_safe(tmp, tmp2, &mgs->mgs_fs_db_list) {
421 fsdb = list_entry(tmp, struct fs_db, fsdb_list);
422 mgs_free_fsdb(mgs, fsdb);
424 mutex_unlock(&mgs->mgs_mutex);
428 int mgs_find_or_make_fsdb(const struct lu_env *env,
429 struct mgs_device *mgs, char *name,
436 mutex_lock(&mgs->mgs_mutex);
437 fsdb = mgs_find_fsdb(mgs, name);
439 mutex_unlock(&mgs->mgs_mutex);
444 CDEBUG(D_MGS, "Creating new db\n");
445 fsdb = mgs_new_fsdb(env, mgs, name);
446 /* lock fsdb_mutex until the db is loaded from llogs */
448 mutex_lock(&fsdb->fsdb_mutex);
449 mutex_unlock(&mgs->mgs_mutex);
451 RETURN(PTR_ERR(fsdb));
453 if (!test_bit(FSDB_MGS_SELF, &fsdb->fsdb_flags)) {
454 /* populate the db from the client llog */
455 rc = mgs_get_fsdb_from_llog(env, mgs, fsdb);
457 CERROR("Can't get db from client log %d\n", rc);
462 /* populate srpc rules from params llog */
463 rc = mgs_get_fsdb_srpc_from_llog(env, mgs, fsdb);
465 CERROR("Can't get db from params log %d\n", rc);
469 mutex_unlock(&fsdb->fsdb_mutex);
475 mutex_unlock(&fsdb->fsdb_mutex);
476 mgs_free_fsdb(mgs, fsdb);
482 -1= empty client log */
483 int mgs_check_index(const struct lu_env *env,
484 struct mgs_device *mgs,
485 struct mgs_target_info *mti)
492 LASSERT(!(mti->mti_flags & LDD_F_NEED_INDEX));
494 rc = mgs_find_or_make_fsdb(env, mgs, mti->mti_fsname, &fsdb);
496 CERROR("Can't get db for %s\n", mti->mti_fsname);
500 if (test_bit(FSDB_LOG_EMPTY, &fsdb->fsdb_flags))
503 if (mti->mti_flags & LDD_F_SV_TYPE_OST)
504 imap = fsdb->fsdb_ost_index_map;
505 else if (mti->mti_flags & LDD_F_SV_TYPE_MDT)
506 imap = fsdb->fsdb_mdt_index_map;
510 if (test_bit(mti->mti_stripe_index, imap))
515 static __inline__ int next_index(void *index_map, int map_len)
518 for (i = 0; i < map_len * 8; i++)
519 if (!test_bit(i, index_map)) {
522 CERROR("max index %d exceeded.\n", i);
527 0 newly marked as in use
529 +EALREADY for update of an old index */
530 static int mgs_set_index(const struct lu_env *env,
531 struct mgs_device *mgs,
532 struct mgs_target_info *mti)
539 rc = mgs_find_or_make_fsdb(env, mgs, mti->mti_fsname, &fsdb);
541 CERROR("Can't get db for %s\n", mti->mti_fsname);
545 mutex_lock(&fsdb->fsdb_mutex);
546 if (mti->mti_flags & LDD_F_SV_TYPE_OST) {
547 imap = fsdb->fsdb_ost_index_map;
548 } else if (mti->mti_flags & LDD_F_SV_TYPE_MDT) {
549 imap = fsdb->fsdb_mdt_index_map;
551 GOTO(out_up, rc = -EINVAL);
554 if (mti->mti_flags & LDD_F_NEED_INDEX) {
555 rc = next_index(imap, INDEX_MAP_SIZE);
557 GOTO(out_up, rc = -ERANGE);
558 mti->mti_stripe_index = rc;
559 if (mti->mti_flags & LDD_F_SV_TYPE_MDT)
560 fsdb->fsdb_mdt_count ++;
563 /* the last index(0xffff) is reserved for default value. */
564 if (mti->mti_stripe_index >= INDEX_MAP_SIZE * 8 - 1) {
565 LCONSOLE_ERROR_MSG(0x13f, "Server %s requested index %u, "
566 "but index must be less than %u.\n",
567 mti->mti_svname, mti->mti_stripe_index,
568 INDEX_MAP_SIZE * 8 - 1);
569 GOTO(out_up, rc = -ERANGE);
572 if (test_bit(mti->mti_stripe_index, imap)) {
573 if ((mti->mti_flags & LDD_F_VIRGIN) &&
574 !(mti->mti_flags & LDD_F_WRITECONF)) {
575 LCONSOLE_ERROR_MSG(0x140, "Server %s requested index "
576 "%d, but that index is already in "
577 "use. Use --writeconf to force\n",
579 mti->mti_stripe_index);
580 GOTO(out_up, rc = -EADDRINUSE);
582 CDEBUG(D_MGS, "Server %s updating index %d\n",
583 mti->mti_svname, mti->mti_stripe_index);
584 GOTO(out_up, rc = EALREADY);
588 set_bit(mti->mti_stripe_index, imap);
589 clear_bit(FSDB_LOG_EMPTY, &fsdb->fsdb_flags);
590 mutex_unlock(&fsdb->fsdb_mutex);
591 server_make_name(mti->mti_flags & ~(LDD_F_VIRGIN | LDD_F_WRITECONF),
592 mti->mti_stripe_index, mti->mti_fsname, mti->mti_svname);
594 CDEBUG(D_MGS, "Set index for %s to %d\n", mti->mti_svname,
595 mti->mti_stripe_index);
599 mutex_unlock(&fsdb->fsdb_mutex);
603 struct mgs_modify_lookup {
604 struct cfg_marker mml_marker;
608 static int mgs_modify_handler(const struct lu_env *env,
609 struct llog_handle *llh,
610 struct llog_rec_hdr *rec, void *data)
612 struct mgs_modify_lookup *mml = data;
613 struct cfg_marker *marker;
614 struct lustre_cfg *lcfg = REC_DATA(rec);
615 int cfg_len = REC_DATA_LEN(rec);
619 if (rec->lrh_type != OBD_CFG_REC) {
620 CERROR("unhandled lrh_type: %#x\n", rec->lrh_type);
624 rc = lustre_cfg_sanity_check(lcfg, cfg_len);
626 CERROR("Insane cfg\n");
630 /* We only care about markers */
631 if (lcfg->lcfg_command != LCFG_MARKER)
634 marker = lustre_cfg_buf(lcfg, 1);
635 if ((strcmp(mml->mml_marker.cm_comment, marker->cm_comment) == 0) &&
636 (strcmp(mml->mml_marker.cm_tgtname, marker->cm_tgtname) == 0) &&
637 !(marker->cm_flags & CM_SKIP)) {
638 /* Found a non-skipped marker match */
639 CDEBUG(D_MGS, "Changing rec %u marker %d %x->%x: %s %s\n",
640 rec->lrh_index, marker->cm_step,
641 marker->cm_flags, mml->mml_marker.cm_flags,
642 marker->cm_tgtname, marker->cm_comment);
643 /* Overwrite the old marker llog entry */
644 marker->cm_flags &= ~CM_EXCLUDE; /* in case we're unexcluding */
645 marker->cm_flags |= mml->mml_marker.cm_flags;
646 marker->cm_canceltime = mml->mml_marker.cm_canceltime;
647 rc = llog_write(env, llh, rec, rec->lrh_index);
656 * Modify an existing config log record (for CM_SKIP or CM_EXCLUDE)
658 * 0 - modified successfully,
659 * 1 - no modification was done
662 static int mgs_modify(const struct lu_env *env, struct mgs_device *mgs,
663 struct fs_db *fsdb, struct mgs_target_info *mti,
664 char *logname, char *devname, char *comment, int flags)
666 struct llog_handle *loghandle;
667 struct llog_ctxt *ctxt;
668 struct mgs_modify_lookup *mml;
673 LASSERT(mutex_is_locked(&fsdb->fsdb_mutex));
674 CDEBUG(D_MGS, "modify %s/%s/%s fl=%x\n", logname, devname, comment,
677 ctxt = llog_get_context(mgs->mgs_obd, LLOG_CONFIG_ORIG_CTXT);
678 LASSERT(ctxt != NULL);
679 rc = llog_open(env, ctxt, &loghandle, NULL, logname, LLOG_OPEN_EXISTS);
686 rc = llog_init_handle(env, loghandle, LLOG_F_IS_PLAIN, NULL);
690 if (llog_get_size(loghandle) <= 1)
691 GOTO(out_close, rc = 0);
695 GOTO(out_close, rc = -ENOMEM);
696 if (strlcpy(mml->mml_marker.cm_comment, comment,
697 sizeof(mml->mml_marker.cm_comment)) >=
698 sizeof(mml->mml_marker.cm_comment))
699 GOTO(out_free, rc = -E2BIG);
700 if (strlcpy(mml->mml_marker.cm_tgtname, devname,
701 sizeof(mml->mml_marker.cm_tgtname)) >=
702 sizeof(mml->mml_marker.cm_tgtname))
703 GOTO(out_free, rc = -E2BIG);
704 /* Modify mostly means cancel */
705 mml->mml_marker.cm_flags = flags;
706 mml->mml_marker.cm_canceltime = flags ? cfs_time_current_sec() : 0;
707 mml->mml_modified = 0;
708 rc = llog_process(env, loghandle, mgs_modify_handler, (void *)mml,
710 if (!rc && !mml->mml_modified)
717 llog_close(env, loghandle);
720 CERROR("%s: modify %s/%s failed: rc = %d\n",
721 mgs->mgs_obd->obd_name, mti->mti_svname, comment, rc);
726 /** This structure is passed to mgs_replace_handler */
727 struct mgs_replace_uuid_lookup {
728 /* Nids are replaced for this target device */
729 struct mgs_target_info target;
730 /* Temporary modified llog */
731 struct llog_handle *temp_llh;
732 /* Flag is set if in target block*/
733 int in_target_device;
734 /* Nids already added. Just skip (multiple nids) */
735 int device_nids_added;
736 /* Flag is set if this block should not be copied */
741 * Check: a) if block should be skipped
742 * b) is it target block
747 * \retval 0 should not to be skipped
748 * \retval 1 should to be skipped
750 static int check_markers(struct lustre_cfg *lcfg,
751 struct mgs_replace_uuid_lookup *mrul)
753 struct cfg_marker *marker;
755 /* Track markers. Find given device */
756 if (lcfg->lcfg_command == LCFG_MARKER) {
757 marker = lustre_cfg_buf(lcfg, 1);
758 /* Clean llog from records marked as CM_EXCLUDE.
759 CM_SKIP records are used for "active" command
760 and can be restored if needed */
761 if ((marker->cm_flags & (CM_EXCLUDE | CM_START)) ==
762 (CM_EXCLUDE | CM_START)) {
767 if ((marker->cm_flags & (CM_EXCLUDE | CM_END)) ==
768 (CM_EXCLUDE | CM_END)) {
773 if (strcmp(mrul->target.mti_svname, marker->cm_tgtname) == 0) {
774 LASSERT(!(marker->cm_flags & CM_START) ||
775 !(marker->cm_flags & CM_END));
776 if (marker->cm_flags & CM_START) {
777 mrul->in_target_device = 1;
778 mrul->device_nids_added = 0;
779 } else if (marker->cm_flags & CM_END)
780 mrul->in_target_device = 0;
787 static int record_base(const struct lu_env *env, struct llog_handle *llh,
788 char *cfgname, lnet_nid_t nid, int cmd,
789 char *s1, char *s2, char *s3, char *s4)
791 struct mgs_thread_info *mgi = mgs_env_info(env);
792 struct llog_cfg_rec *lcr;
795 CDEBUG(D_MGS, "lcfg %s %#x %s %s %s %s\n", cfgname,
796 cmd, s1, s2, s3, s4);
798 lustre_cfg_bufs_reset(&mgi->mgi_bufs, cfgname);
800 lustre_cfg_bufs_set_string(&mgi->mgi_bufs, 1, s1);
802 lustre_cfg_bufs_set_string(&mgi->mgi_bufs, 2, s2);
804 lustre_cfg_bufs_set_string(&mgi->mgi_bufs, 3, s3);
806 lustre_cfg_bufs_set_string(&mgi->mgi_bufs, 4, s4);
808 lcr = lustre_cfg_rec_new(cmd, &mgi->mgi_bufs);
812 lcr->lcr_cfg.lcfg_nid = nid;
813 rc = llog_write(env, llh, &lcr->lcr_hdr, LLOG_NEXT_IDX);
815 lustre_cfg_rec_free(lcr);
819 "failed to write lcfg %s %#x %s %s %s %s: rc = %d\n",
820 cfgname, cmd, s1, s2, s3, s4, rc);
824 static inline int record_add_uuid(const struct lu_env *env,
825 struct llog_handle *llh,
826 uint64_t nid, char *uuid)
828 return record_base(env, llh, NULL, nid, LCFG_ADD_UUID, uuid,
832 static inline int record_add_conn(const struct lu_env *env,
833 struct llog_handle *llh,
834 char *devname, char *uuid)
836 return record_base(env, llh, devname, 0, LCFG_ADD_CONN, uuid,
840 static inline int record_attach(const struct lu_env *env,
841 struct llog_handle *llh, char *devname,
842 char *type, char *uuid)
844 return record_base(env, llh, devname, 0, LCFG_ATTACH, type, uuid,
848 static inline int record_setup(const struct lu_env *env,
849 struct llog_handle *llh, char *devname,
850 char *s1, char *s2, char *s3, char *s4)
852 return record_base(env, llh, devname, 0, LCFG_SETUP, s1, s2, s3, s4);
856 * \retval <0 record processing error
857 * \retval n record is processed. No need copy original one.
858 * \retval 0 record is not processed.
860 static int process_command(const struct lu_env *env, struct lustre_cfg *lcfg,
861 struct mgs_replace_uuid_lookup *mrul)
868 if (lcfg->lcfg_command == LCFG_ADD_UUID) {
869 /* LCFG_ADD_UUID command found. Let's skip original command
870 and add passed nids */
871 ptr = mrul->target.mti_params;
872 while (class_parse_nid(ptr, &nid, &ptr) == 0) {
873 CDEBUG(D_MGS, "add nid %s with uuid %s, "
874 "device %s\n", libcfs_nid2str(nid),
875 mrul->target.mti_params,
876 mrul->target.mti_svname);
877 rc = record_add_uuid(env,
879 mrul->target.mti_params);
884 if (nids_added == 0) {
885 CERROR("No new nids were added, nid %s with uuid %s, "
886 "device %s\n", libcfs_nid2str(nid),
887 mrul->target.mti_params,
888 mrul->target.mti_svname);
891 mrul->device_nids_added = 1;
897 if (mrul->device_nids_added && lcfg->lcfg_command == LCFG_SETUP) {
898 /* LCFG_SETUP command found. UUID should be changed */
899 rc = record_setup(env,
901 /* devname the same */
902 lustre_cfg_string(lcfg, 0),
903 /* s1 is not changed */
904 lustre_cfg_string(lcfg, 1),
905 /* new uuid should be
907 mrul->target.mti_params,
908 /* s3 is not changed */
909 lustre_cfg_string(lcfg, 3),
910 /* s4 is not changed */
911 lustre_cfg_string(lcfg, 4));
915 /* Another commands in target device block */
920 * Handler that called for every record in llog.
921 * Records are processed in order they placed in llog.
923 * \param[in] llh log to be processed
924 * \param[in] rec current record
925 * \param[in] data mgs_replace_uuid_lookup structure
929 static int mgs_replace_handler(const struct lu_env *env,
930 struct llog_handle *llh,
931 struct llog_rec_hdr *rec,
934 struct mgs_replace_uuid_lookup *mrul;
935 struct lustre_cfg *lcfg = REC_DATA(rec);
936 int cfg_len = REC_DATA_LEN(rec);
940 mrul = (struct mgs_replace_uuid_lookup *)data;
942 if (rec->lrh_type != OBD_CFG_REC) {
943 CERROR("unhandled lrh_type: %#x, cmd %x %s %s\n",
944 rec->lrh_type, lcfg->lcfg_command,
945 lustre_cfg_string(lcfg, 0),
946 lustre_cfg_string(lcfg, 1));
950 rc = lustre_cfg_sanity_check(lcfg, cfg_len);
952 /* Do not copy any invalidated records */
953 GOTO(skip_out, rc = 0);
956 rc = check_markers(lcfg, mrul);
957 if (rc || mrul->skip_it)
958 GOTO(skip_out, rc = 0);
960 /* Write to new log all commands outside target device block */
961 if (!mrul->in_target_device)
962 GOTO(copy_out, rc = 0);
964 /* Skip all other LCFG_ADD_UUID and LCFG_ADD_CONN records
965 (failover nids) for this target, assuming that if then
966 primary is changing then so is the failover */
967 if (mrul->device_nids_added &&
968 (lcfg->lcfg_command == LCFG_ADD_UUID ||
969 lcfg->lcfg_command == LCFG_ADD_CONN))
970 GOTO(skip_out, rc = 0);
972 rc = process_command(env, lcfg, mrul);
979 /* Record is placed in temporary llog as is */
980 rc = llog_write(env, mrul->temp_llh, rec, LLOG_NEXT_IDX);
982 CDEBUG(D_MGS, "Copied idx=%d, rc=%d, len=%d, cmd %x %s %s\n",
983 rec->lrh_index, rc, rec->lrh_len, lcfg->lcfg_command,
984 lustre_cfg_string(lcfg, 0), lustre_cfg_string(lcfg, 1));
988 CDEBUG(D_MGS, "Skipped idx=%d, rc=%d, len=%d, cmd %x %s %s\n",
989 rec->lrh_index, rc, rec->lrh_len, lcfg->lcfg_command,
990 lustre_cfg_string(lcfg, 0), lustre_cfg_string(lcfg, 1));
994 static int mgs_log_is_empty(const struct lu_env *env,
995 struct mgs_device *mgs, char *name)
997 struct llog_ctxt *ctxt;
1000 ctxt = llog_get_context(mgs->mgs_obd, LLOG_CONFIG_ORIG_CTXT);
1001 LASSERT(ctxt != NULL);
1003 rc = llog_is_empty(env, ctxt, name);
1004 llog_ctxt_put(ctxt);
1008 static int mgs_replace_nids_log(const struct lu_env *env,
1009 struct obd_device *mgs, struct fs_db *fsdb,
1010 char *logname, char *devname, char *nids)
1012 struct llog_handle *orig_llh, *backup_llh;
1013 struct llog_ctxt *ctxt;
1014 struct mgs_replace_uuid_lookup *mrul;
1015 struct mgs_device *mgs_dev = lu2mgs_dev(mgs->obd_lu_dev);
1016 static struct obd_uuid cfg_uuid = { .uuid = "config_uuid" };
1021 CDEBUG(D_MGS, "Replace nids for %s in %s\n", devname, logname);
1023 ctxt = llog_get_context(mgs, LLOG_CONFIG_ORIG_CTXT);
1024 LASSERT(ctxt != NULL);
1026 if (mgs_log_is_empty(env, mgs_dev, logname)) {
1027 /* Log is empty. Nothing to replace */
1028 GOTO(out_put, rc = 0);
1031 OBD_ALLOC(backup, strlen(logname) + strlen(".bak") + 1);
1033 GOTO(out_put, rc = -ENOMEM);
1035 sprintf(backup, "%s.bak", logname);
1037 rc = llog_backup(env, mgs, ctxt, ctxt, logname, backup);
1039 /* Now erase original log file. Connections are not allowed.
1040 Backup is already saved */
1041 rc = llog_erase(env, ctxt, NULL, logname);
1044 } else if (rc != -ENOENT) {
1045 CERROR("%s: can't make backup for %s: rc = %d\n",
1046 mgs->obd_name, logname, rc);
1050 /* open local log */
1051 rc = llog_open_create(env, ctxt, &orig_llh, NULL, logname);
1053 GOTO(out_restore, rc);
1055 rc = llog_init_handle(env, orig_llh, LLOG_F_IS_PLAIN, &cfg_uuid);
1057 GOTO(out_closel, rc);
1059 /* open backup llog */
1060 rc = llog_open(env, ctxt, &backup_llh, NULL, backup,
1063 GOTO(out_closel, rc);
1065 rc = llog_init_handle(env, backup_llh, LLOG_F_IS_PLAIN, NULL);
1067 GOTO(out_close, rc);
1069 if (llog_get_size(backup_llh) <= 1)
1070 GOTO(out_close, rc = 0);
1072 OBD_ALLOC_PTR(mrul);
1074 GOTO(out_close, rc = -ENOMEM);
1075 /* devname is only needed information to replace UUID records */
1076 strlcpy(mrul->target.mti_svname, devname,
1077 sizeof(mrul->target.mti_svname));
1078 /* parse nids later */
1079 strlcpy(mrul->target.mti_params, nids, sizeof(mrul->target.mti_params));
1080 /* Copy records to this temporary llog */
1081 mrul->temp_llh = orig_llh;
1083 rc = llog_process(env, backup_llh, mgs_replace_handler,
1084 (void *)mrul, NULL);
1087 rc2 = llog_close(NULL, backup_llh);
1091 rc2 = llog_close(NULL, orig_llh);
1097 CERROR("%s: llog should be restored: rc = %d\n",
1099 rc2 = llog_backup(env, mgs, ctxt, ctxt, backup,
1102 CERROR("%s: can't restore backup %s: rc = %d\n",
1103 mgs->obd_name, logname, rc2);
1107 OBD_FREE(backup, strlen(backup) + 1);
1110 llog_ctxt_put(ctxt);
1113 CERROR("%s: failed to replace nids in log %s: rc = %d\n",
1114 mgs->obd_name, logname, rc);
1120 * Parse device name and get file system name and/or device index
1122 * \param[in] devname device name (ex. lustre-MDT0000)
1123 * \param[out] fsname file system name(optional)
1124 * \param[out] index device index(optional)
1128 static int mgs_parse_devname(char *devname, char *fsname, __u32 *index)
1133 /* Extract fsname */
1135 rc = server_name2fsname(devname, fsname, NULL);
1137 CDEBUG(D_MGS, "Device name %s without fsname\n",
1144 rc = server_name2index(devname, index, NULL);
1146 CDEBUG(D_MGS, "Device name %s with wrong index\n",
1155 /* This is only called during replace_nids */
1156 static int only_mgs_is_running(struct obd_device *mgs_obd)
1158 /* TDB: Is global variable with devices count exists? */
1159 int num_devices = get_devices_count();
1160 int num_exports = 0;
1161 struct obd_export *exp;
1163 spin_lock(&mgs_obd->obd_dev_lock);
1164 list_for_each_entry(exp, &mgs_obd->obd_exports, exp_obd_chain) {
1165 /* skip self export */
1166 if (exp == mgs_obd->obd_self_export)
1168 if (exp_connect_flags(exp) & OBD_CONNECT_MDS_MDS)
1173 CERROR("%s: node %s still connected during replace_nids "
1174 "connect_flags:%llx\n",
1176 libcfs_nid2str(exp->exp_nid_stats->nid),
1177 exp_connect_flags(exp));
1180 spin_unlock(&mgs_obd->obd_dev_lock);
1182 /* osd, MGS and MGC + self_export
1183 (wc -l /proc/fs/lustre/devices <= 2) && (non self exports == 0) */
1184 return (num_devices <= 3) && (num_exports == 0);
1187 static int name_create_mdt(char **logname, char *fsname, int i)
1191 sprintf(mdt_index, "-MDT%04x", i);
1192 return name_create(logname, fsname, mdt_index);
1196 * Replace nids for \a device to \a nids values
1198 * \param obd MGS obd device
1199 * \param devname nids need to be replaced for this device
1200 * (ex. lustre-OST0000)
1201 * \param nids nids list (ex. nid1,nid2,nid3)
1205 int mgs_replace_nids(const struct lu_env *env,
1206 struct mgs_device *mgs,
1207 char *devname, char *nids)
1209 /* Assume fsname is part of device name */
1210 char fsname[MTI_NAME_MAXLEN];
1217 struct obd_device *mgs_obd = mgs->mgs_obd;
1220 /* We can only change NIDs if no other nodes are connected */
1221 spin_lock(&mgs_obd->obd_dev_lock);
1222 conn_state = mgs_obd->obd_no_conn;
1223 mgs_obd->obd_no_conn = 1;
1224 spin_unlock(&mgs_obd->obd_dev_lock);
1226 /* We can not change nids if not only MGS is started */
1227 if (!only_mgs_is_running(mgs_obd)) {
1228 CERROR("Only MGS is allowed to be started\n");
1229 GOTO(out, rc = -EINPROGRESS);
1232 /* Get fsname and index*/
1233 rc = mgs_parse_devname(devname, fsname, &index);
1237 rc = mgs_find_or_make_fsdb(env, mgs, fsname, &fsdb);
1239 CERROR("%s: can't find fsdb: rc = %d\n", fsname, rc);
1243 /* Process client llogs */
1244 name_create(&logname, fsname, "-client");
1245 rc = mgs_replace_nids_log(env, mgs_obd, fsdb, logname, devname, nids);
1246 name_destroy(&logname);
1248 CERROR("%s: error while replacing NIDs for %s: rc = %d\n",
1249 fsname, devname, rc);
1253 /* Process MDT llogs */
1254 for (i = 0; i < INDEX_MAP_SIZE * 8; i++) {
1255 if (!test_bit(i, fsdb->fsdb_mdt_index_map))
1257 name_create_mdt(&logname, fsname, i);
1258 rc = mgs_replace_nids_log(env, mgs_obd, fsdb, logname, devname, nids);
1259 name_destroy(&logname);
1265 spin_lock(&mgs_obd->obd_dev_lock);
1266 mgs_obd->obd_no_conn = conn_state;
1267 spin_unlock(&mgs_obd->obd_dev_lock);
1272 static int record_lov_setup(const struct lu_env *env, struct llog_handle *llh,
1273 char *devname, struct lov_desc *desc)
1275 struct mgs_thread_info *mgi = mgs_env_info(env);
1276 struct llog_cfg_rec *lcr;
1279 lustre_cfg_bufs_reset(&mgi->mgi_bufs, devname);
1280 lustre_cfg_bufs_set(&mgi->mgi_bufs, 1, desc, sizeof(*desc));
1281 lcr = lustre_cfg_rec_new(LCFG_SETUP, &mgi->mgi_bufs);
1285 rc = llog_write(env, llh, &lcr->lcr_hdr, LLOG_NEXT_IDX);
1286 lustre_cfg_rec_free(lcr);
1290 static int record_lmv_setup(const struct lu_env *env, struct llog_handle *llh,
1291 char *devname, struct lmv_desc *desc)
1293 struct mgs_thread_info *mgi = mgs_env_info(env);
1294 struct llog_cfg_rec *lcr;
1297 lustre_cfg_bufs_reset(&mgi->mgi_bufs, devname);
1298 lustre_cfg_bufs_set(&mgi->mgi_bufs, 1, desc, sizeof(*desc));
1299 lcr = lustre_cfg_rec_new(LCFG_SETUP, &mgi->mgi_bufs);
1303 rc = llog_write(env, llh, &lcr->lcr_hdr, LLOG_NEXT_IDX);
1304 lustre_cfg_rec_free(lcr);
1308 static inline int record_mdc_add(const struct lu_env *env,
1309 struct llog_handle *llh,
1310 char *logname, char *mdcuuid,
1311 char *mdtuuid, char *index,
1314 return record_base(env,llh,logname,0,LCFG_ADD_MDC,
1315 mdtuuid,index,gen,mdcuuid);
1318 static inline int record_lov_add(const struct lu_env *env,
1319 struct llog_handle *llh,
1320 char *lov_name, char *ost_uuid,
1321 char *index, char *gen)
1323 return record_base(env, llh, lov_name, 0, LCFG_LOV_ADD_OBD,
1324 ost_uuid, index, gen, NULL);
1327 static inline int record_mount_opt(const struct lu_env *env,
1328 struct llog_handle *llh,
1329 char *profile, char *lov_name,
1332 return record_base(env, llh, NULL, 0, LCFG_MOUNTOPT,
1333 profile, lov_name, mdc_name, NULL);
1336 static int record_marker(const struct lu_env *env,
1337 struct llog_handle *llh,
1338 struct fs_db *fsdb, __u32 flags,
1339 char *tgtname, char *comment)
1341 struct mgs_thread_info *mgi = mgs_env_info(env);
1342 struct llog_cfg_rec *lcr;
1346 if (flags & CM_START)
1348 mgi->mgi_marker.cm_step = fsdb->fsdb_gen;
1349 mgi->mgi_marker.cm_flags = flags;
1350 mgi->mgi_marker.cm_vers = LUSTRE_VERSION_CODE;
1351 cplen = strlcpy(mgi->mgi_marker.cm_tgtname, tgtname,
1352 sizeof(mgi->mgi_marker.cm_tgtname));
1353 if (cplen >= sizeof(mgi->mgi_marker.cm_tgtname))
1355 cplen = strlcpy(mgi->mgi_marker.cm_comment, comment,
1356 sizeof(mgi->mgi_marker.cm_comment));
1357 if (cplen >= sizeof(mgi->mgi_marker.cm_comment))
1359 mgi->mgi_marker.cm_createtime = cfs_time_current_sec();
1360 mgi->mgi_marker.cm_canceltime = 0;
1361 lustre_cfg_bufs_reset(&mgi->mgi_bufs, NULL);
1362 lustre_cfg_bufs_set(&mgi->mgi_bufs, 1, &mgi->mgi_marker,
1363 sizeof(mgi->mgi_marker));
1364 lcr = lustre_cfg_rec_new(LCFG_MARKER, &mgi->mgi_bufs);
1368 rc = llog_write(env, llh, &lcr->lcr_hdr, LLOG_NEXT_IDX);
1369 lustre_cfg_rec_free(lcr);
1373 static int record_start_log(const struct lu_env *env, struct mgs_device *mgs,
1374 struct llog_handle **llh, char *name)
1376 static struct obd_uuid cfg_uuid = { .uuid = "config_uuid" };
1377 struct llog_ctxt *ctxt;
1382 GOTO(out, rc = -EBUSY);
1384 ctxt = llog_get_context(mgs->mgs_obd, LLOG_CONFIG_ORIG_CTXT);
1386 GOTO(out, rc = -ENODEV);
1387 LASSERT(ctxt->loc_obd == mgs->mgs_obd);
1389 rc = llog_open_create(env, ctxt, llh, NULL, name);
1392 rc = llog_init_handle(env, *llh, LLOG_F_IS_PLAIN, &cfg_uuid);
1394 llog_close(env, *llh);
1396 llog_ctxt_put(ctxt);
1399 CERROR("%s: can't start log %s: rc = %d\n",
1400 mgs->mgs_obd->obd_name, name, rc);
1406 static int record_end_log(const struct lu_env *env, struct llog_handle **llh)
1410 rc = llog_close(env, *llh);
1416 /******************** config "macros" *********************/
1418 /* write an lcfg directly into a log (with markers) */
1419 static int mgs_write_log_direct(const struct lu_env *env,
1420 struct mgs_device *mgs, struct fs_db *fsdb,
1421 char *logname, struct llog_cfg_rec *lcr,
1422 char *devname, char *comment)
1424 struct llog_handle *llh = NULL;
1429 rc = record_start_log(env, mgs, &llh, logname);
1433 /* FIXME These should be a single journal transaction */
1434 rc = record_marker(env, llh, fsdb, CM_START, devname, comment);
1437 rc = llog_write(env, llh, &lcr->lcr_hdr, LLOG_NEXT_IDX);
1440 rc = record_marker(env, llh, fsdb, CM_END, devname, comment);
1444 record_end_log(env, &llh);
1448 /* write the lcfg in all logs for the given fs */
1449 static int mgs_write_log_direct_all(const struct lu_env *env,
1450 struct mgs_device *mgs,
1452 struct mgs_target_info *mti,
1453 struct llog_cfg_rec *lcr, char *devname,
1454 char *comment, int server_only)
1456 struct list_head log_list;
1457 struct mgs_direntry *dirent, *n;
1458 char *fsname = mti->mti_fsname;
1459 int rc = 0, len = strlen(fsname);
1462 /* Find all the logs in the CONFIGS directory */
1463 rc = class_dentry_readdir(env, mgs, &log_list);
1467 /* Could use fsdb index maps instead of directory listing */
1468 list_for_each_entry_safe(dirent, n, &log_list, mde_list) {
1469 list_del_init(&dirent->mde_list);
1470 /* don't write to sptlrpc rule log */
1471 if (strstr(dirent->mde_name, "-sptlrpc") != NULL)
1474 /* caller wants write server logs only */
1475 if (server_only && strstr(dirent->mde_name, "-client") != NULL)
1478 if (strlen(dirent->mde_name) <= len ||
1479 strncmp(fsname, dirent->mde_name, len) != 0 ||
1480 dirent->mde_name[len] != '-')
1483 CDEBUG(D_MGS, "Changing log %s\n", dirent->mde_name);
1484 /* Erase any old settings of this same parameter */
1485 rc = mgs_modify(env, mgs, fsdb, mti, dirent->mde_name,
1486 devname, comment, CM_SKIP);
1488 CERROR("%s: Can't modify llog %s: rc = %d\n",
1489 mgs->mgs_obd->obd_name, dirent->mde_name, rc);
1492 /* Write the new one */
1493 rc = mgs_write_log_direct(env, mgs, fsdb, dirent->mde_name,
1494 lcr, devname, comment);
1496 CERROR("%s: writing log %s: rc = %d\n",
1497 mgs->mgs_obd->obd_name, dirent->mde_name, rc);
1499 mgs_direntry_free(dirent);
1505 static int mgs_write_log_osp_to_mdt(const struct lu_env *env,
1506 struct mgs_device *mgs,
1508 struct mgs_target_info *mti,
1509 int index, char *logname);
1510 static int mgs_write_log_osc_to_lov(const struct lu_env *env,
1511 struct mgs_device *mgs,
1513 struct mgs_target_info *mti,
1514 char *logname, char *suffix, char *lovname,
1515 enum lustre_sec_part sec_part, int flags);
1516 static int name_create_mdt_and_lov(char **logname, char **lovname,
1517 struct fs_db *fsdb, int i);
1519 static int add_param(char *params, char *key, char *val)
1521 char *start = params + strlen(params);
1522 char *end = params + sizeof(((struct mgs_target_info *)0)->mti_params);
1526 keylen = strlen(key);
1527 if (start + 1 + keylen + strlen(val) >= end) {
1528 CERROR("params are too long: %s %s%s\n",
1529 params, key != NULL ? key : "", val);
1533 sprintf(start, " %s%s", key != NULL ? key : "", val);
1538 * Walk through client config log record and convert the related records
1541 static int mgs_steal_client_llog_handler(const struct lu_env *env,
1542 struct llog_handle *llh,
1543 struct llog_rec_hdr *rec, void *data)
1545 struct mgs_device *mgs;
1546 struct obd_device *obd;
1547 struct mgs_target_info *mti, *tmti;
1549 int cfg_len = rec->lrh_len;
1550 char *cfg_buf = (char*) (rec + 1);
1551 struct lustre_cfg *lcfg;
1553 struct llog_handle *mdt_llh = NULL;
1554 static int got_an_osc_or_mdc = 0;
1555 /* 0: not found any osc/mdc;
1559 static int last_step = -1;
1564 mti = ((struct temp_comp*)data)->comp_mti;
1565 tmti = ((struct temp_comp*)data)->comp_tmti;
1566 fsdb = ((struct temp_comp*)data)->comp_fsdb;
1567 obd = ((struct temp_comp *)data)->comp_obd;
1568 mgs = lu2mgs_dev(obd->obd_lu_dev);
1571 if (rec->lrh_type != OBD_CFG_REC) {
1572 CERROR("unhandled lrh_type: %#x\n", rec->lrh_type);
1576 rc = lustre_cfg_sanity_check(cfg_buf, cfg_len);
1578 CERROR("Insane cfg\n");
1582 lcfg = (struct lustre_cfg *)cfg_buf;
1584 if (lcfg->lcfg_command == LCFG_MARKER) {
1585 struct cfg_marker *marker;
1586 marker = lustre_cfg_buf(lcfg, 1);
1587 if (!strncmp(marker->cm_comment, "add osc", 7) &&
1588 (marker->cm_flags & CM_START) &&
1589 !(marker->cm_flags & CM_SKIP)) {
1590 got_an_osc_or_mdc = 1;
1591 cplen = strlcpy(tmti->mti_svname, marker->cm_tgtname,
1592 sizeof(tmti->mti_svname));
1593 if (cplen >= sizeof(tmti->mti_svname))
1595 rc = record_start_log(env, mgs, &mdt_llh,
1599 rc = record_marker(env, mdt_llh, fsdb, CM_START,
1600 mti->mti_svname, "add osc(copied)");
1601 record_end_log(env, &mdt_llh);
1602 last_step = marker->cm_step;
1605 if (!strncmp(marker->cm_comment, "add osc", 7) &&
1606 (marker->cm_flags & CM_END) &&
1607 !(marker->cm_flags & CM_SKIP)) {
1608 LASSERT(last_step == marker->cm_step);
1610 got_an_osc_or_mdc = 0;
1611 memset(tmti, 0, sizeof(*tmti));
1612 rc = record_start_log(env, mgs, &mdt_llh,
1616 rc = record_marker(env, mdt_llh, fsdb, CM_END,
1617 mti->mti_svname, "add osc(copied)");
1618 record_end_log(env, &mdt_llh);
1621 if (!strncmp(marker->cm_comment, "add mdc", 7) &&
1622 (marker->cm_flags & CM_START) &&
1623 !(marker->cm_flags & CM_SKIP)) {
1624 got_an_osc_or_mdc = 2;
1625 last_step = marker->cm_step;
1626 memcpy(tmti->mti_svname, marker->cm_tgtname,
1627 strlen(marker->cm_tgtname));
1631 if (!strncmp(marker->cm_comment, "add mdc", 7) &&
1632 (marker->cm_flags & CM_END) &&
1633 !(marker->cm_flags & CM_SKIP)) {
1634 LASSERT(last_step == marker->cm_step);
1636 got_an_osc_or_mdc = 0;
1637 memset(tmti, 0, sizeof(*tmti));
1642 if (got_an_osc_or_mdc == 0 || last_step < 0)
1645 if (lcfg->lcfg_command == LCFG_ADD_UUID) {
1646 __u64 nodenid = lcfg->lcfg_nid;
1648 if (strlen(tmti->mti_uuid) == 0) {
1649 /* target uuid not set, this config record is before
1650 * LCFG_SETUP, this nid is one of target node nid.
1652 tmti->mti_nids[tmti->mti_nid_count] = nodenid;
1653 tmti->mti_nid_count++;
1655 char nidstr[LNET_NIDSTR_SIZE];
1657 /* failover node nid */
1658 libcfs_nid2str_r(nodenid, nidstr, sizeof(nidstr));
1659 rc = add_param(tmti->mti_params, PARAM_FAILNODE,
1666 if (lcfg->lcfg_command == LCFG_SETUP) {
1669 target = lustre_cfg_string(lcfg, 1);
1670 memcpy(tmti->mti_uuid, target, strlen(target));
1674 /* ignore client side sptlrpc_conf_log */
1675 if (lcfg->lcfg_command == LCFG_SPTLRPC_CONF)
1678 if (lcfg->lcfg_command == LCFG_ADD_MDC) {
1681 if (sscanf(lustre_cfg_buf(lcfg, 2), "%d", &index) != 1)
1684 memcpy(tmti->mti_fsname, mti->mti_fsname,
1685 strlen(mti->mti_fsname));
1686 tmti->mti_stripe_index = index;
1688 rc = mgs_write_log_osp_to_mdt(env, mgs, fsdb, tmti,
1689 mti->mti_stripe_index,
1691 memset(tmti, 0, sizeof(*tmti));
1695 if (lcfg->lcfg_command == LCFG_LOV_ADD_OBD) {
1698 char *logname, *lovname;
1700 rc = name_create_mdt_and_lov(&logname, &lovname, fsdb,
1701 mti->mti_stripe_index);
1704 sprintf(mdt_index, "-MDT%04x", mti->mti_stripe_index);
1706 if (sscanf(lustre_cfg_buf(lcfg, 2), "%d", &index) != 1) {
1707 name_destroy(&logname);
1708 name_destroy(&lovname);
1712 tmti->mti_stripe_index = index;
1713 rc = mgs_write_log_osc_to_lov(env, mgs, fsdb, tmti, logname,
1716 name_destroy(&logname);
1717 name_destroy(&lovname);
1723 /* fsdb->fsdb_mutex is already held in mgs_write_log_target*/
1724 /* stealed from mgs_get_fsdb_from_llog*/
1725 static int mgs_steal_llog_for_mdt_from_client(const struct lu_env *env,
1726 struct mgs_device *mgs,
1728 struct temp_comp* comp)
1730 struct llog_handle *loghandle;
1731 struct mgs_target_info *tmti;
1732 struct llog_ctxt *ctxt;
1737 ctxt = llog_get_context(mgs->mgs_obd, LLOG_CONFIG_ORIG_CTXT);
1738 LASSERT(ctxt != NULL);
1740 OBD_ALLOC_PTR(tmti);
1742 GOTO(out_ctxt, rc = -ENOMEM);
1744 comp->comp_tmti = tmti;
1745 comp->comp_obd = mgs->mgs_obd;
1747 rc = llog_open(env, ctxt, &loghandle, NULL, client_name,
1755 rc = llog_init_handle(env, loghandle, LLOG_F_IS_PLAIN, NULL);
1757 GOTO(out_close, rc);
1759 rc = llog_process_or_fork(env, loghandle, mgs_steal_client_llog_handler,
1760 (void *)comp, NULL, false);
1761 CDEBUG(D_MGS, "steal llog re = %d\n", rc);
1763 llog_close(env, loghandle);
1767 llog_ctxt_put(ctxt);
1771 /* lmv is the second thing for client logs */
1772 /* copied from mgs_write_log_lov. Please refer to that. */
1773 static int mgs_write_log_lmv(const struct lu_env *env,
1774 struct mgs_device *mgs,
1776 struct mgs_target_info *mti,
1777 char *logname, char *lmvname)
1779 struct llog_handle *llh = NULL;
1780 struct lmv_desc *lmvdesc;
1785 CDEBUG(D_MGS, "Writing lmv(%s) log for %s\n", lmvname,logname);
1787 OBD_ALLOC_PTR(lmvdesc);
1788 if (lmvdesc == NULL)
1790 lmvdesc->ld_active_tgt_count = 0;
1791 lmvdesc->ld_tgt_count = 0;
1792 sprintf((char*)lmvdesc->ld_uuid.uuid, "%s_UUID", lmvname);
1793 uuid = (char *)lmvdesc->ld_uuid.uuid;
1795 rc = record_start_log(env, mgs, &llh, logname);
1798 rc = record_marker(env, llh, fsdb, CM_START, lmvname, "lmv setup");
1801 rc = record_attach(env, llh, lmvname, "lmv", uuid);
1804 rc = record_lmv_setup(env, llh, lmvname, lmvdesc);
1807 rc = record_marker(env, llh, fsdb, CM_END, lmvname, "lmv setup");
1811 record_end_log(env, &llh);
1813 OBD_FREE_PTR(lmvdesc);
1817 /* lov is the first thing in the mdt and client logs */
1818 static int mgs_write_log_lov(const struct lu_env *env, struct mgs_device *mgs,
1819 struct fs_db *fsdb, struct mgs_target_info *mti,
1820 char *logname, char *lovname)
1822 struct llog_handle *llh = NULL;
1823 struct lov_desc *lovdesc;
1828 CDEBUG(D_MGS, "Writing lov(%s) log for %s\n", lovname, logname);
1831 #01 L attach 0:lov_mdsA 1:lov 2:71ccb_lov_mdsA_19f961a9e1
1832 #02 L lov_setup 0:lov_mdsA 1:(struct lov_desc)
1833 uuid=lov1_UUID, stripe count=1, size=1048576, offset=0, pattern=0
1836 /* FIXME just make lov_setup accept empty desc (put uuid in buf 2) */
1837 OBD_ALLOC_PTR(lovdesc);
1838 if (lovdesc == NULL)
1840 lovdesc->ld_magic = LOV_DESC_MAGIC;
1841 lovdesc->ld_tgt_count = 0;
1842 /* Defaults. Can be changed later by lcfg config_param */
1843 lovdesc->ld_default_stripe_count = 1;
1844 lovdesc->ld_pattern = LOV_PATTERN_RAID0;
1845 lovdesc->ld_default_stripe_size = LOV_DESC_STRIPE_SIZE_DEFAULT;
1846 lovdesc->ld_default_stripe_offset = -1;
1847 lovdesc->ld_qos_maxage = LOV_DESC_QOS_MAXAGE_DEFAULT;
1848 sprintf((char*)lovdesc->ld_uuid.uuid, "%s_UUID", lovname);
1849 /* can these be the same? */
1850 uuid = (char *)lovdesc->ld_uuid.uuid;
1852 /* This should always be the first entry in a log.
1853 rc = mgs_clear_log(obd, logname); */
1854 rc = record_start_log(env, mgs, &llh, logname);
1857 /* FIXME these should be a single journal transaction */
1858 rc = record_marker(env, llh, fsdb, CM_START, lovname, "lov setup");
1861 rc = record_attach(env, llh, lovname, "lov", uuid);
1864 rc = record_lov_setup(env, llh, lovname, lovdesc);
1867 rc = record_marker(env, llh, fsdb, CM_END, lovname, "lov setup");
1872 record_end_log(env, &llh);
1874 OBD_FREE_PTR(lovdesc);
1878 /* add failnids to open log */
1879 static int mgs_write_log_failnids(const struct lu_env *env,
1880 struct mgs_target_info *mti,
1881 struct llog_handle *llh,
1884 char *failnodeuuid = NULL;
1885 char *ptr = mti->mti_params;
1890 #03 L add_uuid nid=uml1@tcp(0x20000c0a80201) nal=90 0: 1:uml1_UUID
1891 #04 L add_uuid nid=1@elan(0x1000000000001) nal=90 0: 1:uml1_UUID
1892 #05 L setup 0:OSC_uml1_ost1_mdsA 1:ost1_UUID 2:uml1_UUID
1893 #06 L add_uuid nid=uml2@tcp(0x20000c0a80202) nal=90 0: 1:uml2_UUID
1894 #0x L add_uuid nid=2@elan(0x1000000000002) nal=90 0: 1:uml2_UUID
1895 #07 L add_conn 0:OSC_uml1_ost1_mdsA 1:uml2_UUID
1899 * Pull failnid info out of params string, which may contain something
1900 * like "<nid1>,<nid2>:<nid3>,<nid4>". class_parse_nid() does not
1901 * complain about abnormal inputs like ",:<nid1>", "<nid1>:,<nid2>",
1902 * etc. However, convert_hostnames() should have caught those.
1904 while (class_find_param(ptr, PARAM_FAILNODE, &ptr) == 0) {
1905 while (class_parse_nid(ptr, &nid, &ptr) == 0) {
1906 char nidstr[LNET_NIDSTR_SIZE];
1908 if (failnodeuuid == NULL) {
1909 /* We don't know the failover node name,
1910 * so just use the first nid as the uuid */
1911 libcfs_nid2str_r(nid, nidstr, sizeof(nidstr));
1912 rc = name_create(&failnodeuuid, nidstr, "");
1916 CDEBUG(D_MGS, "add nid %s for failover uuid %s, "
1918 libcfs_nid2str_r(nid, nidstr, sizeof(nidstr)),
1919 failnodeuuid, cliname);
1920 rc = record_add_uuid(env, llh, nid, failnodeuuid);
1922 * If *ptr is ':', we have added all NIDs for
1926 rc = record_add_conn(env, llh, cliname,
1928 name_destroy(&failnodeuuid);
1929 failnodeuuid = NULL;
1933 rc = record_add_conn(env, llh, cliname, failnodeuuid);
1934 name_destroy(&failnodeuuid);
1935 failnodeuuid = NULL;
1942 static int mgs_write_log_mdc_to_lmv(const struct lu_env *env,
1943 struct mgs_device *mgs,
1945 struct mgs_target_info *mti,
1946 char *logname, char *lmvname)
1948 struct llog_handle *llh = NULL;
1949 char *mdcname = NULL;
1950 char *nodeuuid = NULL;
1951 char *mdcuuid = NULL;
1952 char *lmvuuid = NULL;
1954 char nidstr[LNET_NIDSTR_SIZE];
1958 if (mgs_log_is_empty(env, mgs, logname)) {
1959 CERROR("log is empty! Logical error\n");
1963 CDEBUG(D_MGS, "adding mdc for %s to log %s:lmv(%s)\n",
1964 mti->mti_svname, logname, lmvname);
1966 libcfs_nid2str_r(mti->mti_nids[0], nidstr, sizeof(nidstr));
1967 rc = name_create(&nodeuuid, nidstr, "");
1970 rc = name_create(&mdcname, mti->mti_svname, "-mdc");
1973 rc = name_create(&mdcuuid, mdcname, "_UUID");
1976 rc = name_create(&lmvuuid, lmvname, "_UUID");
1980 rc = record_start_log(env, mgs, &llh, logname);
1983 rc = record_marker(env, llh, fsdb, CM_START, mti->mti_svname,
1987 for (i = 0; i < mti->mti_nid_count; i++) {
1988 CDEBUG(D_MGS, "add nid %s for mdt\n",
1989 libcfs_nid2str_r(mti->mti_nids[i],
1990 nidstr, sizeof(nidstr)));
1992 rc = record_add_uuid(env, llh, mti->mti_nids[i], nodeuuid);
1997 rc = record_attach(env, llh, mdcname, LUSTRE_MDC_NAME, lmvuuid);
2000 rc = record_setup(env, llh, mdcname, mti->mti_uuid, nodeuuid,
2004 rc = mgs_write_log_failnids(env, mti, llh, mdcname);
2007 snprintf(index, sizeof(index), "%d", mti->mti_stripe_index);
2008 rc = record_mdc_add(env, llh, lmvname, mdcuuid, mti->mti_uuid,
2012 rc = record_marker(env, llh, fsdb, CM_END, mti->mti_svname,
2017 record_end_log(env, &llh);
2019 name_destroy(&lmvuuid);
2020 name_destroy(&mdcuuid);
2021 name_destroy(&mdcname);
2022 name_destroy(&nodeuuid);
2026 static inline int name_create_lov(char **lovname, char *mdtname,
2027 struct fs_db *fsdb, int index)
2030 if (index == 0 && test_bit(FSDB_OSCNAME18, &fsdb->fsdb_flags))
2031 return name_create(lovname, fsdb->fsdb_name, "-mdtlov");
2033 return name_create(lovname, mdtname, "-mdtlov");
2036 static int name_create_mdt_and_lov(char **logname, char **lovname,
2037 struct fs_db *fsdb, int i)
2041 rc = name_create_mdt(logname, fsdb->fsdb_name, i);
2045 if (i == 0 && test_bit(FSDB_OSCNAME18, &fsdb->fsdb_flags))
2046 rc = name_create(lovname, fsdb->fsdb_name, "-mdtlov");
2048 rc = name_create(lovname, *logname, "-mdtlov");
2050 name_destroy(logname);
2056 static inline int name_create_mdt_osc(char **oscname, char *ostname,
2057 struct fs_db *fsdb, int i)
2061 if (i == 0 && test_bit(FSDB_OSCNAME18, &fsdb->fsdb_flags))
2062 sprintf(suffix, "-osc");
2064 sprintf(suffix, "-osc-MDT%04x", i);
2065 return name_create(oscname, ostname, suffix);
2068 /* add new mdc to already existent MDS */
2069 static int mgs_write_log_osp_to_mdt(const struct lu_env *env,
2070 struct mgs_device *mgs,
2072 struct mgs_target_info *mti,
2073 int mdt_index, char *logname)
2075 struct llog_handle *llh = NULL;
2076 char *nodeuuid = NULL;
2077 char *ospname = NULL;
2078 char *lovuuid = NULL;
2079 char *mdtuuid = NULL;
2080 char *svname = NULL;
2081 char *mdtname = NULL;
2082 char *lovname = NULL;
2084 char nidstr[LNET_NIDSTR_SIZE];
2088 if (mgs_log_is_empty(env, mgs, mti->mti_svname)) {
2089 CERROR("log is empty! Logical error\n");
2093 CDEBUG(D_MGS, "adding osp index %d to %s\n", mti->mti_stripe_index,
2096 rc = name_create_mdt(&mdtname, fsdb->fsdb_name, mti->mti_stripe_index);
2100 libcfs_nid2str_r(mti->mti_nids[0], nidstr, sizeof(nidstr));
2101 rc = name_create(&nodeuuid, nidstr, "");
2103 GOTO(out_destory, rc);
2105 rc = name_create(&svname, mdtname, "-osp");
2107 GOTO(out_destory, rc);
2109 sprintf(index_str, "-MDT%04x", mdt_index);
2110 rc = name_create(&ospname, svname, index_str);
2112 GOTO(out_destory, rc);
2114 rc = name_create_lov(&lovname, logname, fsdb, mdt_index);
2116 GOTO(out_destory, rc);
2118 rc = name_create(&lovuuid, lovname, "_UUID");
2120 GOTO(out_destory, rc);
2122 rc = name_create(&mdtuuid, mdtname, "_UUID");
2124 GOTO(out_destory, rc);
2126 rc = record_start_log(env, mgs, &llh, logname);
2128 GOTO(out_destory, rc);
2130 rc = record_marker(env, llh, fsdb, CM_START, mti->mti_svname,
2133 GOTO(out_destory, rc);
2135 for (i = 0; i < mti->mti_nid_count; i++) {
2136 CDEBUG(D_MGS, "add nid %s for mdt\n",
2137 libcfs_nid2str_r(mti->mti_nids[i],
2138 nidstr, sizeof(nidstr)));
2139 rc = record_add_uuid(env, llh, mti->mti_nids[i], nodeuuid);
2144 rc = record_attach(env, llh, ospname, LUSTRE_OSP_NAME, lovuuid);
2148 rc = record_setup(env, llh, ospname, mti->mti_uuid, nodeuuid,
2153 rc = mgs_write_log_failnids(env, mti, llh, ospname);
2157 /* Add mdc(osp) to lod */
2158 snprintf(index_str, sizeof(index_str), "%d", mti->mti_stripe_index);
2159 rc = record_base(env, llh, lovname, 0, LCFG_ADD_MDC, mti->mti_uuid,
2160 index_str, "1", NULL);
2164 rc = record_marker(env, llh, fsdb, CM_END, mti->mti_svname, "add osp");
2169 record_end_log(env, &llh);
2172 name_destroy(&mdtuuid);
2173 name_destroy(&lovuuid);
2174 name_destroy(&lovname);
2175 name_destroy(&ospname);
2176 name_destroy(&svname);
2177 name_destroy(&nodeuuid);
2178 name_destroy(&mdtname);
2182 static int mgs_write_log_mdt0(const struct lu_env *env,
2183 struct mgs_device *mgs,
2185 struct mgs_target_info *mti)
2187 char *log = mti->mti_svname;
2188 struct llog_handle *llh = NULL;
2189 char *uuid, *lovname;
2191 char *ptr = mti->mti_params;
2192 int rc = 0, failout = 0;
2195 OBD_ALLOC(uuid, sizeof(struct obd_uuid));
2199 if (class_find_param(ptr, PARAM_FAILMODE, &ptr) == 0)
2200 failout = (strncmp(ptr, "failout", 7) == 0);
2202 rc = name_create(&lovname, log, "-mdtlov");
2205 if (mgs_log_is_empty(env, mgs, log)) {
2206 rc = mgs_write_log_lov(env, mgs, fsdb, mti, log, lovname);
2211 sprintf(mdt_index, "%d", mti->mti_stripe_index);
2213 rc = record_start_log(env, mgs, &llh, log);
2217 /* add MDT itself */
2219 /* FIXME this whole fn should be a single journal transaction */
2220 sprintf(uuid, "%s_UUID", log);
2221 rc = record_marker(env, llh, fsdb, CM_START, log, "add mdt");
2224 rc = record_attach(env, llh, log, LUSTRE_MDT_NAME, uuid);
2227 rc = record_mount_opt(env, llh, log, lovname, NULL);
2230 rc = record_setup(env, llh, log, uuid, mdt_index, lovname,
2231 failout ? "n" : "f");
2234 rc = record_marker(env, llh, fsdb, CM_END, log, "add mdt");
2238 record_end_log(env, &llh);
2240 name_destroy(&lovname);
2242 OBD_FREE(uuid, sizeof(struct obd_uuid));
2246 /* envelope method for all layers log */
2247 static int mgs_write_log_mdt(const struct lu_env *env,
2248 struct mgs_device *mgs,
2250 struct mgs_target_info *mti)
2252 struct mgs_thread_info *mgi = mgs_env_info(env);
2253 struct llog_handle *llh = NULL;
2258 CDEBUG(D_MGS, "writing new mdt %s\n", mti->mti_svname);
2260 if (mti->mti_uuid[0] == '\0') {
2261 /* Make up our own uuid */
2262 snprintf(mti->mti_uuid, sizeof(mti->mti_uuid),
2263 "%s_UUID", mti->mti_svname);
2267 rc = mgs_write_log_mdt0(env, mgs, fsdb, mti);
2270 /* Append the mdt info to the client log */
2271 rc = name_create(&cliname, mti->mti_fsname, "-client");
2275 if (mgs_log_is_empty(env, mgs, cliname)) {
2276 /* Start client log */
2277 rc = mgs_write_log_lov(env, mgs, fsdb, mti, cliname,
2281 rc = mgs_write_log_lmv(env, mgs, fsdb, mti, cliname,
2288 #09 L add_uuid nid=uml1@tcp(0x20000c0a80201) 0: 1:uml1_UUID
2289 #10 L attach 0:MDC_uml1_mdsA_MNT_client 1:mdc 2:1d834_MNT_client_03f
2290 #11 L setup 0:MDC_uml1_mdsA_MNT_client 1:mdsA_UUID 2:uml1_UUID
2291 #12 L add_uuid nid=uml2@tcp(0x20000c0a80202) 0: 1:uml2_UUID
2292 #13 L add_conn 0:MDC_uml1_mdsA_MNT_client 1:uml2_UUID
2293 #14 L mount_option 0: 1:client 2:lov1 3:MDC_uml1_mdsA_MNT_client
2296 /* copy client info about lov/lmv */
2297 mgi->mgi_comp.comp_mti = mti;
2298 mgi->mgi_comp.comp_fsdb = fsdb;
2300 rc = mgs_steal_llog_for_mdt_from_client(env, mgs, cliname,
2304 rc = mgs_write_log_mdc_to_lmv(env, mgs, fsdb, mti, cliname,
2310 rc = record_start_log(env, mgs, &llh, cliname);
2314 rc = record_marker(env, llh, fsdb, CM_START, cliname,
2318 rc = record_mount_opt(env, llh, cliname, fsdb->fsdb_clilov,
2322 rc = record_marker(env, llh, fsdb, CM_END, cliname,
2328 /* for_all_existing_mdt except current one */
2329 for (i = 0; i < INDEX_MAP_SIZE * 8; i++) {
2330 if (i != mti->mti_stripe_index &&
2331 test_bit(i, fsdb->fsdb_mdt_index_map)) {
2334 rc = name_create_mdt(&logname, fsdb->fsdb_name, i);
2338 rc = mgs_write_log_osp_to_mdt(env, mgs, fsdb, mti,
2340 name_destroy(&logname);
2346 record_end_log(env, &llh);
2348 name_destroy(&cliname);
2352 /* Add the ost info to the client/mdt lov */
2353 static int mgs_write_log_osc_to_lov(const struct lu_env *env,
2354 struct mgs_device *mgs, struct fs_db *fsdb,
2355 struct mgs_target_info *mti,
2356 char *logname, char *suffix, char *lovname,
2357 enum lustre_sec_part sec_part, int flags)
2359 struct llog_handle *llh = NULL;
2360 char *nodeuuid = NULL;
2361 char *oscname = NULL;
2362 char *oscuuid = NULL;
2363 char *lovuuid = NULL;
2364 char *svname = NULL;
2366 char nidstr[LNET_NIDSTR_SIZE];
2370 CDEBUG(D_INFO, "adding osc for %s to log %s\n",
2371 mti->mti_svname, logname);
2373 if (mgs_log_is_empty(env, mgs, logname)) {
2374 CERROR("log is empty! Logical error\n");
2378 libcfs_nid2str_r(mti->mti_nids[0], nidstr, sizeof(nidstr));
2379 rc = name_create(&nodeuuid, nidstr, "");
2382 rc = name_create(&svname, mti->mti_svname, "-osc");
2386 /* for the system upgraded from old 1.8, keep using the old osc naming
2387 * style for mdt, see name_create_mdt_osc(). LU-1257 */
2388 if (test_bit(FSDB_OSCNAME18, &fsdb->fsdb_flags))
2389 rc = name_create(&oscname, svname, "");
2391 rc = name_create(&oscname, svname, suffix);
2395 rc = name_create(&oscuuid, oscname, "_UUID");
2398 rc = name_create(&lovuuid, lovname, "_UUID");
2404 #03 L add_uuid nid=uml1@tcp(0x20000c0a80201) 0: 1:uml1_UUID
2406 #04 L add_uuid nid=1@elan(0x1000000000001) nal=90 0: 1:uml1_UUID
2407 #04 L attach 0:OSC_uml1_ost1_MNT_client 1:osc 2:89070_lov1_a41dff51a
2408 #05 L setup 0:OSC_uml1_ost1_MNT_client 1:ost1_UUID 2:uml1_UUID
2410 #06 L add_uuid nid=uml2@tcp(0x20000c0a80202) 0: 1:uml2_UUID
2411 #07 L add_conn 0:OSC_uml1_ost1_MNT_client 1:uml2_UUID
2412 #08 L lov_modify_tgts add 0:lov1 1:ost1_UUID 2(index):0 3(gen):1
2415 rc = record_start_log(env, mgs, &llh, logname);
2419 /* FIXME these should be a single journal transaction */
2420 rc = record_marker(env, llh, fsdb, CM_START | flags, mti->mti_svname,
2425 /* NB: don't change record order, because upon MDT steal OSC config
2426 * from client, it treats all nids before LCFG_SETUP as target nids
2427 * (multiple interfaces), while nids after as failover node nids.
2428 * See mgs_steal_client_llog_handler() LCFG_ADD_UUID.
2430 for (i = 0; i < mti->mti_nid_count; i++) {
2431 CDEBUG(D_MGS, "add nid %s\n",
2432 libcfs_nid2str_r(mti->mti_nids[i],
2433 nidstr, sizeof(nidstr)));
2434 rc = record_add_uuid(env, llh, mti->mti_nids[i], nodeuuid);
2438 rc = record_attach(env, llh, oscname, LUSTRE_OSC_NAME, lovuuid);
2441 rc = record_setup(env, llh, oscname, mti->mti_uuid, nodeuuid,
2445 rc = mgs_write_log_failnids(env, mti, llh, oscname);
2449 snprintf(index, sizeof(index), "%d", mti->mti_stripe_index);
2451 rc = record_lov_add(env, llh, lovname, mti->mti_uuid, index, "1");
2454 rc = record_marker(env, llh, fsdb, CM_END | flags, mti->mti_svname,
2459 record_end_log(env, &llh);
2461 name_destroy(&lovuuid);
2462 name_destroy(&oscuuid);
2463 name_destroy(&oscname);
2464 name_destroy(&svname);
2465 name_destroy(&nodeuuid);
2469 static int mgs_write_log_ost(const struct lu_env *env,
2470 struct mgs_device *mgs, struct fs_db *fsdb,
2471 struct mgs_target_info *mti)
2473 struct llog_handle *llh = NULL;
2474 char *logname, *lovname;
2475 char *ptr = mti->mti_params;
2476 int rc, flags = 0, failout = 0, i;
2479 CDEBUG(D_MGS, "writing new ost %s\n", mti->mti_svname);
2481 /* The ost startup log */
2483 /* If the ost log already exists, that means that someone reformatted
2484 the ost and it called target_add again. */
2485 if (!mgs_log_is_empty(env, mgs, mti->mti_svname)) {
2486 LCONSOLE_ERROR_MSG(0x141, "The config log for %s already "
2487 "exists, yet the server claims it never "
2488 "registered. It may have been reformatted, "
2489 "or the index changed. writeconf the MDT to "
2490 "regenerate all logs.\n", mti->mti_svname);
2495 attach obdfilter ost1 ost1_UUID
2496 setup /dev/loop2 ldiskfs f|n errors=remount-ro,user_xattr
2498 if (class_find_param(ptr, PARAM_FAILMODE, &ptr) == 0)
2499 failout = (strncmp(ptr, "failout", 7) == 0);
2500 rc = record_start_log(env, mgs, &llh, mti->mti_svname);
2503 /* FIXME these should be a single journal transaction */
2504 rc = record_marker(env, llh, fsdb, CM_START, mti->mti_svname,"add ost");
2507 if (*mti->mti_uuid == '\0')
2508 snprintf(mti->mti_uuid, sizeof(mti->mti_uuid),
2509 "%s_UUID", mti->mti_svname);
2510 rc = record_attach(env, llh, mti->mti_svname,
2511 "obdfilter"/*LUSTRE_OST_NAME*/, mti->mti_uuid);
2514 rc = record_setup(env, llh, mti->mti_svname,
2515 "dev"/*ignored*/, "type"/*ignored*/,
2516 failout ? "n" : "f", NULL/*options*/);
2519 rc = record_marker(env, llh, fsdb, CM_END, mti->mti_svname, "add ost");
2523 record_end_log(env, &llh);
2526 /* We also have to update the other logs where this osc is part of
2529 if (test_bit(FSDB_OLDLOG14, &fsdb->fsdb_flags)) {
2530 /* If we're upgrading, the old mdt log already has our
2531 entry. Let's do a fake one for fun. */
2532 /* Note that we can't add any new failnids, since we don't
2533 know the old osc names. */
2534 flags = CM_SKIP | CM_UPGRADE146;
2536 } else if ((mti->mti_flags & LDD_F_UPDATE) != LDD_F_UPDATE) {
2537 /* If the update flag isn't set, don't update client/mdt
2540 LCONSOLE_WARN("Client log for %s was not updated; writeconf "
2541 "the MDT first to regenerate it.\n",
2545 /* Add ost to all MDT lov defs */
2546 for (i = 0; i < INDEX_MAP_SIZE * 8; i++){
2547 if (test_bit(i, fsdb->fsdb_mdt_index_map)) {
2550 rc = name_create_mdt_and_lov(&logname, &lovname, fsdb,
2554 sprintf(mdt_index, "-MDT%04x", i);
2555 rc = mgs_write_log_osc_to_lov(env, mgs, fsdb, mti,
2557 lovname, LUSTRE_SP_MDT,
2559 name_destroy(&logname);
2560 name_destroy(&lovname);
2566 /* Append ost info to the client log */
2567 rc = name_create(&logname, mti->mti_fsname, "-client");
2570 if (mgs_log_is_empty(env, mgs, logname)) {
2571 /* Start client log */
2572 rc = mgs_write_log_lov(env, mgs, fsdb, mti, logname,
2576 rc = mgs_write_log_lmv(env, mgs, fsdb, mti, logname,
2581 rc = mgs_write_log_osc_to_lov(env, mgs, fsdb, mti, logname, "",
2582 fsdb->fsdb_clilov, LUSTRE_SP_CLI, flags);
2584 name_destroy(&logname);
2588 static __inline__ int mgs_param_empty(char *ptr)
2592 if ((tmp = strchr(ptr, '=')) && (*(++tmp) == '\0'))
2597 static int mgs_write_log_failnid_internal(const struct lu_env *env,
2598 struct mgs_device *mgs,
2600 struct mgs_target_info *mti,
2601 char *logname, char *cliname)
2604 struct llog_handle *llh = NULL;
2606 if (mgs_param_empty(mti->mti_params)) {
2607 /* Remove _all_ failnids */
2608 rc = mgs_modify(env, mgs, fsdb, mti, logname,
2609 mti->mti_svname, "add failnid", CM_SKIP);
2610 return rc < 0 ? rc : 0;
2613 /* Otherwise failover nids are additive */
2614 rc = record_start_log(env, mgs, &llh, logname);
2617 /* FIXME this should be a single journal transaction */
2618 rc = record_marker(env, llh, fsdb, CM_START, mti->mti_svname,
2622 rc = mgs_write_log_failnids(env, mti, llh, cliname);
2625 rc = record_marker(env, llh, fsdb, CM_END,
2626 mti->mti_svname, "add failnid");
2628 record_end_log(env, &llh);
2633 /* Add additional failnids to an existing log.
2634 The mdc/osc must have been added to logs first */
2635 /* tcp nids must be in dotted-quad ascii -
2636 we can't resolve hostnames from the kernel. */
2637 static int mgs_write_log_add_failnid(const struct lu_env *env,
2638 struct mgs_device *mgs,
2640 struct mgs_target_info *mti)
2642 char *logname, *cliname;
2646 /* FIXME we currently can't erase the failnids
2647 * given when a target first registers, since they aren't part of
2648 * an "add uuid" stanza */
2650 /* Verify that we know about this target */
2651 if (mgs_log_is_empty(env, mgs, mti->mti_svname)) {
2652 LCONSOLE_ERROR_MSG(0x142, "The target %s has not registered "
2653 "yet. It must be started before failnids "
2654 "can be added.\n", mti->mti_svname);
2658 /* Create mdc/osc client name (e.g. lustre-OST0001-osc) */
2659 if (mti->mti_flags & LDD_F_SV_TYPE_MDT) {
2660 rc = name_create(&cliname, mti->mti_svname, "-mdc");
2661 } else if (mti->mti_flags & LDD_F_SV_TYPE_OST) {
2662 rc = name_create(&cliname, mti->mti_svname, "-osc");
2668 /* Add failover nids to the client log */
2669 rc = name_create(&logname, mti->mti_fsname, "-client");
2671 name_destroy(&cliname);
2674 rc = mgs_write_log_failnid_internal(env, mgs, fsdb,mti,logname,cliname);
2675 name_destroy(&logname);
2676 name_destroy(&cliname);
2680 if (mti->mti_flags & LDD_F_SV_TYPE_OST) {
2681 /* Add OST failover nids to the MDT logs as well */
2684 for (i = 0; i < INDEX_MAP_SIZE * 8; i++) {
2685 if (!test_bit(i, fsdb->fsdb_mdt_index_map))
2687 rc = name_create_mdt(&logname, mti->mti_fsname, i);
2690 rc = name_create_mdt_osc(&cliname, mti->mti_svname,
2693 name_destroy(&logname);
2696 rc = mgs_write_log_failnid_internal(env, mgs, fsdb,
2699 name_destroy(&cliname);
2700 name_destroy(&logname);
2709 static int mgs_wlp_lcfg(const struct lu_env *env,
2710 struct mgs_device *mgs, struct fs_db *fsdb,
2711 struct mgs_target_info *mti,
2712 char *logname, struct lustre_cfg_bufs *bufs,
2713 char *tgtname, char *ptr)
2715 char comment[MTI_NAME_MAXLEN];
2717 struct llog_cfg_rec *lcr;
2720 /* Erase any old settings of this same parameter */
2721 memcpy(comment, ptr, MTI_NAME_MAXLEN);
2722 comment[MTI_NAME_MAXLEN - 1] = 0;
2723 /* But don't try to match the value. */
2724 tmp = strchr(comment, '=');
2727 /* FIXME we should skip settings that are the same as old values */
2728 rc = mgs_modify(env, mgs, fsdb, mti, logname, tgtname, comment,CM_SKIP);
2731 del = mgs_param_empty(ptr);
2733 LCONSOLE_INFO("%s parameter %s.%s in log %s\n", del ? "Disabling" : rc ?
2734 "Setting" : "Modifying", tgtname, comment, logname);
2736 /* mgs_modify() will return 1 if nothing had to be done */
2742 lustre_cfg_bufs_reset(bufs, tgtname);
2743 lustre_cfg_bufs_set_string(bufs, 1, ptr);
2744 if (mti->mti_flags & LDD_F_PARAM2)
2745 lustre_cfg_bufs_set_string(bufs, 2, LCTL_UPCALL);
2747 lcr = lustre_cfg_rec_new((mti->mti_flags & LDD_F_PARAM2) ?
2748 LCFG_SET_PARAM : LCFG_PARAM, bufs);
2752 rc = mgs_write_log_direct(env, mgs, fsdb, logname, lcr, tgtname,
2754 lustre_cfg_rec_free(lcr);
2758 static int mgs_write_log_param2(const struct lu_env *env,
2759 struct mgs_device *mgs,
2761 struct mgs_target_info *mti, char *ptr)
2763 struct lustre_cfg_bufs bufs;
2767 CDEBUG(D_MGS, "next param '%s'\n", ptr);
2768 rc = mgs_wlp_lcfg(env, mgs, fsdb, mti, PARAMS_FILENAME, &bufs,
2769 mti->mti_svname, ptr);
2774 /* write global variable settings into log */
2775 static int mgs_write_log_sys(const struct lu_env *env,
2776 struct mgs_device *mgs, struct fs_db *fsdb,
2777 struct mgs_target_info *mti, char *sys, char *ptr)
2779 struct mgs_thread_info *mgi = mgs_env_info(env);
2780 struct lustre_cfg *lcfg;
2781 struct llog_cfg_rec *lcr;
2783 int rc, cmd, convert = 1;
2785 if (class_match_param(ptr, PARAM_TIMEOUT, &tmp) == 0) {
2786 cmd = LCFG_SET_TIMEOUT;
2787 } else if (class_match_param(ptr, PARAM_LDLM_TIMEOUT, &tmp) == 0) {
2788 cmd = LCFG_SET_LDLM_TIMEOUT;
2789 /* Check for known params here so we can return error to lctl */
2790 } else if ((class_match_param(ptr, PARAM_AT_MIN, &tmp) == 0) ||
2791 (class_match_param(ptr, PARAM_AT_MAX, &tmp) == 0) ||
2792 (class_match_param(ptr, PARAM_AT_EXTRA, &tmp) == 0) ||
2793 (class_match_param(ptr, PARAM_AT_EARLY_MARGIN, &tmp) == 0) ||
2794 (class_match_param(ptr, PARAM_AT_HISTORY, &tmp) == 0)) {
2796 } else if (class_match_param(ptr, PARAM_JOBID_VAR, &tmp) == 0) {
2797 convert = 0; /* Don't convert string value to integer */
2803 if (mgs_param_empty(ptr))
2804 CDEBUG(D_MGS, "global '%s' removed\n", sys);
2806 CDEBUG(D_MGS, "global '%s' val=%s\n", sys, tmp);
2808 lustre_cfg_bufs_reset(&mgi->mgi_bufs, NULL);
2809 lustre_cfg_bufs_set_string(&mgi->mgi_bufs, 1, sys);
2810 if (!convert && *tmp != '\0')
2811 lustre_cfg_bufs_set_string(&mgi->mgi_bufs, 2, tmp);
2812 lcr = lustre_cfg_rec_new(cmd, &mgi->mgi_bufs);
2816 lcfg = &lcr->lcr_cfg;
2817 lcfg->lcfg_num = convert ? simple_strtoul(tmp, NULL, 0) : 0;
2818 /* truncate the comment to the parameter name */
2822 /* modify all servers and clients */
2823 rc = mgs_write_log_direct_all(env, mgs, fsdb, mti,
2824 *tmp == '\0' ? NULL : lcr,
2825 mti->mti_fsname, sys, 0);
2826 if (rc == 0 && *tmp != '\0') {
2828 case LCFG_SET_TIMEOUT:
2829 if (!obd_timeout_set || lcfg->lcfg_num > obd_timeout)
2830 class_process_config(lcfg);
2832 case LCFG_SET_LDLM_TIMEOUT:
2833 if (!ldlm_timeout_set || lcfg->lcfg_num > ldlm_timeout)
2834 class_process_config(lcfg);
2841 lustre_cfg_rec_free(lcr);
2845 /* write quota settings into log */
2846 static int mgs_write_log_quota(const struct lu_env *env, struct mgs_device *mgs,
2847 struct fs_db *fsdb, struct mgs_target_info *mti,
2848 char *quota, char *ptr)
2850 struct mgs_thread_info *mgi = mgs_env_info(env);
2851 struct llog_cfg_rec *lcr;
2854 int rc, cmd = LCFG_PARAM;
2856 /* support only 'meta' and 'data' pools so far */
2857 if (class_match_param(ptr, QUOTA_METAPOOL_NAME, &tmp) != 0 &&
2858 class_match_param(ptr, QUOTA_DATAPOOL_NAME, &tmp) != 0) {
2859 CERROR("parameter quota.%s isn't supported (only quota.mdt "
2860 "& quota.ost are)\n", ptr);
2865 CDEBUG(D_MGS, "global '%s' removed\n", quota);
2867 CDEBUG(D_MGS, "global '%s'\n", quota);
2869 if (strchr(tmp, 'u') == NULL && strchr(tmp, 'g') == NULL &&
2870 strcmp(tmp, "none") != 0) {
2871 CERROR("enable option(%s) isn't supported\n", tmp);
2876 lustre_cfg_bufs_reset(&mgi->mgi_bufs, mti->mti_fsname);
2877 lustre_cfg_bufs_set_string(&mgi->mgi_bufs, 1, quota);
2878 lcr = lustre_cfg_rec_new(cmd, &mgi->mgi_bufs);
2882 /* truncate the comment to the parameter name */
2887 /* XXX we duplicated quota enable information in all server
2888 * config logs, it should be moved to a separate config
2889 * log once we cleanup the config log for global param. */
2890 /* modify all servers */
2891 rc = mgs_write_log_direct_all(env, mgs, fsdb, mti,
2892 *tmp == '\0' ? NULL : lcr,
2893 mti->mti_fsname, quota, 1);
2895 lustre_cfg_rec_free(lcr);
2896 return rc < 0 ? rc : 0;
2899 static int mgs_srpc_set_param_disk(const struct lu_env *env,
2900 struct mgs_device *mgs,
2902 struct mgs_target_info *mti,
2905 struct mgs_thread_info *mgi = mgs_env_info(env);
2906 struct llog_cfg_rec *lcr;
2907 struct llog_handle *llh = NULL;
2909 char *comment, *ptr;
2915 ptr = strchr(param, '=');
2916 LASSERT(ptr != NULL);
2919 OBD_ALLOC(comment, len + 1);
2920 if (comment == NULL)
2922 strncpy(comment, param, len);
2923 comment[len] = '\0';
2926 lustre_cfg_bufs_reset(&mgi->mgi_bufs, mti->mti_svname);
2927 lustre_cfg_bufs_set_string(&mgi->mgi_bufs, 1, param);
2928 lcr = lustre_cfg_rec_new(LCFG_SPTLRPC_CONF, &mgi->mgi_bufs);
2930 GOTO(out_comment, rc = -ENOMEM);
2932 /* construct log name */
2933 rc = name_create(&logname, mti->mti_fsname, "-sptlrpc");
2937 if (mgs_log_is_empty(env, mgs, logname)) {
2938 rc = record_start_log(env, mgs, &llh, logname);
2941 record_end_log(env, &llh);
2944 /* obsolete old one */
2945 rc = mgs_modify(env, mgs, fsdb, mti, logname, mti->mti_svname,
2949 /* write the new one */
2950 rc = mgs_write_log_direct(env, mgs, fsdb, logname, lcr,
2951 mti->mti_svname, comment);
2953 CERROR("%s: error writing log %s: rc = %d\n",
2954 mgs->mgs_obd->obd_name, logname, rc);
2956 name_destroy(&logname);
2958 lustre_cfg_rec_free(lcr);
2960 OBD_FREE(comment, len + 1);
2964 static int mgs_srpc_set_param_udesc_mem(struct fs_db *fsdb,
2969 /* disable the adjustable udesc parameter for now, i.e. use default
2970 * setting that client always ship udesc to MDT if possible. to enable
2971 * it simply remove the following line */
2974 ptr = strchr(param, '=');
2979 if (strcmp(param, PARAM_SRPC_UDESC))
2982 if (strcmp(ptr, "yes") == 0) {
2983 set_bit(FSDB_UDESC, &fsdb->fsdb_flags);
2984 CWARN("Enable user descriptor shipping from client to MDT\n");
2985 } else if (strcmp(ptr, "no") == 0) {
2986 clear_bit(FSDB_UDESC, &fsdb->fsdb_flags);
2987 CWARN("Disable user descriptor shipping from client to MDT\n");
2995 CERROR("Invalid param: %s\n", param);
2999 static int mgs_srpc_set_param_mem(struct fs_db *fsdb,
3003 struct sptlrpc_rule rule;
3004 struct sptlrpc_rule_set *rset;
3008 if (strncmp(param, PARAM_SRPC, sizeof(PARAM_SRPC) - 1) != 0) {
3009 CERROR("Invalid sptlrpc parameter: %s\n", param);
3013 if (strncmp(param, PARAM_SRPC_UDESC,
3014 sizeof(PARAM_SRPC_UDESC) - 1) == 0) {
3015 RETURN(mgs_srpc_set_param_udesc_mem(fsdb, param));
3018 if (strncmp(param, PARAM_SRPC_FLVR, sizeof(PARAM_SRPC_FLVR) - 1) != 0) {
3019 CERROR("Invalid sptlrpc flavor parameter: %s\n", param);
3023 param += sizeof(PARAM_SRPC_FLVR) - 1;
3025 rc = sptlrpc_parse_rule(param, &rule);
3029 /* mgs rules implies must be mgc->mgs */
3030 if (test_bit(FSDB_MGS_SELF, &fsdb->fsdb_flags)) {
3031 if ((rule.sr_from != LUSTRE_SP_MGC &&
3032 rule.sr_from != LUSTRE_SP_ANY) ||
3033 (rule.sr_to != LUSTRE_SP_MGS &&
3034 rule.sr_to != LUSTRE_SP_ANY))
3038 /* preapre room for this coming rule. svcname format should be:
3039 * - fsname: general rule
3040 * - fsname-tgtname: target-specific rule
3042 if (strchr(svname, '-')) {
3043 struct mgs_tgt_srpc_conf *tgtconf;
3046 for (tgtconf = fsdb->fsdb_srpc_tgt; tgtconf != NULL;
3047 tgtconf = tgtconf->mtsc_next) {
3048 if (!strcmp(tgtconf->mtsc_tgt, svname)) {
3057 OBD_ALLOC_PTR(tgtconf);
3058 if (tgtconf == NULL)
3061 name_len = strlen(svname);
3063 OBD_ALLOC(tgtconf->mtsc_tgt, name_len + 1);
3064 if (tgtconf->mtsc_tgt == NULL) {
3065 OBD_FREE_PTR(tgtconf);
3068 memcpy(tgtconf->mtsc_tgt, svname, name_len);
3070 tgtconf->mtsc_next = fsdb->fsdb_srpc_tgt;
3071 fsdb->fsdb_srpc_tgt = tgtconf;
3074 rset = &tgtconf->mtsc_rset;
3075 } else if (strcmp(svname, MGSSELF_NAME) == 0) {
3076 /* put _mgs related srpc rule directly in mgs ruleset */
3077 rset = &fsdb->fsdb_mgs->mgs_lut.lut_sptlrpc_rset;
3079 rset = &fsdb->fsdb_srpc_gen;
3082 rc = sptlrpc_rule_set_merge(rset, &rule);
3087 static int mgs_srpc_set_param(const struct lu_env *env,
3088 struct mgs_device *mgs,
3090 struct mgs_target_info *mti,
3100 /* keep a copy of original param, which could be destroied
3102 copy_size = strlen(param) + 1;
3103 OBD_ALLOC(copy, copy_size);
3106 memcpy(copy, param, copy_size);
3108 rc = mgs_srpc_set_param_mem(fsdb, mti->mti_svname, param);
3112 /* previous steps guaranteed the syntax is correct */
3113 rc = mgs_srpc_set_param_disk(env, mgs, fsdb, mti, copy);
3117 if (test_bit(FSDB_MGS_SELF, &fsdb->fsdb_flags)) {
3119 * for mgs rules, make them effective immediately.
3121 LASSERT(fsdb->fsdb_srpc_tgt == NULL);
3122 sptlrpc_target_update_exp_flavor(mgs->mgs_obd,
3123 &fsdb->fsdb_srpc_gen);
3127 OBD_FREE(copy, copy_size);
3131 struct mgs_srpc_read_data {
3132 struct fs_db *msrd_fsdb;
3136 static int mgs_srpc_read_handler(const struct lu_env *env,
3137 struct llog_handle *llh,
3138 struct llog_rec_hdr *rec, void *data)
3140 struct mgs_srpc_read_data *msrd = data;
3141 struct cfg_marker *marker;
3142 struct lustre_cfg *lcfg = REC_DATA(rec);
3143 char *svname, *param;
3147 if (rec->lrh_type != OBD_CFG_REC) {
3148 CERROR("unhandled lrh_type: %#x\n", rec->lrh_type);
3152 cfg_len = REC_DATA_LEN(rec);
3154 rc = lustre_cfg_sanity_check(lcfg, cfg_len);
3156 CERROR("Insane cfg\n");
3160 if (lcfg->lcfg_command == LCFG_MARKER) {
3161 marker = lustre_cfg_buf(lcfg, 1);
3163 if (marker->cm_flags & CM_START &&
3164 marker->cm_flags & CM_SKIP)
3165 msrd->msrd_skip = 1;
3166 if (marker->cm_flags & CM_END)
3167 msrd->msrd_skip = 0;
3172 if (msrd->msrd_skip)
3175 if (lcfg->lcfg_command != LCFG_SPTLRPC_CONF) {
3176 CERROR("invalid command (%x)\n", lcfg->lcfg_command);
3180 svname = lustre_cfg_string(lcfg, 0);
3181 if (svname == NULL) {
3182 CERROR("svname is empty\n");
3186 param = lustre_cfg_string(lcfg, 1);
3187 if (param == NULL) {
3188 CERROR("param is empty\n");
3192 rc = mgs_srpc_set_param_mem(msrd->msrd_fsdb, svname, param);
3194 CERROR("read sptlrpc record error (%d): %s\n", rc, param);
3199 int mgs_get_fsdb_srpc_from_llog(const struct lu_env *env,
3200 struct mgs_device *mgs,
3203 struct llog_handle *llh = NULL;
3204 struct llog_ctxt *ctxt;
3206 struct mgs_srpc_read_data msrd;
3210 /* construct log name */
3211 rc = name_create(&logname, fsdb->fsdb_name, "-sptlrpc");
3215 ctxt = llog_get_context(mgs->mgs_obd, LLOG_CONFIG_ORIG_CTXT);
3216 LASSERT(ctxt != NULL);
3218 if (mgs_log_is_empty(env, mgs, logname))
3221 rc = llog_open(env, ctxt, &llh, NULL, logname,
3229 rc = llog_init_handle(env, llh, LLOG_F_IS_PLAIN, NULL);
3231 GOTO(out_close, rc);
3233 if (llog_get_size(llh) <= 1)
3234 GOTO(out_close, rc = 0);
3236 msrd.msrd_fsdb = fsdb;
3239 rc = llog_process(env, llh, mgs_srpc_read_handler, (void *)&msrd,
3243 llog_close(env, llh);
3245 llog_ctxt_put(ctxt);
3246 name_destroy(&logname);
3249 CERROR("failed to read sptlrpc config database: %d\n", rc);
3253 /* Permanent settings of all parameters by writing into the appropriate
3254 * configuration logs.
3255 * A parameter with null value ("<param>='\0'") means to erase it out of
3258 static int mgs_write_log_param(const struct lu_env *env,
3259 struct mgs_device *mgs, struct fs_db *fsdb,
3260 struct mgs_target_info *mti, char *ptr)
3262 struct mgs_thread_info *mgi = mgs_env_info(env);
3265 int rc = 0, rc2 = 0;
3268 /* For various parameter settings, we have to figure out which logs
3269 care about them (e.g. both mdt and client for lov settings) */
3270 CDEBUG(D_MGS, "next param '%s'\n", ptr);
3272 /* The params are stored in MOUNT_DATA_FILE and modified via
3273 tunefs.lustre, or set using lctl conf_param */
3275 /* Processed in lustre_start_mgc */
3276 if (class_match_param(ptr, PARAM_MGSNODE, NULL) == 0)
3279 /* Processed in ost/mdt */
3280 if (class_match_param(ptr, PARAM_NETWORK, NULL) == 0)
3283 /* Processed in mgs_write_log_ost */
3284 if (class_match_param(ptr, PARAM_FAILMODE, NULL) == 0) {
3285 if (mti->mti_flags & LDD_F_PARAM) {
3286 LCONSOLE_ERROR_MSG(0x169, "%s can only be "
3287 "changed with tunefs.lustre"
3288 "and --writeconf\n", ptr);
3294 if (class_match_param(ptr, PARAM_SRPC, NULL) == 0) {
3295 rc = mgs_srpc_set_param(env, mgs, fsdb, mti, ptr);
3299 if (class_match_param(ptr, PARAM_FAILNODE, NULL) == 0) {
3300 /* Add a failover nidlist */
3302 /* We already processed failovers params for new
3303 targets in mgs_write_log_target */
3304 if (mti->mti_flags & LDD_F_PARAM) {
3305 CDEBUG(D_MGS, "Adding failnode\n");
3306 rc = mgs_write_log_add_failnid(env, mgs, fsdb, mti);
3311 if (class_match_param(ptr, PARAM_SYS, &tmp) == 0) {
3312 rc = mgs_write_log_sys(env, mgs, fsdb, mti, ptr, tmp);
3316 if (class_match_param(ptr, PARAM_QUOTA, &tmp) == 0) {
3317 rc = mgs_write_log_quota(env, mgs, fsdb, mti, ptr, tmp);
3321 if (class_match_param(ptr, PARAM_OSC PARAM_ACTIVE, &tmp) == 0 ||
3322 class_match_param(ptr, PARAM_MDC PARAM_ACTIVE, &tmp) == 0) {
3323 /* active=0 means off, anything else means on */
3324 int flag = (*tmp == '0') ? CM_EXCLUDE : 0;
3325 bool deactive_osc = memcmp(ptr, PARAM_OSC PARAM_ACTIVE,
3326 strlen(PARAM_OSC PARAM_ACTIVE)) == 0;
3329 if (!deactive_osc) {
3332 rc = server_name2index(mti->mti_svname, &index, NULL);
3337 LCONSOLE_ERROR_MSG(0x144, "%s: MDC0 can not be"
3338 " (de)activated.\n",
3340 GOTO(end, rc = -EINVAL);
3344 LCONSOLE_WARN("Permanently %sactivating %s\n",
3345 flag ? "de" : "re", mti->mti_svname);
3347 rc = name_create(&logname, mti->mti_fsname, "-client");
3350 rc = mgs_modify(env, mgs, fsdb, mti, logname,
3352 deactive_osc ? "add osc" : "add mdc", flag);
3353 name_destroy(&logname);
3358 /* Add to all MDT logs for DNE */
3359 for (i = 0; i < INDEX_MAP_SIZE * 8; i++) {
3360 if (!test_bit(i, fsdb->fsdb_mdt_index_map))
3362 rc = name_create_mdt(&logname, mti->mti_fsname, i);
3365 rc = mgs_modify(env, mgs, fsdb, mti, logname,
3367 deactive_osc ? "add osc" : "add osp",
3369 name_destroy(&logname);
3375 LCONSOLE_ERROR_MSG(0x145, "Couldn't find %s in"
3376 "log (%d). No permanent "
3377 "changes were made to the "
3379 mti->mti_svname, rc);
3380 if (test_bit(FSDB_OLDLOG14, &fsdb->fsdb_flags))
3381 LCONSOLE_ERROR_MSG(0x146, "This may be"
3386 "update the logs.\n");
3389 /* Fall through to osc/mdc proc for deactivating live
3390 OSC/OSP on running MDT / clients. */
3392 /* Below here, let obd's XXX_process_config methods handle it */
3394 /* All lov. in proc */
3395 if (class_match_param(ptr, PARAM_LOV, NULL) == 0) {
3398 CDEBUG(D_MGS, "lov param %s\n", ptr);
3399 if (!(mti->mti_flags & LDD_F_SV_TYPE_MDT)) {
3400 LCONSOLE_ERROR_MSG(0x147, "LOV params must be "
3401 "set on the MDT, not %s. "
3408 if (mgs_log_is_empty(env, mgs, mti->mti_svname))
3409 GOTO(end, rc = -ENODEV);
3411 rc = name_create_mdt_and_lov(&logname, &mdtlovname, fsdb,
3412 mti->mti_stripe_index);
3415 rc = mgs_wlp_lcfg(env, mgs, fsdb, mti, mti->mti_svname,
3416 &mgi->mgi_bufs, mdtlovname, ptr);
3417 name_destroy(&logname);
3418 name_destroy(&mdtlovname);
3423 rc = name_create(&logname, mti->mti_fsname, "-client");
3426 rc = mgs_wlp_lcfg(env, mgs, fsdb, mti, logname, &mgi->mgi_bufs,
3427 fsdb->fsdb_clilov, ptr);
3428 name_destroy(&logname);
3432 /* All osc., mdc., llite. params in proc */
3433 if ((class_match_param(ptr, PARAM_OSC, NULL) == 0) ||
3434 (class_match_param(ptr, PARAM_MDC, NULL) == 0) ||
3435 (class_match_param(ptr, PARAM_LLITE, NULL) == 0)) {
3438 if (test_bit(FSDB_OLDLOG14, &fsdb->fsdb_flags)) {
3439 LCONSOLE_ERROR_MSG(0x148, "Upgraded client logs for %s"
3440 " cannot be modified. Consider"
3441 " updating the configuration with"
3444 GOTO(end, rc = -EINVAL);
3446 if (memcmp(ptr, PARAM_LLITE, strlen(PARAM_LLITE)) == 0) {
3447 rc = name_create(&cname, mti->mti_fsname, "-client");
3448 /* Add the client type to match the obdname in
3449 class_config_llog_handler */
3450 } else if (mti->mti_flags & LDD_F_SV_TYPE_MDT) {
3451 rc = name_create(&cname, mti->mti_svname, "-mdc");
3452 } else if (mti->mti_flags & LDD_F_SV_TYPE_OST) {
3453 rc = name_create(&cname, mti->mti_svname, "-osc");
3455 GOTO(end, rc = -EINVAL);
3460 /* Forbid direct update of llite root squash parameters.
3461 * These parameters are indirectly set via the MDT settings.
3463 if ((class_match_param(ptr, PARAM_LLITE, &tmp) == 0) &&
3464 ((memcmp(tmp, "root_squash=", 12) == 0) ||
3465 (memcmp(tmp, "nosquash_nids=", 14) == 0))) {
3466 LCONSOLE_ERROR("%s: root squash parameters can only "
3467 "be updated through MDT component\n",
3469 name_destroy(&cname);
3470 GOTO(end, rc = -EINVAL);
3473 CDEBUG(D_MGS, "%.3s param %s\n", ptr, ptr + 4);
3476 rc = name_create(&logname, mti->mti_fsname, "-client");
3478 name_destroy(&cname);
3481 rc = mgs_wlp_lcfg(env, mgs, fsdb, mti, logname, &mgi->mgi_bufs,
3484 /* osc params affect the MDT as well */
3485 if (!rc && (mti->mti_flags & LDD_F_SV_TYPE_OST)) {
3488 for (i = 0; i < INDEX_MAP_SIZE * 8; i++){
3489 if (!test_bit(i, fsdb->fsdb_mdt_index_map))
3491 name_destroy(&cname);
3492 rc = name_create_mdt_osc(&cname, mti->mti_svname,
3494 name_destroy(&logname);
3497 rc = name_create_mdt(&logname,
3498 mti->mti_fsname, i);
3501 if (!mgs_log_is_empty(env, mgs, logname)) {
3502 rc = mgs_wlp_lcfg(env, mgs, fsdb,
3512 /* For mdc activate/deactivate, it affects OSP on MDT as well */
3513 if (class_match_param(ptr, PARAM_MDC PARAM_ACTIVE, &tmp) == 0 &&
3516 char *lodname = NULL;
3517 char *param_str = NULL;
3521 /* replace mdc with osp */
3522 memcpy(ptr, PARAM_OSP, strlen(PARAM_OSP));
3523 rc = server_name2index(mti->mti_svname, &index, NULL);
3525 memcpy(ptr, PARAM_MDC, strlen(PARAM_MDC));
3529 for (i = 0; i < INDEX_MAP_SIZE * 8; i++) {
3530 if (!test_bit(i, fsdb->fsdb_mdt_index_map))
3536 name_destroy(&logname);
3537 rc = name_create_mdt(&logname, mti->mti_fsname,
3542 if (mgs_log_is_empty(env, mgs, logname))
3545 snprintf(suffix, sizeof(suffix), "-osp-MDT%04x",
3547 name_destroy(&cname);
3548 rc = name_create(&cname, mti->mti_svname,
3553 rc = mgs_wlp_lcfg(env, mgs, fsdb, mti, logname,
3554 &mgi->mgi_bufs, cname, ptr);
3558 /* Add configuration log for noitfying LOD
3559 * to active/deactive the OSP. */
3560 name_destroy(¶m_str);
3561 rc = name_create(¶m_str, cname,
3562 (*tmp == '0') ? ".active=0" :
3567 name_destroy(&lodname);
3568 rc = name_create(&lodname, logname, "-mdtlov");
3572 rc = mgs_wlp_lcfg(env, mgs, fsdb, mti, logname,
3573 &mgi->mgi_bufs, lodname,
3578 memcpy(ptr, PARAM_MDC, strlen(PARAM_MDC));
3579 name_destroy(&lodname);
3580 name_destroy(¶m_str);
3583 name_destroy(&logname);
3584 name_destroy(&cname);
3588 /* All mdt. params in proc */
3589 if (class_match_param(ptr, PARAM_MDT, &tmp) == 0) {
3593 CDEBUG(D_MGS, "%.3s param %s\n", ptr, ptr + 4);
3594 if (strncmp(mti->mti_svname, mti->mti_fsname,
3595 MTI_NAME_MAXLEN) == 0)
3596 /* device is unspecified completely? */
3597 rc = LDD_F_SV_TYPE_MDT | LDD_F_SV_ALL;
3599 rc = server_name2index(mti->mti_svname, &idx, NULL);
3602 if ((rc & LDD_F_SV_TYPE_MDT) == 0)
3604 if (rc & LDD_F_SV_ALL) {
3605 for (i = 0; i < INDEX_MAP_SIZE * 8; i++) {
3607 fsdb->fsdb_mdt_index_map))
3609 rc = name_create_mdt(&logname,
3610 mti->mti_fsname, i);
3613 rc = mgs_wlp_lcfg(env, mgs, fsdb, mti,
3614 logname, &mgi->mgi_bufs,
3616 name_destroy(&logname);
3621 if ((memcmp(tmp, "root_squash=", 12) == 0) ||
3622 (memcmp(tmp, "nosquash_nids=", 14) == 0)) {
3623 LCONSOLE_ERROR("%s: root squash parameters "
3624 "cannot be applied to a single MDT\n",
3626 GOTO(end, rc = -EINVAL);
3628 rc = mgs_wlp_lcfg(env, mgs, fsdb, mti,
3629 mti->mti_svname, &mgi->mgi_bufs,
3630 mti->mti_svname, ptr);
3635 /* root squash settings are also applied to llite
3636 * config log (see LU-1778) */
3638 ((memcmp(tmp, "root_squash=", 12) == 0) ||
3639 (memcmp(tmp, "nosquash_nids=", 14) == 0))) {
3643 rc = name_create(&cname, mti->mti_fsname, "-client");
3646 rc = name_create(&logname, mti->mti_fsname, "-client");
3648 name_destroy(&cname);
3651 rc = name_create(&ptr2, PARAM_LLITE, tmp);
3653 name_destroy(&cname);
3654 name_destroy(&logname);
3657 rc = mgs_wlp_lcfg(env, mgs, fsdb, mti, logname,
3658 &mgi->mgi_bufs, cname, ptr2);
3659 name_destroy(&ptr2);
3660 name_destroy(&logname);
3661 name_destroy(&cname);
3666 /* All mdd., ost. and osd. params in proc */
3667 if ((class_match_param(ptr, PARAM_MDD, NULL) == 0) ||
3668 (class_match_param(ptr, PARAM_OST, NULL) == 0) ||
3669 (class_match_param(ptr, PARAM_OSD, NULL) == 0)) {
3670 CDEBUG(D_MGS, "%.3s param %s\n", ptr, ptr + 4);
3671 if (mgs_log_is_empty(env, mgs, mti->mti_svname))
3672 GOTO(end, rc = -ENODEV);
3674 rc = mgs_wlp_lcfg(env, mgs, fsdb, mti, mti->mti_svname,
3675 &mgi->mgi_bufs, mti->mti_svname, ptr);
3679 LCONSOLE_WARN("Ignoring unrecognized param '%s'\n", ptr);
3684 CERROR("err %d on param '%s'\n", rc, ptr);
3689 /* Not implementing automatic failover nid addition at this time. */
3690 int mgs_check_failnid(const struct lu_env *env, struct mgs_device *mgs,
3691 struct mgs_target_info *mti)
3698 rc = mgs_find_or_make_fsdb(obd, fsname, &fsdb);
3702 if (mgs_log_is_empty(obd, mti->mti_svname))
3703 /* should never happen */
3706 CDEBUG(D_MGS, "Checking for new failnids for %s\n", mti->mti_svname);
3708 /* FIXME We can just check mti->params to see if we're already in
3709 the failover list. Modify mti->params for rewriting back at
3710 server_register_target(). */
3712 mutex_lock(&fsdb->fsdb_mutex);
3713 rc = mgs_write_log_add_failnid(obd, fsdb, mti);
3714 mutex_unlock(&fsdb->fsdb_mutex);
3723 int mgs_write_log_target(const struct lu_env *env, struct mgs_device *mgs,
3724 struct mgs_target_info *mti, struct fs_db *fsdb)
3731 /* set/check the new target index */
3732 rc = mgs_set_index(env, mgs, mti);
3736 if (rc == EALREADY) {
3737 LCONSOLE_WARN("Found index %d for %s, updating log\n",
3738 mti->mti_stripe_index, mti->mti_svname);
3739 /* We would like to mark old log sections as invalid
3740 and add new log sections in the client and mdt logs.
3741 But if we add new sections, then live clients will
3742 get repeat setup instructions for already running
3743 osc's. So don't update the client/mdt logs. */
3744 mti->mti_flags &= ~LDD_F_UPDATE;
3748 mutex_lock(&fsdb->fsdb_mutex);
3750 if (mti->mti_flags &
3751 (LDD_F_VIRGIN | LDD_F_UPGRADE14 | LDD_F_WRITECONF)) {
3752 /* Generate a log from scratch */
3753 if (mti->mti_flags & LDD_F_SV_TYPE_MDT) {
3754 rc = mgs_write_log_mdt(env, mgs, fsdb, mti);
3755 } else if (mti->mti_flags & LDD_F_SV_TYPE_OST) {
3756 rc = mgs_write_log_ost(env, mgs, fsdb, mti);
3758 CERROR("Unknown target type %#x, can't create log for "
3759 "%s\n", mti->mti_flags, mti->mti_svname);
3762 CERROR("Can't write logs for %s (%d)\n",
3763 mti->mti_svname, rc);
3767 /* Just update the params from tunefs in mgs_write_log_params */
3768 CDEBUG(D_MGS, "Update params for %s\n", mti->mti_svname);
3769 mti->mti_flags |= LDD_F_PARAM;
3772 /* allocate temporary buffer, where class_get_next_param will
3773 make copy of a current parameter */
3774 OBD_ALLOC(buf, strlen(mti->mti_params) + 1);
3776 GOTO(out_up, rc = -ENOMEM);
3777 params = mti->mti_params;
3778 while (params != NULL) {
3779 rc = class_get_next_param(¶ms, buf);
3782 /* there is no next parameter, that is
3787 CDEBUG(D_MGS, "remaining string: '%s', param: '%s'\n",
3789 rc = mgs_write_log_param(env, mgs, fsdb, mti, buf);
3794 OBD_FREE(buf, strlen(mti->mti_params) + 1);
3797 mutex_unlock(&fsdb->fsdb_mutex);
3801 int mgs_erase_log(const struct lu_env *env, struct mgs_device *mgs, char *name)
3803 struct llog_ctxt *ctxt;
3806 ctxt = llog_get_context(mgs->mgs_obd, LLOG_CONFIG_ORIG_CTXT);
3808 CERROR("%s: MGS config context doesn't exist\n",
3809 mgs->mgs_obd->obd_name);
3812 rc = llog_erase(env, ctxt, NULL, name);
3813 /* llog may not exist */
3816 llog_ctxt_put(ctxt);
3820 CERROR("%s: failed to clear log %s: %d\n",
3821 mgs->mgs_obd->obd_name, name, rc);
3826 /* erase all logs for the given fs */
3827 int mgs_erase_logs(const struct lu_env *env, struct mgs_device *mgs, char *fsname)
3830 struct list_head log_list;
3831 struct mgs_direntry *dirent, *n;
3832 int rc, len = strlen(fsname);
3836 /* Find all the logs in the CONFIGS directory */
3837 rc = class_dentry_readdir(env, mgs, &log_list);
3841 mutex_lock(&mgs->mgs_mutex);
3843 /* Delete the fs db */
3844 fsdb = mgs_find_fsdb(mgs, fsname);
3846 mgs_free_fsdb(mgs, fsdb);
3848 mutex_unlock(&mgs->mgs_mutex);
3850 list_for_each_entry_safe(dirent, n, &log_list, mde_list) {
3851 list_del_init(&dirent->mde_list);
3852 suffix = strrchr(dirent->mde_name, '-');
3853 if (suffix != NULL) {
3854 if ((len == suffix - dirent->mde_name) &&
3855 (strncmp(fsname, dirent->mde_name, len) == 0)) {
3856 CDEBUG(D_MGS, "Removing log %s\n",
3858 mgs_erase_log(env, mgs, dirent->mde_name);
3861 mgs_direntry_free(dirent);
3867 /* list all logs for the given fs */
3868 int mgs_list_logs(const struct lu_env *env, struct mgs_device *mgs,
3869 struct obd_ioctl_data *data)
3871 struct list_head log_list;
3872 struct mgs_direntry *dirent, *n;
3878 /* Find all the logs in the CONFIGS directory */
3879 rc = class_dentry_readdir(env, mgs, &log_list);
3883 out = data->ioc_bulk;
3884 remains = data->ioc_inllen1;
3885 list_for_each_entry_safe(dirent, n, &log_list, mde_list) {
3886 list_del_init(&dirent->mde_list);
3887 suffix = strrchr(dirent->mde_name, '-');
3888 if (suffix != NULL) {
3889 l = snprintf(out, remains, "config log: $%s\n",
3894 mgs_direntry_free(dirent);
3901 /* from llog_swab */
3902 static void print_lustre_cfg(struct lustre_cfg *lcfg)
3907 CDEBUG(D_MGS, "lustre_cfg: %p\n", lcfg);
3908 CDEBUG(D_MGS, "\tlcfg->lcfg_version: %#x\n", lcfg->lcfg_version);
3910 CDEBUG(D_MGS, "\tlcfg->lcfg_command: %#x\n", lcfg->lcfg_command);
3911 CDEBUG(D_MGS, "\tlcfg->lcfg_num: %#x\n", lcfg->lcfg_num);
3912 CDEBUG(D_MGS, "\tlcfg->lcfg_flags: %#x\n", lcfg->lcfg_flags);
3913 CDEBUG(D_MGS, "\tlcfg->lcfg_nid: %s\n", libcfs_nid2str(lcfg->lcfg_nid));
3915 CDEBUG(D_MGS, "\tlcfg->lcfg_bufcount: %d\n", lcfg->lcfg_bufcount);
3916 if (lcfg->lcfg_bufcount < LUSTRE_CFG_MAX_BUFCOUNT)
3917 for (i = 0; i < lcfg->lcfg_bufcount; i++) {
3918 CDEBUG(D_MGS, "\tlcfg->lcfg_buflens[%d]: %d %s\n",
3919 i, lcfg->lcfg_buflens[i],
3920 lustre_cfg_string(lcfg, i));
3925 /* Setup _mgs fsdb and log
3927 int mgs__mgs_fsdb_setup(const struct lu_env *env, struct mgs_device *mgs,
3933 rc = mgs_find_or_make_fsdb(env, mgs, MGSSELF_NAME, &fsdb);
3938 /* Setup params fsdb and log
3940 int mgs_params_fsdb_setup(const struct lu_env *env, struct mgs_device *mgs,
3943 struct llog_handle *params_llh = NULL;
3947 rc = mgs_find_or_make_fsdb(env, mgs, PARAMS_FILENAME, &fsdb);
3949 mutex_lock(&fsdb->fsdb_mutex);
3950 rc = record_start_log(env, mgs, ¶ms_llh, PARAMS_FILENAME);
3952 rc = record_end_log(env, ¶ms_llh);
3953 mutex_unlock(&fsdb->fsdb_mutex);
3959 /* Cleanup params fsdb and log
3961 int mgs_params_fsdb_cleanup(const struct lu_env *env, struct mgs_device *mgs)
3963 return mgs_erase_logs(env, mgs, PARAMS_FILENAME);
3966 /* Set a permanent (config log) param for a target or fs
3967 * \param lcfg buf0 may contain the device (testfs-MDT0000) name
3968 * buf1 contains the single parameter
3970 int mgs_setparam(const struct lu_env *env, struct mgs_device *mgs,
3971 struct lustre_cfg *lcfg, char *fsname)
3974 struct mgs_target_info *mti;
3975 char *devname, *param;
3982 print_lustre_cfg(lcfg);
3984 /* lustre, lustre-mdtlov, lustre-client, lustre-MDT0000 */
3985 devname = lustre_cfg_string(lcfg, 0);
3986 param = lustre_cfg_string(lcfg, 1);
3988 /* Assume device name embedded in param:
3989 lustre-OST0000.osc.max_dirty_mb=32 */
3990 ptr = strchr(param, '.');
3998 LCONSOLE_ERROR_MSG(0x14d, "No target specified: %s\n", param);
4002 rc = mgs_parse_devname(devname, fsname, NULL);
4003 if (rc == 0 && !mgs_parse_devname(devname, NULL, &index)) {
4004 /* param related to llite isn't allowed to set by OST or MDT */
4005 if (rc == 0 && strncmp(param, PARAM_LLITE,
4006 sizeof(PARAM_LLITE) - 1) == 0)
4009 /* assume devname is the fsname */
4010 strlcpy(fsname, devname, MTI_NAME_MAXLEN);
4012 CDEBUG(D_MGS, "setparam fs='%s' device='%s'\n", fsname, devname);
4014 rc = mgs_find_or_make_fsdb(env, mgs,
4015 lcfg->lcfg_command == LCFG_SET_PARAM ?
4016 PARAMS_FILENAME : fsname, &fsdb);
4020 if (lcfg->lcfg_command != LCFG_SET_PARAM &&
4021 !test_bit(FSDB_MGS_SELF, &fsdb->fsdb_flags) &&
4022 test_bit(FSDB_LOG_EMPTY, &fsdb->fsdb_flags)) {
4023 CERROR("No filesystem targets for %s. cfg_device from lctl "
4024 "is '%s'\n", fsname, devname);
4025 mgs_free_fsdb(mgs, fsdb);
4029 /* Create a fake mti to hold everything */
4032 GOTO(out, rc = -ENOMEM);
4033 if (strlcpy(mti->mti_fsname, fsname, sizeof(mti->mti_fsname))
4034 >= sizeof(mti->mti_fsname))
4035 GOTO(out, rc = -E2BIG);
4036 if (strlcpy(mti->mti_svname, devname, sizeof(mti->mti_svname))
4037 >= sizeof(mti->mti_svname))
4038 GOTO(out, rc = -E2BIG);
4039 if (strlcpy(mti->mti_params, param, sizeof(mti->mti_params))
4040 >= sizeof(mti->mti_params))
4041 GOTO(out, rc = -E2BIG);
4042 rc = server_name2index(mti->mti_svname, &mti->mti_stripe_index, &tmp);
4044 /* Not a valid server; may be only fsname */
4047 /* Strip -osc or -mdc suffix from svname */
4048 if (server_make_name(rc, mti->mti_stripe_index, mti->mti_fsname,
4050 GOTO(out, rc = -EINVAL);
4052 * Revoke lock so everyone updates. Should be alright if
4053 * someone was already reading while we were updating the logs,
4054 * so we don't really need to hold the lock while we're
4057 if (lcfg->lcfg_command == LCFG_SET_PARAM) {
4058 mti->mti_flags = rc | LDD_F_PARAM2;
4059 mutex_lock(&fsdb->fsdb_mutex);
4060 rc = mgs_write_log_param2(env, mgs, fsdb, mti, mti->mti_params);
4061 mutex_unlock(&fsdb->fsdb_mutex);
4062 mgs_revoke_lock(mgs, fsdb, CONFIG_T_PARAMS);
4064 mti->mti_flags = rc | LDD_F_PARAM;
4065 mutex_lock(&fsdb->fsdb_mutex);
4066 rc = mgs_write_log_param(env, mgs, fsdb, mti, mti->mti_params);
4067 mutex_unlock(&fsdb->fsdb_mutex);
4068 mgs_revoke_lock(mgs, fsdb, CONFIG_T_CONFIG);
4076 static int mgs_write_log_pool(const struct lu_env *env,
4077 struct mgs_device *mgs, char *logname,
4078 struct fs_db *fsdb, char *tgtname,
4079 enum lcfg_command_type cmd,
4080 char *fsname, char *poolname,
4081 char *ostname, char *comment)
4083 struct llog_handle *llh = NULL;
4086 rc = record_start_log(env, mgs, &llh, logname);
4089 rc = record_marker(env, llh, fsdb, CM_START, tgtname, comment);
4092 rc = record_base(env, llh, tgtname, 0, cmd,
4093 fsname, poolname, ostname, NULL);
4096 rc = record_marker(env, llh, fsdb, CM_END, tgtname, comment);
4098 record_end_log(env, &llh);
4102 int mgs_nodemap_cmd(const struct lu_env *env, struct mgs_device *mgs,
4103 enum lcfg_command_type cmd, const char *nodemap_name,
4114 case LCFG_NODEMAP_ADD:
4115 rc = nodemap_add(nodemap_name);
4117 case LCFG_NODEMAP_DEL:
4118 rc = nodemap_del(nodemap_name);
4120 case LCFG_NODEMAP_ADD_RANGE:
4121 rc = nodemap_parse_range(param, nid);
4124 rc = nodemap_add_range(nodemap_name, nid);
4126 case LCFG_NODEMAP_DEL_RANGE:
4127 rc = nodemap_parse_range(param, nid);
4130 rc = nodemap_del_range(nodemap_name, nid);
4132 case LCFG_NODEMAP_ADMIN:
4133 bool_switch = simple_strtoul(param, NULL, 10);
4134 rc = nodemap_set_allow_root(nodemap_name, bool_switch);
4136 case LCFG_NODEMAP_TRUSTED:
4137 bool_switch = simple_strtoul(param, NULL, 10);
4138 rc = nodemap_set_trust_client_ids(nodemap_name, bool_switch);
4140 case LCFG_NODEMAP_SQUASH_UID:
4141 int_id = simple_strtoul(param, NULL, 10);
4142 rc = nodemap_set_squash_uid(nodemap_name, int_id);
4144 case LCFG_NODEMAP_SQUASH_GID:
4145 int_id = simple_strtoul(param, NULL, 10);
4146 rc = nodemap_set_squash_gid(nodemap_name, int_id);
4148 case LCFG_NODEMAP_ADD_UIDMAP:
4149 case LCFG_NODEMAP_ADD_GIDMAP:
4150 rc = nodemap_parse_idmap(param, idmap);
4153 if (cmd == LCFG_NODEMAP_ADD_UIDMAP)
4154 rc = nodemap_add_idmap(nodemap_name, NODEMAP_UID,
4157 rc = nodemap_add_idmap(nodemap_name, NODEMAP_GID,
4160 case LCFG_NODEMAP_DEL_UIDMAP:
4161 case LCFG_NODEMAP_DEL_GIDMAP:
4162 rc = nodemap_parse_idmap(param, idmap);
4165 if (cmd == LCFG_NODEMAP_DEL_UIDMAP)
4166 rc = nodemap_del_idmap(nodemap_name, NODEMAP_UID,
4169 rc = nodemap_del_idmap(nodemap_name, NODEMAP_GID,
4179 int mgs_pool_cmd(const struct lu_env *env, struct mgs_device *mgs,
4180 enum lcfg_command_type cmd, char *fsname,
4181 char *poolname, char *ostname)
4186 char *label = NULL, *canceled_label = NULL;
4188 struct mgs_target_info *mti = NULL;
4192 rc = mgs_find_or_make_fsdb(env, mgs, fsname, &fsdb);
4194 CERROR("Can't get db for %s\n", fsname);
4197 if (test_bit(FSDB_LOG_EMPTY, &fsdb->fsdb_flags)) {
4198 CERROR("%s is not defined\n", fsname);
4199 mgs_free_fsdb(mgs, fsdb);
4203 label_sz = 10 + strlen(fsname) + strlen(poolname);
4205 /* check if ostname match fsname */
4206 if (ostname != NULL) {
4209 ptr = strrchr(ostname, '-');
4210 if ((ptr == NULL) ||
4211 (strncmp(fsname, ostname, ptr-ostname) != 0))
4213 label_sz += strlen(ostname);
4216 OBD_ALLOC(label, label_sz);
4223 "new %s.%s", fsname, poolname);
4227 "add %s.%s.%s", fsname, poolname, ostname);
4230 OBD_ALLOC(canceled_label, label_sz);
4231 if (canceled_label == NULL)
4232 GOTO(out_label, rc = -ENOMEM);
4234 "rem %s.%s.%s", fsname, poolname, ostname);
4235 sprintf(canceled_label,
4236 "add %s.%s.%s", fsname, poolname, ostname);
4239 OBD_ALLOC(canceled_label, label_sz);
4240 if (canceled_label == NULL)
4241 GOTO(out_label, rc = -ENOMEM);
4243 "del %s.%s", fsname, poolname);
4244 sprintf(canceled_label,
4245 "new %s.%s", fsname, poolname);
4251 if (canceled_label != NULL) {
4254 GOTO(out_cancel, rc = -ENOMEM);
4257 mutex_lock(&fsdb->fsdb_mutex);
4258 /* write pool def to all MDT logs */
4259 for (i = 0; i < INDEX_MAP_SIZE * 8; i++) {
4260 if (test_bit(i, fsdb->fsdb_mdt_index_map)) {
4261 rc = name_create_mdt_and_lov(&logname, &lovname,
4264 mutex_unlock(&fsdb->fsdb_mutex);
4267 if (canceled_label != NULL) {
4268 strcpy(mti->mti_svname, "lov pool");
4269 rc = mgs_modify(env, mgs, fsdb, mti, logname,
4270 lovname, canceled_label,
4275 rc = mgs_write_log_pool(env, mgs, logname,
4279 name_destroy(&logname);
4280 name_destroy(&lovname);
4282 mutex_unlock(&fsdb->fsdb_mutex);
4288 rc = name_create(&logname, fsname, "-client");
4290 mutex_unlock(&fsdb->fsdb_mutex);
4293 if (canceled_label != NULL) {
4294 rc = mgs_modify(env, mgs, fsdb, mti, logname,
4295 fsdb->fsdb_clilov, canceled_label, CM_SKIP);
4297 mutex_unlock(&fsdb->fsdb_mutex);
4298 name_destroy(&logname);
4303 rc = mgs_write_log_pool(env, mgs, logname, fsdb, fsdb->fsdb_clilov,
4304 cmd, fsname, poolname, ostname, label);
4305 mutex_unlock(&fsdb->fsdb_mutex);
4306 name_destroy(&logname);
4307 /* request for update */
4308 mgs_revoke_lock(mgs, fsdb, CONFIG_T_CONFIG);
4315 if (canceled_label != NULL)
4316 OBD_FREE(canceled_label, label_sz);
4318 OBD_FREE(label, label_sz);