1 /* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*-
2 * vim:expandtab:shiftwidth=8:tabstop=8:
6 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License version 2 only,
10 * as published by the Free Software Foundation.
12 * This program is distributed in the hope that it will be useful, but
13 * WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * General Public License version 2 for more details (a copy is included
16 * in the LICENSE file that accompanied this code).
18 * You should have received a copy of the GNU General Public License
19 * version 2 along with this program; If not, see [sun.com URL with a
22 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
23 * CA 95054 USA or visit www.sun.com if you need additional information or
29 * Copyright 2008 Sun Microsystems, Inc. All rights reserved
30 * Use is subject to license terms.
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>
46 #define DEBUG_SUBSYSTEM S_MGS
47 #define D_MGS D_CONFIG /*|D_WARNING*/
50 #include <linux/module.h>
51 #include <linux/pagemap.h>
57 #include <obd_class.h>
58 #include <lustre_log.h>
60 #include <libcfs/list.h>
61 #include <linux/lvfs.h>
62 #include <lustre_fsfilt.h>
63 #include <lustre_disk.h>
64 #include <lustre_param.h>
65 #include <lustre_sec.h>
66 #include "mgs_internal.h"
68 static int mgs_get_fsdb_srpc_from_llog(struct obd_device *obd,
70 static int mgs_get_srpc_conf_log(struct fs_db *fsdb, const char *tgt,
71 enum lustre_sec_part from,
72 enum lustre_sec_part to,
73 struct sptlrpc_conf_log *log);
75 /********************** Class functions ********************/
77 /* Caller must list_del and OBD_FREE each dentry from the list */
78 int class_dentry_readdir(struct obd_device *obd, struct dentry *dir,
79 struct vfsmount *inmnt,
80 struct list_head *dentry_list){
81 /* see mds_cleanup_pending */
82 struct lvfs_run_ctxt saved;
84 struct dentry *dentry;
89 push_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
92 GOTO(out_pop, rc = PTR_ERR(dentry));
96 GOTO(out_pop, rc = PTR_ERR(mnt));
99 file = dentry_open(dentry, mnt, O_RDONLY);
101 /* dentry_open_it() drops the dentry, mnt refs */
102 GOTO(out_pop, rc = PTR_ERR(file));
104 CFS_INIT_LIST_HEAD(dentry_list);
105 rc = l_readdir(file, dentry_list);
107 /* filp_close->fput() drops the dentry, mnt refs */
110 pop_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
114 /******************** DB functions *********************/
116 static inline int name_create(char **newname, char *prefix, char *suffix)
119 OBD_ALLOC(*newname, strlen(prefix) + strlen(suffix) + 1);
122 sprintf(*newname, "%s%s", prefix, suffix);
126 static inline void name_destroy(char **name)
129 OBD_FREE(*name, strlen(*name) + 1);
133 /* from the (client) config log, figure out:
134 1. which ost's/mdt's are configured (by index)
135 2. what the last config step is
136 3. COMPAT_146 lov name
137 4. COMPAT_146 mdt lov name
138 5. COMPAT_146 mdc name
140 /* It might be better to have a separate db file, instead of parsing the info
141 out of the client log. This is slow and potentially error-prone. */
142 static int mgs_fsdb_handler(struct llog_handle *llh, struct llog_rec_hdr *rec,
145 struct fs_db *fsdb = (struct fs_db *)data;
146 int cfg_len = rec->lrh_len;
147 char *cfg_buf = (char*) (rec + 1);
148 struct lustre_cfg *lcfg;
153 if (rec->lrh_type != OBD_CFG_REC) {
154 CERROR("unhandled lrh_type: %#x\n", rec->lrh_type);
158 rc = lustre_cfg_sanity_check(cfg_buf, cfg_len);
160 CERROR("Insane cfg\n");
164 lcfg = (struct lustre_cfg *)cfg_buf;
166 CDEBUG(D_INFO, "cmd %x %s %s\n", lcfg->lcfg_command,
167 lustre_cfg_string(lcfg, 0), lustre_cfg_string(lcfg, 1));
169 /* Figure out ost indicies */
170 /* lov_modify_tgts add 0:lov1 1:ost1_UUID 2(index):0 3(gen):1 */
171 if (lcfg->lcfg_command == LCFG_LOV_ADD_OBD ||
172 lcfg->lcfg_command == LCFG_LOV_DEL_OBD) {
173 index = simple_strtoul(lustre_cfg_string(lcfg, 2),
175 CDEBUG(D_MGS, "OST index for %s is %u (%s)\n",
176 lustre_cfg_string(lcfg, 1), index,
177 lustre_cfg_string(lcfg, 2));
178 set_bit(index, fsdb->fsdb_ost_index_map);
181 /* Figure out mdt indicies */
182 /* attach 0:MDC_uml1_mdsA_MNT_client 1:mdc 2:1d834_MNT_client_03f */
183 if ((lcfg->lcfg_command == LCFG_ATTACH) &&
184 (strcmp(lustre_cfg_string(lcfg, 1), LUSTRE_MDC_NAME) == 0)) {
185 rc = server_name2index(lustre_cfg_string(lcfg, 0),
187 if (rc != LDD_F_SV_TYPE_MDT) {
188 CWARN("Unparsable MDC name %s, assuming index 0\n",
189 lustre_cfg_string(lcfg, 0));
193 CDEBUG(D_MGS, "MDT index is %u\n", index);
194 set_bit(index, fsdb->fsdb_mdt_index_map);
198 /* figure out the old LOV name. fsdb_gen = 0 means old log */
199 /* #01 L attach 0:lov_mdsA 1:lov 2:cdbe9_lov_mdsA_dc8cf7f3bb */
200 if ((fsdb->fsdb_gen == 0) && (lcfg->lcfg_command == LCFG_ATTACH) &&
201 (strcmp(lustre_cfg_string(lcfg, 1), LUSTRE_LOV_NAME) == 0)) {
202 fsdb->fsdb_flags |= FSDB_OLDLOG14;
203 name_destroy(&fsdb->fsdb_clilov);
204 rc = name_create(&fsdb->fsdb_clilov,
205 lustre_cfg_string(lcfg, 0), "");
208 CDEBUG(D_MGS, "client lov name is %s\n", fsdb->fsdb_clilov);
211 /* figure out the old MDT lov name from the MDT uuid */
212 if ((fsdb->fsdb_gen == 0) && (lcfg->lcfg_command == LCFG_SETUP) &&
213 (strncmp(lustre_cfg_string(lcfg, 0), "MDC_", 4) == 0)) {
215 fsdb->fsdb_flags |= FSDB_OLDLOG14;
216 ptr = strstr(lustre_cfg_string(lcfg, 1), "_UUID");
218 CERROR("Can't parse MDT uuid %s\n",
219 lustre_cfg_string(lcfg, 1));
223 name_destroy(&fsdb->fsdb_mdtlov);
224 rc = name_create(&fsdb->fsdb_mdtlov,
225 "lov_", lustre_cfg_string(lcfg, 1));
228 name_destroy(&fsdb->fsdb_mdc);
229 rc = name_create(&fsdb->fsdb_mdc,
230 lustre_cfg_string(lcfg, 0), "");
233 CDEBUG(D_MGS, "MDT lov name is %s\n", fsdb->fsdb_mdtlov);
237 /* Keep track of the latest marker step */
238 if (lcfg->lcfg_command == LCFG_MARKER) {
239 struct cfg_marker *marker;
240 marker = lustre_cfg_buf(lcfg, 1);
241 fsdb->fsdb_gen = max(fsdb->fsdb_gen, marker->cm_step);
247 /* fsdb->fsdb_sem is already held in mgs_find_or_make_fsdb*/
248 static int mgs_get_fsdb_from_llog(struct obd_device *obd, struct fs_db *fsdb)
251 struct llog_handle *loghandle;
252 struct lvfs_run_ctxt saved;
253 struct llog_ctxt *ctxt;
257 ctxt = llog_get_context(obd, LLOG_CONFIG_ORIG_CTXT);
258 LASSERT(ctxt != NULL);
259 name_create(&logname, fsdb->fsdb_name, "-client");
260 down(&fsdb->fsdb_sem);
261 push_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
262 rc = llog_create(ctxt, &loghandle, NULL, logname);
266 rc = llog_init_handle(loghandle, LLOG_F_IS_PLAIN, NULL);
270 if (llog_get_size(loghandle) <= 1)
271 fsdb->fsdb_flags |= FSDB_LOG_EMPTY;
273 rc = llog_process(loghandle, mgs_fsdb_handler, (void *)fsdb, NULL);
274 CDEBUG(D_INFO, "get_db = %d\n", rc);
276 rc2 = llog_close(loghandle);
280 pop_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
282 name_destroy(&logname);
288 static void mgs_free_fsdb_srpc(struct fs_db *fsdb)
290 struct mgs_tgt_srpc_conf *tgtconf;
292 /* free target-specific rules */
293 while (fsdb->fsdb_srpc_tgt) {
294 tgtconf = fsdb->fsdb_srpc_tgt;
295 fsdb->fsdb_srpc_tgt = tgtconf->mtsc_next;
297 LASSERT(tgtconf->mtsc_tgt);
299 sptlrpc_rule_set_free(&tgtconf->mtsc_rset);
300 OBD_FREE(tgtconf->mtsc_tgt, strlen(tgtconf->mtsc_tgt) + 1);
301 OBD_FREE_PTR(tgtconf);
304 /* free general rules */
305 sptlrpc_rule_set_free(&fsdb->fsdb_srpc_gen);
308 static struct fs_db *mgs_find_fsdb(struct obd_device *obd, char *fsname)
310 struct mgs_obd *mgs = &obd->u.mgs;
312 struct list_head *tmp;
314 list_for_each(tmp, &mgs->mgs_fs_db_list) {
315 fsdb = list_entry(tmp, struct fs_db, fsdb_list);
316 if (strcmp(fsdb->fsdb_name, fsname) == 0)
322 /* caller must hold the mgs->mgs_fs_db_lock */
323 static struct fs_db *mgs_new_fsdb(struct obd_device *obd, char *fsname)
325 struct mgs_obd *mgs = &obd->u.mgs;
334 OBD_ALLOC(fsdb->fsdb_ost_index_map, INDEX_MAP_SIZE);
335 OBD_ALLOC(fsdb->fsdb_mdt_index_map, INDEX_MAP_SIZE);
336 if (!fsdb->fsdb_ost_index_map || !fsdb->fsdb_mdt_index_map) {
337 CERROR("No memory for index maps\n");
341 strncpy(fsdb->fsdb_name, fsname, sizeof(fsdb->fsdb_name));
342 fsdb->fsdb_name[sizeof(fsdb->fsdb_name) - 1] = 0;
343 rc = name_create(&fsdb->fsdb_mdtlov, fsname, "-mdtlov");
346 rc = name_create(&fsdb->fsdb_mdtlmv, fsname, "-mdtlmv");
349 rc = name_create(&fsdb->fsdb_clilov, fsname, "-clilov");
353 rc = name_create(&fsdb->fsdb_clilmv, fsname, "-clilmv");
357 fsdb->fsdb_srpc_fl_udesc = 1;
358 sema_init(&fsdb->fsdb_sem, 1);
359 list_add(&fsdb->fsdb_list, &mgs->mgs_fs_db_list);
360 lproc_mgs_add_live(obd, fsdb);
364 if (fsdb->fsdb_ost_index_map)
365 OBD_FREE(fsdb->fsdb_ost_index_map, INDEX_MAP_SIZE);
366 if (fsdb->fsdb_mdt_index_map)
367 OBD_FREE(fsdb->fsdb_mdt_index_map, INDEX_MAP_SIZE);
368 name_destroy(&fsdb->fsdb_clilov);
369 name_destroy(&fsdb->fsdb_clilmv);
370 name_destroy(&fsdb->fsdb_mdtlov);
371 name_destroy(&fsdb->fsdb_mdtlmv);
376 static void mgs_free_fsdb(struct obd_device *obd, struct fs_db *fsdb)
378 /* wait for anyone with the sem */
379 down(&fsdb->fsdb_sem);
380 lproc_mgs_del_live(obd, fsdb);
381 list_del(&fsdb->fsdb_list);
382 OBD_FREE(fsdb->fsdb_ost_index_map, INDEX_MAP_SIZE);
383 OBD_FREE(fsdb->fsdb_mdt_index_map, INDEX_MAP_SIZE);
384 name_destroy(&fsdb->fsdb_clilov);
385 name_destroy(&fsdb->fsdb_clilmv);
386 name_destroy(&fsdb->fsdb_mdtlov);
387 name_destroy(&fsdb->fsdb_mdtlmv);
388 name_destroy(&fsdb->fsdb_mdc);
389 mgs_free_fsdb_srpc(fsdb);
393 int mgs_init_fsdb_list(struct obd_device *obd)
395 struct mgs_obd *mgs = &obd->u.mgs;
396 CFS_INIT_LIST_HEAD(&mgs->mgs_fs_db_list);
400 int mgs_cleanup_fsdb_list(struct obd_device *obd)
402 struct mgs_obd *mgs = &obd->u.mgs;
404 struct list_head *tmp, *tmp2;
406 list_for_each_safe(tmp, tmp2, &mgs->mgs_fs_db_list) {
407 fsdb = list_entry(tmp, struct fs_db, fsdb_list);
408 mgs_free_fsdb(obd, fsdb);
414 static int mgs_find_or_make_fsdb(struct obd_device *obd, char *name,
417 struct mgs_obd *mgs = &obd->u.mgs;
422 fsdb = mgs_find_fsdb(obd, name);
429 CDEBUG(D_MGS, "Creating new db\n");
430 fsdb = mgs_new_fsdb(obd, name);
435 /* populate the db from the client llog */
436 rc = mgs_get_fsdb_from_llog(obd, fsdb);
438 CERROR("Can't get db from client log %d\n", rc);
439 mgs_free_fsdb(obd, fsdb);
443 /* populate srpc rules from params llog */
444 rc = mgs_get_fsdb_srpc_from_llog(obd, fsdb);
446 CERROR("Can't get db from params log %d\n", rc);
447 mgs_free_fsdb(obd, fsdb);
458 -1= empty client log */
459 int mgs_check_index(struct obd_device *obd, struct mgs_target_info *mti)
466 LASSERT(!(mti->mti_flags & LDD_F_NEED_INDEX));
468 rc = mgs_find_or_make_fsdb(obd, mti->mti_fsname, &fsdb);
470 CERROR("Can't get db for %s\n", mti->mti_fsname);
474 if (fsdb->fsdb_flags & FSDB_LOG_EMPTY)
477 if (mti->mti_flags & LDD_F_SV_TYPE_OST)
478 imap = fsdb->fsdb_ost_index_map;
479 else if (mti->mti_flags & LDD_F_SV_TYPE_MDT)
480 imap = fsdb->fsdb_mdt_index_map;
484 if (test_bit(mti->mti_stripe_index, imap))
489 static __inline__ int next_index(void *index_map, int map_len)
492 for (i = 0; i < map_len * 8; i++)
493 if (!test_bit(i, index_map)) {
496 CERROR("max index %d exceeded.\n", i);
501 0 newly marked as in use
503 +EALREADY for update of an old index */
504 int mgs_set_index(struct obd_device *obd, struct mgs_target_info *mti)
511 rc = mgs_find_or_make_fsdb(obd, mti->mti_fsname, &fsdb);
513 CERROR("Can't get db for %s\n", mti->mti_fsname);
517 if (mti->mti_flags & LDD_F_SV_TYPE_OST)
518 imap = fsdb->fsdb_ost_index_map;
519 else if (mti->mti_flags & LDD_F_SV_TYPE_MDT)
520 imap = fsdb->fsdb_mdt_index_map;
524 if (mti->mti_flags & LDD_F_NEED_INDEX) {
525 rc = next_index(imap, INDEX_MAP_SIZE);
528 mti->mti_stripe_index = rc;
531 if (mti->mti_stripe_index >= INDEX_MAP_SIZE * 8) {
532 LCONSOLE_ERROR_MSG(0x13f, "Server %s requested index %d, "
533 "but the max index is %d.\n",
534 mti->mti_svname, mti->mti_stripe_index,
539 if (test_bit(mti->mti_stripe_index, imap)) {
540 if ((mti->mti_flags & LDD_F_VIRGIN) &&
541 !(mti->mti_flags & LDD_F_WRITECONF)) {
542 LCONSOLE_ERROR_MSG(0x140, "Server %s requested index "
543 "%d, but that index is already in "
544 "use. Use --writeconf to force\n",
546 mti->mti_stripe_index);
549 CDEBUG(D_MGS, "Server %s updating index %d\n",
550 mti->mti_svname, mti->mti_stripe_index);
555 set_bit(mti->mti_stripe_index, imap);
556 fsdb->fsdb_flags &= ~FSDB_LOG_EMPTY;
557 server_make_name(mti->mti_flags, mti->mti_stripe_index,
558 mti->mti_fsname, mti->mti_svname);
560 CDEBUG(D_MGS, "Set index for %s to %d\n", mti->mti_svname,
561 mti->mti_stripe_index);
566 struct mgs_modify_lookup {
567 struct cfg_marker mml_marker;
571 static int mgs_modify_handler(struct llog_handle *llh, struct llog_rec_hdr *rec,
574 struct mgs_modify_lookup *mml = (struct mgs_modify_lookup *)data;
575 struct cfg_marker *marker;
576 struct lustre_cfg *lcfg = (struct lustre_cfg *)(rec + 1);
577 int cfg_len = rec->lrh_len - sizeof(struct llog_rec_hdr) -
578 sizeof(struct llog_rec_tail);
582 if (rec->lrh_type != OBD_CFG_REC) {
583 CERROR("unhandled lrh_type: %#x\n", rec->lrh_type);
587 rc = lustre_cfg_sanity_check(lcfg, cfg_len);
589 CERROR("Insane cfg\n");
593 /* We only care about markers */
594 if (lcfg->lcfg_command != LCFG_MARKER)
597 marker = lustre_cfg_buf(lcfg, 1);
598 if ((strcmp(mml->mml_marker.cm_comment, marker->cm_comment) == 0) &&
599 (strcmp(mml->mml_marker.cm_tgtname, marker->cm_tgtname) == 0) &&
600 !(marker->cm_flags & CM_SKIP)) {
601 /* Found a non-skipped marker match */
602 CDEBUG(D_MGS, "Changing rec %u marker %d %x->%x: %s %s\n",
603 rec->lrh_index, marker->cm_step,
604 marker->cm_flags, mml->mml_marker.cm_flags,
605 marker->cm_tgtname, marker->cm_comment);
606 /* Overwrite the old marker llog entry */
607 marker->cm_flags &= ~CM_EXCLUDE; /* in case we're unexcluding */
608 marker->cm_flags |= mml->mml_marker.cm_flags;
609 marker->cm_canceltime = mml->mml_marker.cm_canceltime;
610 /* Header and tail are added back to lrh_len in
611 llog_lvfs_write_rec */
612 rec->lrh_len = cfg_len;
613 rc = llog_write_rec(llh, rec, NULL, 0, (void *)lcfg,
622 /* Modify an existing config log record (for CM_SKIP or CM_EXCLUDE) */
623 static int mgs_modify(struct obd_device *obd, struct fs_db *fsdb,
624 struct mgs_target_info *mti, char *logname,
625 char *devname, char *comment, int flags)
627 struct llog_handle *loghandle;
628 struct lvfs_run_ctxt saved;
629 struct llog_ctxt *ctxt;
630 struct mgs_modify_lookup *mml;
634 CDEBUG(D_MGS, "modify %s/%s/%s\n", logname, devname, comment);
636 push_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
638 ctxt = llog_get_context(obd, LLOG_CONFIG_ORIG_CTXT);
639 LASSERT(ctxt != NULL);
640 rc = llog_create(ctxt, &loghandle, NULL, logname);
644 rc = llog_init_handle(loghandle, LLOG_F_IS_PLAIN, NULL);
648 if (llog_get_size(loghandle) <= 1)
649 GOTO(out_close, rc = 0);
653 GOTO(out_close, rc = -ENOMEM);
654 strcpy(mml->mml_marker.cm_comment, comment);
655 strcpy(mml->mml_marker.cm_tgtname, devname);
656 /* Modify mostly means cancel */
657 mml->mml_marker.cm_flags = flags;
658 mml->mml_marker.cm_canceltime = flags ? cfs_time_current_sec() : 0;
659 mml->mml_modified = 0;
660 rc = llog_process(loghandle, mgs_modify_handler, (void *)mml, NULL);
661 if (!rc && !mml->mml_modified)
666 rc2 = llog_close(loghandle);
670 pop_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
671 if (rc && rc != -ENODEV)
672 CERROR("modify %s/%s failed %d\n",
673 mti->mti_svname, comment, rc);
678 /******************** config log recording functions *********************/
680 static int record_lcfg(struct obd_device *obd, struct llog_handle *llh,
681 struct lustre_cfg *lcfg)
683 struct lvfs_run_ctxt saved;
684 struct llog_rec_hdr rec;
690 LASSERT(llh->lgh_ctxt);
692 buflen = lustre_cfg_len(lcfg->lcfg_bufcount,
694 rec.lrh_len = llog_data_len(buflen);
695 rec.lrh_type = OBD_CFG_REC;
697 push_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
698 /* idx = -1 means append */
699 rc = llog_write_rec(llh, &rec, NULL, 0, (void *)lcfg, -1);
700 pop_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
702 CERROR("failed %d\n", rc);
706 static int record_base(struct obd_device *obd, struct llog_handle *llh,
707 char *cfgname, lnet_nid_t nid, int cmd,
708 char *s1, char *s2, char *s3, char *s4)
710 struct lustre_cfg_bufs bufs;
711 struct lustre_cfg *lcfg;
714 CDEBUG(D_MGS, "lcfg %s %#x %s %s %s %s\n", cfgname,
715 cmd, s1, s2, s3, s4);
717 lustre_cfg_bufs_reset(&bufs, cfgname);
719 lustre_cfg_bufs_set_string(&bufs, 1, s1);
721 lustre_cfg_bufs_set_string(&bufs, 2, s2);
723 lustre_cfg_bufs_set_string(&bufs, 3, s3);
725 lustre_cfg_bufs_set_string(&bufs, 4, s4);
727 lcfg = lustre_cfg_new(cmd, &bufs);
730 lcfg->lcfg_nid = nid;
732 rc = record_lcfg(obd, llh, lcfg);
734 lustre_cfg_free(lcfg);
737 CERROR("error %d: lcfg %s %#x %s %s %s %s\n", rc, cfgname,
738 cmd, s1, s2, s3, s4);
744 static inline int record_add_uuid(struct obd_device *obd,
745 struct llog_handle *llh,
746 uint64_t nid, char *uuid)
748 return record_base(obd,llh,NULL,nid,LCFG_ADD_UUID,uuid,0,0,0);
752 static inline int record_add_conn(struct obd_device *obd,
753 struct llog_handle *llh,
757 return record_base(obd,llh,devname,0,LCFG_ADD_CONN,uuid,0,0,0);
760 static inline int record_attach(struct obd_device *obd, struct llog_handle *llh,
761 char *devname, char *type, char *uuid)
763 return record_base(obd,llh,devname,0,LCFG_ATTACH,type,uuid,0,0);
766 static inline int record_setup(struct obd_device *obd, struct llog_handle *llh,
768 char *s1, char *s2, char *s3, char *s4)
770 return record_base(obd,llh,devname,0,LCFG_SETUP,s1,s2,s3,s4);
773 static inline int record_sptlrpc_conf(struct obd_device *obd,
774 struct llog_handle *llh,
776 struct sptlrpc_conf_log *srpc_log)
778 struct lustre_cfg_bufs bufs;
779 struct lustre_cfg *lcfg;
782 lustre_cfg_bufs_reset(&bufs, devname);
783 lustre_cfg_bufs_set(&bufs, 1, srpc_log, sizeof(*srpc_log));
784 lcfg = lustre_cfg_new(LCFG_SPTLRPC_CONF, &bufs);
786 rc = record_lcfg(obd, llh, lcfg);
788 lustre_cfg_free(lcfg);
792 static int record_lov_setup(struct obd_device *obd, struct llog_handle *llh,
793 char *devname, struct lov_desc *desc)
795 struct lustre_cfg_bufs bufs;
796 struct lustre_cfg *lcfg;
799 lustre_cfg_bufs_reset(&bufs, devname);
800 lustre_cfg_bufs_set(&bufs, 1, desc, sizeof(*desc));
801 lcfg = lustre_cfg_new(LCFG_SETUP, &bufs);
804 rc = record_lcfg(obd, llh, lcfg);
806 lustre_cfg_free(lcfg);
810 static int record_lmv_setup(struct obd_device *obd, struct llog_handle *llh,
811 char *devname, struct lmv_desc *desc)
813 struct lustre_cfg_bufs bufs;
814 struct lustre_cfg *lcfg;
817 lustre_cfg_bufs_reset(&bufs, devname);
818 lustre_cfg_bufs_set(&bufs, 1, desc, sizeof(*desc));
819 lcfg = lustre_cfg_new(LCFG_SETUP, &bufs);
821 rc = record_lcfg(obd, llh, lcfg);
823 lustre_cfg_free(lcfg);
827 static inline int record_mdc_add(struct obd_device *obd,
828 struct llog_handle *llh,
829 char *logname, char *mdcuuid,
830 char *mdtuuid, char *index,
833 return record_base(obd,llh,logname,0,LCFG_ADD_MDC,
834 mdtuuid,index,gen,mdcuuid);
837 static inline int record_lov_add(struct obd_device *obd,
838 struct llog_handle *llh,
839 char *lov_name, char *ost_uuid,
840 char *index, char *gen)
842 return record_base(obd,llh,lov_name,0,LCFG_LOV_ADD_OBD,
843 ost_uuid,index,gen,0);
846 static inline int record_mount_opt(struct obd_device *obd,
847 struct llog_handle *llh,
848 char *profile, char *lov_name,
851 return record_base(obd,llh,NULL,0,LCFG_MOUNTOPT,
852 profile,lov_name,mdc_name,0);
855 static int record_marker(struct obd_device *obd, struct llog_handle *llh,
856 struct fs_db *fsdb, __u32 flags,
857 char *tgtname, char *comment)
859 struct cfg_marker marker;
860 struct lustre_cfg_bufs bufs;
861 struct lustre_cfg *lcfg;
864 if (flags & CM_START)
866 marker.cm_step = fsdb->fsdb_gen;
867 marker.cm_flags = flags;
868 marker.cm_vers = LUSTRE_VERSION_CODE;
869 strncpy(marker.cm_tgtname, tgtname, sizeof(marker.cm_tgtname));
870 strncpy(marker.cm_comment, comment, sizeof(marker.cm_comment));
871 marker.cm_createtime = cfs_time_current_sec();
872 marker.cm_canceltime = 0;
873 lustre_cfg_bufs_reset(&bufs, NULL);
874 lustre_cfg_bufs_set(&bufs, 1, &marker, sizeof(marker));
875 lcfg = lustre_cfg_new(LCFG_MARKER, &bufs);
878 rc = record_lcfg(obd, llh, lcfg);
880 lustre_cfg_free(lcfg);
884 static int record_start_log(struct obd_device *obd,
885 struct llog_handle **llh, char *name)
887 static struct obd_uuid cfg_uuid = { .uuid = "config_uuid" };
888 struct lvfs_run_ctxt saved;
889 struct llog_ctxt *ctxt;
893 GOTO(out, rc = -EBUSY);
895 ctxt = llog_get_context(obd, LLOG_CONFIG_ORIG_CTXT);
897 GOTO(out, rc = -ENODEV);
899 push_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
900 rc = llog_create(ctxt, llh, NULL, name);
902 llog_init_handle(*llh, LLOG_F_IS_PLAIN, &cfg_uuid);
906 pop_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
911 CERROR("Can't start log %s: %d\n", name, rc);
916 static int record_end_log(struct obd_device *obd, struct llog_handle **llh)
918 struct lvfs_run_ctxt saved;
921 push_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
923 rc = llog_close(*llh);
926 pop_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
930 static int mgs_log_is_empty(struct obd_device *obd, char *name)
932 struct lvfs_run_ctxt saved;
933 struct llog_handle *llh;
934 struct llog_ctxt *ctxt;
937 ctxt = llog_get_context(obd, LLOG_CONFIG_ORIG_CTXT);
938 LASSERT(ctxt != NULL);
939 push_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
940 rc = llog_create(ctxt, &llh, NULL, name);
942 llog_init_handle(llh, LLOG_F_IS_PLAIN, NULL);
943 rc = llog_get_size(llh);
946 pop_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
948 /* header is record 1 */
952 /******************** config "macros" *********************/
954 /* write an lcfg directly into a log (with markers) */
955 static int mgs_write_log_direct(struct obd_device *obd, struct fs_db *fsdb,
956 char *logname, struct lustre_cfg *lcfg,
957 char *devname, char *comment)
959 struct llog_handle *llh = NULL;
966 rc = record_start_log(obd, &llh, logname);
970 /* FIXME These should be a single journal transaction */
971 rc = record_marker(obd, llh, fsdb, CM_START, devname, comment);
973 rc = record_lcfg(obd, llh, lcfg);
975 rc = record_marker(obd, llh, fsdb, CM_END, devname, comment);
976 rc = record_end_log(obd, &llh);
981 /* write the lcfg in all logs for the given fs */
982 int mgs_write_log_direct_all(struct obd_device *obd, struct fs_db *fsdb,
983 struct mgs_target_info *mti,
984 struct lustre_cfg *lcfg,
985 char *devname, char *comment)
987 struct mgs_obd *mgs = &obd->u.mgs;
988 struct list_head dentry_list;
989 struct l_linux_dirent *dirent, *n;
990 char *fsname = mti->mti_fsname;
992 int rc = 0, len = strlen(fsname);
995 /* We need to set params for any future logs
996 as well. FIXME Append this file to every new log.
997 Actually, we should store as params (text), not llogs. Or
999 name_create(&logname, fsname, "-params");
1000 if (mgs_log_is_empty(obd, logname)) {
1001 struct llog_handle *llh = NULL;
1002 rc = record_start_log(obd, &llh, logname);
1003 record_end_log(obd, &llh);
1005 name_destroy(&logname);
1009 /* Find all the logs in the CONFIGS directory */
1010 rc = class_dentry_readdir(obd, mgs->mgs_configs_dir,
1011 mgs->mgs_vfsmnt, &dentry_list);
1013 CERROR("Can't read %s dir\n", MOUNT_CONFIGS_DIR);
1017 /* Could use fsdb index maps instead of directory listing */
1018 list_for_each_entry_safe(dirent, n, &dentry_list, lld_list) {
1019 list_del(&dirent->lld_list);
1020 /* don't write to sptlrpc rule log */
1021 if (strncmp(fsname, dirent->lld_name, len) == 0 &&
1022 strstr(dirent->lld_name, "-sptlrpc") == NULL) {
1023 CDEBUG(D_MGS, "Changing log %s\n", dirent->lld_name);
1024 /* Erase any old settings of this same parameter */
1025 mgs_modify(obd, fsdb, mti, dirent->lld_name, devname,
1027 /* Write the new one */
1028 rc = mgs_write_log_direct(obd, fsdb, dirent->lld_name,
1029 lcfg, devname, comment);
1031 CERROR("err %d writing log %s\n", rc,
1034 OBD_FREE(dirent, sizeof(*dirent));
1042 struct mgs_target_info *comp_tmti;
1043 struct mgs_target_info *comp_mti;
1044 struct fs_db *comp_fsdb;
1045 struct obd_device *comp_obd;
1048 static int mgs_write_log_mdc_to_mdt(struct obd_device *, struct fs_db *,
1049 struct mgs_target_info *, char *);
1051 static int mgs_steal_llog_handler(struct llog_handle *llh,
1052 struct llog_rec_hdr *rec,
1055 struct obd_device * obd;
1056 struct mgs_target_info *mti, *tmti;
1058 int cfg_len = rec->lrh_len;
1059 char *cfg_buf = (char*) (rec + 1);
1060 struct lustre_cfg *lcfg;
1062 struct llog_handle *mdt_llh = NULL;
1063 static int got_an_osc_or_mdc = 0;
1064 /* 0: not found any osc/mdc;
1068 static int last_step = -1;
1072 mti = ((struct temp_comp*)data)->comp_mti;
1073 tmti = ((struct temp_comp*)data)->comp_tmti;
1074 fsdb = ((struct temp_comp*)data)->comp_fsdb;
1075 obd = ((struct temp_comp*)data)->comp_obd;
1077 if (rec->lrh_type != OBD_CFG_REC) {
1078 CERROR("unhandled lrh_type: %#x\n", rec->lrh_type);
1082 rc = lustre_cfg_sanity_check(cfg_buf, cfg_len);
1084 CERROR("Insane cfg\n");
1088 lcfg = (struct lustre_cfg *)cfg_buf;
1090 if (lcfg->lcfg_command == LCFG_MARKER) {
1091 struct cfg_marker *marker;
1092 marker = lustre_cfg_buf(lcfg, 1);
1093 if (!strncmp(marker->cm_comment,"add osc",7) &&
1094 (marker->cm_flags & CM_START)){
1095 got_an_osc_or_mdc = 1;
1096 rc = record_start_log(obd, &mdt_llh, mti->mti_svname);
1097 rc = record_marker(obd, mdt_llh, fsdb, CM_START,
1098 mti->mti_svname,"add osc(copied)");
1099 rc = record_end_log(obd, &mdt_llh);
1100 last_step = marker->cm_step;
1103 if (!strncmp(marker->cm_comment,"add osc",7) &&
1104 (marker->cm_flags & CM_END)){
1105 LASSERT(last_step == marker->cm_step);
1107 got_an_osc_or_mdc = 0;
1108 rc = record_start_log(obd, &mdt_llh, mti->mti_svname);
1109 rc = record_marker(obd, mdt_llh, fsdb, CM_END,
1110 mti->mti_svname,"add osc(copied)");
1111 rc = record_end_log(obd, &mdt_llh);
1114 if (!strncmp(marker->cm_comment,"add mdc",7) &&
1115 (marker->cm_flags & CM_START)){
1116 got_an_osc_or_mdc = 2;
1117 last_step = marker->cm_step;
1118 memcpy(tmti->mti_svname, marker->cm_tgtname,
1119 strlen(marker->cm_tgtname));
1123 if (!strncmp(marker->cm_comment,"add mdc",7) &&
1124 (marker->cm_flags & CM_END)){
1125 LASSERT(last_step == marker->cm_step);
1127 got_an_osc_or_mdc = 0;
1132 if (got_an_osc_or_mdc == 0 || last_step < 0)
1135 if (lcfg->lcfg_command == LCFG_ADD_UUID) {
1137 nodenid = lcfg->lcfg_nid;
1139 tmti->mti_nids[tmti->mti_nid_count] = nodenid;
1140 tmti->mti_nid_count++;
1145 if (lcfg->lcfg_command == LCFG_SETUP) {
1148 target = lustre_cfg_string(lcfg, 1);
1149 memcpy(tmti->mti_uuid, target, strlen(target));
1153 /* ignore client side sptlrpc_conf_log */
1154 if (lcfg->lcfg_command == LCFG_SPTLRPC_CONF)
1157 if (lcfg->lcfg_command == LCFG_ADD_MDC) {
1160 if (sscanf(lustre_cfg_buf(lcfg, 2), "%d", &index) != 1)
1163 memcpy(tmti->mti_fsname, mti->mti_fsname,
1164 strlen(mti->mti_fsname));
1165 tmti->mti_stripe_index = index;
1167 mgs_write_log_mdc_to_mdt(obd, fsdb, tmti, mti->mti_svname);
1168 memset(tmti, 0, sizeof(*tmti));
1174 /* fsdb->fsdb_sem is already held in mgs_write_log_target*/
1175 /* stealed from mgs_get_fsdb_from_llog*/
1176 static int mgs_steal_llog_for_mdt_from_client(struct obd_device *obd,
1178 struct temp_comp* comp)
1180 struct llog_handle *loghandle;
1181 struct lvfs_run_ctxt saved;
1182 struct mgs_target_info *tmti;
1183 struct llog_ctxt *ctxt;
1187 ctxt = llog_get_context(obd, LLOG_CONFIG_ORIG_CTXT);
1188 LASSERT(ctxt != NULL);
1190 OBD_ALLOC_PTR(tmti);
1194 comp->comp_tmti = tmti;
1195 comp->comp_obd = obd;
1197 push_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
1199 rc = llog_create(ctxt, &loghandle, NULL, client_name);
1203 rc = llog_init_handle(loghandle, LLOG_F_IS_PLAIN, NULL);
1205 GOTO(out_close, rc);
1207 rc = llog_process(loghandle, mgs_steal_llog_handler, (void *)comp, NULL);
1208 CDEBUG(D_MGS, "steal llog re = %d\n", rc);
1210 rc2 = llog_close(loghandle);
1214 pop_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
1216 llog_ctxt_put(ctxt);
1220 /* lmv is the second thing for client logs */
1221 /* copied from mgs_write_log_lov. Please refer to that. */
1222 static int mgs_write_log_lmv(struct obd_device *obd, struct fs_db *fsdb,
1223 struct mgs_target_info *mti,
1224 char *logname, char *lmvname)
1226 struct llog_handle *llh = NULL;
1227 struct lmv_desc *lmvdesc;
1232 CDEBUG(D_MGS, "Writing lmv(%s) log for %s\n", lmvname,logname);
1234 OBD_ALLOC(lmvdesc, sizeof(*lmvdesc));
1235 if (lmvdesc == NULL)
1237 lmvdesc->ld_active_tgt_count = 0;
1238 lmvdesc->ld_tgt_count = 0;
1239 sprintf((char*)lmvdesc->ld_uuid.uuid, "%s_UUID", lmvname);
1240 uuid = (char *)lmvdesc->ld_uuid.uuid;
1242 rc = record_start_log(obd, &llh, logname);
1243 rc = record_marker(obd, llh, fsdb, CM_START, lmvname, "lmv setup");
1244 rc = record_attach(obd, llh, lmvname, "lmv", uuid);
1245 rc = record_lmv_setup(obd, llh, lmvname, lmvdesc);
1246 rc = record_marker(obd, llh, fsdb, CM_END, lmvname, "lmv setup");
1247 rc = record_end_log(obd, &llh);
1249 OBD_FREE(lmvdesc, sizeof(*lmvdesc));
1252 /***************************************END PROTO**********************/
1254 /* lov is the first thing in the mdt and client logs */
1255 static int mgs_write_log_lov(struct obd_device *obd, struct fs_db *fsdb,
1256 struct mgs_target_info *mti,
1257 char *logname, char *lovname)
1259 struct llog_handle *llh = NULL;
1260 struct lov_desc *lovdesc;
1265 CDEBUG(D_MGS, "Writing lov(%s) log for %s\n", lovname, logname);
1268 #01 L attach 0:lov_mdsA 1:lov 2:71ccb_lov_mdsA_19f961a9e1
1269 #02 L lov_setup 0:lov_mdsA 1:(struct lov_desc)
1270 uuid=lov1_UUID, stripe count=1, size=1048576, offset=0, pattern=0
1273 /* FIXME just make lov_setup accept empty desc (put uuid in buf 2) */
1274 OBD_ALLOC(lovdesc, sizeof(*lovdesc));
1275 if (lovdesc == NULL)
1277 lovdesc->ld_magic = LOV_DESC_MAGIC;
1278 lovdesc->ld_tgt_count = 0;
1279 /* Defaults. Can be changed later by lcfg config_param */
1280 lovdesc->ld_default_stripe_count = 1;
1281 lovdesc->ld_pattern = LOV_PATTERN_RAID0;
1282 lovdesc->ld_default_stripe_size = 1024 * 1024;
1283 lovdesc->ld_default_stripe_offset = 0;
1284 lovdesc->ld_qos_maxage = QOS_DEFAULT_MAXAGE;
1285 sprintf((char*)lovdesc->ld_uuid.uuid, "%s_UUID", lovname);
1286 /* can these be the same? */
1287 uuid = (char *)lovdesc->ld_uuid.uuid;
1289 /* This should always be the first entry in a log.
1290 rc = mgs_clear_log(obd, logname); */
1291 rc = record_start_log(obd, &llh, logname);
1294 /* FIXME these should be a single journal transaction */
1295 rc = record_marker(obd, llh, fsdb, CM_START, lovname, "lov setup");
1296 rc = record_attach(obd, llh, lovname, "lov", uuid);
1297 rc = record_lov_setup(obd, llh, lovname, lovdesc);
1298 rc = record_marker(obd, llh, fsdb, CM_END, lovname, "lov setup");
1299 rc = record_end_log(obd, &llh);
1301 OBD_FREE(lovdesc, sizeof(*lovdesc));
1305 /* add failnids to open log */
1306 static int mgs_write_log_failnids(struct obd_device *obd,
1307 struct mgs_target_info *mti,
1308 struct llog_handle *llh,
1311 char *failnodeuuid = NULL;
1312 char *ptr = mti->mti_params;
1317 #03 L add_uuid nid=uml1@tcp(0x20000c0a80201) nal=90 0: 1:uml1_UUID
1318 #04 L add_uuid nid=1@elan(0x1000000000001) nal=90 0: 1:uml1_UUID
1319 #05 L setup 0:OSC_uml1_ost1_mdsA 1:ost1_UUID 2:uml1_UUID
1320 #06 L add_uuid nid=uml2@tcp(0x20000c0a80202) nal=90 0: 1:uml2_UUID
1321 #0x L add_uuid nid=2@elan(0x1000000000002) nal=90 0: 1:uml2_UUID
1322 #07 L add_conn 0:OSC_uml1_ost1_mdsA 1:uml2_UUID
1325 /* Pull failnid info out of params string */
1326 while (class_find_param(ptr, PARAM_FAILNODE, &ptr) == 0) {
1327 while (class_parse_nid(ptr, &nid, &ptr) == 0) {
1328 if (failnodeuuid == NULL) {
1329 /* We don't know the failover node name,
1330 so just use the first nid as the uuid */
1331 rc = name_create(&failnodeuuid,
1332 libcfs_nid2str(nid), "");
1336 CDEBUG(D_MGS, "add nid %s for failover uuid %s, "
1337 "client %s\n", libcfs_nid2str(nid),
1338 failnodeuuid, cliname);
1339 rc = record_add_uuid(obd, llh, nid, failnodeuuid);
1342 rc = record_add_conn(obd, llh, cliname, failnodeuuid);
1343 name_destroy(&failnodeuuid);
1344 failnodeuuid = NULL;
1351 static int mgs_write_log_mdc_to_lmv(struct obd_device *obd, struct fs_db *fsdb,
1352 struct mgs_target_info *mti,
1353 char *logname, char *lmvname)
1355 struct llog_handle *llh = NULL;
1356 struct sptlrpc_conf_log *srpc_log;
1357 char *mdcname, *nodeuuid, *mdcuuid, *lmvuuid;
1362 if (mgs_log_is_empty(obd, logname)) {
1363 CERROR("log is empty! Logical error\n");
1367 CDEBUG(D_MGS, "adding mdc for %s to log %s:lmv(%s)\n",
1368 mti->mti_svname, logname, lmvname);
1370 srpc_log = sptlrpc_conf_log_alloc();
1371 if (IS_ERR(srpc_log))
1372 RETURN(PTR_ERR(srpc_log));
1373 srpc_log->scl_part = LUSTRE_SP_CLI;
1375 rc = mgs_get_srpc_conf_log(fsdb, mti->mti_svname,
1376 LUSTRE_SP_CLI, LUSTRE_SP_MDT, srpc_log);
1380 name_create(&nodeuuid, libcfs_nid2str(mti->mti_nids[0]), "");
1381 name_create(&mdcname, mti->mti_svname, "-mdc");
1382 name_create(&mdcuuid, mdcname, "_UUID");
1383 name_create(&lmvuuid, lmvname, "_UUID");
1385 rc = record_start_log(obd, &llh, logname);
1386 rc = record_marker(obd, llh, fsdb, CM_START, mti->mti_svname,
1389 for (i = 0; i < mti->mti_nid_count; i++) {
1390 CDEBUG(D_MGS, "add nid %s for mdt\n",
1391 libcfs_nid2str(mti->mti_nids[i]));
1393 rc = record_add_uuid(obd, llh, mti->mti_nids[i], nodeuuid);
1396 rc = record_attach(obd, llh, mdcname, LUSTRE_MDC_NAME, lmvuuid);
1397 rc = record_setup(obd, llh, mdcname, mti->mti_uuid, nodeuuid, 0, 0);
1398 rc = record_sptlrpc_conf(obd, llh, mdcname, srpc_log);
1399 rc = mgs_write_log_failnids(obd, mti, llh, mdcname);
1400 snprintf(index, sizeof(index), "%d", mti->mti_stripe_index);
1401 rc = record_mdc_add(obd, llh, lmvname, mdcuuid, mti->mti_uuid,
1403 rc = record_marker(obd, llh, fsdb, CM_END, mti->mti_svname,
1405 rc = record_end_log(obd, &llh);
1407 name_destroy(&lmvuuid);
1408 name_destroy(&mdcuuid);
1409 name_destroy(&mdcname);
1410 name_destroy(&nodeuuid);
1412 sptlrpc_conf_log_free(srpc_log);
1416 /* add new mdc to already existent MDS */
1417 static int mgs_write_log_mdc_to_mdt(struct obd_device *obd, struct fs_db *fsdb,
1418 struct mgs_target_info *mti, char *logname)
1420 struct llog_handle *llh = NULL;
1421 struct sptlrpc_conf_log *srpc_log;
1422 char *nodeuuid, *mdcname, *mdcuuid, *mdtuuid;
1423 int idx = mti->mti_stripe_index;
1428 if (mgs_log_is_empty(obd, mti->mti_svname)) {
1429 CERROR("log is empty! Logical error\n");
1433 CDEBUG(D_MGS, "adding mdc index %d to %s\n", idx, logname);
1435 srpc_log = sptlrpc_conf_log_alloc();
1436 if (IS_ERR(srpc_log))
1437 RETURN(PTR_ERR(srpc_log));
1438 srpc_log->scl_part = LUSTRE_SP_MDT;
1440 rc = mgs_get_srpc_conf_log(fsdb, mti->mti_svname,
1441 LUSTRE_SP_MDT, LUSTRE_SP_MDT, srpc_log);
1445 name_create(&nodeuuid, libcfs_nid2str(mti->mti_nids[0]), "");
1446 snprintf(index, sizeof(index), "-mdc%04x", idx);
1447 name_create(&mdcname, logname, index);
1448 name_create(&mdcuuid, mdcname, "_UUID");
1449 name_create(&mdtuuid, logname, "_UUID");
1451 rc = record_start_log(obd, &llh, logname);
1452 rc = record_marker(obd, llh, fsdb, CM_START, mti->mti_svname, "add mdc");
1453 for (i = 0; i < mti->mti_nid_count; i++) {
1454 CDEBUG(D_MGS, "add nid %s for mdt\n",
1455 libcfs_nid2str(mti->mti_nids[i]));
1456 rc = record_add_uuid(obd, llh, mti->mti_nids[i], nodeuuid);
1458 rc = record_attach(obd, llh, mdcname, LUSTRE_MDC_NAME, mdcuuid);
1459 rc = record_setup(obd, llh, mdcname, mti->mti_uuid, nodeuuid, 0, 0);
1460 rc = record_sptlrpc_conf(obd, llh, mdcname, srpc_log);
1461 rc = mgs_write_log_failnids(obd, mti, llh, mdcname);
1462 snprintf(index, sizeof(index), "%d", idx);
1464 rc = record_mdc_add(obd, llh, logname, mdcuuid, mti->mti_uuid,
1466 rc = record_marker(obd, llh, fsdb, CM_END, mti->mti_svname, "add mdc");
1467 rc = record_end_log(obd, &llh);
1469 name_destroy(&mdcuuid);
1470 name_destroy(&mdcname);
1471 name_destroy(&nodeuuid);
1472 name_destroy(&mdtuuid);
1474 sptlrpc_conf_log_free(srpc_log);
1478 static int mgs_write_log_mdt0(struct obd_device *obd, struct fs_db *fsdb,
1479 struct mgs_target_info *mti)
1481 char *log = mti->mti_svname;
1482 struct llog_handle *llh = NULL;
1483 char *uuid, *lovname;
1485 struct sptlrpc_conf_log *srpc_log;
1486 char *ptr = mti->mti_params;
1487 int rc = 0, failout = 0;
1490 srpc_log = sptlrpc_conf_log_alloc();
1491 if (IS_ERR(srpc_log))
1492 RETURN(PTR_ERR(srpc_log));
1493 srpc_log->scl_part = LUSTRE_SP_MDT;
1495 rc = mgs_get_srpc_conf_log(fsdb, mti->mti_svname,
1496 LUSTRE_SP_ANY, LUSTRE_SP_MDT, srpc_log);
1500 OBD_ALLOC(uuid, sizeof(struct obd_uuid));
1502 GOTO(out_srpc, rc = -ENOMEM);
1504 if (class_find_param(ptr, PARAM_FAILMODE, &ptr) == 0)
1505 failout = (strncmp(ptr, "failout", 7) == 0);
1507 name_create(&lovname, log, "-mdtlov");
1508 if (mgs_log_is_empty(obd, log))
1509 rc = mgs_write_log_lov(obd, fsdb, mti, log, lovname);
1511 sprintf(uuid, "%s_UUID", log);
1512 sprintf(mdt_index,"%d",mti->mti_stripe_index);
1514 /* add MDT itself */
1515 rc = record_start_log(obd, &llh, log);
1519 /* FIXME this whole fn should be a single journal transaction */
1520 rc = record_marker(obd, llh, fsdb, CM_START, log, "add mdt");
1521 rc = record_attach(obd, llh, log, LUSTRE_MDT_NAME, uuid);
1522 rc = record_mount_opt(obd, llh, log, lovname, NULL);
1523 rc = record_setup(obd, llh, log, uuid, mdt_index, lovname,
1524 failout ? "n" : "f");
1525 rc = record_sptlrpc_conf(obd, llh, log, srpc_log);
1526 rc = record_marker(obd, llh, fsdb, CM_END, log, "add mdt");
1527 rc = record_end_log(obd, &llh);
1529 name_destroy(&lovname);
1530 OBD_FREE(uuid, sizeof(struct obd_uuid));
1532 sptlrpc_conf_log_free(srpc_log);
1536 /* envelope method for all layers log */
1537 static int mgs_write_log_mdt(struct obd_device *obd, struct fs_db *fsdb,
1538 struct mgs_target_info *mti)
1540 struct llog_handle *llh = NULL;
1542 struct temp_comp comp = { 0 };
1547 CDEBUG(D_MGS, "writing new mdt %s\n", mti->mti_svname);
1551 if (mti->mti_flags & LDD_F_UPGRADE14) {
1552 /* We're starting with an old uuid. Assume old name for lov
1553 as well since the lov entry already exists in the log. */
1554 CDEBUG(D_MGS, "old mds uuid %s\n", mti->mti_uuid);
1555 if (strncmp(mti->mti_uuid, fsdb->fsdb_mdtlov + 4,
1556 strlen(fsdb->fsdb_mdtlov) - 4) != 0) {
1557 CERROR("old mds uuid %s doesn't match log %s (%s)\n",
1558 mti->mti_uuid, fsdb->fsdb_mdtlov,
1559 fsdb->fsdb_mdtlov + 4);
1563 /* end COMPAT_146 */
1565 if (mti->mti_uuid[0] == '\0') {
1566 /* Make up our own uuid */
1567 snprintf(mti->mti_uuid, sizeof(mti->mti_uuid),
1568 "%s_UUID", mti->mti_svname);
1572 rc = mgs_write_log_mdt0(obd, fsdb, mti);
1574 /* Append the mdt info to the client log */
1575 name_create(&cliname, mti->mti_fsname, "-client");
1577 if (mgs_log_is_empty(obd, cliname)) {
1578 /* Start client log */
1579 rc = mgs_write_log_lov(obd, fsdb, mti, cliname,
1581 rc = mgs_write_log_lmv(obd, fsdb, mti, cliname,
1586 #09 L add_uuid nid=uml1@tcp(0x20000c0a80201) 0: 1:uml1_UUID
1587 #10 L attach 0:MDC_uml1_mdsA_MNT_client 1:mdc 2:1d834_MNT_client_03f
1588 #11 L setup 0:MDC_uml1_mdsA_MNT_client 1:mdsA_UUID 2:uml1_UUID
1589 #12 L add_uuid nid=uml2@tcp(0x20000c0a80202) 0: 1:uml2_UUID
1590 #13 L add_conn 0:MDC_uml1_mdsA_MNT_client 1:uml2_UUID
1591 #14 L mount_option 0: 1:client 2:lov1 3:MDC_uml1_mdsA_MNT_client
1596 if (mti->mti_flags & LDD_F_UPGRADE14) {
1597 rc = record_start_log(obd, &llh, cliname);
1601 rc = record_marker(obd, llh, fsdb, CM_START,
1602 mti->mti_svname,"add mdc");
1604 /* Old client log already has MDC entry, but needs mount opt
1605 for new client name (lustre-client) */
1606 /* FIXME Old MDT log already has an old mount opt
1607 which we should remove (currently handled by
1608 class_del_profiles()) */
1609 rc = record_mount_opt(obd, llh, cliname, fsdb->fsdb_clilov,
1611 /* end COMPAT_146 */
1613 rc = record_marker(obd, llh, fsdb, CM_END,
1614 mti->mti_svname, "add mdc");
1618 /* copy client info about lov/lmv */
1619 comp.comp_mti = mti;
1620 comp.comp_fsdb = fsdb;
1622 rc = mgs_steal_llog_for_mdt_from_client(obd, cliname,
1625 rc = mgs_write_log_mdc_to_lmv(obd, fsdb, mti, cliname,
1628 rc = record_start_log(obd, &llh, cliname);
1632 rc = record_marker(obd, llh, fsdb, CM_START, cliname,
1634 rc = record_mount_opt(obd, llh, cliname, fsdb->fsdb_clilov,
1636 rc = record_marker(obd, llh, fsdb, CM_END, cliname,
1640 rc = record_end_log(obd, &llh);
1642 name_destroy(&cliname);
1644 // for_all_existing_mdt except current one
1645 for (i = 0; i < INDEX_MAP_SIZE * 8; i++){
1647 if (i != mti->mti_stripe_index &&
1648 test_bit(i, fsdb->fsdb_mdt_index_map)) {
1649 sprintf(mdt_index,"-MDT%04x",i);
1651 name_create(&mdtname, mti->mti_fsname, mdt_index);
1652 rc = mgs_write_log_mdc_to_mdt(obd, fsdb, mti, mdtname);
1653 name_destroy(&mdtname);
1660 /* Add the ost info to the client/mdt lov */
1661 static int mgs_write_log_osc_to_lov(struct obd_device *obd, struct fs_db *fsdb,
1662 struct mgs_target_info *mti,
1663 char *logname, char *suffix, char *lovname,
1664 enum lustre_sec_part sec_part, int flags)
1666 struct llog_handle *llh = NULL;
1667 struct sptlrpc_conf_log *srpc_log;
1668 char *nodeuuid, *oscname, *oscuuid, *lovuuid, *svname;
1673 CDEBUG(D_INFO, "adding osc for %s to log %s\n",
1674 mti->mti_svname, logname);
1676 srpc_log = sptlrpc_conf_log_alloc();
1677 if (IS_ERR(srpc_log))
1678 RETURN(PTR_ERR(srpc_log));
1679 srpc_log->scl_part = sec_part;
1681 rc = mgs_get_srpc_conf_log(fsdb, mti->mti_svname,
1682 sec_part, LUSTRE_SP_OST, srpc_log);
1686 if (mgs_log_is_empty(obd, logname)) {
1687 /* The first item in the log must be the lov, so we have
1688 somewhere to add our osc. */
1689 rc = mgs_write_log_lov(obd, fsdb, mti, logname, lovname);
1692 name_create(&nodeuuid, libcfs_nid2str(mti->mti_nids[0]), "");
1693 name_create(&svname, mti->mti_svname, "-osc");
1694 name_create(&oscname, svname, suffix);
1695 name_create(&oscuuid, oscname, "_UUID");
1696 name_create(&lovuuid, lovname, "_UUID");
1699 #03 L add_uuid nid=uml1@tcp(0x20000c0a80201) 0: 1:uml1_UUID
1701 #04 L add_uuid nid=1@elan(0x1000000000001) nal=90 0: 1:uml1_UUID
1702 #04 L attach 0:OSC_uml1_ost1_MNT_client 1:osc 2:89070_lov1_a41dff51a
1703 #05 L setup 0:OSC_uml1_ost1_MNT_client 1:ost1_UUID 2:uml1_UUID
1705 #06 L add_uuid nid=uml2@tcp(0x20000c0a80202) 0: 1:uml2_UUID
1706 #07 L add_conn 0:OSC_uml1_ost1_MNT_client 1:uml2_UUID
1707 #08 L lov_modify_tgts add 0:lov1 1:ost1_UUID 2(index):0 3(gen):1
1710 rc = record_start_log(obd, &llh, logname);
1713 /* FIXME these should be a single journal transaction */
1714 rc = record_marker(obd, llh, fsdb, CM_START | flags, mti->mti_svname,
1716 for (i = 0; i < mti->mti_nid_count; i++) {
1717 CDEBUG(D_MGS, "add nid %s\n", libcfs_nid2str(mti->mti_nids[i]));
1718 rc = record_add_uuid(obd, llh, mti->mti_nids[i], nodeuuid);
1720 rc = record_attach(obd, llh, oscname, LUSTRE_OSC_NAME, lovuuid);
1721 rc = record_setup(obd, llh, oscname, mti->mti_uuid, nodeuuid, 0, 0);
1722 rc = record_sptlrpc_conf(obd, llh, oscname, srpc_log);
1723 rc = mgs_write_log_failnids(obd, mti, llh, oscname);
1724 snprintf(index, sizeof(index), "%d", mti->mti_stripe_index);
1725 rc = record_lov_add(obd, llh, lovname, mti->mti_uuid, index, "1");
1726 rc = record_marker(obd, llh, fsdb, CM_END | flags, mti->mti_svname,
1728 rc = record_end_log(obd, &llh);
1730 name_destroy(&lovuuid);
1731 name_destroy(&oscuuid);
1732 name_destroy(&oscname);
1733 name_destroy(&svname);
1734 name_destroy(&nodeuuid);
1736 sptlrpc_conf_log_free(srpc_log);
1740 static int mgs_write_log_ost(struct obd_device *obd, struct fs_db *fsdb,
1741 struct mgs_target_info *mti)
1743 struct llog_handle *llh = NULL;
1744 struct sptlrpc_conf_log *srpc_log;
1745 char *logname, *lovname;
1747 char *ptr = mti->mti_params;
1748 int rc, flags = 0, failout = 0, i;
1751 CDEBUG(D_MGS, "writing new ost %s\n", mti->mti_svname);
1753 /* The ost startup log */
1755 /* If the ost log already exists, that means that someone reformatted
1756 the ost and it called target_add again. */
1757 if (!mgs_log_is_empty(obd, mti->mti_svname)) {
1758 LCONSOLE_ERROR_MSG(0x141, "The config log for %s already "
1759 "exists, yet the server claims it never "
1760 "registered. It may have been reformatted, "
1761 "or the index changed. writeconf the MDT to "
1762 "regenerate all logs.\n", mti->mti_svname);
1766 srpc_log = sptlrpc_conf_log_alloc();
1767 if (IS_ERR(srpc_log))
1768 RETURN(PTR_ERR(srpc_log));
1769 srpc_log->scl_part = LUSTRE_SP_OST;
1771 rc = mgs_get_srpc_conf_log(fsdb, mti->mti_svname,
1772 LUSTRE_SP_ANY, LUSTRE_SP_OST, srpc_log);
1777 attach obdfilter ost1 ost1_UUID
1778 setup /dev/loop2 ldiskfs f|n errors=remount-ro,user_xattr
1780 if (class_find_param(ptr, PARAM_FAILMODE, &ptr) == 0)
1781 failout = (strncmp(ptr, "failout", 7) == 0);
1782 rc = record_start_log(obd, &llh, mti->mti_svname);
1785 /* FIXME these should be a single journal transaction */
1786 rc = record_marker(obd, llh, fsdb, CM_START, mti->mti_svname,"add ost");
1787 if (*mti->mti_uuid == '\0')
1788 snprintf(mti->mti_uuid, sizeof(mti->mti_uuid),
1789 "%s_UUID", mti->mti_svname);
1790 rc = record_attach(obd, llh, mti->mti_svname,
1791 "obdfilter"/*LUSTRE_OST_NAME*/, mti->mti_uuid);
1792 rc = record_setup(obd, llh, mti->mti_svname,
1793 "dev"/*ignored*/, "type"/*ignored*/,
1794 failout ? "n" : "f", 0/*options*/);
1795 rc = record_sptlrpc_conf(obd, llh, mti->mti_svname, srpc_log);
1796 rc = record_marker(obd, llh, fsdb, CM_END, mti->mti_svname, "add ost");
1797 rc = record_end_log(obd, &llh);
1799 /* We also have to update the other logs where this osc is part of
1802 if (fsdb->fsdb_flags & FSDB_OLDLOG14) {
1803 /* If we're upgrading, the old mdt log already has our
1804 entry. Let's do a fake one for fun. */
1805 /* Note that we can't add any new failnids, since we don't
1806 know the old osc names. */
1807 flags = CM_SKIP | CM_UPGRADE146;
1809 } else if ((mti->mti_flags & LDD_F_UPDATE) != LDD_F_UPDATE) {
1810 /* If the update flag isn't set, don't update client/mdt
1813 LCONSOLE_WARN("Client log for %s was not updated; writeconf "
1814 "the MDT first to regenerate it.\n",
1818 // for_all_existing_mdt
1819 for (i = 0; i < INDEX_MAP_SIZE * 8; i++){
1820 if (test_bit(i, fsdb->fsdb_mdt_index_map)) {
1821 sprintf(mdt_index,"-MDT%04x",i);
1822 name_create(&logname, mti->mti_fsname, mdt_index);
1823 name_create(&lovname, logname, "-mdtlov");
1824 mgs_write_log_osc_to_lov(obd, fsdb, mti, logname,
1826 LUSTRE_SP_MDT, flags);
1827 name_destroy(&logname);
1828 name_destroy(&lovname);
1832 /* Append ost info to the client log */
1833 name_create(&logname, mti->mti_fsname, "-client");
1834 mgs_write_log_osc_to_lov(obd, fsdb, mti, logname, "",
1835 fsdb->fsdb_clilov, LUSTRE_SP_CLI, 0);
1836 name_destroy(&logname);
1838 sptlrpc_conf_log_free(srpc_log);
1842 /* Add additional failnids to an existing log.
1843 The mdc/osc must have been added to logs first */
1844 /* tcp nids must be in dotted-quad ascii -
1845 we can't resolve hostnames from the kernel. */
1846 static int mgs_write_log_add_failnid(struct obd_device *obd, struct fs_db *fsdb,
1847 struct mgs_target_info *mti)
1849 char *logname, *cliname;
1850 struct llog_handle *llh = NULL;
1854 /* FIXME how do we delete a failnid? Currently --writeconf is the
1855 only way. Maybe make --erase-params pass a flag to really
1856 erase all params from logs - except it can't erase the failnids
1857 given when a target first registers, since they aren't processed
1860 /* Verify that we know about this target */
1861 if (mgs_log_is_empty(obd, mti->mti_svname)) {
1862 LCONSOLE_ERROR_MSG(0x142, "The target %s has not registered "
1863 "yet. It must be started before failnids "
1864 "can be added.\n", mti->mti_svname);
1868 /* Create mdc/osc client name (e.g. lustre-OST0001-osc) */
1869 if (mti->mti_flags & LDD_F_SV_TYPE_MDT) {
1870 name_create(&cliname, mti->mti_svname, "-mdc");
1871 } else if (mti->mti_flags & LDD_F_SV_TYPE_OST) {
1872 name_create(&cliname, mti->mti_svname, "-osc");
1877 /* Add failover nids to client log */
1878 name_create(&logname, mti->mti_fsname, "-client");
1879 rc = record_start_log(obd, &llh, logname);
1881 /* FIXME this fn should be a single journal transaction */
1882 rc = record_marker(obd, llh, fsdb, CM_START, mti->mti_svname,
1884 rc = mgs_write_log_failnids(obd, mti, llh, cliname);
1885 rc = record_marker(obd, llh, fsdb, CM_END, mti->mti_svname,
1887 rc = record_end_log(obd, &llh);
1889 name_destroy(&logname);
1891 if (mti->mti_flags & LDD_F_SV_TYPE_OST) {
1892 /* Add OST failover nids to the MDT log as well */
1893 name_create(&logname, mti->mti_fsname, "-MDT0000");
1894 rc = record_start_log(obd, &llh, logname);
1896 rc = record_marker(obd, llh, fsdb, CM_START,
1897 mti->mti_svname, "add failnid");
1898 rc = mgs_write_log_failnids(obd, mti, llh, cliname);
1899 rc = record_marker(obd, llh, fsdb, CM_END,
1900 mti->mti_svname, "add failnid");
1901 rc = record_end_log(obd, &llh);
1903 name_destroy(&logname);
1906 name_destroy(&cliname);
1910 static int mgs_wlp_lcfg(struct obd_device *obd, struct fs_db *fsdb,
1911 struct mgs_target_info *mti,
1912 char *logname, struct lustre_cfg_bufs *bufs,
1913 char *tgtname, char *ptr)
1915 char comment[MTI_NAME_MAXLEN];
1917 struct lustre_cfg *lcfg;
1920 /* Erase any old settings of this same parameter */
1921 memcpy(comment, ptr, MTI_NAME_MAXLEN);
1922 comment[MTI_NAME_MAXLEN - 1] = 0;
1923 /* But don't try to match the value. */
1924 if ((tmp = strchr(comment, '=')))
1926 /* FIXME we should skip settings that are the same as old values */
1927 rc = mgs_modify(obd, fsdb, mti, logname, tgtname, comment, CM_SKIP);
1928 LCONSOLE_INFO("%sing parameter %s.%s in log %s\n", rc ?
1929 "Sett" : "Modify", tgtname, comment, logname);
1931 lustre_cfg_bufs_reset(bufs, tgtname);
1932 lustre_cfg_bufs_set_string(bufs, 1, ptr);
1933 lcfg = lustre_cfg_new(LCFG_PARAM, bufs);
1936 rc = mgs_write_log_direct(obd, fsdb, logname, lcfg, tgtname, comment);
1937 lustre_cfg_free(lcfg);
1942 * populate rules which applied to a target device
1944 static int mgs_get_srpc_conf_log(struct fs_db *fsdb, const char *tgt,
1945 enum lustre_sec_part from,
1946 enum lustre_sec_part to,
1947 struct sptlrpc_conf_log *log)
1949 struct mgs_tgt_srpc_conf *tgtconf;
1950 struct sptlrpc_rule_set *tgt_rset;
1951 int found_tgt = 0, rc;
1953 for (tgtconf = fsdb->fsdb_srpc_tgt; tgtconf;
1954 tgtconf = tgtconf->mtsc_next) {
1955 if (!strcmp(tgt, tgtconf->mtsc_tgt)) {
1962 tgt_rset = &tgtconf->mtsc_rset;
1966 rc = sptlrpc_conf_log_populate(&fsdb->fsdb_srpc_gen, tgt_rset,
1967 from, to, fsdb->fsdb_srpc_fl_udesc, log);
1969 CERROR("failed to populate srpc log for %s: %d\n", tgt, rc);
1974 struct mgs_msl_data {
1975 struct obd_device *mmd_obd;
1976 struct fs_db *mmd_fsdb;
1977 struct mgs_target_info *mmd_mti;
1981 enum lustre_sec_part mmd_tgtpart;
1982 char mmd_tgtname[MTI_NAME_MAXLEN];
1985 static void mgs_msl_data_cleanup(struct mgs_msl_data *mmd)
1987 mmd->mmd_attached = 0;
1988 mmd->mmd_tgtname[0] = '\0';
1991 static int mgs_msl_tgt_uuid2name(char *tgtname, char *tgtuuid)
1995 if (tgtuuid == NULL) {
1996 CERROR("missing target UUID???\n");
2000 ptr = strstr(tgtuuid, "_UUID");
2002 CERROR("unrecognized UUID: %s\n", tgtuuid);
2007 strncpy(tgtname, tgtuuid, MTI_NAME_MAXLEN);
2008 tgtname[MTI_NAME_MAXLEN - 1] = '\0';
2013 static int mgs_modify_srpc_log_handler(struct llog_handle *llh,
2014 struct llog_rec_hdr *rec,
2017 struct mgs_msl_data *mmd = (struct mgs_msl_data *)data;
2018 struct cfg_marker *marker;
2019 struct lustre_cfg *lcfg = (struct lustre_cfg *)(rec + 1);
2023 if (rec->lrh_type != OBD_CFG_REC) {
2024 CERROR("unhandled lrh_type: %#x\n", rec->lrh_type);
2028 cfg_len = rec->lrh_len - sizeof(struct llog_rec_hdr) -
2029 sizeof(struct llog_rec_tail);
2031 rc = lustre_cfg_sanity_check(lcfg, cfg_len);
2033 CERROR("Insane cfg\n");
2037 if (lcfg->lcfg_command == LCFG_MARKER) {
2038 marker = lustre_cfg_buf(lcfg, 1);
2040 if (marker->cm_flags & CM_START &&
2041 marker->cm_flags & CM_SKIP)
2043 if (marker->cm_flags & CM_END)
2052 switch (lcfg->lcfg_command) {
2054 mmd->mmd_attached = 1;
2056 if (!strcmp(lustre_cfg_string(lcfg, 1), LUSTRE_OST_NAME)) {
2057 mmd->mmd_server = 1;
2058 mmd->mmd_tgtpart = LUSTRE_SP_OST;
2059 } else if (!strcmp(lustre_cfg_string(lcfg, 1),
2061 mmd->mmd_server = 1;
2062 mmd->mmd_tgtpart = LUSTRE_SP_MDT;
2063 } else if (!strcmp(lustre_cfg_string(lcfg, 1),
2065 mmd->mmd_server = 0;
2066 mmd->mmd_tgtpart = LUSTRE_SP_OST;
2067 } else if (!strcmp(lustre_cfg_string(lcfg, 1),
2069 mmd->mmd_server = 0;
2070 mmd->mmd_tgtpart = LUSTRE_SP_MDT;
2072 mmd->mmd_attached = 0;
2075 if (mmd->mmd_attached && mmd->mmd_server) {
2076 rc = mgs_msl_tgt_uuid2name(mmd->mmd_tgtname,
2077 lustre_cfg_string(lcfg, 2));
2079 mgs_msl_data_cleanup(mmd);
2086 if (!mmd->mmd_attached)
2089 /* already got tgtname at LCFG_ATTACH */
2090 if (mmd->mmd_server)
2093 rc = mgs_msl_tgt_uuid2name(mmd->mmd_tgtname,
2094 lustre_cfg_string(lcfg, 1));
2096 mgs_msl_data_cleanup(mmd);
2101 case LCFG_SPTLRPC_CONF: {
2102 struct sptlrpc_conf_log *log;
2103 enum lustre_sec_part from;
2105 if (!mmd->mmd_attached)
2108 log = sptlrpc_conf_log_extract(lcfg);
2110 CERROR("missing sptlrpc config log???\n");
2111 mgs_msl_data_cleanup(mmd);
2115 if (mmd->mmd_server)
2116 from = LUSTRE_SP_ANY;
2118 from = log->scl_part;
2120 /* cleanup the old log */
2121 sptlrpc_conf_log_cleanup(log);
2123 /* populate new log */
2124 rc = mgs_get_srpc_conf_log(mmd->mmd_fsdb, mmd->mmd_tgtname,
2125 from, mmd->mmd_tgtpart, log);
2127 mgs_msl_data_cleanup(mmd);
2131 /* Overwrite the log */
2132 rec->lrh_len = cfg_len;
2133 rc = llog_write_rec(llh, rec, NULL, 0, (void *)lcfg,
2136 CERROR("overwrite sptlrpc conf log failed: %d\n", rc);
2138 /* append new one */
2139 rc = record_marker(mmd->mmd_obd, llh, mmd->mmd_fsdb, CM_START,
2140 mmd->mmd_mti->mti_svname, "sptlrpc config");
2141 rc = record_sptlrpc_conf(mmd->mmd_obd, llh,
2142 lustre_cfg_string(lcfg, 0), log);
2143 rc = record_marker(mmd->mmd_obd, llh, mmd->mmd_fsdb, CM_END,
2144 mmd->mmd_mti->mti_svname, "sptlrpc config");
2146 mgs_msl_data_cleanup(mmd);
2150 /* ignore all others */
2157 static int mgs_modify_srpc_log(struct obd_device *obd,
2159 struct mgs_target_info *mti,
2162 struct llog_handle *llh;
2163 struct lvfs_run_ctxt saved;
2164 struct llog_ctxt *ctxt;
2165 struct mgs_msl_data *mmd;
2169 CDEBUG(D_MGS, "modify sptlrpc log for %s\n", logname);
2171 push_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
2173 ctxt = llog_get_context(obd, LLOG_CONFIG_ORIG_CTXT);
2174 LASSERT(ctxt != NULL);
2175 rc = llog_create(ctxt, &llh, NULL, logname);
2179 rc = llog_init_handle(llh, LLOG_F_IS_PLAIN, NULL);
2181 GOTO(out_close, rc);
2183 if (llog_get_size(llh) <= 1)
2184 GOTO(out_close, rc = 0);
2188 GOTO(out_close, rc = -ENOMEM);
2191 mmd->mmd_fsdb = fsdb;
2194 rc = llog_process(llh, mgs_modify_srpc_log_handler, (void *) mmd, NULL);
2199 rc2 = llog_close(llh);
2204 pop_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
2205 llog_ctxt_put(ctxt);
2208 CERROR("modify sptlrpc log %s failed %d\n", logname, rc);
2213 * for each of log, remove old conf at first
2215 static int mgs_modify_srpc_log_all(struct obd_device *obd,
2217 struct mgs_target_info *mti)
2224 for (i = 0; i < INDEX_MAP_SIZE * 8; i++){
2225 if (test_bit(i, fsdb->fsdb_mdt_index_map)) {
2226 sprintf(tgt_index,"-MDT%04x",i);
2228 name_create(&logname, mti->mti_fsname, tgt_index);
2229 rc2 = mgs_modify(obd, fsdb, mti, logname,
2230 mti->mti_fsname, "sptlrpc config",
2232 rc2 = mgs_modify_srpc_log(obd, fsdb, mti, logname);
2233 name_destroy(&logname);
2240 for (i = 0; i < INDEX_MAP_SIZE * 8; i++){
2241 if (test_bit(i, fsdb->fsdb_ost_index_map)) {
2242 sprintf(tgt_index,"-OST%04x",i);
2244 name_create(&logname, mti->mti_fsname, tgt_index);
2245 rc2 = mgs_modify(obd, fsdb, mti, logname,
2246 mti->mti_fsname, "sptlrpc config",
2248 rc2 = mgs_modify_srpc_log(obd, fsdb, mti, logname);
2249 name_destroy(&logname);
2256 name_create(&logname, mti->mti_fsname, "-client");
2257 rc2 = mgs_modify(obd, fsdb, mti, logname,
2258 mti->mti_fsname, "sptlrpc config", CM_SKIP);
2259 rc2 = mgs_modify_srpc_log(obd, fsdb, mti, logname);
2260 name_destroy(&logname);
2268 static int mgs_srpc_set_param_disk(struct obd_device *obd,
2270 struct mgs_target_info *mti,
2273 struct llog_handle *llh = NULL;
2275 char *comment, *ptr;
2276 struct lustre_cfg_bufs bufs;
2277 struct lustre_cfg *lcfg;
2282 ptr = strchr(param, '=');
2286 OBD_ALLOC(comment, len + 1);
2287 if (comment == NULL)
2289 strncpy(comment, param, len);
2290 comment[len] = '\0';
2293 lustre_cfg_bufs_reset(&bufs, mti->mti_svname);
2294 lustre_cfg_bufs_set_string(&bufs, 1, param);
2295 lcfg = lustre_cfg_new(0, &bufs);
2297 GOTO(out_comment, rc = -ENOMEM);
2299 /* construct log name */
2300 rc = name_create(&logname, mti->mti_fsname, "-sptlrpc");
2304 if (mgs_log_is_empty(obd, logname)) {
2305 rc = record_start_log(obd, &llh, logname);
2306 record_end_log(obd, &llh);
2311 /* obsolete old one */
2312 mgs_modify(obd, fsdb, mti, logname, mti->mti_svname, comment, CM_SKIP);
2314 /* write the new one */
2315 rc = mgs_write_log_direct(obd, fsdb, logname, lcfg,
2316 mti->mti_svname, comment);
2318 CERROR("err %d writing log %s\n", rc, logname);
2321 name_destroy(&logname);
2323 lustre_cfg_free(lcfg);
2325 OBD_FREE(comment, len + 1);
2329 static int mgs_srpc_set_param_udesc_mem(struct fs_db *fsdb,
2334 /* disable the adjustable udesc parameter for now, i.e. use default
2335 * setting that client always ship udesc to MDT if possible. to enable
2336 * it simply remove the following line */
2339 ptr = strchr(param, '=');
2344 if (strcmp(param, PARAM_SRPC_UDESC))
2347 if (strcmp(ptr, "yes") == 0) {
2348 fsdb->fsdb_srpc_fl_udesc = 1;
2349 CWARN("Enable user descriptor shipping from client to MDT\n");
2350 } else if (strcmp(ptr, "no") == 0) {
2351 fsdb->fsdb_srpc_fl_udesc = 0;
2352 CWARN("Disable user descriptor shipping from client to MDT\n");
2360 CERROR("Invalid param: %s\n", param);
2364 static int mgs_srpc_set_param_mem(struct fs_db *fsdb,
2368 struct sptlrpc_rule rule;
2369 struct sptlrpc_rule_set *rset;
2373 if (strncmp(param, PARAM_SRPC, sizeof(PARAM_SRPC) - 1) != 0) {
2374 CERROR("Invalid sptlrpc parameter: %s\n", param);
2378 if (strncmp(param, PARAM_SRPC_UDESC,
2379 sizeof(PARAM_SRPC_UDESC) - 1) == 0) {
2380 RETURN(mgs_srpc_set_param_udesc_mem(fsdb, param));
2383 if (strncmp(param, PARAM_SRPC_FLVR, sizeof(PARAM_SRPC_FLVR) - 1) != 0) {
2384 CERROR("Invalid sptlrpc flavor parameter: %s\n", param);
2388 param += sizeof(PARAM_SRPC_FLVR) - 1;
2390 rc = sptlrpc_parse_rule(param, &rule);
2394 /* preapre room for this coming rule. svcname format should be:
2395 * - fsname: general rule
2396 * - fsname-tgtname: target-specific rule
2398 if (strchr(svname, '-')) {
2399 struct mgs_tgt_srpc_conf *tgtconf;
2402 for (tgtconf = fsdb->fsdb_srpc_tgt; tgtconf != NULL;
2403 tgtconf = tgtconf->mtsc_next) {
2404 if (!strcmp(tgtconf->mtsc_tgt, svname)) {
2413 OBD_ALLOC_PTR(tgtconf);
2414 if (tgtconf == NULL)
2417 name_len = strlen(svname);
2419 OBD_ALLOC(tgtconf->mtsc_tgt, name_len + 1);
2420 if (tgtconf->mtsc_tgt == NULL) {
2421 OBD_FREE_PTR(tgtconf);
2424 memcpy(tgtconf->mtsc_tgt, svname, name_len);
2426 tgtconf->mtsc_next = fsdb->fsdb_srpc_tgt;
2427 fsdb->fsdb_srpc_tgt = tgtconf;
2430 rset = &tgtconf->mtsc_rset;
2432 rset = &fsdb->fsdb_srpc_gen;
2435 /* limit the maximum number of rules, but allow deletion in any case */
2436 if (rset->srs_nrule >= SPTLRPC_CONF_LOG_MAX / 2 &&
2437 rule.sr_flvr.sf_rpc != SPTLRPC_FLVR_INVALID) {
2438 CERROR("too many (%d) rules already for %s\n",
2439 rset->srs_nrule, svname);
2443 rc = sptlrpc_rule_set_merge(rset, &rule, 1);
2448 static int mgs_srpc_set_param(struct obd_device *obd,
2450 struct mgs_target_info *mti,
2457 /* keep a copy of original param, which could be destroied
2459 copy_size = strlen(param) + 1;
2460 OBD_ALLOC(copy, copy_size);
2463 memcpy(copy, param, copy_size);
2465 rc = mgs_srpc_set_param_mem(fsdb, mti->mti_svname, param);
2469 /* previous steps guaranteed the syntax is correct */
2470 rc = mgs_srpc_set_param_disk(obd, fsdb, mti, copy);
2474 /* now apply the new rules to all existing config logs */
2475 rc = mgs_modify_srpc_log_all(obd, fsdb, mti);
2478 OBD_FREE(copy, copy_size);
2482 struct mgs_srpc_read_data {
2483 struct fs_db *msrd_fsdb;
2487 static int mgs_srpc_read_handler(struct llog_handle *llh,
2488 struct llog_rec_hdr *rec,
2491 struct mgs_srpc_read_data *msrd = (struct mgs_srpc_read_data *) data;
2492 struct cfg_marker *marker;
2493 struct lustre_cfg *lcfg = (struct lustre_cfg *)(rec + 1);
2494 char *svname, *param;
2498 if (rec->lrh_type != OBD_CFG_REC) {
2499 CERROR("unhandled lrh_type: %#x\n", rec->lrh_type);
2503 cfg_len = rec->lrh_len - sizeof(struct llog_rec_hdr) -
2504 sizeof(struct llog_rec_tail);
2506 rc = lustre_cfg_sanity_check(lcfg, cfg_len);
2508 CERROR("Insane cfg\n");
2512 if (lcfg->lcfg_command == LCFG_MARKER) {
2513 marker = lustre_cfg_buf(lcfg, 1);
2515 if (marker->cm_flags & CM_START &&
2516 marker->cm_flags & CM_SKIP)
2517 msrd->msrd_skip = 1;
2518 if (marker->cm_flags & CM_END)
2519 msrd->msrd_skip = 0;
2524 if (msrd->msrd_skip)
2527 if (lcfg->lcfg_command != 0) {
2528 CERROR("invalid command (%x)\n", lcfg->lcfg_command);
2532 svname = lustre_cfg_string(lcfg, 0);
2533 if (svname == NULL) {
2534 CERROR("svname is empty\n");
2538 param = lustre_cfg_string(lcfg, 1);
2539 if (param == NULL) {
2540 CERROR("param is empty\n");
2544 rc = mgs_srpc_set_param_mem(msrd->msrd_fsdb, svname, param);
2546 CERROR("read sptlrpc record error (%d): %s\n", rc, param);
2551 static int mgs_get_fsdb_srpc_from_llog(struct obd_device *obd,
2554 struct llog_handle *llh = NULL;
2555 struct lvfs_run_ctxt saved;
2556 struct llog_ctxt *ctxt;
2558 struct mgs_srpc_read_data msrd;
2562 ctxt = llog_get_context(obd, LLOG_CONFIG_ORIG_CTXT);
2563 LASSERT(ctxt != NULL);
2565 /* construct log name */
2566 rc = name_create(&logname, fsdb->fsdb_name, "-sptlrpc");
2570 if (mgs_log_is_empty(obd, logname))
2573 push_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
2575 rc = llog_create(ctxt, &llh, NULL, logname);
2579 rc = llog_init_handle(llh, LLOG_F_IS_PLAIN, NULL);
2581 GOTO(out_close, rc);
2583 if (llog_get_size(llh) <= 1)
2584 GOTO(out_close, rc = 0);
2586 msrd.msrd_fsdb = fsdb;
2589 rc = llog_process(llh, mgs_srpc_read_handler, (void *) &msrd, NULL);
2594 pop_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
2596 name_destroy(&logname);
2597 llog_ctxt_put(ctxt);
2600 CERROR("failed to read sptlrpc config database: %d\n", rc);
2604 static int mgs_write_log_params(struct obd_device *obd, struct fs_db *fsdb,
2605 struct mgs_target_info *mti)
2607 struct lustre_cfg_bufs bufs;
2608 struct lustre_cfg *lcfg;
2610 char *ptr = mti->mti_params;
2615 if (!mti->mti_params)
2618 /* For various parameter settings, we have to figure out which logs
2619 care about them (e.g. both mdt and client for lov settings) */
2625 endptr = strchr(ptr, ' ');
2628 CDEBUG(D_MGS, "next param '%s'\n", ptr);
2630 /* The params are stored in MOUNT_DATA_FILE and modified
2631 via tunefs.lustre */
2633 /* Processed in lustre_start_mgc */
2634 if (class_match_param(ptr, PARAM_MGSNODE, NULL) == 0)
2635 GOTO(end_while, rc);
2637 /* Processed in mgs_write_log_ost */
2638 if (class_match_param(ptr, PARAM_FAILMODE, NULL) == 0) {
2639 if (mti->mti_flags & LDD_F_PARAM) {
2640 LCONSOLE_ERROR_MSG(0x169, "%s can only be "
2641 "changed with tunefs.lustre"
2642 "and --writeconf\n", ptr);
2645 GOTO(end_while, rc);
2648 if (class_match_param(ptr, PARAM_SRPC, NULL) == 0) {
2649 rc = mgs_srpc_set_param(obd, fsdb, mti, ptr);
2650 GOTO(end_while, rc);
2653 if (class_match_param(ptr, PARAM_FAILNODE, NULL) == 0) {
2654 /* Add a failover nidlist */
2656 /* We already processed failovers params for new
2657 targets in mgs_write_log_target */
2658 if (mti->mti_flags & LDD_F_PARAM) {
2659 CDEBUG(D_MGS, "Adding failnode\n");
2660 rc = mgs_write_log_add_failnid(obd, fsdb, mti);
2662 GOTO(end_while, rc);
2665 if (class_match_param(ptr, PARAM_SYS_TIMEOUT, &tmp) == 0) {
2666 /* Change obd timeout */
2668 timeout = simple_strtoul(tmp, NULL, 0);
2670 CDEBUG(D_MGS, "obd timeout %d\n", timeout);
2671 lustre_cfg_bufs_reset(&bufs, NULL);
2672 lcfg = lustre_cfg_new(LCFG_SET_TIMEOUT, &bufs);
2673 lcfg->lcfg_num = timeout;
2674 /* modify all servers and clients */
2675 rc = mgs_write_log_direct_all(obd, fsdb, mti, lcfg,
2678 lustre_cfg_free(lcfg);
2679 GOTO(end_while, rc);
2682 if (class_match_param(ptr, PARAM_OSC""PARAM_ACTIVE, &tmp) == 0) {
2683 /* active=0 means off, anything else means on */
2685 int flag = (*tmp == '0') ? CM_EXCLUDE : 0;
2688 if (!(mti->mti_flags & LDD_F_SV_TYPE_OST)) {
2689 LCONSOLE_ERROR_MSG(0x144, "%s: Only OSCs can "
2690 "be (de)activated.\n",
2695 LCONSOLE_WARN("Permanently %sactivating %s\n",
2696 flag ? "de": "re", mti->mti_svname);
2698 name_create(&logname, mti->mti_fsname, "-client");
2699 rc = mgs_modify(obd, fsdb, mti, logname,
2700 mti->mti_svname, "add osc", flag);
2701 name_destroy(&logname);
2705 /* FIXME add to all MDT logs for CMD */
2706 for (i = 0; i < INDEX_MAP_SIZE * 8; i++) {
2707 if (!test_bit(i, fsdb->fsdb_mdt_index_map))
2709 sprintf(mdt_index,"-MDT%04x", i);
2710 name_create(&logname, mti->mti_fsname, mdt_index);
2711 rc = mgs_modify(obd, fsdb, mti, logname,
2712 mti->mti_svname, "add osc", flag);
2713 name_destroy(&logname);
2719 LCONSOLE_ERROR_MSG(0x145, "Couldn't find %s in"
2720 "log (%d). No permanent "
2721 "changes were made to the "
2723 mti->mti_svname, rc);
2724 if (fsdb->fsdb_flags & FSDB_OLDLOG14)
2725 LCONSOLE_ERROR_MSG(0x146, "This may be"
2730 "update the logs.\n");
2733 /* Fall through to osc proc for deactivating
2734 live OSC on running MDT / clients. */
2736 /* Below here, let obd's XXX_process_config methods handle it */
2738 /* All lov. in proc */
2739 if (class_match_param(ptr, PARAM_LOV, NULL) == 0) {
2743 CDEBUG(D_MGS, "lov param %s\n", ptr);
2744 if (!(mti->mti_flags & LDD_F_SV_TYPE_MDT)) {
2745 LCONSOLE_ERROR_MSG(0x147, "LOV params must be "
2746 "set on the MDT, not %s. "
2754 if (mgs_log_is_empty(obd, mti->mti_svname))
2755 GOTO(end_while, rc = -ENODEV);
2757 sprintf(mdt_index,"-MDT%04x", mti->mti_stripe_index);
2758 name_create(&logname, mti->mti_fsname, mdt_index);
2759 name_create(&mdtlovname, logname, "-mdtlov");
2760 rc = mgs_wlp_lcfg(obd, fsdb, mti, mti->mti_svname,
2761 &bufs, mdtlovname, ptr);
2762 name_destroy(&logname);
2763 name_destroy(&mdtlovname);
2765 GOTO(end_while, rc);
2768 name_create(&logname, mti->mti_fsname, "-client");
2769 rc = mgs_wlp_lcfg(obd, fsdb, mti, logname, &bufs,
2770 fsdb->fsdb_clilov, ptr);
2771 name_destroy(&logname);
2772 GOTO(end_while, rc);
2775 /* All osc., mdc., llite. params in proc */
2776 if ((class_match_param(ptr, PARAM_OSC, NULL) == 0) ||
2777 (class_match_param(ptr, PARAM_MDC, NULL) == 0) ||
2778 (class_match_param(ptr, PARAM_LLITE, NULL) == 0)) {
2780 if (memcmp(ptr, PARAM_LLITE, strlen(PARAM_LLITE)) == 0) {
2781 name_create(&cname, mti->mti_fsname, "-client");
2782 /* Add the client type to match the obdname
2783 in class_config_llog_handler */
2784 } else if (mti->mti_flags & LDD_F_SV_TYPE_MDT) {
2787 name_create(&cname, fsdb->fsdb_mdc, "");
2789 name_create(&cname, mti->mti_svname,
2791 } else if (mti->mti_flags & LDD_F_SV_TYPE_OST) {
2793 if (fsdb->fsdb_flags & FSDB_OLDLOG14) {
2794 LCONSOLE_ERROR_MSG(0x148, "Upgraded "
2795 "client logs for %s"
2797 "modified. Consider"
2799 "configuration with"
2802 /* We don't know the names of all the
2807 name_create(&cname, mti->mti_svname, "-osc");
2813 CDEBUG(D_MGS, "%.3s param %s\n", ptr, ptr + 4);
2816 name_create(&logname, mti->mti_fsname, "-client");
2817 rc = mgs_wlp_lcfg(obd, fsdb, mti, logname, &bufs,
2820 /* osc params affect the MDT as well */
2821 if (!rc && (mti->mti_flags & LDD_F_SV_TYPE_OST)) {
2825 for (i = 0; i < INDEX_MAP_SIZE * 8; i++){
2826 if (!test_bit(i, fsdb->fsdb_mdt_index_map))
2828 name_destroy(&cname);
2829 sprintf(mdt_index, "-osc-MDT%04x", i);
2830 name_create(&cname, mti->mti_svname,
2832 name_destroy(&logname);
2833 sprintf(mdt_index, "-MDT%04x", i);
2834 name_create(&logname, mti->mti_fsname,
2836 if (!mgs_log_is_empty(obd, logname))
2837 rc = mgs_wlp_lcfg(obd, fsdb,
2845 name_destroy(&logname);
2846 name_destroy(&cname);
2847 GOTO(end_while, rc);
2850 /* All mdt., ost. params in proc */
2851 if ((class_match_param(ptr, PARAM_MDT, NULL) == 0) ||
2852 (class_match_param(ptr, PARAM_OST, NULL) == 0)) {
2853 CDEBUG(D_MGS, "%.3s param %s\n", ptr, ptr + 4);
2854 if (mgs_log_is_empty(obd, mti->mti_svname)) {
2858 rc = mgs_wlp_lcfg(obd, fsdb, mti, mti->mti_svname,
2859 &bufs, mti->mti_svname, ptr);
2860 GOTO(end_while, rc);
2863 LCONSOLE_WARN("Ignoring unrecognized param '%s'\n", ptr);
2867 CERROR("err %d on param '%s\n", rc, ptr);
2882 /* Not implementing automatic failover nid addition at this time. */
2883 int mgs_check_failnid(struct obd_device *obd, struct mgs_target_info *mti)
2890 rc = mgs_find_or_make_fsdb(obd, fsname, &fsdb);
2894 if (mgs_log_is_empty(obd, mti->mti_svname))
2895 /* should never happen */
2898 CDEBUG(D_MGS, "Checking for new failnids for %s\n", mti->mti_svname);
2900 /* FIXME We can just check mti->params to see if we're already in
2901 the failover list. Modify mti->params for rewriting back at
2902 server_register_target(). */
2904 down(&fsdb->fsdb_sem);
2905 rc = mgs_write_log_add_failnid(obd, fsdb, mti);
2906 up(&fsdb->fsdb_sem);
2913 int mgs_write_log_target(struct obd_device *obd,
2914 struct mgs_target_info *mti)
2920 /* set/check the new target index */
2921 rc = mgs_set_index(obd, mti);
2923 CERROR("Can't get index (%d)\n", rc);
2928 if (mti->mti_flags & LDD_F_UPGRADE14) {
2929 if (rc == EALREADY) {
2930 LCONSOLE_INFO("Found index %d for %s 1.4 log, "
2931 "upgrading\n", mti->mti_stripe_index,
2934 LCONSOLE_ERROR_MSG(0x149, "Failed to find %s in the old"
2935 " client log. Apparently it is not "
2936 "part of this filesystem, or the old"
2937 " log is wrong.\nUse 'writeconf' on "
2938 "the MDT to force log regeneration."
2939 "\n", mti->mti_svname);
2940 /* Not in client log? Upgrade anyhow...*/
2941 /* Argument against upgrading: reformat MDT,
2942 upgrade OST, then OST will start but will be SKIPped
2943 in client logs. Maybe error now is better. */
2944 /* RETURN(-EINVAL); */
2946 /* end COMPAT_146 */
2948 if (rc == EALREADY) {
2949 LCONSOLE_WARN("Found index %d for %s, updating log\n",
2950 mti->mti_stripe_index, mti->mti_svname);
2951 /* We would like to mark old log sections as invalid
2952 and add new log sections in the client and mdt logs.
2953 But if we add new sections, then live clients will
2954 get repeat setup instructions for already running
2955 osc's. So don't update the client/mdt logs. */
2956 mti->mti_flags &= ~LDD_F_UPDATE;
2960 rc = mgs_find_or_make_fsdb(obd, mti->mti_fsname, &fsdb);
2962 CERROR("Can't get db for %s\n", mti->mti_fsname);
2966 down(&fsdb->fsdb_sem);
2968 if (mti->mti_flags &
2969 (LDD_F_VIRGIN | LDD_F_UPGRADE14 | LDD_F_WRITECONF)) {
2970 /* Generate a log from scratch */
2971 if (mti->mti_flags & LDD_F_SV_TYPE_MDT) {
2972 rc = mgs_write_log_mdt(obd, fsdb, mti);
2973 } else if (mti->mti_flags & LDD_F_SV_TYPE_OST) {
2974 rc = mgs_write_log_ost(obd, fsdb, mti);
2976 CERROR("Unknown target type %#x, can't create log for "
2977 "%s\n", mti->mti_flags, mti->mti_svname);
2980 CERROR("Can't write logs for %s (%d)\n",
2981 mti->mti_svname, rc);
2985 /* Just update the params from tunefs in mgs_write_log_params */
2986 CDEBUG(D_MGS, "Update params for %s\n", mti->mti_svname);
2987 mti->mti_flags |= LDD_F_PARAM;
2990 rc = mgs_write_log_params(obd, fsdb, mti);
2993 up(&fsdb->fsdb_sem);
2998 /* verify that we can handle the old config logs */
2999 int mgs_upgrade_sv_14(struct obd_device *obd, struct mgs_target_info *mti)
3005 /* Create ost log normally, as servers register. Servers
3006 register with their old uuids (from last_rcvd), so old
3007 (MDT and client) logs should work.
3008 - new MDT won't know about old OSTs, only the ones that have
3009 registered, so we need the old MDT log to get the LOV right
3010 in order for old clients to work.
3011 - Old clients connect to the MDT, not the MGS, for their logs, and
3012 will therefore receive the old client log from the MDT /LOGS dir.
3013 - Old clients can continue to use and connect to old or new OSTs
3014 - New clients will contact the MGS for their log
3017 LCONSOLE_INFO("upgrading server %s from pre-1.6\n", mti->mti_svname);
3018 server_mti_print("upgrade", mti);
3020 rc = mgs_find_or_make_fsdb(obd, mti->mti_fsname, &fsdb);
3024 if (fsdb->fsdb_flags & FSDB_LOG_EMPTY) {
3025 LCONSOLE_ERROR_MSG(0x14a, "The old client log %s-client is "
3026 "missing. Was tunefs.lustre successful?\n",
3031 if (fsdb->fsdb_gen == 0) {
3032 /* There were no markers in the client log, meaning we have
3033 not updated the logs for this fs */
3034 CDEBUG(D_MGS, "found old, unupdated client log\n");
3037 if (mti->mti_flags & LDD_F_SV_TYPE_MDT) {
3038 if (mgs_log_is_empty(obd, mti->mti_svname)) {
3039 LCONSOLE_ERROR_MSG(0x14b, "The old MDT log %s is "
3040 "missing. Was tunefs.lustre "
3045 /* We're starting with an old uuid. Assume old name for lov
3046 as well since the lov entry already exists in the log. */
3047 CDEBUG(D_MGS, "old mds uuid %s\n", mti->mti_uuid);
3048 if (strncmp(mti->mti_uuid, fsdb->fsdb_mdtlov + 4,
3049 strlen(fsdb->fsdb_mdtlov) - 4) != 0) {
3050 CERROR("old mds uuid %s doesn't match log %s (%s)\n",
3051 mti->mti_uuid, fsdb->fsdb_mdtlov,
3052 fsdb->fsdb_mdtlov + 4);
3057 if (!(fsdb->fsdb_flags & FSDB_OLDLOG14)) {
3058 LCONSOLE_ERROR_MSG(0x14c, "%s-client is supposedly an old "
3059 "log, but no old LOV or MDT was found. "
3060 "Consider updating the configuration with"
3061 " --writeconf.\n", mti->mti_fsname);
3066 /* end COMPAT_146 */
3068 int mgs_erase_log(struct obd_device *obd, char *name)
3070 struct lvfs_run_ctxt saved;
3071 struct llog_ctxt *ctxt;
3072 struct llog_handle *llh;
3075 ctxt = llog_get_context(obd, LLOG_CONFIG_ORIG_CTXT);
3076 LASSERT(ctxt != NULL);
3078 push_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
3079 rc = llog_create(ctxt, &llh, NULL, name);
3081 llog_init_handle(llh, LLOG_F_IS_PLAIN, NULL);
3082 rc = llog_destroy(llh);
3083 llog_free_handle(llh);
3085 pop_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
3086 llog_ctxt_put(ctxt);
3089 CERROR("failed to clear log %s: %d\n", name, rc);
3094 /* erase all logs for the given fs */
3095 int mgs_erase_logs(struct obd_device *obd, char *fsname)
3097 struct mgs_obd *mgs = &obd->u.mgs;
3098 static struct fs_db *fsdb;
3099 struct list_head dentry_list;
3100 struct l_linux_dirent *dirent, *n;
3101 int rc, len = strlen(fsname);
3104 /* Find all the logs in the CONFIGS directory */
3105 rc = class_dentry_readdir(obd, mgs->mgs_configs_dir,
3106 mgs->mgs_vfsmnt, &dentry_list);
3108 CERROR("Can't read %s dir\n", MOUNT_CONFIGS_DIR);
3112 down(&mgs->mgs_sem);
3114 /* Delete the fs db */
3115 fsdb = mgs_find_fsdb(obd, fsname);
3117 mgs_free_fsdb(obd, fsdb);
3119 list_for_each_entry_safe(dirent, n, &dentry_list, lld_list) {
3120 list_del(&dirent->lld_list);
3121 if (strncmp(fsname, dirent->lld_name, len) == 0) {
3122 CDEBUG(D_MGS, "Removing log %s\n", dirent->lld_name);
3123 mgs_erase_log(obd, dirent->lld_name);
3125 OBD_FREE(dirent, sizeof(*dirent));
3133 /* from llog_swab */
3134 static void print_lustre_cfg(struct lustre_cfg *lcfg)
3139 CDEBUG(D_MGS, "lustre_cfg: %p\n", lcfg);
3140 CDEBUG(D_MGS, "\tlcfg->lcfg_version: %#x\n", lcfg->lcfg_version);
3142 CDEBUG(D_MGS, "\tlcfg->lcfg_command: %#x\n", lcfg->lcfg_command);
3143 CDEBUG(D_MGS, "\tlcfg->lcfg_num: %#x\n", lcfg->lcfg_num);
3144 CDEBUG(D_MGS, "\tlcfg->lcfg_flags: %#x\n", lcfg->lcfg_flags);
3145 CDEBUG(D_MGS, "\tlcfg->lcfg_nid: %s\n", libcfs_nid2str(lcfg->lcfg_nid));
3147 CDEBUG(D_MGS, "\tlcfg->lcfg_bufcount: %d\n", lcfg->lcfg_bufcount);
3148 if (lcfg->lcfg_bufcount < LUSTRE_CFG_MAX_BUFCOUNT)
3149 for (i = 0; i < lcfg->lcfg_bufcount; i++) {
3150 CDEBUG(D_MGS, "\tlcfg->lcfg_buflens[%d]: %d %s\n",
3151 i, lcfg->lcfg_buflens[i],
3152 lustre_cfg_string(lcfg, i));
3157 /* Set a permanent (config log) param for a target or fs */
3158 int mgs_setparam(struct obd_device *obd, struct lustre_cfg *lcfg, char *fsname)
3161 struct mgs_target_info *mti;
3162 char *devname, *param;
3168 print_lustre_cfg(lcfg);
3170 /* lustre, lustre-mdtlov, lustre-client, lustre-MDT0000 */
3171 devname = lustre_cfg_string(lcfg, 0);
3172 param = lustre_cfg_string(lcfg, 1);
3174 /* Assume device name embedded in param:
3175 lustre-OST0000.osc.max_dirty_mb=32 */
3176 ptr = strchr(param, '.');
3184 LCONSOLE_ERROR_MSG(0x14d, "No target specified: %s\n", param);
3188 /* Extract fsname */
3189 ptr = strrchr(devname, '-');
3190 memset(fsname, 0, MTI_NAME_MAXLEN);
3191 if (ptr && (server_name2index(ptr, &index, NULL) >= 0)) {
3192 strncpy(fsname, devname, ptr - devname);
3194 /* assume devname is the fsname */
3195 strncpy(fsname, devname, MTI_NAME_MAXLEN);
3197 fsname[MTI_NAME_MAXLEN - 1] = 0;
3198 CDEBUG(D_MGS, "setparam on fs %s device %s\n", fsname, devname);
3200 rc = mgs_find_or_make_fsdb(obd, fsname, &fsdb);
3203 if (fsdb->fsdb_flags & FSDB_LOG_EMPTY) {
3204 CERROR("No filesystem targets for %s. cfg_device from lctl "
3205 "is '%s'\n", fsname, devname);
3206 mgs_free_fsdb(obd, fsdb);
3210 /* Create a fake mti to hold everything */
3213 GOTO(out, rc = -ENOMEM);
3214 strncpy(mti->mti_fsname, fsname, MTI_NAME_MAXLEN);
3215 strncpy(mti->mti_svname, devname, MTI_NAME_MAXLEN);
3216 strncpy(mti->mti_params, param, sizeof(mti->mti_params));
3217 rc = server_name2index(mti->mti_svname, &mti->mti_stripe_index, &tmp);
3219 /* Not a valid server; may be only fsname */
3222 /* Strip -osc or -mdc suffix from svname */
3223 if (server_make_name(rc, mti->mti_stripe_index, mti->mti_fsname,
3225 GOTO(out, rc = -EINVAL);
3227 mti->mti_flags = rc | LDD_F_PARAM;
3229 down(&fsdb->fsdb_sem);
3230 rc = mgs_write_log_params(obd, fsdb, mti);
3231 up(&fsdb->fsdb_sem);
3239 /******************** unused *********************/
3240 static int mgs_backup_llog(struct obd_device *obd, char* fsname)
3242 struct file *filp, *bak_filp;
3243 struct lvfs_run_ctxt saved;
3244 char *logname, *buf;
3245 loff_t soff = 0 , doff = 0;
3246 int count = 4096, len;
3249 OBD_ALLOC(logname, PATH_MAX);
3250 if (logname == NULL)
3253 OBD_ALLOC(buf, count);
3255 GOTO(out , rc = -ENOMEM);
3257 len = snprintf(logname, PATH_MAX, "%s/%s.bak",
3258 MOUNT_CONFIGS_DIR, fsname);
3260 if (len >= PATH_MAX - 1) {
3261 GOTO(out, -ENAMETOOLONG);
3264 push_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
3266 bak_filp = l_filp_open(logname, O_RDWR|O_CREAT|O_TRUNC, 0660);
3267 if (IS_ERR(bak_filp)) {
3268 rc = PTR_ERR(bak_filp);
3269 CERROR("backup logfile open %s: %d\n", logname, rc);
3272 sprintf(logname, "%s/%s", MOUNT_CONFIGS_DIR, fsname);
3273 filp = l_filp_open(logname, O_RDONLY, 0);
3276 CERROR("logfile open %s: %d\n", logname, rc);
3280 while ((rc = lustre_fread(filp, buf, count, &soff)) > 0) {
3281 rc = lustre_fwrite(bak_filp, buf, count, &doff);
3285 filp_close(filp, 0);
3287 filp_close(bak_filp, 0);
3289 pop_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
3292 OBD_FREE(buf, count);
3293 OBD_FREE(logname, PATH_MAX);