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);
71 LASSERT(dir->do_index_ops);
73 iops = &dir->do_index_ops->dio_it;
74 it = iops->init(env, dir, LUDA_64BITHASH, BYPASS_CAPA);
78 rc = iops->load(env, it, 0);
84 key = (void *)iops->key(env, it);
86 CERROR("%s: key failed when listing %s: rc = %d\n",
87 mgs->mgs_obd->obd_name, MOUNT_CONFIGS_DIR,
91 key_sz = iops->key_size(env, it);
94 /* filter out "." and ".." entries */
98 if (key_sz == 2 && key[1] == '.')
102 de = mgs_direntry_alloc(key_sz + 1);
108 memcpy(de->name, key, key_sz);
109 de->name[key_sz] = 0;
111 cfs_list_add(&de->list, list);
114 rc = iops->next(env, it);
123 CERROR("%s: key failed when listing %s: rc = %d\n",
124 mgs->mgs_obd->obd_name, MOUNT_CONFIGS_DIR, rc);
128 /******************** DB functions *********************/
130 static inline int name_create(char **newname, char *prefix, char *suffix)
133 OBD_ALLOC(*newname, strlen(prefix) + strlen(suffix) + 1);
136 sprintf(*newname, "%s%s", prefix, suffix);
140 static inline void name_destroy(char **name)
143 OBD_FREE(*name, strlen(*name) + 1);
147 struct mgs_fsdb_handler_data
153 /* from the (client) config log, figure out:
154 1. which ost's/mdt's are configured (by index)
155 2. what the last config step is
156 3. COMPAT_18 osc name
158 /* It might be better to have a separate db file, instead of parsing the info
159 out of the client log. This is slow and potentially error-prone. */
160 static int mgs_fsdb_handler(const struct lu_env *env, struct llog_handle *llh,
161 struct llog_rec_hdr *rec, void *data)
163 struct mgs_fsdb_handler_data *d = data;
164 struct fs_db *fsdb = d->fsdb;
165 int cfg_len = rec->lrh_len;
166 char *cfg_buf = (char*) (rec + 1);
167 struct lustre_cfg *lcfg;
172 if (rec->lrh_type != OBD_CFG_REC) {
173 CERROR("unhandled lrh_type: %#x\n", rec->lrh_type);
177 rc = lustre_cfg_sanity_check(cfg_buf, cfg_len);
179 CERROR("Insane cfg\n");
183 lcfg = (struct lustre_cfg *)cfg_buf;
185 CDEBUG(D_INFO, "cmd %x %s %s\n", lcfg->lcfg_command,
186 lustre_cfg_string(lcfg, 0), lustre_cfg_string(lcfg, 1));
188 /* Figure out ost indicies */
189 /* lov_modify_tgts add 0:lov1 1:ost1_UUID 2(index):0 3(gen):1 */
190 if (lcfg->lcfg_command == LCFG_LOV_ADD_OBD ||
191 lcfg->lcfg_command == LCFG_LOV_DEL_OBD) {
192 index = simple_strtoul(lustre_cfg_string(lcfg, 2),
194 CDEBUG(D_MGS, "OST index for %s is %u (%s)\n",
195 lustre_cfg_string(lcfg, 1), index,
196 lustre_cfg_string(lcfg, 2));
197 set_bit(index, fsdb->fsdb_ost_index_map);
200 /* Figure out mdt indicies */
201 /* attach 0:MDC_uml1_mdsA_MNT_client 1:mdc 2:1d834_MNT_client_03f */
202 if ((lcfg->lcfg_command == LCFG_ATTACH) &&
203 (strcmp(lustre_cfg_string(lcfg, 1), LUSTRE_MDC_NAME) == 0)) {
204 rc = server_name2index(lustre_cfg_string(lcfg, 0),
206 if (rc != LDD_F_SV_TYPE_MDT) {
207 CWARN("Unparsable MDC name %s, assuming index 0\n",
208 lustre_cfg_string(lcfg, 0));
212 CDEBUG(D_MGS, "MDT index is %u\n", index);
213 set_bit(index, fsdb->fsdb_mdt_index_map);
214 fsdb->fsdb_mdt_count ++;
218 * figure out the old config. fsdb_gen = 0 means old log
219 * It is obsoleted and not supported anymore
221 if (fsdb->fsdb_gen == 0) {
222 CERROR("Old config format is not supported\n");
227 * compat to 1.8, check osc name used by MDT0 to OSTs, bz18548.
229 if (!test_bit(FSDB_OSCNAME18, &fsdb->fsdb_flags) &&
230 lcfg->lcfg_command == LCFG_ATTACH &&
231 strcmp(lustre_cfg_string(lcfg, 1), LUSTRE_OSC_NAME) == 0) {
232 if (OBD_OCD_VERSION_MAJOR(d->ver) == 1 &&
233 OBD_OCD_VERSION_MINOR(d->ver) <= 8) {
234 CWARN("MDT using 1.8 OSC name scheme\n");
235 set_bit(FSDB_OSCNAME18, &fsdb->fsdb_flags);
239 if (lcfg->lcfg_command == LCFG_MARKER) {
240 struct cfg_marker *marker;
241 marker = lustre_cfg_buf(lcfg, 1);
243 d->ver = marker->cm_vers;
245 /* Keep track of the latest marker step */
246 fsdb->fsdb_gen = max(fsdb->fsdb_gen, marker->cm_step);
252 /* fsdb->fsdb_mutex is already held in mgs_find_or_make_fsdb*/
253 static int mgs_get_fsdb_from_llog(const struct lu_env *env,
254 struct mgs_device *mgs,
258 struct llog_handle *loghandle;
259 struct llog_ctxt *ctxt;
260 struct mgs_fsdb_handler_data d = { fsdb, 0 };
265 ctxt = llog_get_context(mgs->mgs_obd, LLOG_CONFIG_ORIG_CTXT);
266 LASSERT(ctxt != NULL);
267 rc = name_create(&logname, fsdb->fsdb_name, "-client");
270 rc = llog_open_create(env, ctxt, &loghandle, NULL, logname);
274 rc = llog_init_handle(env, loghandle, LLOG_F_IS_PLAIN, NULL);
278 if (llog_get_size(loghandle) <= 1)
279 set_bit(FSDB_LOG_EMPTY, &fsdb->fsdb_flags);
281 rc = llog_process(env, loghandle, mgs_fsdb_handler, (void *)&d, NULL);
282 CDEBUG(D_INFO, "get_db = %d\n", rc);
284 llog_close(env, loghandle);
286 name_destroy(&logname);
293 static void mgs_free_fsdb_srpc(struct fs_db *fsdb)
295 struct mgs_tgt_srpc_conf *tgtconf;
297 /* free target-specific rules */
298 while (fsdb->fsdb_srpc_tgt) {
299 tgtconf = fsdb->fsdb_srpc_tgt;
300 fsdb->fsdb_srpc_tgt = tgtconf->mtsc_next;
302 LASSERT(tgtconf->mtsc_tgt);
304 sptlrpc_rule_set_free(&tgtconf->mtsc_rset);
305 OBD_FREE(tgtconf->mtsc_tgt, strlen(tgtconf->mtsc_tgt) + 1);
306 OBD_FREE_PTR(tgtconf);
309 /* free general rules */
310 sptlrpc_rule_set_free(&fsdb->fsdb_srpc_gen);
313 struct fs_db *mgs_find_fsdb(struct mgs_device *mgs, char *fsname)
318 cfs_list_for_each(tmp, &mgs->mgs_fs_db_list) {
319 fsdb = cfs_list_entry(tmp, struct fs_db, fsdb_list);
320 if (strcmp(fsdb->fsdb_name, fsname) == 0)
326 /* caller must hold the mgs->mgs_fs_db_lock */
327 static struct fs_db *mgs_new_fsdb(const struct lu_env *env,
328 struct mgs_device *mgs, char *fsname)
334 if (strlen(fsname) >= sizeof(fsdb->fsdb_name)) {
335 CERROR("fsname %s is too long\n", fsname);
343 strcpy(fsdb->fsdb_name, fsname);
344 mutex_init(&fsdb->fsdb_mutex);
345 set_bit(FSDB_UDESC, &fsdb->fsdb_flags);
348 if (strcmp(fsname, MGSSELF_NAME) == 0) {
349 set_bit(FSDB_MGS_SELF, &fsdb->fsdb_flags);
351 OBD_ALLOC(fsdb->fsdb_ost_index_map, INDEX_MAP_SIZE);
352 OBD_ALLOC(fsdb->fsdb_mdt_index_map, INDEX_MAP_SIZE);
353 if (!fsdb->fsdb_ost_index_map || !fsdb->fsdb_mdt_index_map) {
354 CERROR("No memory for index maps\n");
355 GOTO(err, rc = -ENOMEM);
358 rc = name_create(&fsdb->fsdb_clilov, fsname, "-clilov");
361 rc = name_create(&fsdb->fsdb_clilmv, fsname, "-clilmv");
365 /* initialise data for NID table */
366 mgs_ir_init_fs(env, mgs, fsdb);
368 lproc_mgs_add_live(mgs, fsdb);
371 cfs_list_add(&fsdb->fsdb_list, &mgs->mgs_fs_db_list);
375 if (fsdb->fsdb_ost_index_map)
376 OBD_FREE(fsdb->fsdb_ost_index_map, INDEX_MAP_SIZE);
377 if (fsdb->fsdb_mdt_index_map)
378 OBD_FREE(fsdb->fsdb_mdt_index_map, INDEX_MAP_SIZE);
379 name_destroy(&fsdb->fsdb_clilov);
380 name_destroy(&fsdb->fsdb_clilmv);
385 static void mgs_free_fsdb(struct mgs_device *mgs, struct fs_db *fsdb)
387 /* wait for anyone with the sem */
388 mutex_lock(&fsdb->fsdb_mutex);
389 lproc_mgs_del_live(mgs, fsdb);
390 cfs_list_del(&fsdb->fsdb_list);
392 /* deinitialize fsr */
393 mgs_ir_fini_fs(mgs, fsdb);
395 if (fsdb->fsdb_ost_index_map)
396 OBD_FREE(fsdb->fsdb_ost_index_map, INDEX_MAP_SIZE);
397 if (fsdb->fsdb_mdt_index_map)
398 OBD_FREE(fsdb->fsdb_mdt_index_map, INDEX_MAP_SIZE);
399 name_destroy(&fsdb->fsdb_clilov);
400 name_destroy(&fsdb->fsdb_clilmv);
401 mgs_free_fsdb_srpc(fsdb);
402 mutex_unlock(&fsdb->fsdb_mutex);
406 int mgs_init_fsdb_list(struct mgs_device *mgs)
408 CFS_INIT_LIST_HEAD(&mgs->mgs_fs_db_list);
412 int mgs_cleanup_fsdb_list(struct mgs_device *mgs)
415 cfs_list_t *tmp, *tmp2;
416 mutex_lock(&mgs->mgs_mutex);
417 cfs_list_for_each_safe(tmp, tmp2, &mgs->mgs_fs_db_list) {
418 fsdb = cfs_list_entry(tmp, struct fs_db, fsdb_list);
419 mgs_free_fsdb(mgs, fsdb);
421 mutex_unlock(&mgs->mgs_mutex);
425 int mgs_find_or_make_fsdb(const struct lu_env *env,
426 struct mgs_device *mgs, char *name,
433 mutex_lock(&mgs->mgs_mutex);
434 fsdb = mgs_find_fsdb(mgs, name);
436 mutex_unlock(&mgs->mgs_mutex);
441 CDEBUG(D_MGS, "Creating new db\n");
442 fsdb = mgs_new_fsdb(env, mgs, name);
443 /* lock fsdb_mutex until the db is loaded from llogs */
445 mutex_lock(&fsdb->fsdb_mutex);
446 mutex_unlock(&mgs->mgs_mutex);
450 if (!test_bit(FSDB_MGS_SELF, &fsdb->fsdb_flags)) {
451 /* populate the db from the client llog */
452 rc = mgs_get_fsdb_from_llog(env, mgs, fsdb);
454 CERROR("Can't get db from client log %d\n", rc);
459 /* populate srpc rules from params llog */
460 rc = mgs_get_fsdb_srpc_from_llog(env, mgs, fsdb);
462 CERROR("Can't get db from params log %d\n", rc);
466 mutex_unlock(&fsdb->fsdb_mutex);
472 mutex_unlock(&fsdb->fsdb_mutex);
473 mgs_free_fsdb(mgs, fsdb);
479 -1= empty client log */
480 int mgs_check_index(const struct lu_env *env,
481 struct mgs_device *mgs,
482 struct mgs_target_info *mti)
489 LASSERT(!(mti->mti_flags & LDD_F_NEED_INDEX));
491 rc = mgs_find_or_make_fsdb(env, mgs, mti->mti_fsname, &fsdb);
493 CERROR("Can't get db for %s\n", mti->mti_fsname);
497 if (test_bit(FSDB_LOG_EMPTY, &fsdb->fsdb_flags))
500 if (mti->mti_flags & LDD_F_SV_TYPE_OST)
501 imap = fsdb->fsdb_ost_index_map;
502 else if (mti->mti_flags & LDD_F_SV_TYPE_MDT)
503 imap = fsdb->fsdb_mdt_index_map;
507 if (test_bit(mti->mti_stripe_index, imap))
512 static __inline__ int next_index(void *index_map, int map_len)
515 for (i = 0; i < map_len * 8; i++)
516 if (!test_bit(i, index_map)) {
519 CERROR("max index %d exceeded.\n", i);
524 0 newly marked as in use
526 +EALREADY for update of an old index */
527 static int mgs_set_index(const struct lu_env *env,
528 struct mgs_device *mgs,
529 struct mgs_target_info *mti)
536 rc = mgs_find_or_make_fsdb(env, mgs, mti->mti_fsname, &fsdb);
538 CERROR("Can't get db for %s\n", mti->mti_fsname);
542 mutex_lock(&fsdb->fsdb_mutex);
543 if (mti->mti_flags & LDD_F_SV_TYPE_OST) {
544 imap = fsdb->fsdb_ost_index_map;
545 } else if (mti->mti_flags & LDD_F_SV_TYPE_MDT) {
546 imap = fsdb->fsdb_mdt_index_map;
548 GOTO(out_up, rc = -EINVAL);
551 if (mti->mti_flags & LDD_F_NEED_INDEX) {
552 rc = next_index(imap, INDEX_MAP_SIZE);
554 GOTO(out_up, rc = -ERANGE);
555 mti->mti_stripe_index = rc;
556 if (mti->mti_flags & LDD_F_SV_TYPE_MDT)
557 fsdb->fsdb_mdt_count ++;
560 if (mti->mti_stripe_index >= INDEX_MAP_SIZE * 8) {
561 LCONSOLE_ERROR_MSG(0x13f, "Server %s requested index %d, "
562 "but the max index is %d.\n",
563 mti->mti_svname, mti->mti_stripe_index,
565 GOTO(out_up, rc = -ERANGE);
568 if (test_bit(mti->mti_stripe_index, imap)) {
569 if ((mti->mti_flags & LDD_F_VIRGIN) &&
570 !(mti->mti_flags & LDD_F_WRITECONF)) {
571 LCONSOLE_ERROR_MSG(0x140, "Server %s requested index "
572 "%d, but that index is already in "
573 "use. Use --writeconf to force\n",
575 mti->mti_stripe_index);
576 GOTO(out_up, rc = -EADDRINUSE);
578 CDEBUG(D_MGS, "Server %s updating index %d\n",
579 mti->mti_svname, mti->mti_stripe_index);
580 GOTO(out_up, rc = EALREADY);
584 set_bit(mti->mti_stripe_index, imap);
585 clear_bit(FSDB_LOG_EMPTY, &fsdb->fsdb_flags);
586 mutex_unlock(&fsdb->fsdb_mutex);
587 server_make_name(mti->mti_flags & ~(LDD_F_VIRGIN | LDD_F_WRITECONF),
588 mti->mti_stripe_index, mti->mti_fsname, mti->mti_svname);
590 CDEBUG(D_MGS, "Set index for %s to %d\n", mti->mti_svname,
591 mti->mti_stripe_index);
595 mutex_unlock(&fsdb->fsdb_mutex);
599 struct mgs_modify_lookup {
600 struct cfg_marker mml_marker;
604 static int mgs_modify_handler(const struct lu_env *env,
605 struct llog_handle *llh,
606 struct llog_rec_hdr *rec, void *data)
608 struct mgs_modify_lookup *mml = data;
609 struct cfg_marker *marker;
610 struct lustre_cfg *lcfg = REC_DATA(rec);
611 int cfg_len = REC_DATA_LEN(rec);
615 if (rec->lrh_type != OBD_CFG_REC) {
616 CERROR("unhandled lrh_type: %#x\n", rec->lrh_type);
620 rc = lustre_cfg_sanity_check(lcfg, cfg_len);
622 CERROR("Insane cfg\n");
626 /* We only care about markers */
627 if (lcfg->lcfg_command != LCFG_MARKER)
630 marker = lustre_cfg_buf(lcfg, 1);
631 if ((strcmp(mml->mml_marker.cm_comment, marker->cm_comment) == 0) &&
632 (strcmp(mml->mml_marker.cm_tgtname, marker->cm_tgtname) == 0) &&
633 !(marker->cm_flags & CM_SKIP)) {
634 /* Found a non-skipped marker match */
635 CDEBUG(D_MGS, "Changing rec %u marker %d %x->%x: %s %s\n",
636 rec->lrh_index, marker->cm_step,
637 marker->cm_flags, mml->mml_marker.cm_flags,
638 marker->cm_tgtname, marker->cm_comment);
639 /* Overwrite the old marker llog entry */
640 marker->cm_flags &= ~CM_EXCLUDE; /* in case we're unexcluding */
641 marker->cm_flags |= mml->mml_marker.cm_flags;
642 marker->cm_canceltime = mml->mml_marker.cm_canceltime;
643 /* Header and tail are added back to lrh_len in
644 llog_lvfs_write_rec */
645 rec->lrh_len = cfg_len;
646 rc = llog_write(env, llh, rec, NULL, 0, (void *)lcfg,
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 strcpy(mml->mml_marker.cm_comment, comment);
697 strcpy(mml->mml_marker.cm_tgtname, devname);
698 /* Modify mostly means cancel */
699 mml->mml_marker.cm_flags = flags;
700 mml->mml_marker.cm_canceltime = flags ? cfs_time_current_sec() : 0;
701 mml->mml_modified = 0;
702 rc = llog_process(env, loghandle, mgs_modify_handler, (void *)mml,
704 if (!rc && !mml->mml_modified)
709 llog_close(env, loghandle);
712 CERROR("%s: modify %s/%s failed: rc = %d\n",
713 mgs->mgs_obd->obd_name, mti->mti_svname, comment, rc);
718 /** This structure is passed to mgs_replace_handler */
719 struct mgs_replace_uuid_lookup {
720 /* Nids are replaced for this target device */
721 struct mgs_target_info target;
722 /* Temporary modified llog */
723 struct llog_handle *temp_llh;
724 /* Flag is set if in target block*/
725 int in_target_device;
726 /* Nids already added. Just skip (multiple nids) */
727 int device_nids_added;
728 /* Flag is set if this block should not be copied */
733 * Check: a) if block should be skipped
734 * b) is it target block
739 * \retval 0 should not to be skipped
740 * \retval 1 should to be skipped
742 static int check_markers(struct lustre_cfg *lcfg,
743 struct mgs_replace_uuid_lookup *mrul)
745 struct cfg_marker *marker;
747 /* Track markers. Find given device */
748 if (lcfg->lcfg_command == LCFG_MARKER) {
749 marker = lustre_cfg_buf(lcfg, 1);
750 /* Clean llog from records marked as CM_EXCLUDE.
751 CM_SKIP records are used for "active" command
752 and can be restored if needed */
753 if ((marker->cm_flags & (CM_EXCLUDE | CM_START)) ==
754 (CM_EXCLUDE | CM_START)) {
759 if ((marker->cm_flags & (CM_EXCLUDE | CM_END)) ==
760 (CM_EXCLUDE | CM_END)) {
765 if (strcmp(mrul->target.mti_svname, marker->cm_tgtname) == 0) {
766 LASSERT(!(marker->cm_flags & CM_START) ||
767 !(marker->cm_flags & CM_END));
768 if (marker->cm_flags & CM_START) {
769 mrul->in_target_device = 1;
770 mrul->device_nids_added = 0;
771 } else if (marker->cm_flags & CM_END)
772 mrul->in_target_device = 0;
779 static int record_lcfg(const struct lu_env *env, struct llog_handle *llh,
780 struct lustre_cfg *lcfg)
782 struct llog_rec_hdr rec;
788 LASSERT(llh->lgh_ctxt);
790 buflen = lustre_cfg_len(lcfg->lcfg_bufcount,
792 rec.lrh_len = llog_data_len(buflen);
793 rec.lrh_type = OBD_CFG_REC;
795 /* idx = -1 means append */
796 rc = llog_write(env, llh, &rec, NULL, 0, (void *)lcfg, -1);
798 CERROR("failed %d\n", rc);
802 static int record_base(const struct lu_env *env, struct llog_handle *llh,
803 char *cfgname, lnet_nid_t nid, int cmd,
804 char *s1, char *s2, char *s3, char *s4)
806 struct mgs_thread_info *mgi = mgs_env_info(env);
807 struct lustre_cfg *lcfg;
810 CDEBUG(D_MGS, "lcfg %s %#x %s %s %s %s\n", cfgname,
811 cmd, s1, s2, s3, s4);
813 lustre_cfg_bufs_reset(&mgi->mgi_bufs, cfgname);
815 lustre_cfg_bufs_set_string(&mgi->mgi_bufs, 1, s1);
817 lustre_cfg_bufs_set_string(&mgi->mgi_bufs, 2, s2);
819 lustre_cfg_bufs_set_string(&mgi->mgi_bufs, 3, s3);
821 lustre_cfg_bufs_set_string(&mgi->mgi_bufs, 4, s4);
823 lcfg = lustre_cfg_new(cmd, &mgi->mgi_bufs);
826 lcfg->lcfg_nid = nid;
828 rc = record_lcfg(env, llh, lcfg);
830 lustre_cfg_free(lcfg);
833 CERROR("error %d: lcfg %s %#x %s %s %s %s\n", rc, cfgname,
834 cmd, s1, s2, s3, s4);
839 static inline int record_add_uuid(const struct lu_env *env,
840 struct llog_handle *llh,
841 uint64_t nid, char *uuid)
843 return record_base(env, llh, NULL, nid, LCFG_ADD_UUID, uuid, 0, 0, 0);
846 static inline int record_add_conn(const struct lu_env *env,
847 struct llog_handle *llh,
848 char *devname, char *uuid)
850 return record_base(env, llh, devname, 0, LCFG_ADD_CONN, uuid, 0, 0, 0);
853 static inline int record_attach(const struct lu_env *env,
854 struct llog_handle *llh, char *devname,
855 char *type, char *uuid)
857 return record_base(env, llh,devname, 0, LCFG_ATTACH, type, uuid, 0, 0);
860 static inline int record_setup(const struct lu_env *env,
861 struct llog_handle *llh, char *devname,
862 char *s1, char *s2, char *s3, char *s4)
864 return record_base(env, llh, devname, 0, LCFG_SETUP, s1, s2, s3, s4);
868 * \retval <0 record processing error
869 * \retval n record is processed. No need copy original one.
870 * \retval 0 record is not processed.
872 static int process_command(const struct lu_env *env, struct lustre_cfg *lcfg,
873 struct mgs_replace_uuid_lookup *mrul)
880 if (lcfg->lcfg_command == LCFG_ADD_UUID) {
881 /* LCFG_ADD_UUID command found. Let's skip original command
882 and add passed nids */
883 ptr = mrul->target.mti_params;
884 while (class_parse_nid(ptr, &nid, &ptr) == 0) {
885 CDEBUG(D_MGS, "add nid %s with uuid %s, "
886 "device %s\n", libcfs_nid2str(nid),
887 mrul->target.mti_params,
888 mrul->target.mti_svname);
889 rc = record_add_uuid(env,
891 mrul->target.mti_params);
896 if (nids_added == 0) {
897 CERROR("No new nids were added, nid %s with uuid %s, "
898 "device %s\n", libcfs_nid2str(nid),
899 mrul->target.mti_params,
900 mrul->target.mti_svname);
903 mrul->device_nids_added = 1;
909 if (mrul->device_nids_added && lcfg->lcfg_command == LCFG_SETUP) {
910 /* LCFG_SETUP command found. UUID should be changed */
911 rc = record_setup(env,
913 /* devname the same */
914 lustre_cfg_string(lcfg, 0),
915 /* s1 is not changed */
916 lustre_cfg_string(lcfg, 1),
917 /* new uuid should be
919 mrul->target.mti_params,
920 /* s3 is not changed */
921 lustre_cfg_string(lcfg, 3),
922 /* s4 is not changed */
923 lustre_cfg_string(lcfg, 4));
927 /* Another commands in target device block */
932 * Handler that called for every record in llog.
933 * Records are processed in order they placed in llog.
935 * \param[in] llh log to be processed
936 * \param[in] rec current record
937 * \param[in] data mgs_replace_uuid_lookup structure
941 static int mgs_replace_handler(const struct lu_env *env,
942 struct llog_handle *llh,
943 struct llog_rec_hdr *rec,
946 struct mgs_replace_uuid_lookup *mrul;
947 struct lustre_cfg *lcfg = REC_DATA(rec);
948 int cfg_len = REC_DATA_LEN(rec);
952 mrul = (struct mgs_replace_uuid_lookup *)data;
954 if (rec->lrh_type != OBD_CFG_REC) {
955 CERROR("unhandled lrh_type: %#x, cmd %x %s %s\n",
956 rec->lrh_type, lcfg->lcfg_command,
957 lustre_cfg_string(lcfg, 0),
958 lustre_cfg_string(lcfg, 1));
962 rc = lustre_cfg_sanity_check(lcfg, cfg_len);
964 /* Do not copy any invalidated records */
965 GOTO(skip_out, rc = 0);
968 rc = check_markers(lcfg, mrul);
969 if (rc || mrul->skip_it)
970 GOTO(skip_out, rc = 0);
972 /* Write to new log all commands outside target device block */
973 if (!mrul->in_target_device)
974 GOTO(copy_out, rc = 0);
976 /* Skip all other LCFG_ADD_UUID and LCFG_ADD_CONN records
977 (failover nids) for this target, assuming that if then
978 primary is changing then so is the failover */
979 if (mrul->device_nids_added &&
980 (lcfg->lcfg_command == LCFG_ADD_UUID ||
981 lcfg->lcfg_command == LCFG_ADD_CONN))
982 GOTO(skip_out, rc = 0);
984 rc = process_command(env, lcfg, mrul);
991 /* Record is placed in temporary llog as is */
992 rc = llog_write(env, mrul->temp_llh, rec, NULL, 0, NULL, -1);
994 CDEBUG(D_MGS, "Copied idx=%d, rc=%d, len=%d, cmd %x %s %s\n",
995 rec->lrh_index, rc, rec->lrh_len, lcfg->lcfg_command,
996 lustre_cfg_string(lcfg, 0), lustre_cfg_string(lcfg, 1));
1000 CDEBUG(D_MGS, "Skipped idx=%d, rc=%d, len=%d, cmd %x %s %s\n",
1001 rec->lrh_index, rc, rec->lrh_len, lcfg->lcfg_command,
1002 lustre_cfg_string(lcfg, 0), lustre_cfg_string(lcfg, 1));
1006 static int mgs_log_is_empty(const struct lu_env *env,
1007 struct mgs_device *mgs, char *name)
1009 struct llog_ctxt *ctxt;
1012 ctxt = llog_get_context(mgs->mgs_obd, LLOG_CONFIG_ORIG_CTXT);
1013 LASSERT(ctxt != NULL);
1015 rc = llog_is_empty(env, ctxt, name);
1016 llog_ctxt_put(ctxt);
1020 static int mgs_replace_nids_log(const struct lu_env *env,
1021 struct obd_device *mgs, struct fs_db *fsdb,
1022 char *logname, char *devname, char *nids)
1024 struct llog_handle *orig_llh, *backup_llh;
1025 struct llog_ctxt *ctxt;
1026 struct mgs_replace_uuid_lookup *mrul;
1027 struct mgs_device *mgs_dev = lu2mgs_dev(mgs->obd_lu_dev);
1028 static struct obd_uuid cfg_uuid = { .uuid = "config_uuid" };
1033 CDEBUG(D_MGS, "Replace nids for %s in %s\n", devname, logname);
1035 ctxt = llog_get_context(mgs, LLOG_CONFIG_ORIG_CTXT);
1036 LASSERT(ctxt != NULL);
1038 if (mgs_log_is_empty(env, mgs_dev, logname)) {
1039 /* Log is empty. Nothing to replace */
1040 GOTO(out_put, rc = 0);
1043 OBD_ALLOC(backup, strlen(logname) + strlen(".bak") + 1);
1045 GOTO(out_put, rc = -ENOMEM);
1047 sprintf(backup, "%s.bak", logname);
1049 rc = llog_backup(env, mgs, ctxt, ctxt, logname, backup);
1051 /* Now erase original log file. Connections are not allowed.
1052 Backup is already saved */
1053 rc = llog_erase(env, ctxt, NULL, logname);
1056 } else if (rc != -ENOENT) {
1057 CERROR("%s: can't make backup for %s: rc = %d\n",
1058 mgs->obd_name, logname, rc);
1062 /* open local log */
1063 rc = llog_open_create(env, ctxt, &orig_llh, NULL, logname);
1065 GOTO(out_restore, rc);
1067 rc = llog_init_handle(env, orig_llh, LLOG_F_IS_PLAIN, &cfg_uuid);
1069 GOTO(out_closel, rc);
1071 /* open backup llog */
1072 rc = llog_open(env, ctxt, &backup_llh, NULL, backup,
1075 GOTO(out_closel, rc);
1077 rc = llog_init_handle(env, backup_llh, LLOG_F_IS_PLAIN, NULL);
1079 GOTO(out_close, rc);
1081 if (llog_get_size(backup_llh) <= 1)
1082 GOTO(out_close, rc = 0);
1084 OBD_ALLOC_PTR(mrul);
1086 GOTO(out_close, rc = -ENOMEM);
1087 /* devname is only needed information to replace UUID records */
1088 strncpy(mrul->target.mti_svname, devname, MTI_NAME_MAXLEN);
1089 /* parse nids later */
1090 strncpy(mrul->target.mti_params, nids, MTI_PARAM_MAXLEN);
1091 /* Copy records to this temporary llog */
1092 mrul->temp_llh = orig_llh;
1094 rc = llog_process(env, backup_llh, mgs_replace_handler,
1095 (void *)mrul, NULL);
1098 rc2 = llog_close(NULL, backup_llh);
1102 rc2 = llog_close(NULL, orig_llh);
1108 CERROR("%s: llog should be restored: rc = %d\n",
1110 rc2 = llog_backup(env, mgs, ctxt, ctxt, backup,
1113 CERROR("%s: can't restore backup %s: rc = %d\n",
1114 mgs->obd_name, logname, rc2);
1118 OBD_FREE(backup, strlen(backup) + 1);
1121 llog_ctxt_put(ctxt);
1124 CERROR("%s: failed to replace nids in log %s: rc = %d\n",
1125 mgs->obd_name, logname, rc);
1131 * Parse device name and get file system name and/or device index
1133 * \param[in] devname device name (ex. lustre-MDT0000)
1134 * \param[out] fsname file system name(optional)
1135 * \param[out] index device index(optional)
1139 static int mgs_parse_devname(char *devname, char *fsname, __u32 *index)
1144 /* Extract fsname */
1146 rc = server_name2fsname(devname, fsname, NULL);
1148 CDEBUG(D_MGS, "Device name %s without fsname\n",
1155 rc = server_name2index(devname, index, NULL);
1157 CDEBUG(D_MGS, "Device name %s with wrong index\n",
1166 static int only_mgs_is_running(struct obd_device *mgs_obd)
1168 /* TDB: Is global variable with devices count exists? */
1169 int num_devices = get_devices_count();
1170 /* osd, MGS and MGC + self_export
1171 (wc -l /proc/fs/lustre/devices <= 2) && (num_exports <= 2) */
1172 return (num_devices <= 3) && (mgs_obd->obd_num_exports <= 2);
1175 static int name_create_mdt(char **logname, char *fsname, int i)
1179 sprintf(mdt_index, "-MDT%04x", i);
1180 return name_create(logname, fsname, mdt_index);
1184 * Replace nids for \a device to \a nids values
1186 * \param obd MGS obd device
1187 * \param devname nids need to be replaced for this device
1188 * (ex. lustre-OST0000)
1189 * \param nids nids list (ex. nid1,nid2,nid3)
1193 int mgs_replace_nids(const struct lu_env *env,
1194 struct mgs_device *mgs,
1195 char *devname, char *nids)
1197 /* Assume fsname is part of device name */
1198 char fsname[MTI_NAME_MAXLEN];
1205 struct obd_device *mgs_obd = mgs->mgs_obd;
1208 /* We can only change NIDs if no other nodes are connected */
1209 spin_lock(&mgs_obd->obd_dev_lock);
1210 conn_state = mgs_obd->obd_no_conn;
1211 mgs_obd->obd_no_conn = 1;
1212 spin_unlock(&mgs_obd->obd_dev_lock);
1214 /* We can not change nids if not only MGS is started */
1215 if (!only_mgs_is_running(mgs_obd)) {
1216 CERROR("Only MGS is allowed to be started\n");
1217 GOTO(out, rc = -EINPROGRESS);
1220 /* Get fsname and index*/
1221 rc = mgs_parse_devname(devname, fsname, &index);
1225 rc = mgs_find_or_make_fsdb(env, mgs, fsname, &fsdb);
1227 CERROR("%s: can't find fsdb: rc = %d\n", fsname, rc);
1231 /* Process client llogs */
1232 name_create(&logname, fsname, "-client");
1233 rc = mgs_replace_nids_log(env, mgs_obd, fsdb, logname, devname, nids);
1234 name_destroy(&logname);
1236 CERROR("%s: error while replacing NIDs for %s: rc = %d\n",
1237 fsname, devname, rc);
1241 /* Process MDT llogs */
1242 for (i = 0; i < INDEX_MAP_SIZE * 8; i++) {
1243 if (!test_bit(i, fsdb->fsdb_mdt_index_map))
1245 name_create_mdt(&logname, fsname, i);
1246 rc = mgs_replace_nids_log(env, mgs_obd, fsdb, logname, devname, nids);
1247 name_destroy(&logname);
1253 spin_lock(&mgs_obd->obd_dev_lock);
1254 mgs_obd->obd_no_conn = conn_state;
1255 spin_unlock(&mgs_obd->obd_dev_lock);
1260 static int record_lov_setup(const struct lu_env *env, struct llog_handle *llh,
1261 char *devname, struct lov_desc *desc)
1263 struct mgs_thread_info *mgi = mgs_env_info(env);
1264 struct lustre_cfg *lcfg;
1267 lustre_cfg_bufs_reset(&mgi->mgi_bufs, devname);
1268 lustre_cfg_bufs_set(&mgi->mgi_bufs, 1, desc, sizeof(*desc));
1269 lcfg = lustre_cfg_new(LCFG_SETUP, &mgi->mgi_bufs);
1272 rc = record_lcfg(env, llh, lcfg);
1274 lustre_cfg_free(lcfg);
1278 static int record_lmv_setup(const struct lu_env *env, struct llog_handle *llh,
1279 char *devname, struct lmv_desc *desc)
1281 struct mgs_thread_info *mgi = mgs_env_info(env);
1282 struct lustre_cfg *lcfg;
1285 lustre_cfg_bufs_reset(&mgi->mgi_bufs, devname);
1286 lustre_cfg_bufs_set(&mgi->mgi_bufs, 1, desc, sizeof(*desc));
1287 lcfg = lustre_cfg_new(LCFG_SETUP, &mgi->mgi_bufs);
1289 rc = record_lcfg(env, llh, lcfg);
1291 lustre_cfg_free(lcfg);
1295 static inline int record_mdc_add(const struct lu_env *env,
1296 struct llog_handle *llh,
1297 char *logname, char *mdcuuid,
1298 char *mdtuuid, char *index,
1301 return record_base(env,llh,logname,0,LCFG_ADD_MDC,
1302 mdtuuid,index,gen,mdcuuid);
1305 static inline int record_lov_add(const struct lu_env *env,
1306 struct llog_handle *llh,
1307 char *lov_name, char *ost_uuid,
1308 char *index, char *gen)
1310 return record_base(env,llh,lov_name,0,LCFG_LOV_ADD_OBD,
1311 ost_uuid, index, gen, 0);
1314 static inline int record_mount_opt(const struct lu_env *env,
1315 struct llog_handle *llh,
1316 char *profile, char *lov_name,
1319 return record_base(env,llh,NULL,0,LCFG_MOUNTOPT,
1320 profile,lov_name,mdc_name,0);
1323 static int record_marker(const struct lu_env *env,
1324 struct llog_handle *llh,
1325 struct fs_db *fsdb, __u32 flags,
1326 char *tgtname, char *comment)
1328 struct mgs_thread_info *mgi = mgs_env_info(env);
1329 struct lustre_cfg *lcfg;
1333 if (flags & CM_START)
1335 mgi->mgi_marker.cm_step = fsdb->fsdb_gen;
1336 mgi->mgi_marker.cm_flags = flags;
1337 mgi->mgi_marker.cm_vers = LUSTRE_VERSION_CODE;
1338 cplen = strlcpy(mgi->mgi_marker.cm_tgtname, tgtname,
1339 sizeof(mgi->mgi_marker.cm_tgtname));
1340 if (cplen >= sizeof(mgi->mgi_marker.cm_tgtname))
1342 cplen = strlcpy(mgi->mgi_marker.cm_comment, comment,
1343 sizeof(mgi->mgi_marker.cm_comment));
1344 if (cplen >= sizeof(mgi->mgi_marker.cm_comment))
1346 mgi->mgi_marker.cm_createtime = cfs_time_current_sec();
1347 mgi->mgi_marker.cm_canceltime = 0;
1348 lustre_cfg_bufs_reset(&mgi->mgi_bufs, NULL);
1349 lustre_cfg_bufs_set(&mgi->mgi_bufs, 1, &mgi->mgi_marker,
1350 sizeof(mgi->mgi_marker));
1351 lcfg = lustre_cfg_new(LCFG_MARKER, &mgi->mgi_bufs);
1354 rc = record_lcfg(env, llh, lcfg);
1356 lustre_cfg_free(lcfg);
1360 static int record_start_log(const struct lu_env *env, struct mgs_device *mgs,
1361 struct llog_handle **llh, char *name)
1363 static struct obd_uuid cfg_uuid = { .uuid = "config_uuid" };
1364 struct llog_ctxt *ctxt;
1368 GOTO(out, rc = -EBUSY);
1370 ctxt = llog_get_context(mgs->mgs_obd, LLOG_CONFIG_ORIG_CTXT);
1372 GOTO(out, rc = -ENODEV);
1373 LASSERT(ctxt->loc_obd == mgs->mgs_obd);
1375 rc = llog_open_create(env, ctxt, llh, NULL, name);
1378 rc = llog_init_handle(env, *llh, LLOG_F_IS_PLAIN, &cfg_uuid);
1380 llog_close(env, *llh);
1382 llog_ctxt_put(ctxt);
1385 CERROR("%s: can't start log %s: rc = %d\n",
1386 mgs->mgs_obd->obd_name, name, rc);
1392 static int record_end_log(const struct lu_env *env, struct llog_handle **llh)
1396 rc = llog_close(env, *llh);
1402 /******************** config "macros" *********************/
1404 /* write an lcfg directly into a log (with markers) */
1405 static int mgs_write_log_direct(const struct lu_env *env,
1406 struct mgs_device *mgs, struct fs_db *fsdb,
1407 char *logname, struct lustre_cfg *lcfg,
1408 char *devname, char *comment)
1410 struct llog_handle *llh = NULL;
1417 rc = record_start_log(env, mgs, &llh, logname);
1421 /* FIXME These should be a single journal transaction */
1422 rc = record_marker(env, llh, fsdb, CM_START, devname, comment);
1425 rc = record_lcfg(env, llh, lcfg);
1428 rc = record_marker(env, llh, fsdb, CM_END, devname, comment);
1432 record_end_log(env, &llh);
1436 /* write the lcfg in all logs for the given fs */
1437 int mgs_write_log_direct_all(const struct lu_env *env,
1438 struct mgs_device *mgs,
1440 struct mgs_target_info *mti,
1441 struct lustre_cfg *lcfg,
1442 char *devname, char *comment,
1446 struct mgs_direntry *dirent, *n;
1447 char *fsname = mti->mti_fsname;
1449 int rc = 0, len = strlen(fsname);
1452 /* We need to set params for any future logs
1453 as well. FIXME Append this file to every new log.
1454 Actually, we should store as params (text), not llogs. Or
1456 rc = name_create(&logname, fsname, "-params");
1459 if (mgs_log_is_empty(env, mgs, logname)) {
1460 struct llog_handle *llh = NULL;
1461 rc = record_start_log(env, mgs, &llh, logname);
1462 record_end_log(env, &llh);
1464 name_destroy(&logname);
1468 /* Find all the logs in the CONFIGS directory */
1469 rc = class_dentry_readdir(env, mgs, &list);
1473 /* Could use fsdb index maps instead of directory listing */
1474 cfs_list_for_each_entry_safe(dirent, n, &list, list) {
1475 cfs_list_del(&dirent->list);
1476 /* don't write to sptlrpc rule log */
1477 if (strstr(dirent->name, "-sptlrpc") != NULL)
1480 /* caller wants write server logs only */
1481 if (server_only && strstr(dirent->name, "-client") != NULL)
1484 if (strncmp(fsname, dirent->name, len) == 0) {
1485 CDEBUG(D_MGS, "Changing log %s\n", dirent->name);
1486 /* Erase any old settings of this same parameter */
1487 rc = mgs_modify(env, mgs, fsdb, mti, dirent->name,
1488 devname, comment, CM_SKIP);
1490 CERROR("%s: Can't modify llog %s: rc = %d\n",
1491 mgs->mgs_obd->obd_name, dirent->name,rc);
1492 /* Write the new one */
1494 rc = mgs_write_log_direct(env, mgs, fsdb,
1499 CERROR("%s: writing log %s: rc = %d\n",
1500 mgs->mgs_obd->obd_name,
1505 mgs_direntry_free(dirent);
1511 static int mgs_write_log_osp_to_mdt(const struct lu_env *env,
1512 struct mgs_device *mgs,
1514 struct mgs_target_info *mti,
1515 int index, char *logname);
1516 static int mgs_write_log_osc_to_lov(const struct lu_env *env,
1517 struct mgs_device *mgs,
1519 struct mgs_target_info *mti,
1520 char *logname, char *suffix, char *lovname,
1521 enum lustre_sec_part sec_part, int flags);
1522 static int name_create_mdt_and_lov(char **logname, char **lovname,
1523 struct fs_db *fsdb, int i);
1525 static int add_param(char *params, char *key, char *val)
1527 char *start = params + strlen(params);
1528 char *end = params + sizeof(((struct mgs_target_info *)0)->mti_params);
1532 keylen = strlen(key);
1533 if (start + 1 + keylen + strlen(val) >= end) {
1534 CERROR("params are too long: %s %s%s\n",
1535 params, key != NULL ? key : "", val);
1539 sprintf(start, " %s%s", key != NULL ? key : "", val);
1544 * Walk through client config log record and convert the related records
1547 static int mgs_steal_client_llog_handler(const struct lu_env *env,
1548 struct llog_handle *llh,
1549 struct llog_rec_hdr *rec, void *data)
1551 struct mgs_device *mgs;
1552 struct obd_device *obd;
1553 struct mgs_target_info *mti, *tmti;
1555 int cfg_len = rec->lrh_len;
1556 char *cfg_buf = (char*) (rec + 1);
1557 struct lustre_cfg *lcfg;
1559 struct llog_handle *mdt_llh = NULL;
1560 static int got_an_osc_or_mdc = 0;
1561 /* 0: not found any osc/mdc;
1565 static int last_step = -1;
1570 mti = ((struct temp_comp*)data)->comp_mti;
1571 tmti = ((struct temp_comp*)data)->comp_tmti;
1572 fsdb = ((struct temp_comp*)data)->comp_fsdb;
1573 obd = ((struct temp_comp *)data)->comp_obd;
1574 mgs = lu2mgs_dev(obd->obd_lu_dev);
1577 if (rec->lrh_type != OBD_CFG_REC) {
1578 CERROR("unhandled lrh_type: %#x\n", rec->lrh_type);
1582 rc = lustre_cfg_sanity_check(cfg_buf, cfg_len);
1584 CERROR("Insane cfg\n");
1588 lcfg = (struct lustre_cfg *)cfg_buf;
1590 if (lcfg->lcfg_command == LCFG_MARKER) {
1591 struct cfg_marker *marker;
1592 marker = lustre_cfg_buf(lcfg, 1);
1593 if (!strncmp(marker->cm_comment, "add osc", 7) &&
1594 (marker->cm_flags & CM_START) &&
1595 !(marker->cm_flags & CM_SKIP)) {
1596 got_an_osc_or_mdc = 1;
1597 cplen = strlcpy(tmti->mti_svname, marker->cm_tgtname,
1598 sizeof(tmti->mti_svname));
1599 if (cplen >= sizeof(tmti->mti_svname))
1601 rc = record_start_log(env, mgs, &mdt_llh,
1605 rc = record_marker(env, mdt_llh, fsdb, CM_START,
1606 mti->mti_svname, "add osc(copied)");
1607 record_end_log(env, &mdt_llh);
1608 last_step = marker->cm_step;
1611 if (!strncmp(marker->cm_comment, "add osc", 7) &&
1612 (marker->cm_flags & CM_END) &&
1613 !(marker->cm_flags & CM_SKIP)) {
1614 LASSERT(last_step == marker->cm_step);
1616 got_an_osc_or_mdc = 0;
1617 memset(tmti, 0, sizeof(*tmti));
1618 rc = record_start_log(env, mgs, &mdt_llh,
1622 rc = record_marker(env, mdt_llh, fsdb, CM_END,
1623 mti->mti_svname, "add osc(copied)");
1624 record_end_log(env, &mdt_llh);
1627 if (!strncmp(marker->cm_comment, "add mdc", 7) &&
1628 (marker->cm_flags & CM_START) &&
1629 !(marker->cm_flags & CM_SKIP)) {
1630 got_an_osc_or_mdc = 2;
1631 last_step = marker->cm_step;
1632 memcpy(tmti->mti_svname, marker->cm_tgtname,
1633 strlen(marker->cm_tgtname));
1637 if (!strncmp(marker->cm_comment, "add mdc", 7) &&
1638 (marker->cm_flags & CM_END) &&
1639 !(marker->cm_flags & CM_SKIP)) {
1640 LASSERT(last_step == marker->cm_step);
1642 got_an_osc_or_mdc = 0;
1643 memset(tmti, 0, sizeof(*tmti));
1648 if (got_an_osc_or_mdc == 0 || last_step < 0)
1651 if (lcfg->lcfg_command == LCFG_ADD_UUID) {
1652 uint64_t nodenid = lcfg->lcfg_nid;
1654 if (strlen(tmti->mti_uuid) == 0) {
1655 /* target uuid not set, this config record is before
1656 * LCFG_SETUP, this nid is one of target node nid.
1658 tmti->mti_nids[tmti->mti_nid_count] = nodenid;
1659 tmti->mti_nid_count++;
1661 /* failover node nid */
1662 rc = add_param(tmti->mti_params, PARAM_FAILNODE,
1663 libcfs_nid2str(nodenid));
1669 if (lcfg->lcfg_command == LCFG_SETUP) {
1672 target = lustre_cfg_string(lcfg, 1);
1673 memcpy(tmti->mti_uuid, target, strlen(target));
1677 /* ignore client side sptlrpc_conf_log */
1678 if (lcfg->lcfg_command == LCFG_SPTLRPC_CONF)
1681 if (lcfg->lcfg_command == LCFG_ADD_MDC) {
1684 if (sscanf(lustre_cfg_buf(lcfg, 2), "%d", &index) != 1)
1687 memcpy(tmti->mti_fsname, mti->mti_fsname,
1688 strlen(mti->mti_fsname));
1689 tmti->mti_stripe_index = index;
1691 rc = mgs_write_log_osp_to_mdt(env, mgs, fsdb, tmti,
1692 mti->mti_stripe_index,
1694 memset(tmti, 0, sizeof(*tmti));
1698 if (lcfg->lcfg_command == LCFG_LOV_ADD_OBD) {
1701 char *logname, *lovname;
1703 rc = name_create_mdt_and_lov(&logname, &lovname, fsdb,
1704 mti->mti_stripe_index);
1707 sprintf(mdt_index, "-MDT%04x", mti->mti_stripe_index);
1709 if (sscanf(lustre_cfg_buf(lcfg, 2), "%d", &index) != 1) {
1710 name_destroy(&logname);
1711 name_destroy(&lovname);
1715 tmti->mti_stripe_index = index;
1716 rc = mgs_write_log_osc_to_lov(env, mgs, fsdb, tmti, logname,
1719 name_destroy(&logname);
1720 name_destroy(&lovname);
1726 /* fsdb->fsdb_mutex is already held in mgs_write_log_target*/
1727 /* stealed from mgs_get_fsdb_from_llog*/
1728 static int mgs_steal_llog_for_mdt_from_client(const struct lu_env *env,
1729 struct mgs_device *mgs,
1731 struct temp_comp* comp)
1733 struct llog_handle *loghandle;
1734 struct mgs_target_info *tmti;
1735 struct llog_ctxt *ctxt;
1740 ctxt = llog_get_context(mgs->mgs_obd, LLOG_CONFIG_ORIG_CTXT);
1741 LASSERT(ctxt != NULL);
1743 OBD_ALLOC_PTR(tmti);
1745 GOTO(out_ctxt, rc = -ENOMEM);
1747 comp->comp_tmti = tmti;
1748 comp->comp_obd = mgs->mgs_obd;
1750 rc = llog_open(env, ctxt, &loghandle, NULL, client_name,
1758 rc = llog_init_handle(env, loghandle, LLOG_F_IS_PLAIN, NULL);
1760 GOTO(out_close, rc);
1762 rc = llog_process_or_fork(env, loghandle, mgs_steal_client_llog_handler,
1763 (void *)comp, NULL, false);
1764 CDEBUG(D_MGS, "steal llog re = %d\n", rc);
1766 llog_close(env, loghandle);
1770 llog_ctxt_put(ctxt);
1774 /* lmv is the second thing for client logs */
1775 /* copied from mgs_write_log_lov. Please refer to that. */
1776 static int mgs_write_log_lmv(const struct lu_env *env,
1777 struct mgs_device *mgs,
1779 struct mgs_target_info *mti,
1780 char *logname, char *lmvname)
1782 struct llog_handle *llh = NULL;
1783 struct lmv_desc *lmvdesc;
1788 CDEBUG(D_MGS, "Writing lmv(%s) log for %s\n", lmvname,logname);
1790 OBD_ALLOC_PTR(lmvdesc);
1791 if (lmvdesc == NULL)
1793 lmvdesc->ld_active_tgt_count = 0;
1794 lmvdesc->ld_tgt_count = 0;
1795 sprintf((char*)lmvdesc->ld_uuid.uuid, "%s_UUID", lmvname);
1796 uuid = (char *)lmvdesc->ld_uuid.uuid;
1798 rc = record_start_log(env, mgs, &llh, logname);
1801 rc = record_marker(env, llh, fsdb, CM_START, lmvname, "lmv setup");
1804 rc = record_attach(env, llh, lmvname, "lmv", uuid);
1807 rc = record_lmv_setup(env, llh, lmvname, lmvdesc);
1810 rc = record_marker(env, llh, fsdb, CM_END, lmvname, "lmv setup");
1814 record_end_log(env, &llh);
1816 OBD_FREE_PTR(lmvdesc);
1820 /* lov is the first thing in the mdt and client logs */
1821 static int mgs_write_log_lov(const struct lu_env *env, struct mgs_device *mgs,
1822 struct fs_db *fsdb, struct mgs_target_info *mti,
1823 char *logname, char *lovname)
1825 struct llog_handle *llh = NULL;
1826 struct lov_desc *lovdesc;
1831 CDEBUG(D_MGS, "Writing lov(%s) log for %s\n", lovname, logname);
1834 #01 L attach 0:lov_mdsA 1:lov 2:71ccb_lov_mdsA_19f961a9e1
1835 #02 L lov_setup 0:lov_mdsA 1:(struct lov_desc)
1836 uuid=lov1_UUID, stripe count=1, size=1048576, offset=0, pattern=0
1839 /* FIXME just make lov_setup accept empty desc (put uuid in buf 2) */
1840 OBD_ALLOC_PTR(lovdesc);
1841 if (lovdesc == NULL)
1843 lovdesc->ld_magic = LOV_DESC_MAGIC;
1844 lovdesc->ld_tgt_count = 0;
1845 /* Defaults. Can be changed later by lcfg config_param */
1846 lovdesc->ld_default_stripe_count = 1;
1847 lovdesc->ld_pattern = LOV_PATTERN_RAID0;
1848 lovdesc->ld_default_stripe_size = 1024 * 1024;
1849 lovdesc->ld_default_stripe_offset = -1;
1850 lovdesc->ld_qos_maxage = QOS_DEFAULT_MAXAGE;
1851 sprintf((char*)lovdesc->ld_uuid.uuid, "%s_UUID", lovname);
1852 /* can these be the same? */
1853 uuid = (char *)lovdesc->ld_uuid.uuid;
1855 /* This should always be the first entry in a log.
1856 rc = mgs_clear_log(obd, logname); */
1857 rc = record_start_log(env, mgs, &llh, logname);
1860 /* FIXME these should be a single journal transaction */
1861 rc = record_marker(env, llh, fsdb, CM_START, lovname, "lov setup");
1864 rc = record_attach(env, llh, lovname, "lov", uuid);
1867 rc = record_lov_setup(env, llh, lovname, lovdesc);
1870 rc = record_marker(env, llh, fsdb, CM_END, lovname, "lov setup");
1875 record_end_log(env, &llh);
1877 OBD_FREE_PTR(lovdesc);
1881 /* add failnids to open log */
1882 static int mgs_write_log_failnids(const struct lu_env *env,
1883 struct mgs_target_info *mti,
1884 struct llog_handle *llh,
1887 char *failnodeuuid = NULL;
1888 char *ptr = mti->mti_params;
1893 #03 L add_uuid nid=uml1@tcp(0x20000c0a80201) nal=90 0: 1:uml1_UUID
1894 #04 L add_uuid nid=1@elan(0x1000000000001) nal=90 0: 1:uml1_UUID
1895 #05 L setup 0:OSC_uml1_ost1_mdsA 1:ost1_UUID 2:uml1_UUID
1896 #06 L add_uuid nid=uml2@tcp(0x20000c0a80202) nal=90 0: 1:uml2_UUID
1897 #0x L add_uuid nid=2@elan(0x1000000000002) nal=90 0: 1:uml2_UUID
1898 #07 L add_conn 0:OSC_uml1_ost1_mdsA 1:uml2_UUID
1901 /* Pull failnid info out of params string */
1902 while (class_find_param(ptr, PARAM_FAILNODE, &ptr) == 0) {
1903 while (class_parse_nid(ptr, &nid, &ptr) == 0) {
1904 if (failnodeuuid == NULL) {
1905 /* We don't know the failover node name,
1906 so just use the first nid as the uuid */
1907 rc = name_create(&failnodeuuid,
1908 libcfs_nid2str(nid), "");
1912 CDEBUG(D_MGS, "add nid %s for failover uuid %s, "
1913 "client %s\n", libcfs_nid2str(nid),
1914 failnodeuuid, cliname);
1915 rc = record_add_uuid(env, llh, nid, failnodeuuid);
1918 rc = record_add_conn(env, llh, cliname, failnodeuuid);
1921 name_destroy(&failnodeuuid);
1925 static int mgs_write_log_mdc_to_lmv(const struct lu_env *env,
1926 struct mgs_device *mgs,
1928 struct mgs_target_info *mti,
1929 char *logname, char *lmvname)
1931 struct llog_handle *llh = NULL;
1932 char *mdcname = NULL;
1933 char *nodeuuid = NULL;
1934 char *mdcuuid = NULL;
1935 char *lmvuuid = NULL;
1940 if (mgs_log_is_empty(env, mgs, logname)) {
1941 CERROR("log is empty! Logical error\n");
1945 CDEBUG(D_MGS, "adding mdc for %s to log %s:lmv(%s)\n",
1946 mti->mti_svname, logname, lmvname);
1948 rc = name_create(&nodeuuid, libcfs_nid2str(mti->mti_nids[0]), "");
1951 rc = name_create(&mdcname, mti->mti_svname, "-mdc");
1954 rc = name_create(&mdcuuid, mdcname, "_UUID");
1957 rc = name_create(&lmvuuid, lmvname, "_UUID");
1961 rc = record_start_log(env, mgs, &llh, logname);
1964 rc = record_marker(env, llh, fsdb, CM_START, mti->mti_svname,
1968 for (i = 0; i < mti->mti_nid_count; i++) {
1969 CDEBUG(D_MGS, "add nid %s for mdt\n",
1970 libcfs_nid2str(mti->mti_nids[i]));
1972 rc = record_add_uuid(env, llh, mti->mti_nids[i], nodeuuid);
1977 rc = record_attach(env, llh, mdcname, LUSTRE_MDC_NAME, lmvuuid);
1980 rc = record_setup(env, llh, mdcname, mti->mti_uuid, nodeuuid, 0, 0);
1983 rc = mgs_write_log_failnids(env, mti, llh, mdcname);
1986 snprintf(index, sizeof(index), "%d", mti->mti_stripe_index);
1987 rc = record_mdc_add(env, llh, lmvname, mdcuuid, mti->mti_uuid,
1991 rc = record_marker(env, llh, fsdb, CM_END, mti->mti_svname,
1996 record_end_log(env, &llh);
1998 name_destroy(&lmvuuid);
1999 name_destroy(&mdcuuid);
2000 name_destroy(&mdcname);
2001 name_destroy(&nodeuuid);
2005 static inline int name_create_lov(char **lovname, char *mdtname,
2006 struct fs_db *fsdb, int index)
2009 if (index == 0 && test_bit(FSDB_OSCNAME18, &fsdb->fsdb_flags))
2010 return name_create(lovname, fsdb->fsdb_name, "-mdtlov");
2012 return name_create(lovname, mdtname, "-mdtlov");
2015 static int name_create_mdt_and_lov(char **logname, char **lovname,
2016 struct fs_db *fsdb, int i)
2020 rc = name_create_mdt(logname, fsdb->fsdb_name, i);
2024 if (i == 0 && test_bit(FSDB_OSCNAME18, &fsdb->fsdb_flags))
2025 rc = name_create(lovname, fsdb->fsdb_name, "-mdtlov");
2027 rc = name_create(lovname, *logname, "-mdtlov");
2029 name_destroy(logname);
2035 static inline int name_create_mdt_osc(char **oscname, char *ostname,
2036 struct fs_db *fsdb, int i)
2040 if (i == 0 && test_bit(FSDB_OSCNAME18, &fsdb->fsdb_flags))
2041 sprintf(suffix, "-osc");
2043 sprintf(suffix, "-osc-MDT%04x", i);
2044 return name_create(oscname, ostname, suffix);
2047 /* add new mdc to already existent MDS */
2048 static int mgs_write_log_osp_to_mdt(const struct lu_env *env,
2049 struct mgs_device *mgs,
2051 struct mgs_target_info *mti,
2052 int mdt_index, char *logname)
2054 struct llog_handle *llh = NULL;
2055 char *nodeuuid = NULL;
2056 char *ospname = NULL;
2057 char *lovuuid = NULL;
2058 char *mdtuuid = NULL;
2059 char *svname = NULL;
2060 char *mdtname = NULL;
2061 char *lovname = NULL;
2066 if (mgs_log_is_empty(env, mgs, mti->mti_svname)) {
2067 CERROR("log is empty! Logical error\n");
2071 CDEBUG(D_MGS, "adding osp index %d to %s\n", mti->mti_stripe_index,
2074 rc = name_create_mdt(&mdtname, fsdb->fsdb_name, mti->mti_stripe_index);
2078 rc = name_create(&nodeuuid, libcfs_nid2str(mti->mti_nids[0]), "");
2080 GOTO(out_destory, rc);
2082 rc = name_create(&svname, mdtname, "-osp");
2084 GOTO(out_destory, rc);
2086 sprintf(index_str, "-MDT%04x", mdt_index);
2087 rc = name_create(&ospname, svname, index_str);
2089 GOTO(out_destory, rc);
2091 rc = name_create_lov(&lovname, logname, fsdb, mdt_index);
2093 GOTO(out_destory, rc);
2095 rc = name_create(&lovuuid, lovname, "_UUID");
2097 GOTO(out_destory, rc);
2099 rc = name_create(&mdtuuid, mdtname, "_UUID");
2101 GOTO(out_destory, rc);
2103 rc = record_start_log(env, mgs, &llh, logname);
2105 GOTO(out_destory, rc);
2107 rc = record_marker(env, llh, fsdb, CM_START, mti->mti_svname,
2110 GOTO(out_destory, rc);
2112 for (i = 0; i < mti->mti_nid_count; i++) {
2113 CDEBUG(D_MGS, "add nid %s for mdt\n",
2114 libcfs_nid2str(mti->mti_nids[i]));
2115 rc = record_add_uuid(env, llh, mti->mti_nids[i], nodeuuid);
2120 rc = record_attach(env, llh, ospname, LUSTRE_OSP_NAME, lovuuid);
2124 rc = record_setup(env, llh, ospname, mti->mti_uuid, nodeuuid,
2129 rc = mgs_write_log_failnids(env, mti, llh, ospname);
2133 /* Add mdc(osp) to lod */
2134 snprintf(index_str, sizeof(mti->mti_stripe_index), "%d",
2135 mti->mti_stripe_index);
2136 rc = record_base(env, llh, lovname, 0, LCFG_ADD_MDC, mti->mti_uuid,
2137 index_str, "1", NULL);
2141 rc = record_marker(env, llh, fsdb, CM_END, mti->mti_svname, "add osp");
2146 record_end_log(env, &llh);
2149 name_destroy(&mdtuuid);
2150 name_destroy(&lovuuid);
2151 name_destroy(&lovname);
2152 name_destroy(&ospname);
2153 name_destroy(&svname);
2154 name_destroy(&nodeuuid);
2155 name_destroy(&mdtname);
2159 static int mgs_write_log_mdt0(const struct lu_env *env,
2160 struct mgs_device *mgs,
2162 struct mgs_target_info *mti)
2164 char *log = mti->mti_svname;
2165 struct llog_handle *llh = NULL;
2166 char *uuid, *lovname;
2168 char *ptr = mti->mti_params;
2169 int rc = 0, failout = 0;
2172 OBD_ALLOC(uuid, sizeof(struct obd_uuid));
2176 if (class_find_param(ptr, PARAM_FAILMODE, &ptr) == 0)
2177 failout = (strncmp(ptr, "failout", 7) == 0);
2179 rc = name_create(&lovname, log, "-mdtlov");
2182 if (mgs_log_is_empty(env, mgs, log)) {
2183 rc = mgs_write_log_lov(env, mgs, fsdb, mti, log, lovname);
2188 sprintf(mdt_index, "%d", mti->mti_stripe_index);
2190 rc = record_start_log(env, mgs, &llh, log);
2194 /* add MDT itself */
2196 /* FIXME this whole fn should be a single journal transaction */
2197 sprintf(uuid, "%s_UUID", log);
2198 rc = record_marker(env, llh, fsdb, CM_START, log, "add mdt");
2201 rc = record_attach(env, llh, log, LUSTRE_MDT_NAME, uuid);
2204 rc = record_mount_opt(env, llh, log, lovname, NULL);
2207 rc = record_setup(env, llh, log, uuid, mdt_index, lovname,
2208 failout ? "n" : "f");
2211 rc = record_marker(env, llh, fsdb, CM_END, log, "add mdt");
2215 record_end_log(env, &llh);
2217 name_destroy(&lovname);
2219 OBD_FREE(uuid, sizeof(struct obd_uuid));
2223 /* envelope method for all layers log */
2224 static int mgs_write_log_mdt(const struct lu_env *env,
2225 struct mgs_device *mgs,
2227 struct mgs_target_info *mti)
2229 struct mgs_thread_info *mgi = mgs_env_info(env);
2230 struct llog_handle *llh = NULL;
2235 CDEBUG(D_MGS, "writing new mdt %s\n", mti->mti_svname);
2237 if (mti->mti_uuid[0] == '\0') {
2238 /* Make up our own uuid */
2239 snprintf(mti->mti_uuid, sizeof(mti->mti_uuid),
2240 "%s_UUID", mti->mti_svname);
2244 rc = mgs_write_log_mdt0(env, mgs, fsdb, mti);
2247 /* Append the mdt info to the client log */
2248 rc = name_create(&cliname, mti->mti_fsname, "-client");
2252 if (mgs_log_is_empty(env, mgs, cliname)) {
2253 /* Start client log */
2254 rc = mgs_write_log_lov(env, mgs, fsdb, mti, cliname,
2258 rc = mgs_write_log_lmv(env, mgs, fsdb, mti, cliname,
2265 #09 L add_uuid nid=uml1@tcp(0x20000c0a80201) 0: 1:uml1_UUID
2266 #10 L attach 0:MDC_uml1_mdsA_MNT_client 1:mdc 2:1d834_MNT_client_03f
2267 #11 L setup 0:MDC_uml1_mdsA_MNT_client 1:mdsA_UUID 2:uml1_UUID
2268 #12 L add_uuid nid=uml2@tcp(0x20000c0a80202) 0: 1:uml2_UUID
2269 #13 L add_conn 0:MDC_uml1_mdsA_MNT_client 1:uml2_UUID
2270 #14 L mount_option 0: 1:client 2:lov1 3:MDC_uml1_mdsA_MNT_client
2273 /* copy client info about lov/lmv */
2274 mgi->mgi_comp.comp_mti = mti;
2275 mgi->mgi_comp.comp_fsdb = fsdb;
2277 rc = mgs_steal_llog_for_mdt_from_client(env, mgs, cliname,
2281 rc = mgs_write_log_mdc_to_lmv(env, mgs, fsdb, mti, cliname,
2287 rc = record_start_log(env, mgs, &llh, cliname);
2291 rc = record_marker(env, llh, fsdb, CM_START, cliname,
2295 rc = record_mount_opt(env, llh, cliname, fsdb->fsdb_clilov,
2299 rc = record_marker(env, llh, fsdb, CM_END, cliname,
2305 /* for_all_existing_mdt except current one */
2306 for (i = 0; i < INDEX_MAP_SIZE * 8; i++) {
2307 if (i != mti->mti_stripe_index &&
2308 test_bit(i, fsdb->fsdb_mdt_index_map)) {
2311 rc = name_create_mdt(&logname, fsdb->fsdb_name, i);
2315 rc = mgs_write_log_osp_to_mdt(env, mgs, fsdb, mti,
2317 name_destroy(&logname);
2323 record_end_log(env, &llh);
2325 name_destroy(&cliname);
2329 /* Add the ost info to the client/mdt lov */
2330 static int mgs_write_log_osc_to_lov(const struct lu_env *env,
2331 struct mgs_device *mgs, struct fs_db *fsdb,
2332 struct mgs_target_info *mti,
2333 char *logname, char *suffix, char *lovname,
2334 enum lustre_sec_part sec_part, int flags)
2336 struct llog_handle *llh = NULL;
2337 char *nodeuuid = NULL;
2338 char *oscname = NULL;
2339 char *oscuuid = NULL;
2340 char *lovuuid = NULL;
2341 char *svname = NULL;
2346 CDEBUG(D_INFO, "adding osc for %s to log %s\n",
2347 mti->mti_svname, logname);
2349 if (mgs_log_is_empty(env, mgs, logname)) {
2350 CERROR("log is empty! Logical error\n");
2354 rc = name_create(&nodeuuid, libcfs_nid2str(mti->mti_nids[0]), "");
2357 rc = name_create(&svname, mti->mti_svname, "-osc");
2361 /* for the system upgraded from old 1.8, keep using the old osc naming
2362 * style for mdt, see name_create_mdt_osc(). LU-1257 */
2363 if (test_bit(FSDB_OSCNAME18, &fsdb->fsdb_flags))
2364 rc = name_create(&oscname, svname, "");
2366 rc = name_create(&oscname, svname, suffix);
2370 rc = name_create(&oscuuid, oscname, "_UUID");
2373 rc = name_create(&lovuuid, lovname, "_UUID");
2379 #03 L add_uuid nid=uml1@tcp(0x20000c0a80201) 0: 1:uml1_UUID
2381 #04 L add_uuid nid=1@elan(0x1000000000001) nal=90 0: 1:uml1_UUID
2382 #04 L attach 0:OSC_uml1_ost1_MNT_client 1:osc 2:89070_lov1_a41dff51a
2383 #05 L setup 0:OSC_uml1_ost1_MNT_client 1:ost1_UUID 2:uml1_UUID
2385 #06 L add_uuid nid=uml2@tcp(0x20000c0a80202) 0: 1:uml2_UUID
2386 #07 L add_conn 0:OSC_uml1_ost1_MNT_client 1:uml2_UUID
2387 #08 L lov_modify_tgts add 0:lov1 1:ost1_UUID 2(index):0 3(gen):1
2390 rc = record_start_log(env, mgs, &llh, logname);
2394 /* FIXME these should be a single journal transaction */
2395 rc = record_marker(env, llh, fsdb, CM_START | flags, mti->mti_svname,
2400 /* NB: don't change record order, because upon MDT steal OSC config
2401 * from client, it treats all nids before LCFG_SETUP as target nids
2402 * (multiple interfaces), while nids after as failover node nids.
2403 * See mgs_steal_client_llog_handler() LCFG_ADD_UUID.
2405 for (i = 0; i < mti->mti_nid_count; i++) {
2406 CDEBUG(D_MGS, "add nid %s\n", libcfs_nid2str(mti->mti_nids[i]));
2407 rc = record_add_uuid(env, llh, mti->mti_nids[i], nodeuuid);
2411 rc = record_attach(env, llh, oscname, LUSTRE_OSC_NAME, lovuuid);
2414 rc = record_setup(env, llh, oscname, mti->mti_uuid, nodeuuid, 0, 0);
2417 rc = mgs_write_log_failnids(env, mti, llh, oscname);
2421 snprintf(index, sizeof(index), "%d", mti->mti_stripe_index);
2423 rc = record_lov_add(env, llh, lovname, mti->mti_uuid, index, "1");
2426 rc = record_marker(env, llh, fsdb, CM_END | flags, mti->mti_svname,
2431 record_end_log(env, &llh);
2433 name_destroy(&lovuuid);
2434 name_destroy(&oscuuid);
2435 name_destroy(&oscname);
2436 name_destroy(&svname);
2437 name_destroy(&nodeuuid);
2441 static int mgs_write_log_ost(const struct lu_env *env,
2442 struct mgs_device *mgs, struct fs_db *fsdb,
2443 struct mgs_target_info *mti)
2445 struct llog_handle *llh = NULL;
2446 char *logname, *lovname;
2447 char *ptr = mti->mti_params;
2448 int rc, flags = 0, failout = 0, i;
2451 CDEBUG(D_MGS, "writing new ost %s\n", mti->mti_svname);
2453 /* The ost startup log */
2455 /* If the ost log already exists, that means that someone reformatted
2456 the ost and it called target_add again. */
2457 if (!mgs_log_is_empty(env, mgs, mti->mti_svname)) {
2458 LCONSOLE_ERROR_MSG(0x141, "The config log for %s already "
2459 "exists, yet the server claims it never "
2460 "registered. It may have been reformatted, "
2461 "or the index changed. writeconf the MDT to "
2462 "regenerate all logs.\n", mti->mti_svname);
2467 attach obdfilter ost1 ost1_UUID
2468 setup /dev/loop2 ldiskfs f|n errors=remount-ro,user_xattr
2470 if (class_find_param(ptr, PARAM_FAILMODE, &ptr) == 0)
2471 failout = (strncmp(ptr, "failout", 7) == 0);
2472 rc = record_start_log(env, mgs, &llh, mti->mti_svname);
2475 /* FIXME these should be a single journal transaction */
2476 rc = record_marker(env, llh, fsdb, CM_START, mti->mti_svname,"add ost");
2479 if (*mti->mti_uuid == '\0')
2480 snprintf(mti->mti_uuid, sizeof(mti->mti_uuid),
2481 "%s_UUID", mti->mti_svname);
2482 rc = record_attach(env, llh, mti->mti_svname,
2483 "obdfilter"/*LUSTRE_OST_NAME*/, mti->mti_uuid);
2486 rc = record_setup(env, llh, mti->mti_svname,
2487 "dev"/*ignored*/, "type"/*ignored*/,
2488 failout ? "n" : "f", 0/*options*/);
2491 rc = record_marker(env, llh, fsdb, CM_END, mti->mti_svname, "add ost");
2495 record_end_log(env, &llh);
2498 /* We also have to update the other logs where this osc is part of
2501 if (test_bit(FSDB_OLDLOG14, &fsdb->fsdb_flags)) {
2502 /* If we're upgrading, the old mdt log already has our
2503 entry. Let's do a fake one for fun. */
2504 /* Note that we can't add any new failnids, since we don't
2505 know the old osc names. */
2506 flags = CM_SKIP | CM_UPGRADE146;
2508 } else if ((mti->mti_flags & LDD_F_UPDATE) != LDD_F_UPDATE) {
2509 /* If the update flag isn't set, don't update client/mdt
2512 LCONSOLE_WARN("Client log for %s was not updated; writeconf "
2513 "the MDT first to regenerate it.\n",
2517 /* Add ost to all MDT lov defs */
2518 for (i = 0; i < INDEX_MAP_SIZE * 8; i++){
2519 if (test_bit(i, fsdb->fsdb_mdt_index_map)) {
2522 rc = name_create_mdt_and_lov(&logname, &lovname, fsdb,
2526 sprintf(mdt_index, "-MDT%04x", i);
2527 rc = mgs_write_log_osc_to_lov(env, mgs, fsdb, mti,
2529 lovname, LUSTRE_SP_MDT,
2531 name_destroy(&logname);
2532 name_destroy(&lovname);
2538 /* Append ost info to the client log */
2539 rc = name_create(&logname, mti->mti_fsname, "-client");
2542 if (mgs_log_is_empty(env, mgs, logname)) {
2543 /* Start client log */
2544 rc = mgs_write_log_lov(env, mgs, fsdb, mti, logname,
2548 rc = mgs_write_log_lmv(env, mgs, fsdb, mti, logname,
2553 rc = mgs_write_log_osc_to_lov(env, mgs, fsdb, mti, logname, "",
2554 fsdb->fsdb_clilov, LUSTRE_SP_CLI, 0);
2556 name_destroy(&logname);
2560 static __inline__ int mgs_param_empty(char *ptr)
2564 if ((tmp = strchr(ptr, '=')) && (*(++tmp) == '\0'))
2569 static int mgs_write_log_failnid_internal(const struct lu_env *env,
2570 struct mgs_device *mgs,
2572 struct mgs_target_info *mti,
2573 char *logname, char *cliname)
2576 struct llog_handle *llh = NULL;
2578 if (mgs_param_empty(mti->mti_params)) {
2579 /* Remove _all_ failnids */
2580 rc = mgs_modify(env, mgs, fsdb, mti, logname,
2581 mti->mti_svname, "add failnid", CM_SKIP);
2582 return rc < 0 ? rc : 0;
2585 /* Otherwise failover nids are additive */
2586 rc = record_start_log(env, mgs, &llh, logname);
2589 /* FIXME this should be a single journal transaction */
2590 rc = record_marker(env, llh, fsdb, CM_START, mti->mti_svname,
2594 rc = mgs_write_log_failnids(env, mti, llh, cliname);
2597 rc = record_marker(env, llh, fsdb, CM_END,
2598 mti->mti_svname, "add failnid");
2600 record_end_log(env, &llh);
2605 /* Add additional failnids to an existing log.
2606 The mdc/osc must have been added to logs first */
2607 /* tcp nids must be in dotted-quad ascii -
2608 we can't resolve hostnames from the kernel. */
2609 static int mgs_write_log_add_failnid(const struct lu_env *env,
2610 struct mgs_device *mgs,
2612 struct mgs_target_info *mti)
2614 char *logname, *cliname;
2618 /* FIXME we currently can't erase the failnids
2619 * given when a target first registers, since they aren't part of
2620 * an "add uuid" stanza */
2622 /* Verify that we know about this target */
2623 if (mgs_log_is_empty(env, mgs, mti->mti_svname)) {
2624 LCONSOLE_ERROR_MSG(0x142, "The target %s has not registered "
2625 "yet. It must be started before failnids "
2626 "can be added.\n", mti->mti_svname);
2630 /* Create mdc/osc client name (e.g. lustre-OST0001-osc) */
2631 if (mti->mti_flags & LDD_F_SV_TYPE_MDT) {
2632 rc = name_create(&cliname, mti->mti_svname, "-mdc");
2633 } else if (mti->mti_flags & LDD_F_SV_TYPE_OST) {
2634 rc = name_create(&cliname, mti->mti_svname, "-osc");
2640 /* Add failover nids to the client log */
2641 rc = name_create(&logname, mti->mti_fsname, "-client");
2643 name_destroy(&cliname);
2646 rc = mgs_write_log_failnid_internal(env, mgs, fsdb,mti,logname,cliname);
2647 name_destroy(&logname);
2648 name_destroy(&cliname);
2652 if (mti->mti_flags & LDD_F_SV_TYPE_OST) {
2653 /* Add OST failover nids to the MDT logs as well */
2656 for (i = 0; i < INDEX_MAP_SIZE * 8; i++) {
2657 if (!test_bit(i, fsdb->fsdb_mdt_index_map))
2659 rc = name_create_mdt(&logname, mti->mti_fsname, i);
2662 rc = name_create_mdt_osc(&cliname, mti->mti_svname,
2665 name_destroy(&logname);
2668 rc = mgs_write_log_failnid_internal(env, mgs, fsdb,
2671 name_destroy(&cliname);
2672 name_destroy(&logname);
2681 static int mgs_wlp_lcfg(const struct lu_env *env,
2682 struct mgs_device *mgs, struct fs_db *fsdb,
2683 struct mgs_target_info *mti,
2684 char *logname, struct lustre_cfg_bufs *bufs,
2685 char *tgtname, char *ptr)
2687 char comment[MTI_NAME_MAXLEN];
2689 struct lustre_cfg *lcfg;
2692 /* Erase any old settings of this same parameter */
2693 memcpy(comment, ptr, MTI_NAME_MAXLEN);
2694 comment[MTI_NAME_MAXLEN - 1] = 0;
2695 /* But don't try to match the value. */
2696 if ((tmp = strchr(comment, '=')))
2698 /* FIXME we should skip settings that are the same as old values */
2699 rc = mgs_modify(env, mgs, fsdb, mti, logname, tgtname, comment,CM_SKIP);
2702 del = mgs_param_empty(ptr);
2704 LCONSOLE_INFO("%sing parameter %s.%s in log %s\n", del ? "Disabl" : rc ?
2705 "Sett" : "Modify", tgtname, comment, logname);
2709 lustre_cfg_bufs_reset(bufs, tgtname);
2710 lustre_cfg_bufs_set_string(bufs, 1, ptr);
2711 if (mti->mti_flags & LDD_F_PARAM2)
2712 lustre_cfg_bufs_set_string(bufs, 2, LCTL_UPCALL);
2714 lcfg = lustre_cfg_new((mti->mti_flags & LDD_F_PARAM2) ?
2715 LCFG_SET_PARAM : LCFG_PARAM, bufs);
2719 rc = mgs_write_log_direct(env, mgs, fsdb, logname,lcfg,tgtname,comment);
2720 lustre_cfg_free(lcfg);
2724 static int mgs_write_log_param2(const struct lu_env *env,
2725 struct mgs_device *mgs,
2727 struct mgs_target_info *mti, char *ptr)
2729 struct lustre_cfg_bufs bufs;
2733 CDEBUG(D_MGS, "next param '%s'\n", ptr);
2734 rc = mgs_wlp_lcfg(env, mgs, fsdb, mti, PARAMS_FILENAME, &bufs,
2735 mti->mti_svname, ptr);
2740 /* write global variable settings into log */
2741 static int mgs_write_log_sys(const struct lu_env *env,
2742 struct mgs_device *mgs, struct fs_db *fsdb,
2743 struct mgs_target_info *mti, char *sys, char *ptr)
2745 struct mgs_thread_info *mgi = mgs_env_info(env);
2746 struct lustre_cfg *lcfg;
2748 int rc, cmd, convert = 1;
2750 if (class_match_param(ptr, PARAM_TIMEOUT, &tmp) == 0) {
2751 cmd = LCFG_SET_TIMEOUT;
2752 } else if (class_match_param(ptr, PARAM_LDLM_TIMEOUT, &tmp) == 0) {
2753 cmd = LCFG_SET_LDLM_TIMEOUT;
2754 /* Check for known params here so we can return error to lctl */
2755 } else if ((class_match_param(ptr, PARAM_AT_MIN, &tmp) == 0) ||
2756 (class_match_param(ptr, PARAM_AT_MAX, &tmp) == 0) ||
2757 (class_match_param(ptr, PARAM_AT_EXTRA, &tmp) == 0) ||
2758 (class_match_param(ptr, PARAM_AT_EARLY_MARGIN, &tmp) == 0) ||
2759 (class_match_param(ptr, PARAM_AT_HISTORY, &tmp) == 0)) {
2761 } else if (class_match_param(ptr, PARAM_JOBID_VAR, &tmp) == 0) {
2762 convert = 0; /* Don't convert string value to integer */
2768 if (mgs_param_empty(ptr))
2769 CDEBUG(D_MGS, "global '%s' removed\n", sys);
2771 CDEBUG(D_MGS, "global '%s' val=%s\n", sys, tmp);
2773 lustre_cfg_bufs_reset(&mgi->mgi_bufs, NULL);
2774 lustre_cfg_bufs_set_string(&mgi->mgi_bufs, 1, sys);
2775 if (!convert && *tmp != '\0')
2776 lustre_cfg_bufs_set_string(&mgi->mgi_bufs, 2, tmp);
2777 lcfg = lustre_cfg_new(cmd, &mgi->mgi_bufs);
2778 lcfg->lcfg_num = convert ? simple_strtoul(tmp, NULL, 0) : 0;
2779 /* truncate the comment to the parameter name */
2783 /* modify all servers and clients */
2784 rc = mgs_write_log_direct_all(env, mgs, fsdb, mti,
2785 *tmp == '\0' ? NULL : lcfg,
2786 mti->mti_fsname, sys, 0);
2787 if (rc == 0 && *tmp != '\0') {
2789 case LCFG_SET_TIMEOUT:
2790 if (!obd_timeout_set || lcfg->lcfg_num > obd_timeout)
2791 class_process_config(lcfg);
2793 case LCFG_SET_LDLM_TIMEOUT:
2794 if (!ldlm_timeout_set || lcfg->lcfg_num > ldlm_timeout)
2795 class_process_config(lcfg);
2802 lustre_cfg_free(lcfg);
2806 /* write quota settings into log */
2807 static int mgs_write_log_quota(const struct lu_env *env, struct mgs_device *mgs,
2808 struct fs_db *fsdb, struct mgs_target_info *mti,
2809 char *quota, char *ptr)
2811 struct mgs_thread_info *mgi = mgs_env_info(env);
2812 struct lustre_cfg *lcfg;
2815 int rc, cmd = LCFG_PARAM;
2817 /* support only 'meta' and 'data' pools so far */
2818 if (class_match_param(ptr, QUOTA_METAPOOL_NAME, &tmp) != 0 &&
2819 class_match_param(ptr, QUOTA_DATAPOOL_NAME, &tmp) != 0) {
2820 CERROR("parameter quota.%s isn't supported (only quota.mdt "
2821 "& quota.ost are)\n", ptr);
2826 CDEBUG(D_MGS, "global '%s' removed\n", quota);
2828 CDEBUG(D_MGS, "global '%s'\n", quota);
2830 if (strchr(tmp, 'u') == NULL && strchr(tmp, 'g') == NULL &&
2831 strcmp(tmp, "none") != 0) {
2832 CERROR("enable option(%s) isn't supported\n", tmp);
2837 lustre_cfg_bufs_reset(&mgi->mgi_bufs, mti->mti_fsname);
2838 lustre_cfg_bufs_set_string(&mgi->mgi_bufs, 1, quota);
2839 lcfg = lustre_cfg_new(cmd, &mgi->mgi_bufs);
2840 /* truncate the comment to the parameter name */
2845 /* XXX we duplicated quota enable information in all server
2846 * config logs, it should be moved to a separate config
2847 * log once we cleanup the config log for global param. */
2848 /* modify all servers */
2849 rc = mgs_write_log_direct_all(env, mgs, fsdb, mti,
2850 *tmp == '\0' ? NULL : lcfg,
2851 mti->mti_fsname, quota, 1);
2853 lustre_cfg_free(lcfg);
2854 return rc < 0 ? rc : 0;
2857 static int mgs_srpc_set_param_disk(const struct lu_env *env,
2858 struct mgs_device *mgs,
2860 struct mgs_target_info *mti,
2863 struct mgs_thread_info *mgi = mgs_env_info(env);
2864 struct llog_handle *llh = NULL;
2866 char *comment, *ptr;
2867 struct lustre_cfg *lcfg;
2872 ptr = strchr(param, '=');
2876 OBD_ALLOC(comment, len + 1);
2877 if (comment == NULL)
2879 strncpy(comment, param, len);
2880 comment[len] = '\0';
2883 lustre_cfg_bufs_reset(&mgi->mgi_bufs, mti->mti_svname);
2884 lustre_cfg_bufs_set_string(&mgi->mgi_bufs, 1, param);
2885 lcfg = lustre_cfg_new(LCFG_SPTLRPC_CONF, &mgi->mgi_bufs);
2887 GOTO(out_comment, rc = -ENOMEM);
2889 /* construct log name */
2890 rc = name_create(&logname, mti->mti_fsname, "-sptlrpc");
2894 if (mgs_log_is_empty(env, mgs, logname)) {
2895 rc = record_start_log(env, mgs, &llh, logname);
2898 record_end_log(env, &llh);
2901 /* obsolete old one */
2902 rc = mgs_modify(env, mgs, fsdb, mti, logname, mti->mti_svname,
2906 /* write the new one */
2907 rc = mgs_write_log_direct(env, mgs, fsdb, logname, lcfg,
2908 mti->mti_svname, comment);
2910 CERROR("err %d writing log %s\n", rc, logname);
2912 name_destroy(&logname);
2914 lustre_cfg_free(lcfg);
2916 OBD_FREE(comment, len + 1);
2920 static int mgs_srpc_set_param_udesc_mem(struct fs_db *fsdb,
2925 /* disable the adjustable udesc parameter for now, i.e. use default
2926 * setting that client always ship udesc to MDT if possible. to enable
2927 * it simply remove the following line */
2930 ptr = strchr(param, '=');
2935 if (strcmp(param, PARAM_SRPC_UDESC))
2938 if (strcmp(ptr, "yes") == 0) {
2939 set_bit(FSDB_UDESC, &fsdb->fsdb_flags);
2940 CWARN("Enable user descriptor shipping from client to MDT\n");
2941 } else if (strcmp(ptr, "no") == 0) {
2942 clear_bit(FSDB_UDESC, &fsdb->fsdb_flags);
2943 CWARN("Disable user descriptor shipping from client to MDT\n");
2951 CERROR("Invalid param: %s\n", param);
2955 static int mgs_srpc_set_param_mem(struct fs_db *fsdb,
2959 struct sptlrpc_rule rule;
2960 struct sptlrpc_rule_set *rset;
2964 if (strncmp(param, PARAM_SRPC, sizeof(PARAM_SRPC) - 1) != 0) {
2965 CERROR("Invalid sptlrpc parameter: %s\n", param);
2969 if (strncmp(param, PARAM_SRPC_UDESC,
2970 sizeof(PARAM_SRPC_UDESC) - 1) == 0) {
2971 RETURN(mgs_srpc_set_param_udesc_mem(fsdb, param));
2974 if (strncmp(param, PARAM_SRPC_FLVR, sizeof(PARAM_SRPC_FLVR) - 1) != 0) {
2975 CERROR("Invalid sptlrpc flavor parameter: %s\n", param);
2979 param += sizeof(PARAM_SRPC_FLVR) - 1;
2981 rc = sptlrpc_parse_rule(param, &rule);
2985 /* mgs rules implies must be mgc->mgs */
2986 if (test_bit(FSDB_MGS_SELF, &fsdb->fsdb_flags)) {
2987 if ((rule.sr_from != LUSTRE_SP_MGC &&
2988 rule.sr_from != LUSTRE_SP_ANY) ||
2989 (rule.sr_to != LUSTRE_SP_MGS &&
2990 rule.sr_to != LUSTRE_SP_ANY))
2994 /* preapre room for this coming rule. svcname format should be:
2995 * - fsname: general rule
2996 * - fsname-tgtname: target-specific rule
2998 if (strchr(svname, '-')) {
2999 struct mgs_tgt_srpc_conf *tgtconf;
3002 for (tgtconf = fsdb->fsdb_srpc_tgt; tgtconf != NULL;
3003 tgtconf = tgtconf->mtsc_next) {
3004 if (!strcmp(tgtconf->mtsc_tgt, svname)) {
3013 OBD_ALLOC_PTR(tgtconf);
3014 if (tgtconf == NULL)
3017 name_len = strlen(svname);
3019 OBD_ALLOC(tgtconf->mtsc_tgt, name_len + 1);
3020 if (tgtconf->mtsc_tgt == NULL) {
3021 OBD_FREE_PTR(tgtconf);
3024 memcpy(tgtconf->mtsc_tgt, svname, name_len);
3026 tgtconf->mtsc_next = fsdb->fsdb_srpc_tgt;
3027 fsdb->fsdb_srpc_tgt = tgtconf;
3030 rset = &tgtconf->mtsc_rset;
3032 rset = &fsdb->fsdb_srpc_gen;
3035 rc = sptlrpc_rule_set_merge(rset, &rule);
3040 static int mgs_srpc_set_param(const struct lu_env *env,
3041 struct mgs_device *mgs,
3043 struct mgs_target_info *mti,
3053 /* keep a copy of original param, which could be destroied
3055 copy_size = strlen(param) + 1;
3056 OBD_ALLOC(copy, copy_size);
3059 memcpy(copy, param, copy_size);
3061 rc = mgs_srpc_set_param_mem(fsdb, mti->mti_svname, param);
3065 /* previous steps guaranteed the syntax is correct */
3066 rc = mgs_srpc_set_param_disk(env, mgs, fsdb, mti, copy);
3070 if (test_bit(FSDB_MGS_SELF, &fsdb->fsdb_flags)) {
3072 * for mgs rules, make them effective immediately.
3074 LASSERT(fsdb->fsdb_srpc_tgt == NULL);
3075 sptlrpc_target_update_exp_flavor(mgs->mgs_obd,
3076 &fsdb->fsdb_srpc_gen);
3080 OBD_FREE(copy, copy_size);
3084 struct mgs_srpc_read_data {
3085 struct fs_db *msrd_fsdb;
3089 static int mgs_srpc_read_handler(const struct lu_env *env,
3090 struct llog_handle *llh,
3091 struct llog_rec_hdr *rec, void *data)
3093 struct mgs_srpc_read_data *msrd = data;
3094 struct cfg_marker *marker;
3095 struct lustre_cfg *lcfg = REC_DATA(rec);
3096 char *svname, *param;
3100 if (rec->lrh_type != OBD_CFG_REC) {
3101 CERROR("unhandled lrh_type: %#x\n", rec->lrh_type);
3105 cfg_len = rec->lrh_len - sizeof(struct llog_rec_hdr) -
3106 sizeof(struct llog_rec_tail);
3108 rc = lustre_cfg_sanity_check(lcfg, cfg_len);
3110 CERROR("Insane cfg\n");
3114 if (lcfg->lcfg_command == LCFG_MARKER) {
3115 marker = lustre_cfg_buf(lcfg, 1);
3117 if (marker->cm_flags & CM_START &&
3118 marker->cm_flags & CM_SKIP)
3119 msrd->msrd_skip = 1;
3120 if (marker->cm_flags & CM_END)
3121 msrd->msrd_skip = 0;
3126 if (msrd->msrd_skip)
3129 if (lcfg->lcfg_command != LCFG_SPTLRPC_CONF) {
3130 CERROR("invalid command (%x)\n", lcfg->lcfg_command);
3134 svname = lustre_cfg_string(lcfg, 0);
3135 if (svname == NULL) {
3136 CERROR("svname is empty\n");
3140 param = lustre_cfg_string(lcfg, 1);
3141 if (param == NULL) {
3142 CERROR("param is empty\n");
3146 rc = mgs_srpc_set_param_mem(msrd->msrd_fsdb, svname, param);
3148 CERROR("read sptlrpc record error (%d): %s\n", rc, param);
3153 int mgs_get_fsdb_srpc_from_llog(const struct lu_env *env,
3154 struct mgs_device *mgs,
3157 struct llog_handle *llh = NULL;
3158 struct llog_ctxt *ctxt;
3160 struct mgs_srpc_read_data msrd;
3164 /* construct log name */
3165 rc = name_create(&logname, fsdb->fsdb_name, "-sptlrpc");
3169 ctxt = llog_get_context(mgs->mgs_obd, LLOG_CONFIG_ORIG_CTXT);
3170 LASSERT(ctxt != NULL);
3172 if (mgs_log_is_empty(env, mgs, logname))
3175 rc = llog_open(env, ctxt, &llh, NULL, logname,
3183 rc = llog_init_handle(env, llh, LLOG_F_IS_PLAIN, NULL);
3185 GOTO(out_close, rc);
3187 if (llog_get_size(llh) <= 1)
3188 GOTO(out_close, rc = 0);
3190 msrd.msrd_fsdb = fsdb;
3193 rc = llog_process(env, llh, mgs_srpc_read_handler, (void *)&msrd,
3197 llog_close(env, llh);
3199 llog_ctxt_put(ctxt);
3200 name_destroy(&logname);
3203 CERROR("failed to read sptlrpc config database: %d\n", rc);
3207 /* Permanent settings of all parameters by writing into the appropriate
3208 * configuration logs.
3209 * A parameter with null value ("<param>='\0'") means to erase it out of
3212 static int mgs_write_log_param(const struct lu_env *env,
3213 struct mgs_device *mgs, struct fs_db *fsdb,
3214 struct mgs_target_info *mti, char *ptr)
3216 struct mgs_thread_info *mgi = mgs_env_info(env);
3219 int rc = 0, rc2 = 0;
3222 /* For various parameter settings, we have to figure out which logs
3223 care about them (e.g. both mdt and client for lov settings) */
3224 CDEBUG(D_MGS, "next param '%s'\n", ptr);
3226 /* The params are stored in MOUNT_DATA_FILE and modified via
3227 tunefs.lustre, or set using lctl conf_param */
3229 /* Processed in lustre_start_mgc */
3230 if (class_match_param(ptr, PARAM_MGSNODE, NULL) == 0)
3233 /* Processed in ost/mdt */
3234 if (class_match_param(ptr, PARAM_NETWORK, NULL) == 0)
3237 /* Processed in mgs_write_log_ost */
3238 if (class_match_param(ptr, PARAM_FAILMODE, NULL) == 0) {
3239 if (mti->mti_flags & LDD_F_PARAM) {
3240 LCONSOLE_ERROR_MSG(0x169, "%s can only be "
3241 "changed with tunefs.lustre"
3242 "and --writeconf\n", ptr);
3248 if (class_match_param(ptr, PARAM_SRPC, NULL) == 0) {
3249 rc = mgs_srpc_set_param(env, mgs, fsdb, mti, ptr);
3253 if (class_match_param(ptr, PARAM_FAILNODE, NULL) == 0) {
3254 /* Add a failover nidlist */
3256 /* We already processed failovers params for new
3257 targets in mgs_write_log_target */
3258 if (mti->mti_flags & LDD_F_PARAM) {
3259 CDEBUG(D_MGS, "Adding failnode\n");
3260 rc = mgs_write_log_add_failnid(env, mgs, fsdb, mti);
3265 if (class_match_param(ptr, PARAM_SYS, &tmp) == 0) {
3266 rc = mgs_write_log_sys(env, mgs, fsdb, mti, ptr, tmp);
3270 if (class_match_param(ptr, PARAM_QUOTA, &tmp) == 0) {
3271 rc = mgs_write_log_quota(env, mgs, fsdb, mti, ptr, tmp);
3275 if (class_match_param(ptr, PARAM_OSC""PARAM_ACTIVE, &tmp) == 0) {
3276 /* active=0 means off, anything else means on */
3277 int flag = (*tmp == '0') ? CM_EXCLUDE : 0;
3280 if (!(mti->mti_flags & LDD_F_SV_TYPE_OST)) {
3281 LCONSOLE_ERROR_MSG(0x144, "%s: Only OSCs can "
3282 "be (de)activated.\n",
3284 GOTO(end, rc = -EINVAL);
3286 LCONSOLE_WARN("Permanently %sactivating %s\n",
3287 flag ? "de": "re", mti->mti_svname);
3289 rc = name_create(&logname, mti->mti_fsname, "-client");
3292 rc = mgs_modify(env, mgs, fsdb, mti, logname,
3293 mti->mti_svname, "add osc", flag);
3294 name_destroy(&logname);
3298 /* Add to all MDT logs for CMD */
3299 for (i = 0; i < INDEX_MAP_SIZE * 8; i++) {
3300 if (!test_bit(i, fsdb->fsdb_mdt_index_map))
3302 rc = name_create_mdt(&logname, mti->mti_fsname, i);
3305 rc = mgs_modify(env, mgs, fsdb, mti, logname,
3306 mti->mti_svname, "add osc", flag);
3307 name_destroy(&logname);
3313 LCONSOLE_ERROR_MSG(0x145, "Couldn't find %s in"
3314 "log (%d). No permanent "
3315 "changes were made to the "
3317 mti->mti_svname, rc);
3318 if (test_bit(FSDB_OLDLOG14, &fsdb->fsdb_flags))
3319 LCONSOLE_ERROR_MSG(0x146, "This may be"
3324 "update the logs.\n");
3327 /* Fall through to osc proc for deactivating live OSC
3328 on running MDT / clients. */
3330 /* Below here, let obd's XXX_process_config methods handle it */
3332 /* All lov. in proc */
3333 if (class_match_param(ptr, PARAM_LOV, NULL) == 0) {
3336 CDEBUG(D_MGS, "lov param %s\n", ptr);
3337 if (!(mti->mti_flags & LDD_F_SV_TYPE_MDT)) {
3338 LCONSOLE_ERROR_MSG(0x147, "LOV params must be "
3339 "set on the MDT, not %s. "
3346 if (mgs_log_is_empty(env, mgs, mti->mti_svname))
3347 GOTO(end, rc = -ENODEV);
3349 rc = name_create_mdt_and_lov(&logname, &mdtlovname, fsdb,
3350 mti->mti_stripe_index);
3353 rc = mgs_wlp_lcfg(env, mgs, fsdb, mti, mti->mti_svname,
3354 &mgi->mgi_bufs, mdtlovname, ptr);
3355 name_destroy(&logname);
3356 name_destroy(&mdtlovname);
3361 rc = name_create(&logname, mti->mti_fsname, "-client");
3364 rc = mgs_wlp_lcfg(env, mgs, fsdb, mti, logname, &mgi->mgi_bufs,
3365 fsdb->fsdb_clilov, ptr);
3366 name_destroy(&logname);
3370 /* All osc., mdc., llite. params in proc */
3371 if ((class_match_param(ptr, PARAM_OSC, NULL) == 0) ||
3372 (class_match_param(ptr, PARAM_MDC, NULL) == 0) ||
3373 (class_match_param(ptr, PARAM_LLITE, NULL) == 0)) {
3376 if (test_bit(FSDB_OLDLOG14, &fsdb->fsdb_flags)) {
3377 LCONSOLE_ERROR_MSG(0x148, "Upgraded client logs for %s"
3378 " cannot be modified. Consider"
3379 " updating the configuration with"
3382 GOTO(end, rc = -EINVAL);
3384 if (memcmp(ptr, PARAM_LLITE, strlen(PARAM_LLITE)) == 0) {
3385 rc = name_create(&cname, mti->mti_fsname, "-client");
3386 /* Add the client type to match the obdname in
3387 class_config_llog_handler */
3388 } else if (mti->mti_flags & LDD_F_SV_TYPE_MDT) {
3389 rc = name_create(&cname, mti->mti_svname, "-mdc");
3390 } else if (mti->mti_flags & LDD_F_SV_TYPE_OST) {
3391 rc = name_create(&cname, mti->mti_svname, "-osc");
3393 GOTO(end, rc = -EINVAL);
3398 CDEBUG(D_MGS, "%.3s param %s\n", ptr, ptr + 4);
3401 rc = name_create(&logname, mti->mti_fsname, "-client");
3403 name_destroy(&cname);
3406 rc = mgs_wlp_lcfg(env, mgs, fsdb, mti, logname, &mgi->mgi_bufs,
3409 /* osc params affect the MDT as well */
3410 if (!rc && (mti->mti_flags & LDD_F_SV_TYPE_OST)) {
3413 for (i = 0; i < INDEX_MAP_SIZE * 8; i++){
3414 if (!test_bit(i, fsdb->fsdb_mdt_index_map))
3416 name_destroy(&cname);
3417 rc = name_create_mdt_osc(&cname, mti->mti_svname,
3419 name_destroy(&logname);
3422 rc = name_create_mdt(&logname,
3423 mti->mti_fsname, i);
3426 if (!mgs_log_is_empty(env, mgs, logname)) {
3427 rc = mgs_wlp_lcfg(env, mgs, fsdb,
3436 name_destroy(&logname);
3437 name_destroy(&cname);
3441 /* All mdt. params in proc */
3442 if (class_match_param(ptr, PARAM_MDT, NULL) == 0) {
3446 CDEBUG(D_MGS, "%.3s param %s\n", ptr, ptr + 4);
3447 if (strncmp(mti->mti_svname, mti->mti_fsname,
3448 MTI_NAME_MAXLEN) == 0)
3449 /* device is unspecified completely? */
3450 rc = LDD_F_SV_TYPE_MDT | LDD_F_SV_ALL;
3452 rc = server_name2index(mti->mti_svname, &idx, NULL);
3455 if ((rc & LDD_F_SV_TYPE_MDT) == 0)
3457 if (rc & LDD_F_SV_ALL) {
3458 for (i = 0; i < INDEX_MAP_SIZE * 8; i++) {
3460 fsdb->fsdb_mdt_index_map))
3462 rc = name_create_mdt(&logname,
3463 mti->mti_fsname, i);
3466 rc = mgs_wlp_lcfg(env, mgs, fsdb, mti,
3467 logname, &mgi->mgi_bufs,
3469 name_destroy(&logname);
3474 rc = mgs_wlp_lcfg(env, mgs, fsdb, mti,
3475 mti->mti_svname, &mgi->mgi_bufs,
3476 mti->mti_svname, ptr);
3483 /* All mdd., ost. params in proc */
3484 if ((class_match_param(ptr, PARAM_MDD, NULL) == 0) ||
3485 (class_match_param(ptr, PARAM_OST, NULL) == 0)) {
3486 CDEBUG(D_MGS, "%.3s param %s\n", ptr, ptr + 4);
3487 if (mgs_log_is_empty(env, mgs, mti->mti_svname))
3488 GOTO(end, rc = -ENODEV);
3490 rc = mgs_wlp_lcfg(env, mgs, fsdb, mti, mti->mti_svname,
3491 &mgi->mgi_bufs, mti->mti_svname, ptr);
3495 LCONSOLE_WARN("Ignoring unrecognized param '%s'\n", ptr);
3500 CERROR("err %d on param '%s'\n", rc, ptr);
3505 /* Not implementing automatic failover nid addition at this time. */
3506 int mgs_check_failnid(const struct lu_env *env, struct mgs_device *mgs,
3507 struct mgs_target_info *mti)
3514 rc = mgs_find_or_make_fsdb(obd, fsname, &fsdb);
3518 if (mgs_log_is_empty(obd, mti->mti_svname))
3519 /* should never happen */
3522 CDEBUG(D_MGS, "Checking for new failnids for %s\n", mti->mti_svname);
3524 /* FIXME We can just check mti->params to see if we're already in
3525 the failover list. Modify mti->params for rewriting back at
3526 server_register_target(). */
3528 mutex_lock(&fsdb->fsdb_mutex);
3529 rc = mgs_write_log_add_failnid(obd, fsdb, mti);
3530 mutex_unlock(&fsdb->fsdb_mutex);
3537 int mgs_write_log_target(const struct lu_env *env,
3538 struct mgs_device *mgs,
3539 struct mgs_target_info *mti,
3546 /* set/check the new target index */
3547 rc = mgs_set_index(env, mgs, mti);
3549 CERROR("Can't get index (%d)\n", rc);
3553 if (rc == EALREADY) {
3554 LCONSOLE_WARN("Found index %d for %s, updating log\n",
3555 mti->mti_stripe_index, mti->mti_svname);
3556 /* We would like to mark old log sections as invalid
3557 and add new log sections in the client and mdt logs.
3558 But if we add new sections, then live clients will
3559 get repeat setup instructions for already running
3560 osc's. So don't update the client/mdt logs. */
3561 mti->mti_flags &= ~LDD_F_UPDATE;
3565 mutex_lock(&fsdb->fsdb_mutex);
3567 if (mti->mti_flags &
3568 (LDD_F_VIRGIN | LDD_F_UPGRADE14 | LDD_F_WRITECONF)) {
3569 /* Generate a log from scratch */
3570 if (mti->mti_flags & LDD_F_SV_TYPE_MDT) {
3571 rc = mgs_write_log_mdt(env, mgs, fsdb, mti);
3572 } else if (mti->mti_flags & LDD_F_SV_TYPE_OST) {
3573 rc = mgs_write_log_ost(env, mgs, fsdb, mti);
3575 CERROR("Unknown target type %#x, can't create log for "
3576 "%s\n", mti->mti_flags, mti->mti_svname);
3579 CERROR("Can't write logs for %s (%d)\n",
3580 mti->mti_svname, rc);
3584 /* Just update the params from tunefs in mgs_write_log_params */
3585 CDEBUG(D_MGS, "Update params for %s\n", mti->mti_svname);
3586 mti->mti_flags |= LDD_F_PARAM;
3589 /* allocate temporary buffer, where class_get_next_param will
3590 make copy of a current parameter */
3591 OBD_ALLOC(buf, strlen(mti->mti_params) + 1);
3593 GOTO(out_up, rc = -ENOMEM);
3594 params = mti->mti_params;
3595 while (params != NULL) {
3596 rc = class_get_next_param(¶ms, buf);
3599 /* there is no next parameter, that is
3604 CDEBUG(D_MGS, "remaining string: '%s', param: '%s'\n",
3606 rc = mgs_write_log_param(env, mgs, fsdb, mti, buf);
3611 OBD_FREE(buf, strlen(mti->mti_params) + 1);
3614 mutex_unlock(&fsdb->fsdb_mutex);
3618 int mgs_erase_log(const struct lu_env *env, struct mgs_device *mgs, char *name)
3620 struct llog_ctxt *ctxt;
3623 ctxt = llog_get_context(mgs->mgs_obd, LLOG_CONFIG_ORIG_CTXT);
3625 CERROR("%s: MGS config context doesn't exist\n",
3626 mgs->mgs_obd->obd_name);
3629 rc = llog_erase(env, ctxt, NULL, name);
3630 /* llog may not exist */
3633 llog_ctxt_put(ctxt);
3637 CERROR("%s: failed to clear log %s: %d\n",
3638 mgs->mgs_obd->obd_name, name, rc);
3643 /* erase all logs for the given fs */
3644 int mgs_erase_logs(const struct lu_env *env, struct mgs_device *mgs, char *fsname)
3648 struct mgs_direntry *dirent, *n;
3649 int rc, len = strlen(fsname);
3653 /* Find all the logs in the CONFIGS directory */
3654 rc = class_dentry_readdir(env, mgs, &list);
3658 mutex_lock(&mgs->mgs_mutex);
3660 /* Delete the fs db */
3661 fsdb = mgs_find_fsdb(mgs, fsname);
3663 mgs_free_fsdb(mgs, fsdb);
3665 mutex_unlock(&mgs->mgs_mutex);
3667 cfs_list_for_each_entry_safe(dirent, n, &list, list) {
3668 cfs_list_del(&dirent->list);
3669 suffix = strrchr(dirent->name, '-');
3670 if (suffix != NULL) {
3671 if ((len == suffix - dirent->name) &&
3672 (strncmp(fsname, dirent->name, len) == 0)) {
3673 CDEBUG(D_MGS, "Removing log %s\n",
3675 mgs_erase_log(env, mgs, dirent->name);
3678 mgs_direntry_free(dirent);
3684 /* from llog_swab */
3685 static void print_lustre_cfg(struct lustre_cfg *lcfg)
3690 CDEBUG(D_MGS, "lustre_cfg: %p\n", lcfg);
3691 CDEBUG(D_MGS, "\tlcfg->lcfg_version: %#x\n", lcfg->lcfg_version);
3693 CDEBUG(D_MGS, "\tlcfg->lcfg_command: %#x\n", lcfg->lcfg_command);
3694 CDEBUG(D_MGS, "\tlcfg->lcfg_num: %#x\n", lcfg->lcfg_num);
3695 CDEBUG(D_MGS, "\tlcfg->lcfg_flags: %#x\n", lcfg->lcfg_flags);
3696 CDEBUG(D_MGS, "\tlcfg->lcfg_nid: %s\n", libcfs_nid2str(lcfg->lcfg_nid));
3698 CDEBUG(D_MGS, "\tlcfg->lcfg_bufcount: %d\n", lcfg->lcfg_bufcount);
3699 if (lcfg->lcfg_bufcount < LUSTRE_CFG_MAX_BUFCOUNT)
3700 for (i = 0; i < lcfg->lcfg_bufcount; i++) {
3701 CDEBUG(D_MGS, "\tlcfg->lcfg_buflens[%d]: %d %s\n",
3702 i, lcfg->lcfg_buflens[i],
3703 lustre_cfg_string(lcfg, i));
3708 /* Set a permanent (config log) param for a target or fs
3709 * \param lcfg buf0 may contain the device (testfs-MDT0000) name
3710 * buf1 contains the single parameter
3712 int mgs_setparam(const struct lu_env *env, struct mgs_device *mgs,
3713 struct lustre_cfg *lcfg, char *fsname)
3716 struct mgs_target_info *mti;
3717 char *devname, *param;
3724 print_lustre_cfg(lcfg);
3726 /* lustre, lustre-mdtlov, lustre-client, lustre-MDT0000 */
3727 devname = lustre_cfg_string(lcfg, 0);
3728 param = lustre_cfg_string(lcfg, 1);
3730 /* Assume device name embedded in param:
3731 lustre-OST0000.osc.max_dirty_mb=32 */
3732 ptr = strchr(param, '.');
3740 LCONSOLE_ERROR_MSG(0x14d, "No target specified: %s\n", param);
3744 rc = mgs_parse_devname(devname, fsname, NULL);
3745 if (rc == 0 && !mgs_parse_devname(devname, NULL, &index)) {
3746 /* param related to llite isn't allowed to set by OST or MDT */
3747 if (rc == 0 && strncmp(param, PARAM_LLITE,
3748 sizeof(PARAM_LLITE)) == 0)
3751 /* assume devname is the fsname */
3752 memset(fsname, 0, MTI_NAME_MAXLEN);
3753 strncpy(fsname, devname, MTI_NAME_MAXLEN);
3754 fsname[MTI_NAME_MAXLEN - 1] = 0;
3756 CDEBUG(D_MGS, "setparam fs='%s' device='%s'\n", fsname, devname);
3758 rc = mgs_find_or_make_fsdb(env, mgs,
3759 lcfg->lcfg_command == LCFG_SET_PARAM ?
3760 PARAMS_FILENAME : fsname, &fsdb);
3764 if (lcfg->lcfg_command != LCFG_SET_PARAM &&
3765 !test_bit(FSDB_MGS_SELF, &fsdb->fsdb_flags) &&
3766 test_bit(FSDB_LOG_EMPTY, &fsdb->fsdb_flags)) {
3767 CERROR("No filesystem targets for %s. cfg_device from lctl "
3768 "is '%s'\n", fsname, devname);
3769 mgs_free_fsdb(mgs, fsdb);
3773 /* Create a fake mti to hold everything */
3776 GOTO(out, rc = -ENOMEM);
3777 if (strlcpy(mti->mti_fsname, fsname, sizeof(mti->mti_fsname))
3778 >= sizeof(mti->mti_fsname))
3779 GOTO(out, rc = -E2BIG);
3780 if (strlcpy(mti->mti_svname, devname, sizeof(mti->mti_svname))
3781 >= sizeof(mti->mti_svname))
3782 GOTO(out, rc = -E2BIG);
3783 if (strlcpy(mti->mti_params, param, sizeof(mti->mti_params))
3784 >= sizeof(mti->mti_params))
3785 GOTO(out, rc = -E2BIG);
3786 rc = server_name2index(mti->mti_svname, &mti->mti_stripe_index, &tmp);
3788 /* Not a valid server; may be only fsname */
3791 /* Strip -osc or -mdc suffix from svname */
3792 if (server_make_name(rc, mti->mti_stripe_index, mti->mti_fsname,
3794 GOTO(out, rc = -EINVAL);
3796 * Revoke lock so everyone updates. Should be alright if
3797 * someone was already reading while we were updating the logs,
3798 * so we don't really need to hold the lock while we're
3801 if (lcfg->lcfg_command == LCFG_SET_PARAM) {
3802 mti->mti_flags = rc | LDD_F_PARAM2;
3803 mutex_lock(&fsdb->fsdb_mutex);
3804 rc = mgs_write_log_param2(env, mgs, fsdb, mti, mti->mti_params);
3805 mutex_unlock(&fsdb->fsdb_mutex);
3806 mgs_revoke_lock(mgs, fsdb, CONFIG_T_PARAMS);
3808 mti->mti_flags = rc | LDD_F_PARAM;
3809 mutex_lock(&fsdb->fsdb_mutex);
3810 rc = mgs_write_log_param(env, mgs, fsdb, mti, mti->mti_params);
3811 mutex_unlock(&fsdb->fsdb_mutex);
3812 mgs_revoke_lock(mgs, fsdb, CONFIG_T_CONFIG);
3820 static int mgs_write_log_pool(const struct lu_env *env,
3821 struct mgs_device *mgs, char *logname,
3822 struct fs_db *fsdb, char *lovname,
3823 enum lcfg_command_type cmd,
3824 char *poolname, char *fsname,
3825 char *ostname, char *comment)
3827 struct llog_handle *llh = NULL;
3830 rc = record_start_log(env, mgs, &llh, logname);
3833 rc = record_marker(env, llh, fsdb, CM_START, lovname, comment);
3836 rc = record_base(env, llh, lovname, 0, cmd, poolname, fsname, ostname, 0);
3839 rc = record_marker(env, llh, fsdb, CM_END, lovname, comment);
3841 record_end_log(env, &llh);
3845 int mgs_pool_cmd(const struct lu_env *env, struct mgs_device *mgs,
3846 enum lcfg_command_type cmd, char *fsname,
3847 char *poolname, char *ostname)
3852 char *label = NULL, *canceled_label = NULL;
3854 struct mgs_target_info *mti = NULL;
3858 rc = mgs_find_or_make_fsdb(env, mgs, fsname, &fsdb);
3860 CERROR("Can't get db for %s\n", fsname);
3863 if (test_bit(FSDB_LOG_EMPTY, &fsdb->fsdb_flags)) {
3864 CERROR("%s is not defined\n", fsname);
3865 mgs_free_fsdb(mgs, fsdb);
3869 label_sz = 10 + strlen(fsname) + strlen(poolname);
3871 /* check if ostname match fsname */
3872 if (ostname != NULL) {
3875 ptr = strrchr(ostname, '-');
3876 if ((ptr == NULL) ||
3877 (strncmp(fsname, ostname, ptr-ostname) != 0))
3879 label_sz += strlen(ostname);
3882 OBD_ALLOC(label, label_sz);
3889 "new %s.%s", fsname, poolname);
3893 "add %s.%s.%s", fsname, poolname, ostname);
3896 OBD_ALLOC(canceled_label, label_sz);
3897 if (canceled_label == NULL)
3898 GOTO(out_label, rc = -ENOMEM);
3900 "rem %s.%s.%s", fsname, poolname, ostname);
3901 sprintf(canceled_label,
3902 "add %s.%s.%s", fsname, poolname, ostname);
3905 OBD_ALLOC(canceled_label, label_sz);
3906 if (canceled_label == NULL)
3907 GOTO(out_label, rc = -ENOMEM);
3909 "del %s.%s", fsname, poolname);
3910 sprintf(canceled_label,
3911 "new %s.%s", fsname, poolname);
3917 if (canceled_label != NULL) {
3920 GOTO(out_cancel, rc = -ENOMEM);
3923 mutex_lock(&fsdb->fsdb_mutex);
3924 /* write pool def to all MDT logs */
3925 for (i = 0; i < INDEX_MAP_SIZE * 8; i++) {
3926 if (test_bit(i, fsdb->fsdb_mdt_index_map)) {
3927 rc = name_create_mdt_and_lov(&logname, &lovname,
3930 mutex_unlock(&fsdb->fsdb_mutex);
3933 if (canceled_label != NULL) {
3934 strcpy(mti->mti_svname, "lov pool");
3935 rc = mgs_modify(env, mgs, fsdb, mti, logname,
3936 lovname, canceled_label,
3941 rc = mgs_write_log_pool(env, mgs, logname,
3945 name_destroy(&logname);
3946 name_destroy(&lovname);
3948 mutex_unlock(&fsdb->fsdb_mutex);
3954 rc = name_create(&logname, fsname, "-client");
3956 mutex_unlock(&fsdb->fsdb_mutex);
3959 if (canceled_label != NULL) {
3960 rc = mgs_modify(env, mgs, fsdb, mti, logname,
3961 fsdb->fsdb_clilov, canceled_label, CM_SKIP);
3963 mutex_unlock(&fsdb->fsdb_mutex);
3964 name_destroy(&logname);
3969 rc = mgs_write_log_pool(env, mgs, logname, fsdb, fsdb->fsdb_clilov,
3970 cmd, fsname, poolname, ostname, label);
3971 mutex_unlock(&fsdb->fsdb_mutex);
3972 name_destroy(&logname);
3973 /* request for update */
3974 mgs_revoke_lock(mgs, fsdb, CONFIG_T_CONFIG);
3981 if (canceled_label != NULL)
3982 OBD_FREE(canceled_label, label_sz);
3984 OBD_FREE(label, label_sz);