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, 2013, 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
50 #include <lustre_param.h>
51 #include <lustre_sec.h>
52 #include <lustre_quota.h>
54 #include "mgs_internal.h"
56 /********************** Class functions ********************/
58 int class_dentry_readdir(const struct lu_env *env,
59 struct mgs_device *mgs, cfs_list_t *list)
61 struct dt_object *dir = mgs->mgs_configs_dir;
62 const struct dt_it_ops *iops;
64 struct mgs_direntry *de;
68 CFS_INIT_LIST_HEAD(list);
70 if (!dt_try_as_dir(env, dir))
71 GOTO(out, rc = -ENOTDIR);
74 LASSERT(dir->do_index_ops);
76 iops = &dir->do_index_ops->dio_it;
77 it = iops->init(env, dir, LUDA_64BITHASH, BYPASS_CAPA);
81 rc = iops->load(env, it, 0);
87 key = (void *)iops->key(env, it);
89 CERROR("%s: key failed when listing %s: rc = %d\n",
90 mgs->mgs_obd->obd_name, MOUNT_CONFIGS_DIR,
94 key_sz = iops->key_size(env, it);
97 /* filter out "." and ".." entries */
101 if (key_sz == 2 && key[1] == '.')
105 de = mgs_direntry_alloc(key_sz + 1);
111 memcpy(de->name, key, key_sz);
112 de->name[key_sz] = 0;
114 cfs_list_add(&de->list, list);
117 rc = iops->next(env, it);
127 CERROR("%s: key failed when listing %s: rc = %d\n",
128 mgs->mgs_obd->obd_name, MOUNT_CONFIGS_DIR, rc);
132 /******************** DB functions *********************/
134 static inline int name_create(char **newname, char *prefix, char *suffix)
137 OBD_ALLOC(*newname, strlen(prefix) + strlen(suffix) + 1);
140 sprintf(*newname, "%s%s", prefix, suffix);
144 static inline void name_destroy(char **name)
147 OBD_FREE(*name, strlen(*name) + 1);
151 struct mgs_fsdb_handler_data
157 /* from the (client) config log, figure out:
158 1. which ost's/mdt's are configured (by index)
159 2. what the last config step is
160 3. COMPAT_18 osc name
162 /* It might be better to have a separate db file, instead of parsing the info
163 out of the client log. This is slow and potentially error-prone. */
164 static int mgs_fsdb_handler(const struct lu_env *env, struct llog_handle *llh,
165 struct llog_rec_hdr *rec, void *data)
167 struct mgs_fsdb_handler_data *d = data;
168 struct fs_db *fsdb = d->fsdb;
169 int cfg_len = rec->lrh_len;
170 char *cfg_buf = (char*) (rec + 1);
171 struct lustre_cfg *lcfg;
176 if (rec->lrh_type != OBD_CFG_REC) {
177 CERROR("unhandled lrh_type: %#x\n", rec->lrh_type);
181 rc = lustre_cfg_sanity_check(cfg_buf, cfg_len);
183 CERROR("Insane cfg\n");
187 lcfg = (struct lustre_cfg *)cfg_buf;
189 CDEBUG(D_INFO, "cmd %x %s %s\n", lcfg->lcfg_command,
190 lustre_cfg_string(lcfg, 0), lustre_cfg_string(lcfg, 1));
192 /* Figure out ost indicies */
193 /* lov_modify_tgts add 0:lov1 1:ost1_UUID 2(index):0 3(gen):1 */
194 if (lcfg->lcfg_command == LCFG_LOV_ADD_OBD ||
195 lcfg->lcfg_command == LCFG_LOV_DEL_OBD) {
196 index = simple_strtoul(lustre_cfg_string(lcfg, 2),
198 CDEBUG(D_MGS, "OST index for %s is %u (%s)\n",
199 lustre_cfg_string(lcfg, 1), index,
200 lustre_cfg_string(lcfg, 2));
201 set_bit(index, fsdb->fsdb_ost_index_map);
204 /* Figure out mdt indicies */
205 /* attach 0:MDC_uml1_mdsA_MNT_client 1:mdc 2:1d834_MNT_client_03f */
206 if ((lcfg->lcfg_command == LCFG_ATTACH) &&
207 (strcmp(lustre_cfg_string(lcfg, 1), LUSTRE_MDC_NAME) == 0)) {
208 rc = server_name2index(lustre_cfg_string(lcfg, 0),
210 if (rc != LDD_F_SV_TYPE_MDT) {
211 CWARN("Unparsable MDC name %s, assuming index 0\n",
212 lustre_cfg_string(lcfg, 0));
216 CDEBUG(D_MGS, "MDT index is %u\n", index);
217 set_bit(index, fsdb->fsdb_mdt_index_map);
218 fsdb->fsdb_mdt_count ++;
222 * figure out the old config. fsdb_gen = 0 means old log
223 * It is obsoleted and not supported anymore
225 if (fsdb->fsdb_gen == 0) {
226 CERROR("Old config format is not supported\n");
231 * compat to 1.8, check osc name used by MDT0 to OSTs, bz18548.
233 if (!test_bit(FSDB_OSCNAME18, &fsdb->fsdb_flags) &&
234 lcfg->lcfg_command == LCFG_ATTACH &&
235 strcmp(lustre_cfg_string(lcfg, 1), LUSTRE_OSC_NAME) == 0) {
236 if (OBD_OCD_VERSION_MAJOR(d->ver) == 1 &&
237 OBD_OCD_VERSION_MINOR(d->ver) <= 8) {
238 CWARN("MDT using 1.8 OSC name scheme\n");
239 set_bit(FSDB_OSCNAME18, &fsdb->fsdb_flags);
243 if (lcfg->lcfg_command == LCFG_MARKER) {
244 struct cfg_marker *marker;
245 marker = lustre_cfg_buf(lcfg, 1);
247 d->ver = marker->cm_vers;
249 /* Keep track of the latest marker step */
250 fsdb->fsdb_gen = max(fsdb->fsdb_gen, marker->cm_step);
256 /* fsdb->fsdb_mutex is already held in mgs_find_or_make_fsdb*/
257 static int mgs_get_fsdb_from_llog(const struct lu_env *env,
258 struct mgs_device *mgs,
262 struct llog_handle *loghandle;
263 struct llog_ctxt *ctxt;
264 struct mgs_fsdb_handler_data d = { fsdb, 0 };
269 ctxt = llog_get_context(mgs->mgs_obd, LLOG_CONFIG_ORIG_CTXT);
270 LASSERT(ctxt != NULL);
271 rc = name_create(&logname, fsdb->fsdb_name, "-client");
274 rc = llog_open_create(env, ctxt, &loghandle, NULL, logname);
278 rc = llog_init_handle(env, loghandle, LLOG_F_IS_PLAIN, NULL);
282 if (llog_get_size(loghandle) <= 1)
283 set_bit(FSDB_LOG_EMPTY, &fsdb->fsdb_flags);
285 rc = llog_process(env, loghandle, mgs_fsdb_handler, (void *)&d, NULL);
286 CDEBUG(D_INFO, "get_db = %d\n", rc);
288 llog_close(env, loghandle);
290 name_destroy(&logname);
297 static void mgs_free_fsdb_srpc(struct fs_db *fsdb)
299 struct mgs_tgt_srpc_conf *tgtconf;
301 /* free target-specific rules */
302 while (fsdb->fsdb_srpc_tgt) {
303 tgtconf = fsdb->fsdb_srpc_tgt;
304 fsdb->fsdb_srpc_tgt = tgtconf->mtsc_next;
306 LASSERT(tgtconf->mtsc_tgt);
308 sptlrpc_rule_set_free(&tgtconf->mtsc_rset);
309 OBD_FREE(tgtconf->mtsc_tgt, strlen(tgtconf->mtsc_tgt) + 1);
310 OBD_FREE_PTR(tgtconf);
313 /* free general rules */
314 sptlrpc_rule_set_free(&fsdb->fsdb_srpc_gen);
317 struct fs_db *mgs_find_fsdb(struct mgs_device *mgs, char *fsname)
322 cfs_list_for_each(tmp, &mgs->mgs_fs_db_list) {
323 fsdb = cfs_list_entry(tmp, struct fs_db, fsdb_list);
324 if (strcmp(fsdb->fsdb_name, fsname) == 0)
330 /* caller must hold the mgs->mgs_fs_db_lock */
331 static struct fs_db *mgs_new_fsdb(const struct lu_env *env,
332 struct mgs_device *mgs, char *fsname)
338 if (strlen(fsname) >= sizeof(fsdb->fsdb_name)) {
339 CERROR("fsname %s is too long\n", fsname);
347 strcpy(fsdb->fsdb_name, fsname);
348 mutex_init(&fsdb->fsdb_mutex);
349 set_bit(FSDB_UDESC, &fsdb->fsdb_flags);
352 if (strcmp(fsname, MGSSELF_NAME) == 0) {
353 set_bit(FSDB_MGS_SELF, &fsdb->fsdb_flags);
355 OBD_ALLOC(fsdb->fsdb_ost_index_map, INDEX_MAP_SIZE);
356 OBD_ALLOC(fsdb->fsdb_mdt_index_map, INDEX_MAP_SIZE);
357 if (!fsdb->fsdb_ost_index_map || !fsdb->fsdb_mdt_index_map) {
358 CERROR("No memory for index maps\n");
359 GOTO(err, rc = -ENOMEM);
362 rc = name_create(&fsdb->fsdb_clilov, fsname, "-clilov");
365 rc = name_create(&fsdb->fsdb_clilmv, fsname, "-clilmv");
369 /* initialise data for NID table */
370 mgs_ir_init_fs(env, mgs, fsdb);
372 lproc_mgs_add_live(mgs, fsdb);
375 cfs_list_add(&fsdb->fsdb_list, &mgs->mgs_fs_db_list);
379 if (fsdb->fsdb_ost_index_map)
380 OBD_FREE(fsdb->fsdb_ost_index_map, INDEX_MAP_SIZE);
381 if (fsdb->fsdb_mdt_index_map)
382 OBD_FREE(fsdb->fsdb_mdt_index_map, INDEX_MAP_SIZE);
383 name_destroy(&fsdb->fsdb_clilov);
384 name_destroy(&fsdb->fsdb_clilmv);
389 static void mgs_free_fsdb(struct mgs_device *mgs, struct fs_db *fsdb)
391 /* wait for anyone with the sem */
392 mutex_lock(&fsdb->fsdb_mutex);
393 lproc_mgs_del_live(mgs, fsdb);
394 cfs_list_del(&fsdb->fsdb_list);
396 /* deinitialize fsr */
397 mgs_ir_fini_fs(mgs, fsdb);
399 if (fsdb->fsdb_ost_index_map)
400 OBD_FREE(fsdb->fsdb_ost_index_map, INDEX_MAP_SIZE);
401 if (fsdb->fsdb_mdt_index_map)
402 OBD_FREE(fsdb->fsdb_mdt_index_map, INDEX_MAP_SIZE);
403 name_destroy(&fsdb->fsdb_clilov);
404 name_destroy(&fsdb->fsdb_clilmv);
405 mgs_free_fsdb_srpc(fsdb);
406 mutex_unlock(&fsdb->fsdb_mutex);
410 int mgs_init_fsdb_list(struct mgs_device *mgs)
412 CFS_INIT_LIST_HEAD(&mgs->mgs_fs_db_list);
416 int mgs_cleanup_fsdb_list(struct mgs_device *mgs)
419 cfs_list_t *tmp, *tmp2;
420 mutex_lock(&mgs->mgs_mutex);
421 cfs_list_for_each_safe(tmp, tmp2, &mgs->mgs_fs_db_list) {
422 fsdb = cfs_list_entry(tmp, struct fs_db, fsdb_list);
423 mgs_free_fsdb(mgs, fsdb);
425 mutex_unlock(&mgs->mgs_mutex);
429 int mgs_find_or_make_fsdb(const struct lu_env *env,
430 struct mgs_device *mgs, char *name,
437 mutex_lock(&mgs->mgs_mutex);
438 fsdb = mgs_find_fsdb(mgs, name);
440 mutex_unlock(&mgs->mgs_mutex);
445 CDEBUG(D_MGS, "Creating new db\n");
446 fsdb = mgs_new_fsdb(env, mgs, name);
447 /* lock fsdb_mutex until the db is loaded from llogs */
449 mutex_lock(&fsdb->fsdb_mutex);
450 mutex_unlock(&mgs->mgs_mutex);
454 if (!test_bit(FSDB_MGS_SELF, &fsdb->fsdb_flags)) {
455 /* populate the db from the client llog */
456 rc = mgs_get_fsdb_from_llog(env, mgs, fsdb);
458 CERROR("Can't get db from client log %d\n", rc);
463 /* populate srpc rules from params llog */
464 rc = mgs_get_fsdb_srpc_from_llog(env, mgs, fsdb);
466 CERROR("Can't get db from params log %d\n", rc);
470 mutex_unlock(&fsdb->fsdb_mutex);
476 mutex_unlock(&fsdb->fsdb_mutex);
477 mgs_free_fsdb(mgs, fsdb);
483 -1= empty client log */
484 int mgs_check_index(const struct lu_env *env,
485 struct mgs_device *mgs,
486 struct mgs_target_info *mti)
493 LASSERT(!(mti->mti_flags & LDD_F_NEED_INDEX));
495 rc = mgs_find_or_make_fsdb(env, mgs, mti->mti_fsname, &fsdb);
497 CERROR("Can't get db for %s\n", mti->mti_fsname);
501 if (test_bit(FSDB_LOG_EMPTY, &fsdb->fsdb_flags))
504 if (mti->mti_flags & LDD_F_SV_TYPE_OST)
505 imap = fsdb->fsdb_ost_index_map;
506 else if (mti->mti_flags & LDD_F_SV_TYPE_MDT)
507 imap = fsdb->fsdb_mdt_index_map;
511 if (test_bit(mti->mti_stripe_index, imap))
516 static __inline__ int next_index(void *index_map, int map_len)
519 for (i = 0; i < map_len * 8; i++)
520 if (!test_bit(i, index_map)) {
523 CERROR("max index %d exceeded.\n", i);
528 0 newly marked as in use
530 +EALREADY for update of an old index */
531 static int mgs_set_index(const struct lu_env *env,
532 struct mgs_device *mgs,
533 struct mgs_target_info *mti)
540 rc = mgs_find_or_make_fsdb(env, mgs, mti->mti_fsname, &fsdb);
542 CERROR("Can't get db for %s\n", mti->mti_fsname);
546 mutex_lock(&fsdb->fsdb_mutex);
547 if (mti->mti_flags & LDD_F_SV_TYPE_OST) {
548 imap = fsdb->fsdb_ost_index_map;
549 } else if (mti->mti_flags & LDD_F_SV_TYPE_MDT) {
550 imap = fsdb->fsdb_mdt_index_map;
552 GOTO(out_up, rc = -EINVAL);
555 if (mti->mti_flags & LDD_F_NEED_INDEX) {
556 rc = next_index(imap, INDEX_MAP_SIZE);
558 GOTO(out_up, rc = -ERANGE);
559 mti->mti_stripe_index = rc;
560 if (mti->mti_flags & LDD_F_SV_TYPE_MDT)
561 fsdb->fsdb_mdt_count ++;
564 if (mti->mti_stripe_index >= INDEX_MAP_SIZE * 8) {
565 LCONSOLE_ERROR_MSG(0x13f, "Server %s requested index %d, "
566 "but the max index is %d.\n",
567 mti->mti_svname, mti->mti_stripe_index,
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 /* Header and tail are added back to lrh_len in
648 llog_lvfs_write_rec */
649 rec->lrh_len = cfg_len;
650 rc = llog_write(env, llh, rec, NULL, 0, (void *)lcfg,
660 * Modify an existing config log record (for CM_SKIP or CM_EXCLUDE)
662 * 0 - modified successfully,
663 * 1 - no modification was done
666 static int mgs_modify(const struct lu_env *env, struct mgs_device *mgs,
667 struct fs_db *fsdb, struct mgs_target_info *mti,
668 char *logname, char *devname, char *comment, int flags)
670 struct llog_handle *loghandle;
671 struct llog_ctxt *ctxt;
672 struct mgs_modify_lookup *mml;
677 LASSERT(mutex_is_locked(&fsdb->fsdb_mutex));
678 CDEBUG(D_MGS, "modify %s/%s/%s fl=%x\n", logname, devname, comment,
681 ctxt = llog_get_context(mgs->mgs_obd, LLOG_CONFIG_ORIG_CTXT);
682 LASSERT(ctxt != NULL);
683 rc = llog_open(env, ctxt, &loghandle, NULL, logname, LLOG_OPEN_EXISTS);
690 rc = llog_init_handle(env, loghandle, LLOG_F_IS_PLAIN, NULL);
694 if (llog_get_size(loghandle) <= 1)
695 GOTO(out_close, rc = 0);
699 GOTO(out_close, rc = -ENOMEM);
700 strcpy(mml->mml_marker.cm_comment, comment);
701 strcpy(mml->mml_marker.cm_tgtname, devname);
702 /* Modify mostly means cancel */
703 mml->mml_marker.cm_flags = flags;
704 mml->mml_marker.cm_canceltime = flags ? cfs_time_current_sec() : 0;
705 mml->mml_modified = 0;
706 rc = llog_process(env, loghandle, mgs_modify_handler, (void *)mml,
708 if (!rc && !mml->mml_modified)
713 llog_close(env, loghandle);
716 CERROR("%s: modify %s/%s failed: rc = %d\n",
717 mgs->mgs_obd->obd_name, mti->mti_svname, comment, rc);
722 /** This structure is passed to mgs_replace_handler */
723 struct mgs_replace_uuid_lookup {
724 /* Nids are replaced for this target device */
725 struct mgs_target_info target;
726 /* Temporary modified llog */
727 struct llog_handle *temp_llh;
728 /* Flag is set if in target block*/
729 int in_target_device;
730 /* Nids already added. Just skip (multiple nids) */
731 int device_nids_added;
732 /* Flag is set if this block should not be copied */
737 * Check: a) if block should be skipped
738 * b) is it target block
743 * \retval 0 should not to be skipped
744 * \retval 1 should to be skipped
746 static int check_markers(struct lustre_cfg *lcfg,
747 struct mgs_replace_uuid_lookup *mrul)
749 struct cfg_marker *marker;
751 /* Track markers. Find given device */
752 if (lcfg->lcfg_command == LCFG_MARKER) {
753 marker = lustre_cfg_buf(lcfg, 1);
754 /* Clean llog from records marked as CM_EXCLUDE.
755 CM_SKIP records are used for "active" command
756 and can be restored if needed */
757 if ((marker->cm_flags & (CM_EXCLUDE | CM_START)) ==
758 (CM_EXCLUDE | CM_START)) {
763 if ((marker->cm_flags & (CM_EXCLUDE | CM_END)) ==
764 (CM_EXCLUDE | CM_END)) {
769 if (strcmp(mrul->target.mti_svname, marker->cm_tgtname) == 0) {
770 LASSERT(!(marker->cm_flags & CM_START) ||
771 !(marker->cm_flags & CM_END));
772 if (marker->cm_flags & CM_START) {
773 mrul->in_target_device = 1;
774 mrul->device_nids_added = 0;
775 } else if (marker->cm_flags & CM_END)
776 mrul->in_target_device = 0;
783 static int record_lcfg(const struct lu_env *env, struct llog_handle *llh,
784 struct lustre_cfg *lcfg)
786 struct llog_rec_hdr rec;
792 LASSERT(llh->lgh_ctxt);
794 buflen = lustre_cfg_len(lcfg->lcfg_bufcount,
796 rec.lrh_len = llog_data_len(buflen);
797 rec.lrh_type = OBD_CFG_REC;
799 /* idx = -1 means append */
800 rc = llog_write(env, llh, &rec, NULL, 0, (void *)lcfg, -1);
802 CERROR("failed %d\n", rc);
806 static int record_base(const struct lu_env *env, struct llog_handle *llh,
807 char *cfgname, lnet_nid_t nid, int cmd,
808 char *s1, char *s2, char *s3, char *s4)
810 struct mgs_thread_info *mgi = mgs_env_info(env);
811 struct lustre_cfg *lcfg;
814 CDEBUG(D_MGS, "lcfg %s %#x %s %s %s %s\n", cfgname,
815 cmd, s1, s2, s3, s4);
817 lustre_cfg_bufs_reset(&mgi->mgi_bufs, cfgname);
819 lustre_cfg_bufs_set_string(&mgi->mgi_bufs, 1, s1);
821 lustre_cfg_bufs_set_string(&mgi->mgi_bufs, 2, s2);
823 lustre_cfg_bufs_set_string(&mgi->mgi_bufs, 3, s3);
825 lustre_cfg_bufs_set_string(&mgi->mgi_bufs, 4, s4);
827 lcfg = lustre_cfg_new(cmd, &mgi->mgi_bufs);
830 lcfg->lcfg_nid = nid;
832 rc = record_lcfg(env, llh, lcfg);
834 lustre_cfg_free(lcfg);
837 CERROR("error %d: lcfg %s %#x %s %s %s %s\n", rc, cfgname,
838 cmd, s1, s2, s3, s4);
843 static inline int record_add_uuid(const struct lu_env *env,
844 struct llog_handle *llh,
845 uint64_t nid, char *uuid)
847 return record_base(env, llh, NULL, nid, LCFG_ADD_UUID, uuid, 0, 0, 0);
850 static inline int record_add_conn(const struct lu_env *env,
851 struct llog_handle *llh,
852 char *devname, char *uuid)
854 return record_base(env, llh, devname, 0, LCFG_ADD_CONN, uuid, 0, 0, 0);
857 static inline int record_attach(const struct lu_env *env,
858 struct llog_handle *llh, char *devname,
859 char *type, char *uuid)
861 return record_base(env, llh,devname, 0, LCFG_ATTACH, type, uuid, 0, 0);
864 static inline int record_setup(const struct lu_env *env,
865 struct llog_handle *llh, char *devname,
866 char *s1, char *s2, char *s3, char *s4)
868 return record_base(env, llh, devname, 0, LCFG_SETUP, s1, s2, s3, s4);
872 * \retval <0 record processing error
873 * \retval n record is processed. No need copy original one.
874 * \retval 0 record is not processed.
876 static int process_command(const struct lu_env *env, struct lustre_cfg *lcfg,
877 struct mgs_replace_uuid_lookup *mrul)
884 if (lcfg->lcfg_command == LCFG_ADD_UUID) {
885 /* LCFG_ADD_UUID command found. Let's skip original command
886 and add passed nids */
887 ptr = mrul->target.mti_params;
888 while (class_parse_nid(ptr, &nid, &ptr) == 0) {
889 CDEBUG(D_MGS, "add nid %s with uuid %s, "
890 "device %s\n", libcfs_nid2str(nid),
891 mrul->target.mti_params,
892 mrul->target.mti_svname);
893 rc = record_add_uuid(env,
895 mrul->target.mti_params);
900 if (nids_added == 0) {
901 CERROR("No new nids were added, nid %s with uuid %s, "
902 "device %s\n", libcfs_nid2str(nid),
903 mrul->target.mti_params,
904 mrul->target.mti_svname);
907 mrul->device_nids_added = 1;
913 if (mrul->device_nids_added && lcfg->lcfg_command == LCFG_SETUP) {
914 /* LCFG_SETUP command found. UUID should be changed */
915 rc = record_setup(env,
917 /* devname the same */
918 lustre_cfg_string(lcfg, 0),
919 /* s1 is not changed */
920 lustre_cfg_string(lcfg, 1),
921 /* new uuid should be
923 mrul->target.mti_params,
924 /* s3 is not changed */
925 lustre_cfg_string(lcfg, 3),
926 /* s4 is not changed */
927 lustre_cfg_string(lcfg, 4));
931 /* Another commands in target device block */
936 * Handler that called for every record in llog.
937 * Records are processed in order they placed in llog.
939 * \param[in] llh log to be processed
940 * \param[in] rec current record
941 * \param[in] data mgs_replace_uuid_lookup structure
945 static int mgs_replace_handler(const struct lu_env *env,
946 struct llog_handle *llh,
947 struct llog_rec_hdr *rec,
950 struct mgs_replace_uuid_lookup *mrul;
951 struct lustre_cfg *lcfg = REC_DATA(rec);
952 int cfg_len = REC_DATA_LEN(rec);
956 mrul = (struct mgs_replace_uuid_lookup *)data;
958 if (rec->lrh_type != OBD_CFG_REC) {
959 CERROR("unhandled lrh_type: %#x, cmd %x %s %s\n",
960 rec->lrh_type, lcfg->lcfg_command,
961 lustre_cfg_string(lcfg, 0),
962 lustre_cfg_string(lcfg, 1));
966 rc = lustre_cfg_sanity_check(lcfg, cfg_len);
968 /* Do not copy any invalidated records */
969 GOTO(skip_out, rc = 0);
972 rc = check_markers(lcfg, mrul);
973 if (rc || mrul->skip_it)
974 GOTO(skip_out, rc = 0);
976 /* Write to new log all commands outside target device block */
977 if (!mrul->in_target_device)
978 GOTO(copy_out, rc = 0);
980 /* Skip all other LCFG_ADD_UUID and LCFG_ADD_CONN records
981 (failover nids) for this target, assuming that if then
982 primary is changing then so is the failover */
983 if (mrul->device_nids_added &&
984 (lcfg->lcfg_command == LCFG_ADD_UUID ||
985 lcfg->lcfg_command == LCFG_ADD_CONN))
986 GOTO(skip_out, rc = 0);
988 rc = process_command(env, lcfg, mrul);
995 /* Record is placed in temporary llog as is */
996 rc = llog_write(env, mrul->temp_llh, rec, NULL, 0, NULL, -1);
998 CDEBUG(D_MGS, "Copied idx=%d, rc=%d, len=%d, cmd %x %s %s\n",
999 rec->lrh_index, rc, rec->lrh_len, lcfg->lcfg_command,
1000 lustre_cfg_string(lcfg, 0), lustre_cfg_string(lcfg, 1));
1004 CDEBUG(D_MGS, "Skipped idx=%d, rc=%d, len=%d, cmd %x %s %s\n",
1005 rec->lrh_index, rc, rec->lrh_len, lcfg->lcfg_command,
1006 lustre_cfg_string(lcfg, 0), lustre_cfg_string(lcfg, 1));
1010 static int mgs_log_is_empty(const struct lu_env *env,
1011 struct mgs_device *mgs, char *name)
1013 struct llog_ctxt *ctxt;
1016 ctxt = llog_get_context(mgs->mgs_obd, LLOG_CONFIG_ORIG_CTXT);
1017 LASSERT(ctxt != NULL);
1019 rc = llog_is_empty(env, ctxt, name);
1020 llog_ctxt_put(ctxt);
1024 static int mgs_replace_nids_log(const struct lu_env *env,
1025 struct obd_device *mgs, struct fs_db *fsdb,
1026 char *logname, char *devname, char *nids)
1028 struct llog_handle *orig_llh, *backup_llh;
1029 struct llog_ctxt *ctxt;
1030 struct mgs_replace_uuid_lookup *mrul;
1031 struct mgs_device *mgs_dev = lu2mgs_dev(mgs->obd_lu_dev);
1032 static struct obd_uuid cfg_uuid = { .uuid = "config_uuid" };
1037 CDEBUG(D_MGS, "Replace nids for %s in %s\n", devname, logname);
1039 ctxt = llog_get_context(mgs, LLOG_CONFIG_ORIG_CTXT);
1040 LASSERT(ctxt != NULL);
1042 if (mgs_log_is_empty(env, mgs_dev, logname)) {
1043 /* Log is empty. Nothing to replace */
1044 GOTO(out_put, rc = 0);
1047 OBD_ALLOC(backup, strlen(logname) + strlen(".bak") + 1);
1049 GOTO(out_put, rc = -ENOMEM);
1051 sprintf(backup, "%s.bak", logname);
1053 rc = llog_backup(env, mgs, ctxt, ctxt, logname, backup);
1055 /* Now erase original log file. Connections are not allowed.
1056 Backup is already saved */
1057 rc = llog_erase(env, ctxt, NULL, logname);
1060 } else if (rc != -ENOENT) {
1061 CERROR("%s: can't make backup for %s: rc = %d\n",
1062 mgs->obd_name, logname, rc);
1066 /* open local log */
1067 rc = llog_open_create(env, ctxt, &orig_llh, NULL, logname);
1069 GOTO(out_restore, rc);
1071 rc = llog_init_handle(env, orig_llh, LLOG_F_IS_PLAIN, &cfg_uuid);
1073 GOTO(out_closel, rc);
1075 /* open backup llog */
1076 rc = llog_open(env, ctxt, &backup_llh, NULL, backup,
1079 GOTO(out_closel, rc);
1081 rc = llog_init_handle(env, backup_llh, LLOG_F_IS_PLAIN, NULL);
1083 GOTO(out_close, rc);
1085 if (llog_get_size(backup_llh) <= 1)
1086 GOTO(out_close, rc = 0);
1088 OBD_ALLOC_PTR(mrul);
1090 GOTO(out_close, rc = -ENOMEM);
1091 /* devname is only needed information to replace UUID records */
1092 strncpy(mrul->target.mti_svname, devname, MTI_NAME_MAXLEN);
1093 /* parse nids later */
1094 strncpy(mrul->target.mti_params, nids, MTI_PARAM_MAXLEN);
1095 /* Copy records to this temporary llog */
1096 mrul->temp_llh = orig_llh;
1098 rc = llog_process(env, backup_llh, mgs_replace_handler,
1099 (void *)mrul, NULL);
1102 rc2 = llog_close(NULL, backup_llh);
1106 rc2 = llog_close(NULL, orig_llh);
1112 CERROR("%s: llog should be restored: rc = %d\n",
1114 rc2 = llog_backup(env, mgs, ctxt, ctxt, backup,
1117 CERROR("%s: can't restore backup %s: rc = %d\n",
1118 mgs->obd_name, logname, rc2);
1122 OBD_FREE(backup, strlen(backup) + 1);
1125 llog_ctxt_put(ctxt);
1128 CERROR("%s: failed to replace nids in log %s: rc = %d\n",
1129 mgs->obd_name, logname, rc);
1135 * Parse device name and get file system name and/or device index
1137 * \param[in] devname device name (ex. lustre-MDT0000)
1138 * \param[out] fsname file system name(optional)
1139 * \param[out] index device index(optional)
1143 static int mgs_parse_devname(char *devname, char *fsname, __u32 *index)
1148 /* Extract fsname */
1150 rc = server_name2fsname(devname, fsname, NULL);
1152 CDEBUG(D_MGS, "Device name %s without fsname\n",
1159 rc = server_name2index(devname, index, NULL);
1161 CDEBUG(D_MGS, "Device name %s with wrong index\n",
1170 static int only_mgs_is_running(struct obd_device *mgs_obd)
1172 /* TDB: Is global variable with devices count exists? */
1173 int num_devices = get_devices_count();
1174 /* osd, MGS and MGC + self_export
1175 (wc -l /proc/fs/lustre/devices <= 2) && (num_exports <= 2) */
1176 return (num_devices <= 3) && (mgs_obd->obd_num_exports <= 2);
1179 static int name_create_mdt(char **logname, char *fsname, int i)
1183 sprintf(mdt_index, "-MDT%04x", i);
1184 return name_create(logname, fsname, mdt_index);
1188 * Replace nids for \a device to \a nids values
1190 * \param obd MGS obd device
1191 * \param devname nids need to be replaced for this device
1192 * (ex. lustre-OST0000)
1193 * \param nids nids list (ex. nid1,nid2,nid3)
1197 int mgs_replace_nids(const struct lu_env *env,
1198 struct mgs_device *mgs,
1199 char *devname, char *nids)
1201 /* Assume fsname is part of device name */
1202 char fsname[MTI_NAME_MAXLEN];
1209 struct obd_device *mgs_obd = mgs->mgs_obd;
1212 /* We can only change NIDs if no other nodes are connected */
1213 spin_lock(&mgs_obd->obd_dev_lock);
1214 conn_state = mgs_obd->obd_no_conn;
1215 mgs_obd->obd_no_conn = 1;
1216 spin_unlock(&mgs_obd->obd_dev_lock);
1218 /* We can not change nids if not only MGS is started */
1219 if (!only_mgs_is_running(mgs_obd)) {
1220 CERROR("Only MGS is allowed to be started\n");
1221 GOTO(out, rc = -EINPROGRESS);
1224 /* Get fsname and index*/
1225 rc = mgs_parse_devname(devname, fsname, &index);
1229 rc = mgs_find_or_make_fsdb(env, mgs, fsname, &fsdb);
1231 CERROR("%s: can't find fsdb: rc = %d\n", fsname, rc);
1235 /* Process client llogs */
1236 name_create(&logname, fsname, "-client");
1237 rc = mgs_replace_nids_log(env, mgs_obd, fsdb, logname, devname, nids);
1238 name_destroy(&logname);
1240 CERROR("%s: error while replacing NIDs for %s: rc = %d\n",
1241 fsname, devname, rc);
1245 /* Process MDT llogs */
1246 for (i = 0; i < INDEX_MAP_SIZE * 8; i++) {
1247 if (!test_bit(i, fsdb->fsdb_mdt_index_map))
1249 name_create_mdt(&logname, fsname, i);
1250 rc = mgs_replace_nids_log(env, mgs_obd, fsdb, logname, devname, nids);
1251 name_destroy(&logname);
1257 spin_lock(&mgs_obd->obd_dev_lock);
1258 mgs_obd->obd_no_conn = conn_state;
1259 spin_unlock(&mgs_obd->obd_dev_lock);
1264 static int record_lov_setup(const struct lu_env *env, struct llog_handle *llh,
1265 char *devname, struct lov_desc *desc)
1267 struct mgs_thread_info *mgi = mgs_env_info(env);
1268 struct lustre_cfg *lcfg;
1271 lustre_cfg_bufs_reset(&mgi->mgi_bufs, devname);
1272 lustre_cfg_bufs_set(&mgi->mgi_bufs, 1, desc, sizeof(*desc));
1273 lcfg = lustre_cfg_new(LCFG_SETUP, &mgi->mgi_bufs);
1276 rc = record_lcfg(env, llh, lcfg);
1278 lustre_cfg_free(lcfg);
1282 static int record_lmv_setup(const struct lu_env *env, struct llog_handle *llh,
1283 char *devname, struct lmv_desc *desc)
1285 struct mgs_thread_info *mgi = mgs_env_info(env);
1286 struct lustre_cfg *lcfg;
1289 lustre_cfg_bufs_reset(&mgi->mgi_bufs, devname);
1290 lustre_cfg_bufs_set(&mgi->mgi_bufs, 1, desc, sizeof(*desc));
1291 lcfg = lustre_cfg_new(LCFG_SETUP, &mgi->mgi_bufs);
1293 rc = record_lcfg(env, llh, lcfg);
1295 lustre_cfg_free(lcfg);
1299 static inline int record_mdc_add(const struct lu_env *env,
1300 struct llog_handle *llh,
1301 char *logname, char *mdcuuid,
1302 char *mdtuuid, char *index,
1305 return record_base(env,llh,logname,0,LCFG_ADD_MDC,
1306 mdtuuid,index,gen,mdcuuid);
1309 static inline int record_lov_add(const struct lu_env *env,
1310 struct llog_handle *llh,
1311 char *lov_name, char *ost_uuid,
1312 char *index, char *gen)
1314 return record_base(env,llh,lov_name,0,LCFG_LOV_ADD_OBD,
1315 ost_uuid, index, gen, 0);
1318 static inline int record_mount_opt(const struct lu_env *env,
1319 struct llog_handle *llh,
1320 char *profile, char *lov_name,
1323 return record_base(env,llh,NULL,0,LCFG_MOUNTOPT,
1324 profile,lov_name,mdc_name,0);
1327 static int record_marker(const struct lu_env *env,
1328 struct llog_handle *llh,
1329 struct fs_db *fsdb, __u32 flags,
1330 char *tgtname, char *comment)
1332 struct mgs_thread_info *mgi = mgs_env_info(env);
1333 struct lustre_cfg *lcfg;
1337 if (flags & CM_START)
1339 mgi->mgi_marker.cm_step = fsdb->fsdb_gen;
1340 mgi->mgi_marker.cm_flags = flags;
1341 mgi->mgi_marker.cm_vers = LUSTRE_VERSION_CODE;
1342 cplen = strlcpy(mgi->mgi_marker.cm_tgtname, tgtname,
1343 sizeof(mgi->mgi_marker.cm_tgtname));
1344 if (cplen >= sizeof(mgi->mgi_marker.cm_tgtname))
1346 cplen = strlcpy(mgi->mgi_marker.cm_comment, comment,
1347 sizeof(mgi->mgi_marker.cm_comment));
1348 if (cplen >= sizeof(mgi->mgi_marker.cm_comment))
1350 mgi->mgi_marker.cm_createtime = cfs_time_current_sec();
1351 mgi->mgi_marker.cm_canceltime = 0;
1352 lustre_cfg_bufs_reset(&mgi->mgi_bufs, NULL);
1353 lustre_cfg_bufs_set(&mgi->mgi_bufs, 1, &mgi->mgi_marker,
1354 sizeof(mgi->mgi_marker));
1355 lcfg = lustre_cfg_new(LCFG_MARKER, &mgi->mgi_bufs);
1358 rc = record_lcfg(env, llh, lcfg);
1360 lustre_cfg_free(lcfg);
1364 static int record_start_log(const struct lu_env *env, struct mgs_device *mgs,
1365 struct llog_handle **llh, char *name)
1367 static struct obd_uuid cfg_uuid = { .uuid = "config_uuid" };
1368 struct llog_ctxt *ctxt;
1372 GOTO(out, rc = -EBUSY);
1374 ctxt = llog_get_context(mgs->mgs_obd, LLOG_CONFIG_ORIG_CTXT);
1376 GOTO(out, rc = -ENODEV);
1377 LASSERT(ctxt->loc_obd == mgs->mgs_obd);
1379 rc = llog_open_create(env, ctxt, llh, NULL, name);
1382 rc = llog_init_handle(env, *llh, LLOG_F_IS_PLAIN, &cfg_uuid);
1384 llog_close(env, *llh);
1386 llog_ctxt_put(ctxt);
1389 CERROR("%s: can't start log %s: rc = %d\n",
1390 mgs->mgs_obd->obd_name, name, rc);
1396 static int record_end_log(const struct lu_env *env, struct llog_handle **llh)
1400 rc = llog_close(env, *llh);
1406 /******************** config "macros" *********************/
1408 /* write an lcfg directly into a log (with markers) */
1409 static int mgs_write_log_direct(const struct lu_env *env,
1410 struct mgs_device *mgs, struct fs_db *fsdb,
1411 char *logname, struct lustre_cfg *lcfg,
1412 char *devname, char *comment)
1414 struct llog_handle *llh = NULL;
1421 rc = record_start_log(env, mgs, &llh, logname);
1425 /* FIXME These should be a single journal transaction */
1426 rc = record_marker(env, llh, fsdb, CM_START, devname, comment);
1429 rc = record_lcfg(env, llh, lcfg);
1432 rc = record_marker(env, llh, fsdb, CM_END, devname, comment);
1436 record_end_log(env, &llh);
1440 /* write the lcfg in all logs for the given fs */
1441 int mgs_write_log_direct_all(const struct lu_env *env,
1442 struct mgs_device *mgs,
1444 struct mgs_target_info *mti,
1445 struct lustre_cfg *lcfg,
1446 char *devname, char *comment,
1450 struct mgs_direntry *dirent, *n;
1451 char *fsname = mti->mti_fsname;
1453 int rc = 0, len = strlen(fsname);
1456 /* We need to set params for any future logs
1457 as well. FIXME Append this file to every new log.
1458 Actually, we should store as params (text), not llogs. Or
1460 rc = name_create(&logname, fsname, "-params");
1463 if (mgs_log_is_empty(env, mgs, logname)) {
1464 struct llog_handle *llh = NULL;
1465 rc = record_start_log(env, mgs, &llh, logname);
1466 record_end_log(env, &llh);
1468 name_destroy(&logname);
1472 /* Find all the logs in the CONFIGS directory */
1473 rc = class_dentry_readdir(env, mgs, &list);
1477 /* Could use fsdb index maps instead of directory listing */
1478 cfs_list_for_each_entry_safe(dirent, n, &list, list) {
1479 cfs_list_del(&dirent->list);
1480 /* don't write to sptlrpc rule log */
1481 if (strstr(dirent->name, "-sptlrpc") != NULL)
1484 /* caller wants write server logs only */
1485 if (server_only && strstr(dirent->name, "-client") != NULL)
1488 if (strncmp(fsname, dirent->name, len) == 0) {
1489 CDEBUG(D_MGS, "Changing log %s\n", dirent->name);
1490 /* Erase any old settings of this same parameter */
1491 rc = mgs_modify(env, mgs, fsdb, mti, dirent->name,
1492 devname, comment, CM_SKIP);
1494 CERROR("%s: Can't modify llog %s: rc = %d\n",
1495 mgs->mgs_obd->obd_name, dirent->name,rc);
1496 /* Write the new one */
1498 rc = mgs_write_log_direct(env, mgs, fsdb,
1503 CERROR("%s: writing log %s: rc = %d\n",
1504 mgs->mgs_obd->obd_name,
1509 mgs_direntry_free(dirent);
1515 static int mgs_write_log_osp_to_mdt(const struct lu_env *env,
1516 struct mgs_device *mgs,
1518 struct mgs_target_info *mti,
1519 int index, char *logname);
1520 static int mgs_write_log_osc_to_lov(const struct lu_env *env,
1521 struct mgs_device *mgs,
1523 struct mgs_target_info *mti,
1524 char *logname, char *suffix, char *lovname,
1525 enum lustre_sec_part sec_part, int flags);
1526 static int name_create_mdt_and_lov(char **logname, char **lovname,
1527 struct fs_db *fsdb, int i);
1529 static int add_param(char *params, char *key, char *val)
1531 char *start = params + strlen(params);
1532 char *end = params + sizeof(((struct mgs_target_info *)0)->mti_params);
1536 keylen = strlen(key);
1537 if (start + 1 + keylen + strlen(val) >= end) {
1538 CERROR("params are too long: %s %s%s\n",
1539 params, key != NULL ? key : "", val);
1543 sprintf(start, " %s%s", key != NULL ? key : "", val);
1548 * Walk through client config log record and convert the related records
1551 static int mgs_steal_client_llog_handler(const struct lu_env *env,
1552 struct llog_handle *llh,
1553 struct llog_rec_hdr *rec, void *data)
1555 struct mgs_device *mgs;
1556 struct obd_device *obd;
1557 struct mgs_target_info *mti, *tmti;
1559 int cfg_len = rec->lrh_len;
1560 char *cfg_buf = (char*) (rec + 1);
1561 struct lustre_cfg *lcfg;
1563 struct llog_handle *mdt_llh = NULL;
1564 static int got_an_osc_or_mdc = 0;
1565 /* 0: not found any osc/mdc;
1569 static int last_step = -1;
1574 mti = ((struct temp_comp*)data)->comp_mti;
1575 tmti = ((struct temp_comp*)data)->comp_tmti;
1576 fsdb = ((struct temp_comp*)data)->comp_fsdb;
1577 obd = ((struct temp_comp *)data)->comp_obd;
1578 mgs = lu2mgs_dev(obd->obd_lu_dev);
1581 if (rec->lrh_type != OBD_CFG_REC) {
1582 CERROR("unhandled lrh_type: %#x\n", rec->lrh_type);
1586 rc = lustre_cfg_sanity_check(cfg_buf, cfg_len);
1588 CERROR("Insane cfg\n");
1592 lcfg = (struct lustre_cfg *)cfg_buf;
1594 if (lcfg->lcfg_command == LCFG_MARKER) {
1595 struct cfg_marker *marker;
1596 marker = lustre_cfg_buf(lcfg, 1);
1597 if (!strncmp(marker->cm_comment, "add osc", 7) &&
1598 (marker->cm_flags & CM_START) &&
1599 !(marker->cm_flags & CM_SKIP)) {
1600 got_an_osc_or_mdc = 1;
1601 cplen = strlcpy(tmti->mti_svname, marker->cm_tgtname,
1602 sizeof(tmti->mti_svname));
1603 if (cplen >= sizeof(tmti->mti_svname))
1605 rc = record_start_log(env, mgs, &mdt_llh,
1609 rc = record_marker(env, mdt_llh, fsdb, CM_START,
1610 mti->mti_svname, "add osc(copied)");
1611 record_end_log(env, &mdt_llh);
1612 last_step = marker->cm_step;
1615 if (!strncmp(marker->cm_comment, "add osc", 7) &&
1616 (marker->cm_flags & CM_END) &&
1617 !(marker->cm_flags & CM_SKIP)) {
1618 LASSERT(last_step == marker->cm_step);
1620 got_an_osc_or_mdc = 0;
1621 memset(tmti, 0, sizeof(*tmti));
1622 rc = record_start_log(env, mgs, &mdt_llh,
1626 rc = record_marker(env, mdt_llh, fsdb, CM_END,
1627 mti->mti_svname, "add osc(copied)");
1628 record_end_log(env, &mdt_llh);
1631 if (!strncmp(marker->cm_comment, "add mdc", 7) &&
1632 (marker->cm_flags & CM_START) &&
1633 !(marker->cm_flags & CM_SKIP)) {
1634 got_an_osc_or_mdc = 2;
1635 last_step = marker->cm_step;
1636 memcpy(tmti->mti_svname, marker->cm_tgtname,
1637 strlen(marker->cm_tgtname));
1641 if (!strncmp(marker->cm_comment, "add mdc", 7) &&
1642 (marker->cm_flags & CM_END) &&
1643 !(marker->cm_flags & CM_SKIP)) {
1644 LASSERT(last_step == marker->cm_step);
1646 got_an_osc_or_mdc = 0;
1647 memset(tmti, 0, sizeof(*tmti));
1652 if (got_an_osc_or_mdc == 0 || last_step < 0)
1655 if (lcfg->lcfg_command == LCFG_ADD_UUID) {
1656 uint64_t nodenid = lcfg->lcfg_nid;
1658 if (strlen(tmti->mti_uuid) == 0) {
1659 /* target uuid not set, this config record is before
1660 * LCFG_SETUP, this nid is one of target node nid.
1662 tmti->mti_nids[tmti->mti_nid_count] = nodenid;
1663 tmti->mti_nid_count++;
1665 /* failover node nid */
1666 rc = add_param(tmti->mti_params, PARAM_FAILNODE,
1667 libcfs_nid2str(nodenid));
1673 if (lcfg->lcfg_command == LCFG_SETUP) {
1676 target = lustre_cfg_string(lcfg, 1);
1677 memcpy(tmti->mti_uuid, target, strlen(target));
1681 /* ignore client side sptlrpc_conf_log */
1682 if (lcfg->lcfg_command == LCFG_SPTLRPC_CONF)
1685 if (lcfg->lcfg_command == LCFG_ADD_MDC) {
1688 if (sscanf(lustre_cfg_buf(lcfg, 2), "%d", &index) != 1)
1691 memcpy(tmti->mti_fsname, mti->mti_fsname,
1692 strlen(mti->mti_fsname));
1693 tmti->mti_stripe_index = index;
1695 rc = mgs_write_log_osp_to_mdt(env, mgs, fsdb, tmti,
1696 mti->mti_stripe_index,
1698 memset(tmti, 0, sizeof(*tmti));
1702 if (lcfg->lcfg_command == LCFG_LOV_ADD_OBD) {
1705 char *logname, *lovname;
1707 rc = name_create_mdt_and_lov(&logname, &lovname, fsdb,
1708 mti->mti_stripe_index);
1711 sprintf(mdt_index, "-MDT%04x", mti->mti_stripe_index);
1713 if (sscanf(lustre_cfg_buf(lcfg, 2), "%d", &index) != 1) {
1714 name_destroy(&logname);
1715 name_destroy(&lovname);
1719 tmti->mti_stripe_index = index;
1720 rc = mgs_write_log_osc_to_lov(env, mgs, fsdb, tmti, logname,
1723 name_destroy(&logname);
1724 name_destroy(&lovname);
1730 /* fsdb->fsdb_mutex is already held in mgs_write_log_target*/
1731 /* stealed from mgs_get_fsdb_from_llog*/
1732 static int mgs_steal_llog_for_mdt_from_client(const struct lu_env *env,
1733 struct mgs_device *mgs,
1735 struct temp_comp* comp)
1737 struct llog_handle *loghandle;
1738 struct mgs_target_info *tmti;
1739 struct llog_ctxt *ctxt;
1744 ctxt = llog_get_context(mgs->mgs_obd, LLOG_CONFIG_ORIG_CTXT);
1745 LASSERT(ctxt != NULL);
1747 OBD_ALLOC_PTR(tmti);
1749 GOTO(out_ctxt, rc = -ENOMEM);
1751 comp->comp_tmti = tmti;
1752 comp->comp_obd = mgs->mgs_obd;
1754 rc = llog_open(env, ctxt, &loghandle, NULL, client_name,
1762 rc = llog_init_handle(env, loghandle, LLOG_F_IS_PLAIN, NULL);
1764 GOTO(out_close, rc);
1766 rc = llog_process_or_fork(env, loghandle, mgs_steal_client_llog_handler,
1767 (void *)comp, NULL, false);
1768 CDEBUG(D_MGS, "steal llog re = %d\n", rc);
1770 llog_close(env, loghandle);
1774 llog_ctxt_put(ctxt);
1778 /* lmv is the second thing for client logs */
1779 /* copied from mgs_write_log_lov. Please refer to that. */
1780 static int mgs_write_log_lmv(const struct lu_env *env,
1781 struct mgs_device *mgs,
1783 struct mgs_target_info *mti,
1784 char *logname, char *lmvname)
1786 struct llog_handle *llh = NULL;
1787 struct lmv_desc *lmvdesc;
1792 CDEBUG(D_MGS, "Writing lmv(%s) log for %s\n", lmvname,logname);
1794 OBD_ALLOC_PTR(lmvdesc);
1795 if (lmvdesc == NULL)
1797 lmvdesc->ld_active_tgt_count = 0;
1798 lmvdesc->ld_tgt_count = 0;
1799 sprintf((char*)lmvdesc->ld_uuid.uuid, "%s_UUID", lmvname);
1800 uuid = (char *)lmvdesc->ld_uuid.uuid;
1802 rc = record_start_log(env, mgs, &llh, logname);
1805 rc = record_marker(env, llh, fsdb, CM_START, lmvname, "lmv setup");
1808 rc = record_attach(env, llh, lmvname, "lmv", uuid);
1811 rc = record_lmv_setup(env, llh, lmvname, lmvdesc);
1814 rc = record_marker(env, llh, fsdb, CM_END, lmvname, "lmv setup");
1818 record_end_log(env, &llh);
1820 OBD_FREE_PTR(lmvdesc);
1824 /* lov is the first thing in the mdt and client logs */
1825 static int mgs_write_log_lov(const struct lu_env *env, struct mgs_device *mgs,
1826 struct fs_db *fsdb, struct mgs_target_info *mti,
1827 char *logname, char *lovname)
1829 struct llog_handle *llh = NULL;
1830 struct lov_desc *lovdesc;
1835 CDEBUG(D_MGS, "Writing lov(%s) log for %s\n", lovname, logname);
1838 #01 L attach 0:lov_mdsA 1:lov 2:71ccb_lov_mdsA_19f961a9e1
1839 #02 L lov_setup 0:lov_mdsA 1:(struct lov_desc)
1840 uuid=lov1_UUID, stripe count=1, size=1048576, offset=0, pattern=0
1843 /* FIXME just make lov_setup accept empty desc (put uuid in buf 2) */
1844 OBD_ALLOC_PTR(lovdesc);
1845 if (lovdesc == NULL)
1847 lovdesc->ld_magic = LOV_DESC_MAGIC;
1848 lovdesc->ld_tgt_count = 0;
1849 /* Defaults. Can be changed later by lcfg config_param */
1850 lovdesc->ld_default_stripe_count = 1;
1851 lovdesc->ld_pattern = LOV_PATTERN_RAID0;
1852 lovdesc->ld_default_stripe_size = 1024 * 1024;
1853 lovdesc->ld_default_stripe_offset = -1;
1854 lovdesc->ld_qos_maxage = QOS_DEFAULT_MAXAGE;
1855 sprintf((char*)lovdesc->ld_uuid.uuid, "%s_UUID", lovname);
1856 /* can these be the same? */
1857 uuid = (char *)lovdesc->ld_uuid.uuid;
1859 /* This should always be the first entry in a log.
1860 rc = mgs_clear_log(obd, logname); */
1861 rc = record_start_log(env, mgs, &llh, logname);
1864 /* FIXME these should be a single journal transaction */
1865 rc = record_marker(env, llh, fsdb, CM_START, lovname, "lov setup");
1868 rc = record_attach(env, llh, lovname, "lov", uuid);
1871 rc = record_lov_setup(env, llh, lovname, lovdesc);
1874 rc = record_marker(env, llh, fsdb, CM_END, lovname, "lov setup");
1879 record_end_log(env, &llh);
1881 OBD_FREE_PTR(lovdesc);
1885 /* add failnids to open log */
1886 static int mgs_write_log_failnids(const struct lu_env *env,
1887 struct mgs_target_info *mti,
1888 struct llog_handle *llh,
1891 char *failnodeuuid = NULL;
1892 char *ptr = mti->mti_params;
1897 #03 L add_uuid nid=uml1@tcp(0x20000c0a80201) nal=90 0: 1:uml1_UUID
1898 #04 L add_uuid nid=1@elan(0x1000000000001) nal=90 0: 1:uml1_UUID
1899 #05 L setup 0:OSC_uml1_ost1_mdsA 1:ost1_UUID 2:uml1_UUID
1900 #06 L add_uuid nid=uml2@tcp(0x20000c0a80202) nal=90 0: 1:uml2_UUID
1901 #0x L add_uuid nid=2@elan(0x1000000000002) nal=90 0: 1:uml2_UUID
1902 #07 L add_conn 0:OSC_uml1_ost1_mdsA 1:uml2_UUID
1905 /* Pull failnid info out of params string */
1906 while (class_find_param(ptr, PARAM_FAILNODE, &ptr) == 0) {
1907 while (class_parse_nid(ptr, &nid, &ptr) == 0) {
1908 if (failnodeuuid == NULL) {
1909 /* We don't know the failover node name,
1910 so just use the first nid as the uuid */
1911 rc = name_create(&failnodeuuid,
1912 libcfs_nid2str(nid), "");
1916 CDEBUG(D_MGS, "add nid %s for failover uuid %s, "
1917 "client %s\n", libcfs_nid2str(nid),
1918 failnodeuuid, cliname);
1919 rc = record_add_uuid(env, llh, nid, failnodeuuid);
1922 rc = record_add_conn(env, llh, cliname, failnodeuuid);
1925 name_destroy(&failnodeuuid);
1929 static int mgs_write_log_mdc_to_lmv(const struct lu_env *env,
1930 struct mgs_device *mgs,
1932 struct mgs_target_info *mti,
1933 char *logname, char *lmvname)
1935 struct llog_handle *llh = NULL;
1936 char *mdcname = NULL;
1937 char *nodeuuid = NULL;
1938 char *mdcuuid = NULL;
1939 char *lmvuuid = NULL;
1944 if (mgs_log_is_empty(env, mgs, logname)) {
1945 CERROR("log is empty! Logical error\n");
1949 CDEBUG(D_MGS, "adding mdc for %s to log %s:lmv(%s)\n",
1950 mti->mti_svname, logname, lmvname);
1952 rc = name_create(&nodeuuid, libcfs_nid2str(mti->mti_nids[0]), "");
1955 rc = name_create(&mdcname, mti->mti_svname, "-mdc");
1958 rc = name_create(&mdcuuid, mdcname, "_UUID");
1961 rc = name_create(&lmvuuid, lmvname, "_UUID");
1965 rc = record_start_log(env, mgs, &llh, logname);
1968 rc = record_marker(env, llh, fsdb, CM_START, mti->mti_svname,
1972 for (i = 0; i < mti->mti_nid_count; i++) {
1973 CDEBUG(D_MGS, "add nid %s for mdt\n",
1974 libcfs_nid2str(mti->mti_nids[i]));
1976 rc = record_add_uuid(env, llh, mti->mti_nids[i], nodeuuid);
1981 rc = record_attach(env, llh, mdcname, LUSTRE_MDC_NAME, lmvuuid);
1984 rc = record_setup(env, llh, mdcname, mti->mti_uuid, nodeuuid, 0, 0);
1987 rc = mgs_write_log_failnids(env, mti, llh, mdcname);
1990 snprintf(index, sizeof(index), "%d", mti->mti_stripe_index);
1991 rc = record_mdc_add(env, llh, lmvname, mdcuuid, mti->mti_uuid,
1995 rc = record_marker(env, llh, fsdb, CM_END, mti->mti_svname,
2000 record_end_log(env, &llh);
2002 name_destroy(&lmvuuid);
2003 name_destroy(&mdcuuid);
2004 name_destroy(&mdcname);
2005 name_destroy(&nodeuuid);
2009 static inline int name_create_lov(char **lovname, char *mdtname,
2010 struct fs_db *fsdb, int index)
2013 if (index == 0 && test_bit(FSDB_OSCNAME18, &fsdb->fsdb_flags))
2014 return name_create(lovname, fsdb->fsdb_name, "-mdtlov");
2016 return name_create(lovname, mdtname, "-mdtlov");
2019 static int name_create_mdt_and_lov(char **logname, char **lovname,
2020 struct fs_db *fsdb, int i)
2024 rc = name_create_mdt(logname, fsdb->fsdb_name, i);
2028 if (i == 0 && test_bit(FSDB_OSCNAME18, &fsdb->fsdb_flags))
2029 rc = name_create(lovname, fsdb->fsdb_name, "-mdtlov");
2031 rc = name_create(lovname, *logname, "-mdtlov");
2033 name_destroy(logname);
2039 static inline int name_create_mdt_osc(char **oscname, char *ostname,
2040 struct fs_db *fsdb, int i)
2044 if (i == 0 && test_bit(FSDB_OSCNAME18, &fsdb->fsdb_flags))
2045 sprintf(suffix, "-osc");
2047 sprintf(suffix, "-osc-MDT%04x", i);
2048 return name_create(oscname, ostname, suffix);
2051 /* add new mdc to already existent MDS */
2052 static int mgs_write_log_osp_to_mdt(const struct lu_env *env,
2053 struct mgs_device *mgs,
2055 struct mgs_target_info *mti,
2056 int mdt_index, char *logname)
2058 struct llog_handle *llh = NULL;
2059 char *nodeuuid = NULL;
2060 char *ospname = NULL;
2061 char *lovuuid = NULL;
2062 char *mdtuuid = NULL;
2063 char *svname = NULL;
2064 char *mdtname = NULL;
2065 char *lovname = NULL;
2070 if (mgs_log_is_empty(env, mgs, mti->mti_svname)) {
2071 CERROR("log is empty! Logical error\n");
2075 CDEBUG(D_MGS, "adding osp index %d to %s\n", mti->mti_stripe_index,
2078 rc = name_create_mdt(&mdtname, fsdb->fsdb_name, mti->mti_stripe_index);
2082 rc = name_create(&nodeuuid, libcfs_nid2str(mti->mti_nids[0]), "");
2084 GOTO(out_destory, rc);
2086 rc = name_create(&svname, mdtname, "-osp");
2088 GOTO(out_destory, rc);
2090 sprintf(index_str, "-MDT%04x", mdt_index);
2091 rc = name_create(&ospname, svname, index_str);
2093 GOTO(out_destory, rc);
2095 rc = name_create_lov(&lovname, logname, fsdb, mdt_index);
2097 GOTO(out_destory, rc);
2099 rc = name_create(&lovuuid, lovname, "_UUID");
2101 GOTO(out_destory, rc);
2103 rc = name_create(&mdtuuid, mdtname, "_UUID");
2105 GOTO(out_destory, rc);
2107 rc = record_start_log(env, mgs, &llh, logname);
2109 GOTO(out_destory, rc);
2111 rc = record_marker(env, llh, fsdb, CM_START, mti->mti_svname,
2114 GOTO(out_destory, rc);
2116 for (i = 0; i < mti->mti_nid_count; i++) {
2117 CDEBUG(D_MGS, "add nid %s for mdt\n",
2118 libcfs_nid2str(mti->mti_nids[i]));
2119 rc = record_add_uuid(env, llh, mti->mti_nids[i], nodeuuid);
2124 rc = record_attach(env, llh, ospname, LUSTRE_OSP_NAME, lovuuid);
2128 rc = record_setup(env, llh, ospname, mti->mti_uuid, nodeuuid,
2133 rc = mgs_write_log_failnids(env, mti, llh, ospname);
2137 /* Add mdc(osp) to lod */
2138 snprintf(index_str, sizeof(mti->mti_stripe_index), "%d",
2139 mti->mti_stripe_index);
2140 rc = record_base(env, llh, lovname, 0, LCFG_ADD_MDC, mti->mti_uuid,
2141 index_str, "1", NULL);
2145 rc = record_marker(env, llh, fsdb, CM_END, mti->mti_svname, "add osp");
2150 record_end_log(env, &llh);
2153 name_destroy(&mdtuuid);
2154 name_destroy(&lovuuid);
2155 name_destroy(&lovname);
2156 name_destroy(&ospname);
2157 name_destroy(&svname);
2158 name_destroy(&nodeuuid);
2159 name_destroy(&mdtname);
2163 static int mgs_write_log_mdt0(const struct lu_env *env,
2164 struct mgs_device *mgs,
2166 struct mgs_target_info *mti)
2168 char *log = mti->mti_svname;
2169 struct llog_handle *llh = NULL;
2170 char *uuid, *lovname;
2172 char *ptr = mti->mti_params;
2173 int rc = 0, failout = 0;
2176 OBD_ALLOC(uuid, sizeof(struct obd_uuid));
2180 if (class_find_param(ptr, PARAM_FAILMODE, &ptr) == 0)
2181 failout = (strncmp(ptr, "failout", 7) == 0);
2183 rc = name_create(&lovname, log, "-mdtlov");
2186 if (mgs_log_is_empty(env, mgs, log)) {
2187 rc = mgs_write_log_lov(env, mgs, fsdb, mti, log, lovname);
2192 sprintf(mdt_index, "%d", mti->mti_stripe_index);
2194 rc = record_start_log(env, mgs, &llh, log);
2198 /* add MDT itself */
2200 /* FIXME this whole fn should be a single journal transaction */
2201 sprintf(uuid, "%s_UUID", log);
2202 rc = record_marker(env, llh, fsdb, CM_START, log, "add mdt");
2205 rc = record_attach(env, llh, log, LUSTRE_MDT_NAME, uuid);
2208 rc = record_mount_opt(env, llh, log, lovname, NULL);
2211 rc = record_setup(env, llh, log, uuid, mdt_index, lovname,
2212 failout ? "n" : "f");
2215 rc = record_marker(env, llh, fsdb, CM_END, log, "add mdt");
2219 record_end_log(env, &llh);
2221 name_destroy(&lovname);
2223 OBD_FREE(uuid, sizeof(struct obd_uuid));
2227 /* envelope method for all layers log */
2228 static int mgs_write_log_mdt(const struct lu_env *env,
2229 struct mgs_device *mgs,
2231 struct mgs_target_info *mti)
2233 struct mgs_thread_info *mgi = mgs_env_info(env);
2234 struct llog_handle *llh = NULL;
2239 CDEBUG(D_MGS, "writing new mdt %s\n", mti->mti_svname);
2241 if (mti->mti_uuid[0] == '\0') {
2242 /* Make up our own uuid */
2243 snprintf(mti->mti_uuid, sizeof(mti->mti_uuid),
2244 "%s_UUID", mti->mti_svname);
2248 rc = mgs_write_log_mdt0(env, mgs, fsdb, mti);
2251 /* Append the mdt info to the client log */
2252 rc = name_create(&cliname, mti->mti_fsname, "-client");
2256 if (mgs_log_is_empty(env, mgs, cliname)) {
2257 /* Start client log */
2258 rc = mgs_write_log_lov(env, mgs, fsdb, mti, cliname,
2262 rc = mgs_write_log_lmv(env, mgs, fsdb, mti, cliname,
2269 #09 L add_uuid nid=uml1@tcp(0x20000c0a80201) 0: 1:uml1_UUID
2270 #10 L attach 0:MDC_uml1_mdsA_MNT_client 1:mdc 2:1d834_MNT_client_03f
2271 #11 L setup 0:MDC_uml1_mdsA_MNT_client 1:mdsA_UUID 2:uml1_UUID
2272 #12 L add_uuid nid=uml2@tcp(0x20000c0a80202) 0: 1:uml2_UUID
2273 #13 L add_conn 0:MDC_uml1_mdsA_MNT_client 1:uml2_UUID
2274 #14 L mount_option 0: 1:client 2:lov1 3:MDC_uml1_mdsA_MNT_client
2277 /* copy client info about lov/lmv */
2278 mgi->mgi_comp.comp_mti = mti;
2279 mgi->mgi_comp.comp_fsdb = fsdb;
2281 rc = mgs_steal_llog_for_mdt_from_client(env, mgs, cliname,
2285 rc = mgs_write_log_mdc_to_lmv(env, mgs, fsdb, mti, cliname,
2291 rc = record_start_log(env, mgs, &llh, cliname);
2295 rc = record_marker(env, llh, fsdb, CM_START, cliname,
2299 rc = record_mount_opt(env, llh, cliname, fsdb->fsdb_clilov,
2303 rc = record_marker(env, llh, fsdb, CM_END, cliname,
2309 /* for_all_existing_mdt except current one */
2310 for (i = 0; i < INDEX_MAP_SIZE * 8; i++) {
2311 if (i != mti->mti_stripe_index &&
2312 test_bit(i, fsdb->fsdb_mdt_index_map)) {
2315 rc = name_create_mdt(&logname, fsdb->fsdb_name, i);
2319 rc = mgs_write_log_osp_to_mdt(env, mgs, fsdb, mti,
2321 name_destroy(&logname);
2327 record_end_log(env, &llh);
2329 name_destroy(&cliname);
2333 /* Add the ost info to the client/mdt lov */
2334 static int mgs_write_log_osc_to_lov(const struct lu_env *env,
2335 struct mgs_device *mgs, struct fs_db *fsdb,
2336 struct mgs_target_info *mti,
2337 char *logname, char *suffix, char *lovname,
2338 enum lustre_sec_part sec_part, int flags)
2340 struct llog_handle *llh = NULL;
2341 char *nodeuuid = NULL;
2342 char *oscname = NULL;
2343 char *oscuuid = NULL;
2344 char *lovuuid = NULL;
2345 char *svname = NULL;
2350 CDEBUG(D_INFO, "adding osc for %s to log %s\n",
2351 mti->mti_svname, logname);
2353 if (mgs_log_is_empty(env, mgs, logname)) {
2354 CERROR("log is empty! Logical error\n");
2358 rc = name_create(&nodeuuid, libcfs_nid2str(mti->mti_nids[0]), "");
2361 rc = name_create(&svname, mti->mti_svname, "-osc");
2365 /* for the system upgraded from old 1.8, keep using the old osc naming
2366 * style for mdt, see name_create_mdt_osc(). LU-1257 */
2367 if (test_bit(FSDB_OSCNAME18, &fsdb->fsdb_flags))
2368 rc = name_create(&oscname, svname, "");
2370 rc = name_create(&oscname, svname, suffix);
2374 rc = name_create(&oscuuid, oscname, "_UUID");
2377 rc = name_create(&lovuuid, lovname, "_UUID");
2383 #03 L add_uuid nid=uml1@tcp(0x20000c0a80201) 0: 1:uml1_UUID
2385 #04 L add_uuid nid=1@elan(0x1000000000001) nal=90 0: 1:uml1_UUID
2386 #04 L attach 0:OSC_uml1_ost1_MNT_client 1:osc 2:89070_lov1_a41dff51a
2387 #05 L setup 0:OSC_uml1_ost1_MNT_client 1:ost1_UUID 2:uml1_UUID
2389 #06 L add_uuid nid=uml2@tcp(0x20000c0a80202) 0: 1:uml2_UUID
2390 #07 L add_conn 0:OSC_uml1_ost1_MNT_client 1:uml2_UUID
2391 #08 L lov_modify_tgts add 0:lov1 1:ost1_UUID 2(index):0 3(gen):1
2394 rc = record_start_log(env, mgs, &llh, logname);
2398 /* FIXME these should be a single journal transaction */
2399 rc = record_marker(env, llh, fsdb, CM_START | flags, mti->mti_svname,
2404 /* NB: don't change record order, because upon MDT steal OSC config
2405 * from client, it treats all nids before LCFG_SETUP as target nids
2406 * (multiple interfaces), while nids after as failover node nids.
2407 * See mgs_steal_client_llog_handler() LCFG_ADD_UUID.
2409 for (i = 0; i < mti->mti_nid_count; i++) {
2410 CDEBUG(D_MGS, "add nid %s\n", libcfs_nid2str(mti->mti_nids[i]));
2411 rc = record_add_uuid(env, llh, mti->mti_nids[i], nodeuuid);
2415 rc = record_attach(env, llh, oscname, LUSTRE_OSC_NAME, lovuuid);
2418 rc = record_setup(env, llh, oscname, mti->mti_uuid, nodeuuid, 0, 0);
2421 rc = mgs_write_log_failnids(env, mti, llh, oscname);
2425 snprintf(index, sizeof(index), "%d", mti->mti_stripe_index);
2427 rc = record_lov_add(env, llh, lovname, mti->mti_uuid, index, "1");
2430 rc = record_marker(env, llh, fsdb, CM_END | flags, mti->mti_svname,
2435 record_end_log(env, &llh);
2437 name_destroy(&lovuuid);
2438 name_destroy(&oscuuid);
2439 name_destroy(&oscname);
2440 name_destroy(&svname);
2441 name_destroy(&nodeuuid);
2445 static int mgs_write_log_ost(const struct lu_env *env,
2446 struct mgs_device *mgs, struct fs_db *fsdb,
2447 struct mgs_target_info *mti)
2449 struct llog_handle *llh = NULL;
2450 char *logname, *lovname;
2451 char *ptr = mti->mti_params;
2452 int rc, flags = 0, failout = 0, i;
2455 CDEBUG(D_MGS, "writing new ost %s\n", mti->mti_svname);
2457 /* The ost startup log */
2459 /* If the ost log already exists, that means that someone reformatted
2460 the ost and it called target_add again. */
2461 if (!mgs_log_is_empty(env, mgs, mti->mti_svname)) {
2462 LCONSOLE_ERROR_MSG(0x141, "The config log for %s already "
2463 "exists, yet the server claims it never "
2464 "registered. It may have been reformatted, "
2465 "or the index changed. writeconf the MDT to "
2466 "regenerate all logs.\n", mti->mti_svname);
2471 attach obdfilter ost1 ost1_UUID
2472 setup /dev/loop2 ldiskfs f|n errors=remount-ro,user_xattr
2474 if (class_find_param(ptr, PARAM_FAILMODE, &ptr) == 0)
2475 failout = (strncmp(ptr, "failout", 7) == 0);
2476 rc = record_start_log(env, mgs, &llh, mti->mti_svname);
2479 /* FIXME these should be a single journal transaction */
2480 rc = record_marker(env, llh, fsdb, CM_START, mti->mti_svname,"add ost");
2483 if (*mti->mti_uuid == '\0')
2484 snprintf(mti->mti_uuid, sizeof(mti->mti_uuid),
2485 "%s_UUID", mti->mti_svname);
2486 rc = record_attach(env, llh, mti->mti_svname,
2487 "obdfilter"/*LUSTRE_OST_NAME*/, mti->mti_uuid);
2490 rc = record_setup(env, llh, mti->mti_svname,
2491 "dev"/*ignored*/, "type"/*ignored*/,
2492 failout ? "n" : "f", 0/*options*/);
2495 rc = record_marker(env, llh, fsdb, CM_END, mti->mti_svname, "add ost");
2499 record_end_log(env, &llh);
2502 /* We also have to update the other logs where this osc is part of
2505 if (test_bit(FSDB_OLDLOG14, &fsdb->fsdb_flags)) {
2506 /* If we're upgrading, the old mdt log already has our
2507 entry. Let's do a fake one for fun. */
2508 /* Note that we can't add any new failnids, since we don't
2509 know the old osc names. */
2510 flags = CM_SKIP | CM_UPGRADE146;
2512 } else if ((mti->mti_flags & LDD_F_UPDATE) != LDD_F_UPDATE) {
2513 /* If the update flag isn't set, don't update client/mdt
2516 LCONSOLE_WARN("Client log for %s was not updated; writeconf "
2517 "the MDT first to regenerate it.\n",
2521 /* Add ost to all MDT lov defs */
2522 for (i = 0; i < INDEX_MAP_SIZE * 8; i++){
2523 if (test_bit(i, fsdb->fsdb_mdt_index_map)) {
2526 rc = name_create_mdt_and_lov(&logname, &lovname, fsdb,
2530 sprintf(mdt_index, "-MDT%04x", i);
2531 rc = mgs_write_log_osc_to_lov(env, mgs, fsdb, mti,
2533 lovname, LUSTRE_SP_MDT,
2535 name_destroy(&logname);
2536 name_destroy(&lovname);
2542 /* Append ost info to the client log */
2543 rc = name_create(&logname, mti->mti_fsname, "-client");
2546 if (mgs_log_is_empty(env, mgs, logname)) {
2547 /* Start client log */
2548 rc = mgs_write_log_lov(env, mgs, fsdb, mti, logname,
2552 rc = mgs_write_log_lmv(env, mgs, fsdb, mti, logname,
2557 rc = mgs_write_log_osc_to_lov(env, mgs, fsdb, mti, logname, "",
2558 fsdb->fsdb_clilov, LUSTRE_SP_CLI, 0);
2560 name_destroy(&logname);
2564 static __inline__ int mgs_param_empty(char *ptr)
2568 if ((tmp = strchr(ptr, '=')) && (*(++tmp) == '\0'))
2573 static int mgs_write_log_failnid_internal(const struct lu_env *env,
2574 struct mgs_device *mgs,
2576 struct mgs_target_info *mti,
2577 char *logname, char *cliname)
2580 struct llog_handle *llh = NULL;
2582 if (mgs_param_empty(mti->mti_params)) {
2583 /* Remove _all_ failnids */
2584 rc = mgs_modify(env, mgs, fsdb, mti, logname,
2585 mti->mti_svname, "add failnid", CM_SKIP);
2586 return rc < 0 ? rc : 0;
2589 /* Otherwise failover nids are additive */
2590 rc = record_start_log(env, mgs, &llh, logname);
2593 /* FIXME this should be a single journal transaction */
2594 rc = record_marker(env, llh, fsdb, CM_START, mti->mti_svname,
2598 rc = mgs_write_log_failnids(env, mti, llh, cliname);
2601 rc = record_marker(env, llh, fsdb, CM_END,
2602 mti->mti_svname, "add failnid");
2604 record_end_log(env, &llh);
2609 /* Add additional failnids to an existing log.
2610 The mdc/osc must have been added to logs first */
2611 /* tcp nids must be in dotted-quad ascii -
2612 we can't resolve hostnames from the kernel. */
2613 static int mgs_write_log_add_failnid(const struct lu_env *env,
2614 struct mgs_device *mgs,
2616 struct mgs_target_info *mti)
2618 char *logname, *cliname;
2622 /* FIXME we currently can't erase the failnids
2623 * given when a target first registers, since they aren't part of
2624 * an "add uuid" stanza */
2626 /* Verify that we know about this target */
2627 if (mgs_log_is_empty(env, mgs, mti->mti_svname)) {
2628 LCONSOLE_ERROR_MSG(0x142, "The target %s has not registered "
2629 "yet. It must be started before failnids "
2630 "can be added.\n", mti->mti_svname);
2634 /* Create mdc/osc client name (e.g. lustre-OST0001-osc) */
2635 if (mti->mti_flags & LDD_F_SV_TYPE_MDT) {
2636 rc = name_create(&cliname, mti->mti_svname, "-mdc");
2637 } else if (mti->mti_flags & LDD_F_SV_TYPE_OST) {
2638 rc = name_create(&cliname, mti->mti_svname, "-osc");
2644 /* Add failover nids to the client log */
2645 rc = name_create(&logname, mti->mti_fsname, "-client");
2647 name_destroy(&cliname);
2650 rc = mgs_write_log_failnid_internal(env, mgs, fsdb,mti,logname,cliname);
2651 name_destroy(&logname);
2652 name_destroy(&cliname);
2656 if (mti->mti_flags & LDD_F_SV_TYPE_OST) {
2657 /* Add OST failover nids to the MDT logs as well */
2660 for (i = 0; i < INDEX_MAP_SIZE * 8; i++) {
2661 if (!test_bit(i, fsdb->fsdb_mdt_index_map))
2663 rc = name_create_mdt(&logname, mti->mti_fsname, i);
2666 rc = name_create_mdt_osc(&cliname, mti->mti_svname,
2669 name_destroy(&logname);
2672 rc = mgs_write_log_failnid_internal(env, mgs, fsdb,
2675 name_destroy(&cliname);
2676 name_destroy(&logname);
2685 static int mgs_wlp_lcfg(const struct lu_env *env,
2686 struct mgs_device *mgs, struct fs_db *fsdb,
2687 struct mgs_target_info *mti,
2688 char *logname, struct lustre_cfg_bufs *bufs,
2689 char *tgtname, char *ptr)
2691 char comment[MTI_NAME_MAXLEN];
2693 struct lustre_cfg *lcfg;
2696 /* Erase any old settings of this same parameter */
2697 memcpy(comment, ptr, MTI_NAME_MAXLEN);
2698 comment[MTI_NAME_MAXLEN - 1] = 0;
2699 /* But don't try to match the value. */
2700 if ((tmp = strchr(comment, '=')))
2702 /* FIXME we should skip settings that are the same as old values */
2703 rc = mgs_modify(env, mgs, fsdb, mti, logname, tgtname, comment,CM_SKIP);
2706 del = mgs_param_empty(ptr);
2708 LCONSOLE_INFO("%sing parameter %s.%s in log %s\n", del ? "Disabl" : rc ?
2709 "Sett" : "Modify", tgtname, comment, logname);
2713 lustre_cfg_bufs_reset(bufs, tgtname);
2714 lustre_cfg_bufs_set_string(bufs, 1, ptr);
2715 if (mti->mti_flags & LDD_F_PARAM2)
2716 lustre_cfg_bufs_set_string(bufs, 2, LCTL_UPCALL);
2718 lcfg = lustre_cfg_new((mti->mti_flags & LDD_F_PARAM2) ?
2719 LCFG_SET_PARAM : LCFG_PARAM, bufs);
2723 rc = mgs_write_log_direct(env, mgs, fsdb, logname,lcfg,tgtname,comment);
2724 lustre_cfg_free(lcfg);
2728 static int mgs_write_log_param2(const struct lu_env *env,
2729 struct mgs_device *mgs,
2731 struct mgs_target_info *mti, char *ptr)
2733 struct lustre_cfg_bufs bufs;
2737 CDEBUG(D_MGS, "next param '%s'\n", ptr);
2738 rc = mgs_wlp_lcfg(env, mgs, fsdb, mti, PARAMS_FILENAME, &bufs,
2739 mti->mti_svname, ptr);
2744 /* write global variable settings into log */
2745 static int mgs_write_log_sys(const struct lu_env *env,
2746 struct mgs_device *mgs, struct fs_db *fsdb,
2747 struct mgs_target_info *mti, char *sys, char *ptr)
2749 struct mgs_thread_info *mgi = mgs_env_info(env);
2750 struct lustre_cfg *lcfg;
2752 int rc, cmd, convert = 1;
2754 if (class_match_param(ptr, PARAM_TIMEOUT, &tmp) == 0) {
2755 cmd = LCFG_SET_TIMEOUT;
2756 } else if (class_match_param(ptr, PARAM_LDLM_TIMEOUT, &tmp) == 0) {
2757 cmd = LCFG_SET_LDLM_TIMEOUT;
2758 /* Check for known params here so we can return error to lctl */
2759 } else if ((class_match_param(ptr, PARAM_AT_MIN, &tmp) == 0) ||
2760 (class_match_param(ptr, PARAM_AT_MAX, &tmp) == 0) ||
2761 (class_match_param(ptr, PARAM_AT_EXTRA, &tmp) == 0) ||
2762 (class_match_param(ptr, PARAM_AT_EARLY_MARGIN, &tmp) == 0) ||
2763 (class_match_param(ptr, PARAM_AT_HISTORY, &tmp) == 0)) {
2765 } else if (class_match_param(ptr, PARAM_JOBID_VAR, &tmp) == 0) {
2766 convert = 0; /* Don't convert string value to integer */
2772 if (mgs_param_empty(ptr))
2773 CDEBUG(D_MGS, "global '%s' removed\n", sys);
2775 CDEBUG(D_MGS, "global '%s' val=%s\n", sys, tmp);
2777 lustre_cfg_bufs_reset(&mgi->mgi_bufs, NULL);
2778 lustre_cfg_bufs_set_string(&mgi->mgi_bufs, 1, sys);
2779 if (!convert && *tmp != '\0')
2780 lustre_cfg_bufs_set_string(&mgi->mgi_bufs, 2, tmp);
2781 lcfg = lustre_cfg_new(cmd, &mgi->mgi_bufs);
2782 lcfg->lcfg_num = convert ? simple_strtoul(tmp, NULL, 0) : 0;
2783 /* truncate the comment to the parameter name */
2787 /* modify all servers and clients */
2788 rc = mgs_write_log_direct_all(env, mgs, fsdb, mti,
2789 *tmp == '\0' ? NULL : lcfg,
2790 mti->mti_fsname, sys, 0);
2791 if (rc == 0 && *tmp != '\0') {
2793 case LCFG_SET_TIMEOUT:
2794 if (!obd_timeout_set || lcfg->lcfg_num > obd_timeout)
2795 class_process_config(lcfg);
2797 case LCFG_SET_LDLM_TIMEOUT:
2798 if (!ldlm_timeout_set || lcfg->lcfg_num > ldlm_timeout)
2799 class_process_config(lcfg);
2806 lustre_cfg_free(lcfg);
2810 /* write quota settings into log */
2811 static int mgs_write_log_quota(const struct lu_env *env, struct mgs_device *mgs,
2812 struct fs_db *fsdb, struct mgs_target_info *mti,
2813 char *quota, char *ptr)
2815 struct mgs_thread_info *mgi = mgs_env_info(env);
2816 struct lustre_cfg *lcfg;
2819 int rc, cmd = LCFG_PARAM;
2821 /* support only 'meta' and 'data' pools so far */
2822 if (class_match_param(ptr, QUOTA_METAPOOL_NAME, &tmp) != 0 &&
2823 class_match_param(ptr, QUOTA_DATAPOOL_NAME, &tmp) != 0) {
2824 CERROR("parameter quota.%s isn't supported (only quota.mdt "
2825 "& quota.ost are)\n", ptr);
2830 CDEBUG(D_MGS, "global '%s' removed\n", quota);
2832 CDEBUG(D_MGS, "global '%s'\n", quota);
2834 if (strchr(tmp, 'u') == NULL && strchr(tmp, 'g') == NULL &&
2835 strcmp(tmp, "none") != 0) {
2836 CERROR("enable option(%s) isn't supported\n", tmp);
2841 lustre_cfg_bufs_reset(&mgi->mgi_bufs, mti->mti_fsname);
2842 lustre_cfg_bufs_set_string(&mgi->mgi_bufs, 1, quota);
2843 lcfg = lustre_cfg_new(cmd, &mgi->mgi_bufs);
2844 /* truncate the comment to the parameter name */
2849 /* XXX we duplicated quota enable information in all server
2850 * config logs, it should be moved to a separate config
2851 * log once we cleanup the config log for global param. */
2852 /* modify all servers */
2853 rc = mgs_write_log_direct_all(env, mgs, fsdb, mti,
2854 *tmp == '\0' ? NULL : lcfg,
2855 mti->mti_fsname, quota, 1);
2857 lustre_cfg_free(lcfg);
2858 return rc < 0 ? rc : 0;
2861 static int mgs_srpc_set_param_disk(const struct lu_env *env,
2862 struct mgs_device *mgs,
2864 struct mgs_target_info *mti,
2867 struct mgs_thread_info *mgi = mgs_env_info(env);
2868 struct llog_handle *llh = NULL;
2870 char *comment, *ptr;
2871 struct lustre_cfg *lcfg;
2876 ptr = strchr(param, '=');
2880 OBD_ALLOC(comment, len + 1);
2881 if (comment == NULL)
2883 strncpy(comment, param, len);
2884 comment[len] = '\0';
2887 lustre_cfg_bufs_reset(&mgi->mgi_bufs, mti->mti_svname);
2888 lustre_cfg_bufs_set_string(&mgi->mgi_bufs, 1, param);
2889 lcfg = lustre_cfg_new(LCFG_SPTLRPC_CONF, &mgi->mgi_bufs);
2891 GOTO(out_comment, rc = -ENOMEM);
2893 /* construct log name */
2894 rc = name_create(&logname, mti->mti_fsname, "-sptlrpc");
2898 if (mgs_log_is_empty(env, mgs, logname)) {
2899 rc = record_start_log(env, mgs, &llh, logname);
2902 record_end_log(env, &llh);
2905 /* obsolete old one */
2906 rc = mgs_modify(env, mgs, fsdb, mti, logname, mti->mti_svname,
2910 /* write the new one */
2911 rc = mgs_write_log_direct(env, mgs, fsdb, logname, lcfg,
2912 mti->mti_svname, comment);
2914 CERROR("err %d writing log %s\n", rc, logname);
2916 name_destroy(&logname);
2918 lustre_cfg_free(lcfg);
2920 OBD_FREE(comment, len + 1);
2924 static int mgs_srpc_set_param_udesc_mem(struct fs_db *fsdb,
2929 /* disable the adjustable udesc parameter for now, i.e. use default
2930 * setting that client always ship udesc to MDT if possible. to enable
2931 * it simply remove the following line */
2934 ptr = strchr(param, '=');
2939 if (strcmp(param, PARAM_SRPC_UDESC))
2942 if (strcmp(ptr, "yes") == 0) {
2943 set_bit(FSDB_UDESC, &fsdb->fsdb_flags);
2944 CWARN("Enable user descriptor shipping from client to MDT\n");
2945 } else if (strcmp(ptr, "no") == 0) {
2946 clear_bit(FSDB_UDESC, &fsdb->fsdb_flags);
2947 CWARN("Disable user descriptor shipping from client to MDT\n");
2955 CERROR("Invalid param: %s\n", param);
2959 static int mgs_srpc_set_param_mem(struct fs_db *fsdb,
2963 struct sptlrpc_rule rule;
2964 struct sptlrpc_rule_set *rset;
2968 if (strncmp(param, PARAM_SRPC, sizeof(PARAM_SRPC) - 1) != 0) {
2969 CERROR("Invalid sptlrpc parameter: %s\n", param);
2973 if (strncmp(param, PARAM_SRPC_UDESC,
2974 sizeof(PARAM_SRPC_UDESC) - 1) == 0) {
2975 RETURN(mgs_srpc_set_param_udesc_mem(fsdb, param));
2978 if (strncmp(param, PARAM_SRPC_FLVR, sizeof(PARAM_SRPC_FLVR) - 1) != 0) {
2979 CERROR("Invalid sptlrpc flavor parameter: %s\n", param);
2983 param += sizeof(PARAM_SRPC_FLVR) - 1;
2985 rc = sptlrpc_parse_rule(param, &rule);
2989 /* mgs rules implies must be mgc->mgs */
2990 if (test_bit(FSDB_MGS_SELF, &fsdb->fsdb_flags)) {
2991 if ((rule.sr_from != LUSTRE_SP_MGC &&
2992 rule.sr_from != LUSTRE_SP_ANY) ||
2993 (rule.sr_to != LUSTRE_SP_MGS &&
2994 rule.sr_to != LUSTRE_SP_ANY))
2998 /* preapre room for this coming rule. svcname format should be:
2999 * - fsname: general rule
3000 * - fsname-tgtname: target-specific rule
3002 if (strchr(svname, '-')) {
3003 struct mgs_tgt_srpc_conf *tgtconf;
3006 for (tgtconf = fsdb->fsdb_srpc_tgt; tgtconf != NULL;
3007 tgtconf = tgtconf->mtsc_next) {
3008 if (!strcmp(tgtconf->mtsc_tgt, svname)) {
3017 OBD_ALLOC_PTR(tgtconf);
3018 if (tgtconf == NULL)
3021 name_len = strlen(svname);
3023 OBD_ALLOC(tgtconf->mtsc_tgt, name_len + 1);
3024 if (tgtconf->mtsc_tgt == NULL) {
3025 OBD_FREE_PTR(tgtconf);
3028 memcpy(tgtconf->mtsc_tgt, svname, name_len);
3030 tgtconf->mtsc_next = fsdb->fsdb_srpc_tgt;
3031 fsdb->fsdb_srpc_tgt = tgtconf;
3034 rset = &tgtconf->mtsc_rset;
3036 rset = &fsdb->fsdb_srpc_gen;
3039 rc = sptlrpc_rule_set_merge(rset, &rule);
3044 static int mgs_srpc_set_param(const struct lu_env *env,
3045 struct mgs_device *mgs,
3047 struct mgs_target_info *mti,
3057 /* keep a copy of original param, which could be destroied
3059 copy_size = strlen(param) + 1;
3060 OBD_ALLOC(copy, copy_size);
3063 memcpy(copy, param, copy_size);
3065 rc = mgs_srpc_set_param_mem(fsdb, mti->mti_svname, param);
3069 /* previous steps guaranteed the syntax is correct */
3070 rc = mgs_srpc_set_param_disk(env, mgs, fsdb, mti, copy);
3074 if (test_bit(FSDB_MGS_SELF, &fsdb->fsdb_flags)) {
3076 * for mgs rules, make them effective immediately.
3078 LASSERT(fsdb->fsdb_srpc_tgt == NULL);
3079 sptlrpc_target_update_exp_flavor(mgs->mgs_obd,
3080 &fsdb->fsdb_srpc_gen);
3084 OBD_FREE(copy, copy_size);
3088 struct mgs_srpc_read_data {
3089 struct fs_db *msrd_fsdb;
3093 static int mgs_srpc_read_handler(const struct lu_env *env,
3094 struct llog_handle *llh,
3095 struct llog_rec_hdr *rec, void *data)
3097 struct mgs_srpc_read_data *msrd = data;
3098 struct cfg_marker *marker;
3099 struct lustre_cfg *lcfg = REC_DATA(rec);
3100 char *svname, *param;
3104 if (rec->lrh_type != OBD_CFG_REC) {
3105 CERROR("unhandled lrh_type: %#x\n", rec->lrh_type);
3109 cfg_len = rec->lrh_len - sizeof(struct llog_rec_hdr) -
3110 sizeof(struct llog_rec_tail);
3112 rc = lustre_cfg_sanity_check(lcfg, cfg_len);
3114 CERROR("Insane cfg\n");
3118 if (lcfg->lcfg_command == LCFG_MARKER) {
3119 marker = lustre_cfg_buf(lcfg, 1);
3121 if (marker->cm_flags & CM_START &&
3122 marker->cm_flags & CM_SKIP)
3123 msrd->msrd_skip = 1;
3124 if (marker->cm_flags & CM_END)
3125 msrd->msrd_skip = 0;
3130 if (msrd->msrd_skip)
3133 if (lcfg->lcfg_command != LCFG_SPTLRPC_CONF) {
3134 CERROR("invalid command (%x)\n", lcfg->lcfg_command);
3138 svname = lustre_cfg_string(lcfg, 0);
3139 if (svname == NULL) {
3140 CERROR("svname is empty\n");
3144 param = lustre_cfg_string(lcfg, 1);
3145 if (param == NULL) {
3146 CERROR("param is empty\n");
3150 rc = mgs_srpc_set_param_mem(msrd->msrd_fsdb, svname, param);
3152 CERROR("read sptlrpc record error (%d): %s\n", rc, param);
3157 int mgs_get_fsdb_srpc_from_llog(const struct lu_env *env,
3158 struct mgs_device *mgs,
3161 struct llog_handle *llh = NULL;
3162 struct llog_ctxt *ctxt;
3164 struct mgs_srpc_read_data msrd;
3168 /* construct log name */
3169 rc = name_create(&logname, fsdb->fsdb_name, "-sptlrpc");
3173 ctxt = llog_get_context(mgs->mgs_obd, LLOG_CONFIG_ORIG_CTXT);
3174 LASSERT(ctxt != NULL);
3176 if (mgs_log_is_empty(env, mgs, logname))
3179 rc = llog_open(env, ctxt, &llh, NULL, logname,
3187 rc = llog_init_handle(env, llh, LLOG_F_IS_PLAIN, NULL);
3189 GOTO(out_close, rc);
3191 if (llog_get_size(llh) <= 1)
3192 GOTO(out_close, rc = 0);
3194 msrd.msrd_fsdb = fsdb;
3197 rc = llog_process(env, llh, mgs_srpc_read_handler, (void *)&msrd,
3201 llog_close(env, llh);
3203 llog_ctxt_put(ctxt);
3204 name_destroy(&logname);
3207 CERROR("failed to read sptlrpc config database: %d\n", rc);
3211 /* Permanent settings of all parameters by writing into the appropriate
3212 * configuration logs.
3213 * A parameter with null value ("<param>='\0'") means to erase it out of
3216 static int mgs_write_log_param(const struct lu_env *env,
3217 struct mgs_device *mgs, struct fs_db *fsdb,
3218 struct mgs_target_info *mti, char *ptr)
3220 struct mgs_thread_info *mgi = mgs_env_info(env);
3223 int rc = 0, rc2 = 0;
3226 /* For various parameter settings, we have to figure out which logs
3227 care about them (e.g. both mdt and client for lov settings) */
3228 CDEBUG(D_MGS, "next param '%s'\n", ptr);
3230 /* The params are stored in MOUNT_DATA_FILE and modified via
3231 tunefs.lustre, or set using lctl conf_param */
3233 /* Processed in lustre_start_mgc */
3234 if (class_match_param(ptr, PARAM_MGSNODE, NULL) == 0)
3237 /* Processed in ost/mdt */
3238 if (class_match_param(ptr, PARAM_NETWORK, NULL) == 0)
3241 /* Processed in mgs_write_log_ost */
3242 if (class_match_param(ptr, PARAM_FAILMODE, NULL) == 0) {
3243 if (mti->mti_flags & LDD_F_PARAM) {
3244 LCONSOLE_ERROR_MSG(0x169, "%s can only be "
3245 "changed with tunefs.lustre"
3246 "and --writeconf\n", ptr);
3252 if (class_match_param(ptr, PARAM_SRPC, NULL) == 0) {
3253 rc = mgs_srpc_set_param(env, mgs, fsdb, mti, ptr);
3257 if (class_match_param(ptr, PARAM_FAILNODE, NULL) == 0) {
3258 /* Add a failover nidlist */
3260 /* We already processed failovers params for new
3261 targets in mgs_write_log_target */
3262 if (mti->mti_flags & LDD_F_PARAM) {
3263 CDEBUG(D_MGS, "Adding failnode\n");
3264 rc = mgs_write_log_add_failnid(env, mgs, fsdb, mti);
3269 if (class_match_param(ptr, PARAM_SYS, &tmp) == 0) {
3270 rc = mgs_write_log_sys(env, mgs, fsdb, mti, ptr, tmp);
3274 if (class_match_param(ptr, PARAM_QUOTA, &tmp) == 0) {
3275 rc = mgs_write_log_quota(env, mgs, fsdb, mti, ptr, tmp);
3279 if (class_match_param(ptr, PARAM_OSC""PARAM_ACTIVE, &tmp) == 0) {
3280 /* active=0 means off, anything else means on */
3281 int flag = (*tmp == '0') ? CM_EXCLUDE : 0;
3284 if (!(mti->mti_flags & LDD_F_SV_TYPE_OST)) {
3285 LCONSOLE_ERROR_MSG(0x144, "%s: Only OSCs can "
3286 "be (de)activated.\n",
3288 GOTO(end, rc = -EINVAL);
3290 LCONSOLE_WARN("Permanently %sactivating %s\n",
3291 flag ? "de": "re", mti->mti_svname);
3293 rc = name_create(&logname, mti->mti_fsname, "-client");
3296 rc = mgs_modify(env, mgs, fsdb, mti, logname,
3297 mti->mti_svname, "add osc", flag);
3298 name_destroy(&logname);
3302 /* Add to all MDT logs for CMD */
3303 for (i = 0; i < INDEX_MAP_SIZE * 8; i++) {
3304 if (!test_bit(i, fsdb->fsdb_mdt_index_map))
3306 rc = name_create_mdt(&logname, mti->mti_fsname, i);
3309 rc = mgs_modify(env, mgs, fsdb, mti, logname,
3310 mti->mti_svname, "add osc", flag);
3311 name_destroy(&logname);
3317 LCONSOLE_ERROR_MSG(0x145, "Couldn't find %s in"
3318 "log (%d). No permanent "
3319 "changes were made to the "
3321 mti->mti_svname, rc);
3322 if (test_bit(FSDB_OLDLOG14, &fsdb->fsdb_flags))
3323 LCONSOLE_ERROR_MSG(0x146, "This may be"
3328 "update the logs.\n");
3331 /* Fall through to osc proc for deactivating live OSC
3332 on running MDT / clients. */
3334 /* Below here, let obd's XXX_process_config methods handle it */
3336 /* All lov. in proc */
3337 if (class_match_param(ptr, PARAM_LOV, NULL) == 0) {
3340 CDEBUG(D_MGS, "lov param %s\n", ptr);
3341 if (!(mti->mti_flags & LDD_F_SV_TYPE_MDT)) {
3342 LCONSOLE_ERROR_MSG(0x147, "LOV params must be "
3343 "set on the MDT, not %s. "
3350 if (mgs_log_is_empty(env, mgs, mti->mti_svname))
3351 GOTO(end, rc = -ENODEV);
3353 rc = name_create_mdt_and_lov(&logname, &mdtlovname, fsdb,
3354 mti->mti_stripe_index);
3357 rc = mgs_wlp_lcfg(env, mgs, fsdb, mti, mti->mti_svname,
3358 &mgi->mgi_bufs, mdtlovname, ptr);
3359 name_destroy(&logname);
3360 name_destroy(&mdtlovname);
3365 rc = name_create(&logname, mti->mti_fsname, "-client");
3368 rc = mgs_wlp_lcfg(env, mgs, fsdb, mti, logname, &mgi->mgi_bufs,
3369 fsdb->fsdb_clilov, ptr);
3370 name_destroy(&logname);
3374 /* All osc., mdc., llite. params in proc */
3375 if ((class_match_param(ptr, PARAM_OSC, NULL) == 0) ||
3376 (class_match_param(ptr, PARAM_MDC, NULL) == 0) ||
3377 (class_match_param(ptr, PARAM_LLITE, NULL) == 0)) {
3380 if (test_bit(FSDB_OLDLOG14, &fsdb->fsdb_flags)) {
3381 LCONSOLE_ERROR_MSG(0x148, "Upgraded client logs for %s"
3382 " cannot be modified. Consider"
3383 " updating the configuration with"
3386 GOTO(end, rc = -EINVAL);
3388 if (memcmp(ptr, PARAM_LLITE, strlen(PARAM_LLITE)) == 0) {
3389 rc = name_create(&cname, mti->mti_fsname, "-client");
3390 /* Add the client type to match the obdname in
3391 class_config_llog_handler */
3392 } else if (mti->mti_flags & LDD_F_SV_TYPE_MDT) {
3393 rc = name_create(&cname, mti->mti_svname, "-mdc");
3394 } else if (mti->mti_flags & LDD_F_SV_TYPE_OST) {
3395 rc = name_create(&cname, mti->mti_svname, "-osc");
3397 GOTO(end, rc = -EINVAL);
3402 CDEBUG(D_MGS, "%.3s param %s\n", ptr, ptr + 4);
3405 rc = name_create(&logname, mti->mti_fsname, "-client");
3407 name_destroy(&cname);
3410 rc = mgs_wlp_lcfg(env, mgs, fsdb, mti, logname, &mgi->mgi_bufs,
3413 /* osc params affect the MDT as well */
3414 if (!rc && (mti->mti_flags & LDD_F_SV_TYPE_OST)) {
3417 for (i = 0; i < INDEX_MAP_SIZE * 8; i++){
3418 if (!test_bit(i, fsdb->fsdb_mdt_index_map))
3420 name_destroy(&cname);
3421 rc = name_create_mdt_osc(&cname, mti->mti_svname,
3423 name_destroy(&logname);
3426 rc = name_create_mdt(&logname,
3427 mti->mti_fsname, i);
3430 if (!mgs_log_is_empty(env, mgs, logname)) {
3431 rc = mgs_wlp_lcfg(env, mgs, fsdb,
3440 name_destroy(&logname);
3441 name_destroy(&cname);
3445 /* All mdt. params in proc */
3446 if (class_match_param(ptr, PARAM_MDT, NULL) == 0) {
3450 CDEBUG(D_MGS, "%.3s param %s\n", ptr, ptr + 4);
3451 if (strncmp(mti->mti_svname, mti->mti_fsname,
3452 MTI_NAME_MAXLEN) == 0)
3453 /* device is unspecified completely? */
3454 rc = LDD_F_SV_TYPE_MDT | LDD_F_SV_ALL;
3456 rc = server_name2index(mti->mti_svname, &idx, NULL);
3459 if ((rc & LDD_F_SV_TYPE_MDT) == 0)
3461 if (rc & LDD_F_SV_ALL) {
3462 for (i = 0; i < INDEX_MAP_SIZE * 8; i++) {
3464 fsdb->fsdb_mdt_index_map))
3466 rc = name_create_mdt(&logname,
3467 mti->mti_fsname, i);
3470 rc = mgs_wlp_lcfg(env, mgs, fsdb, mti,
3471 logname, &mgi->mgi_bufs,
3473 name_destroy(&logname);
3478 rc = mgs_wlp_lcfg(env, mgs, fsdb, mti,
3479 mti->mti_svname, &mgi->mgi_bufs,
3480 mti->mti_svname, ptr);
3487 /* All mdd., ost. params in proc */
3488 if ((class_match_param(ptr, PARAM_MDD, NULL) == 0) ||
3489 (class_match_param(ptr, PARAM_OST, NULL) == 0)) {
3490 CDEBUG(D_MGS, "%.3s param %s\n", ptr, ptr + 4);
3491 if (mgs_log_is_empty(env, mgs, mti->mti_svname))
3492 GOTO(end, rc = -ENODEV);
3494 rc = mgs_wlp_lcfg(env, mgs, fsdb, mti, mti->mti_svname,
3495 &mgi->mgi_bufs, mti->mti_svname, ptr);
3499 LCONSOLE_WARN("Ignoring unrecognized param '%s'\n", ptr);
3504 CERROR("err %d on param '%s'\n", rc, ptr);
3509 /* Not implementing automatic failover nid addition at this time. */
3510 int mgs_check_failnid(const struct lu_env *env, struct mgs_device *mgs,
3511 struct mgs_target_info *mti)
3518 rc = mgs_find_or_make_fsdb(obd, fsname, &fsdb);
3522 if (mgs_log_is_empty(obd, mti->mti_svname))
3523 /* should never happen */
3526 CDEBUG(D_MGS, "Checking for new failnids for %s\n", mti->mti_svname);
3528 /* FIXME We can just check mti->params to see if we're already in
3529 the failover list. Modify mti->params for rewriting back at
3530 server_register_target(). */
3532 mutex_lock(&fsdb->fsdb_mutex);
3533 rc = mgs_write_log_add_failnid(obd, fsdb, mti);
3534 mutex_unlock(&fsdb->fsdb_mutex);
3541 int mgs_write_log_target(const struct lu_env *env,
3542 struct mgs_device *mgs,
3543 struct mgs_target_info *mti,
3550 /* set/check the new target index */
3551 rc = mgs_set_index(env, mgs, mti);
3553 CERROR("Can't get index (%d)\n", rc);
3557 if (rc == EALREADY) {
3558 LCONSOLE_WARN("Found index %d for %s, updating log\n",
3559 mti->mti_stripe_index, mti->mti_svname);
3560 /* We would like to mark old log sections as invalid
3561 and add new log sections in the client and mdt logs.
3562 But if we add new sections, then live clients will
3563 get repeat setup instructions for already running
3564 osc's. So don't update the client/mdt logs. */
3565 mti->mti_flags &= ~LDD_F_UPDATE;
3569 mutex_lock(&fsdb->fsdb_mutex);
3571 if (mti->mti_flags &
3572 (LDD_F_VIRGIN | LDD_F_UPGRADE14 | LDD_F_WRITECONF)) {
3573 /* Generate a log from scratch */
3574 if (mti->mti_flags & LDD_F_SV_TYPE_MDT) {
3575 rc = mgs_write_log_mdt(env, mgs, fsdb, mti);
3576 } else if (mti->mti_flags & LDD_F_SV_TYPE_OST) {
3577 rc = mgs_write_log_ost(env, mgs, fsdb, mti);
3579 CERROR("Unknown target type %#x, can't create log for "
3580 "%s\n", mti->mti_flags, mti->mti_svname);
3583 CERROR("Can't write logs for %s (%d)\n",
3584 mti->mti_svname, rc);
3588 /* Just update the params from tunefs in mgs_write_log_params */
3589 CDEBUG(D_MGS, "Update params for %s\n", mti->mti_svname);
3590 mti->mti_flags |= LDD_F_PARAM;
3593 /* allocate temporary buffer, where class_get_next_param will
3594 make copy of a current parameter */
3595 OBD_ALLOC(buf, strlen(mti->mti_params) + 1);
3597 GOTO(out_up, rc = -ENOMEM);
3598 params = mti->mti_params;
3599 while (params != NULL) {
3600 rc = class_get_next_param(¶ms, buf);
3603 /* there is no next parameter, that is
3608 CDEBUG(D_MGS, "remaining string: '%s', param: '%s'\n",
3610 rc = mgs_write_log_param(env, mgs, fsdb, mti, buf);
3615 OBD_FREE(buf, strlen(mti->mti_params) + 1);
3618 mutex_unlock(&fsdb->fsdb_mutex);
3622 int mgs_erase_log(const struct lu_env *env, struct mgs_device *mgs, char *name)
3624 struct llog_ctxt *ctxt;
3627 ctxt = llog_get_context(mgs->mgs_obd, LLOG_CONFIG_ORIG_CTXT);
3629 CERROR("%s: MGS config context doesn't exist\n",
3630 mgs->mgs_obd->obd_name);
3633 rc = llog_erase(env, ctxt, NULL, name);
3634 /* llog may not exist */
3637 llog_ctxt_put(ctxt);
3641 CERROR("%s: failed to clear log %s: %d\n",
3642 mgs->mgs_obd->obd_name, name, rc);
3647 /* erase all logs for the given fs */
3648 int mgs_erase_logs(const struct lu_env *env, struct mgs_device *mgs, char *fsname)
3652 struct mgs_direntry *dirent, *n;
3653 int rc, len = strlen(fsname);
3657 /* Find all the logs in the CONFIGS directory */
3658 rc = class_dentry_readdir(env, mgs, &list);
3662 mutex_lock(&mgs->mgs_mutex);
3664 /* Delete the fs db */
3665 fsdb = mgs_find_fsdb(mgs, fsname);
3667 mgs_free_fsdb(mgs, fsdb);
3669 mutex_unlock(&mgs->mgs_mutex);
3671 cfs_list_for_each_entry_safe(dirent, n, &list, list) {
3672 cfs_list_del(&dirent->list);
3673 suffix = strrchr(dirent->name, '-');
3674 if (suffix != NULL) {
3675 if ((len == suffix - dirent->name) &&
3676 (strncmp(fsname, dirent->name, len) == 0)) {
3677 CDEBUG(D_MGS, "Removing log %s\n",
3679 mgs_erase_log(env, mgs, dirent->name);
3682 mgs_direntry_free(dirent);
3688 /* from llog_swab */
3689 static void print_lustre_cfg(struct lustre_cfg *lcfg)
3694 CDEBUG(D_MGS, "lustre_cfg: %p\n", lcfg);
3695 CDEBUG(D_MGS, "\tlcfg->lcfg_version: %#x\n", lcfg->lcfg_version);
3697 CDEBUG(D_MGS, "\tlcfg->lcfg_command: %#x\n", lcfg->lcfg_command);
3698 CDEBUG(D_MGS, "\tlcfg->lcfg_num: %#x\n", lcfg->lcfg_num);
3699 CDEBUG(D_MGS, "\tlcfg->lcfg_flags: %#x\n", lcfg->lcfg_flags);
3700 CDEBUG(D_MGS, "\tlcfg->lcfg_nid: %s\n", libcfs_nid2str(lcfg->lcfg_nid));
3702 CDEBUG(D_MGS, "\tlcfg->lcfg_bufcount: %d\n", lcfg->lcfg_bufcount);
3703 if (lcfg->lcfg_bufcount < LUSTRE_CFG_MAX_BUFCOUNT)
3704 for (i = 0; i < lcfg->lcfg_bufcount; i++) {
3705 CDEBUG(D_MGS, "\tlcfg->lcfg_buflens[%d]: %d %s\n",
3706 i, lcfg->lcfg_buflens[i],
3707 lustre_cfg_string(lcfg, i));
3712 /* Set a permanent (config log) param for a target or fs
3713 * \param lcfg buf0 may contain the device (testfs-MDT0000) name
3714 * buf1 contains the single parameter
3716 int mgs_setparam(const struct lu_env *env, struct mgs_device *mgs,
3717 struct lustre_cfg *lcfg, char *fsname)
3720 struct mgs_target_info *mti;
3721 char *devname, *param;
3728 print_lustre_cfg(lcfg);
3730 /* lustre, lustre-mdtlov, lustre-client, lustre-MDT0000 */
3731 devname = lustre_cfg_string(lcfg, 0);
3732 param = lustre_cfg_string(lcfg, 1);
3734 /* Assume device name embedded in param:
3735 lustre-OST0000.osc.max_dirty_mb=32 */
3736 ptr = strchr(param, '.');
3744 LCONSOLE_ERROR_MSG(0x14d, "No target specified: %s\n", param);
3748 rc = mgs_parse_devname(devname, fsname, NULL);
3749 if (rc == 0 && !mgs_parse_devname(devname, NULL, &index)) {
3750 /* param related to llite isn't allowed to set by OST or MDT */
3751 if (rc == 0 && strncmp(param, PARAM_LLITE,
3752 sizeof(PARAM_LLITE)) == 0)
3755 /* assume devname is the fsname */
3756 memset(fsname, 0, MTI_NAME_MAXLEN);
3757 strncpy(fsname, devname, MTI_NAME_MAXLEN);
3758 fsname[MTI_NAME_MAXLEN - 1] = 0;
3760 CDEBUG(D_MGS, "setparam fs='%s' device='%s'\n", fsname, devname);
3762 rc = mgs_find_or_make_fsdb(env, mgs,
3763 lcfg->lcfg_command == LCFG_SET_PARAM ?
3764 PARAMS_FILENAME : fsname, &fsdb);
3768 if (lcfg->lcfg_command != LCFG_SET_PARAM &&
3769 !test_bit(FSDB_MGS_SELF, &fsdb->fsdb_flags) &&
3770 test_bit(FSDB_LOG_EMPTY, &fsdb->fsdb_flags)) {
3771 CERROR("No filesystem targets for %s. cfg_device from lctl "
3772 "is '%s'\n", fsname, devname);
3773 mgs_free_fsdb(mgs, fsdb);
3777 /* Create a fake mti to hold everything */
3780 GOTO(out, rc = -ENOMEM);
3781 if (strlcpy(mti->mti_fsname, fsname, sizeof(mti->mti_fsname))
3782 >= sizeof(mti->mti_fsname))
3783 GOTO(out, rc = -E2BIG);
3784 if (strlcpy(mti->mti_svname, devname, sizeof(mti->mti_svname))
3785 >= sizeof(mti->mti_svname))
3786 GOTO(out, rc = -E2BIG);
3787 if (strlcpy(mti->mti_params, param, sizeof(mti->mti_params))
3788 >= sizeof(mti->mti_params))
3789 GOTO(out, rc = -E2BIG);
3790 rc = server_name2index(mti->mti_svname, &mti->mti_stripe_index, &tmp);
3792 /* Not a valid server; may be only fsname */
3795 /* Strip -osc or -mdc suffix from svname */
3796 if (server_make_name(rc, mti->mti_stripe_index, mti->mti_fsname,
3798 GOTO(out, rc = -EINVAL);
3800 * Revoke lock so everyone updates. Should be alright if
3801 * someone was already reading while we were updating the logs,
3802 * so we don't really need to hold the lock while we're
3805 if (lcfg->lcfg_command == LCFG_SET_PARAM) {
3806 mti->mti_flags = rc | LDD_F_PARAM2;
3807 mutex_lock(&fsdb->fsdb_mutex);
3808 rc = mgs_write_log_param2(env, mgs, fsdb, mti, mti->mti_params);
3809 mutex_unlock(&fsdb->fsdb_mutex);
3810 mgs_revoke_lock(mgs, fsdb, CONFIG_T_PARAMS);
3812 mti->mti_flags = rc | LDD_F_PARAM;
3813 mutex_lock(&fsdb->fsdb_mutex);
3814 rc = mgs_write_log_param(env, mgs, fsdb, mti, mti->mti_params);
3815 mutex_unlock(&fsdb->fsdb_mutex);
3816 mgs_revoke_lock(mgs, fsdb, CONFIG_T_CONFIG);
3824 static int mgs_write_log_pool(const struct lu_env *env,
3825 struct mgs_device *mgs, char *logname,
3826 struct fs_db *fsdb, char *lovname,
3827 enum lcfg_command_type cmd,
3828 char *poolname, char *fsname,
3829 char *ostname, char *comment)
3831 struct llog_handle *llh = NULL;
3834 rc = record_start_log(env, mgs, &llh, logname);
3837 rc = record_marker(env, llh, fsdb, CM_START, lovname, comment);
3840 rc = record_base(env, llh, lovname, 0, cmd, poolname, fsname, ostname, 0);
3843 rc = record_marker(env, llh, fsdb, CM_END, lovname, comment);
3845 record_end_log(env, &llh);
3849 int mgs_pool_cmd(const struct lu_env *env, struct mgs_device *mgs,
3850 enum lcfg_command_type cmd, char *fsname,
3851 char *poolname, char *ostname)
3856 char *label = NULL, *canceled_label = NULL;
3858 struct mgs_target_info *mti = NULL;
3862 rc = mgs_find_or_make_fsdb(env, mgs, fsname, &fsdb);
3864 CERROR("Can't get db for %s\n", fsname);
3867 if (test_bit(FSDB_LOG_EMPTY, &fsdb->fsdb_flags)) {
3868 CERROR("%s is not defined\n", fsname);
3869 mgs_free_fsdb(mgs, fsdb);
3873 label_sz = 10 + strlen(fsname) + strlen(poolname);
3875 /* check if ostname match fsname */
3876 if (ostname != NULL) {
3879 ptr = strrchr(ostname, '-');
3880 if ((ptr == NULL) ||
3881 (strncmp(fsname, ostname, ptr-ostname) != 0))
3883 label_sz += strlen(ostname);
3886 OBD_ALLOC(label, label_sz);
3893 "new %s.%s", fsname, poolname);
3897 "add %s.%s.%s", fsname, poolname, ostname);
3900 OBD_ALLOC(canceled_label, label_sz);
3901 if (canceled_label == NULL)
3902 GOTO(out_label, rc = -ENOMEM);
3904 "rem %s.%s.%s", fsname, poolname, ostname);
3905 sprintf(canceled_label,
3906 "add %s.%s.%s", fsname, poolname, ostname);
3909 OBD_ALLOC(canceled_label, label_sz);
3910 if (canceled_label == NULL)
3911 GOTO(out_label, rc = -ENOMEM);
3913 "del %s.%s", fsname, poolname);
3914 sprintf(canceled_label,
3915 "new %s.%s", fsname, poolname);
3921 if (canceled_label != NULL) {
3924 GOTO(out_cancel, rc = -ENOMEM);
3927 mutex_lock(&fsdb->fsdb_mutex);
3928 /* write pool def to all MDT logs */
3929 for (i = 0; i < INDEX_MAP_SIZE * 8; i++) {
3930 if (test_bit(i, fsdb->fsdb_mdt_index_map)) {
3931 rc = name_create_mdt_and_lov(&logname, &lovname,
3934 mutex_unlock(&fsdb->fsdb_mutex);
3937 if (canceled_label != NULL) {
3938 strcpy(mti->mti_svname, "lov pool");
3939 rc = mgs_modify(env, mgs, fsdb, mti, logname,
3940 lovname, canceled_label,
3945 rc = mgs_write_log_pool(env, mgs, logname,
3949 name_destroy(&logname);
3950 name_destroy(&lovname);
3952 mutex_unlock(&fsdb->fsdb_mutex);
3958 rc = name_create(&logname, fsname, "-client");
3960 mutex_unlock(&fsdb->fsdb_mutex);
3963 if (canceled_label != NULL) {
3964 rc = mgs_modify(env, mgs, fsdb, mti, logname,
3965 fsdb->fsdb_clilov, canceled_label, CM_SKIP);
3967 mutex_unlock(&fsdb->fsdb_mutex);
3968 name_destroy(&logname);
3973 rc = mgs_write_log_pool(env, mgs, logname, fsdb, fsdb->fsdb_clilov,
3974 cmd, fsname, poolname, ostname, label);
3975 mutex_unlock(&fsdb->fsdb_mutex);
3976 name_destroy(&logname);
3977 /* request for update */
3978 mgs_revoke_lock(mgs, fsdb, CONFIG_T_CONFIG);
3985 if (canceled_label != NULL)
3986 OBD_FREE(canceled_label, label_sz);
3988 OBD_FREE(label, label_sz);