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
20 * http://www.sun.com/software/products/lustre/docs/GPLv2.pdf
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_PTR(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_PTR(lmvdesc);
1253 /* lov is the first thing in the mdt and client logs */
1254 static int mgs_write_log_lov(struct obd_device *obd, struct fs_db *fsdb,
1255 struct mgs_target_info *mti,
1256 char *logname, char *lovname)
1258 struct llog_handle *llh = NULL;
1259 struct lov_desc *lovdesc;
1264 CDEBUG(D_MGS, "Writing lov(%s) log for %s\n", lovname, logname);
1267 #01 L attach 0:lov_mdsA 1:lov 2:71ccb_lov_mdsA_19f961a9e1
1268 #02 L lov_setup 0:lov_mdsA 1:(struct lov_desc)
1269 uuid=lov1_UUID, stripe count=1, size=1048576, offset=0, pattern=0
1272 /* FIXME just make lov_setup accept empty desc (put uuid in buf 2) */
1273 OBD_ALLOC_PTR(lovdesc);
1274 if (lovdesc == NULL)
1276 lovdesc->ld_magic = LOV_DESC_MAGIC;
1277 lovdesc->ld_tgt_count = 0;
1278 /* Defaults. Can be changed later by lcfg config_param */
1279 lovdesc->ld_default_stripe_count = 1;
1280 lovdesc->ld_pattern = LOV_PATTERN_RAID0;
1281 lovdesc->ld_default_stripe_size = 1024 * 1024;
1282 lovdesc->ld_default_stripe_offset = 0;
1283 lovdesc->ld_qos_maxage = QOS_DEFAULT_MAXAGE;
1284 sprintf((char*)lovdesc->ld_uuid.uuid, "%s_UUID", lovname);
1285 /* can these be the same? */
1286 uuid = (char *)lovdesc->ld_uuid.uuid;
1288 /* This should always be the first entry in a log.
1289 rc = mgs_clear_log(obd, logname); */
1290 rc = record_start_log(obd, &llh, logname);
1293 /* FIXME these should be a single journal transaction */
1294 rc = record_marker(obd, llh, fsdb, CM_START, lovname, "lov setup");
1295 rc = record_attach(obd, llh, lovname, "lov", uuid);
1296 rc = record_lov_setup(obd, llh, lovname, lovdesc);
1297 rc = record_marker(obd, llh, fsdb, CM_END, lovname, "lov setup");
1298 rc = record_end_log(obd, &llh);
1302 OBD_FREE_PTR(lovdesc);
1306 /* add failnids to open log */
1307 static int mgs_write_log_failnids(struct obd_device *obd,
1308 struct mgs_target_info *mti,
1309 struct llog_handle *llh,
1312 char *failnodeuuid = NULL;
1313 char *ptr = mti->mti_params;
1318 #03 L add_uuid nid=uml1@tcp(0x20000c0a80201) nal=90 0: 1:uml1_UUID
1319 #04 L add_uuid nid=1@elan(0x1000000000001) nal=90 0: 1:uml1_UUID
1320 #05 L setup 0:OSC_uml1_ost1_mdsA 1:ost1_UUID 2:uml1_UUID
1321 #06 L add_uuid nid=uml2@tcp(0x20000c0a80202) nal=90 0: 1:uml2_UUID
1322 #0x L add_uuid nid=2@elan(0x1000000000002) nal=90 0: 1:uml2_UUID
1323 #07 L add_conn 0:OSC_uml1_ost1_mdsA 1:uml2_UUID
1326 /* Pull failnid info out of params string */
1327 while (class_find_param(ptr, PARAM_FAILNODE, &ptr) == 0) {
1328 while (class_parse_nid(ptr, &nid, &ptr) == 0) {
1329 if (failnodeuuid == NULL) {
1330 /* We don't know the failover node name,
1331 so just use the first nid as the uuid */
1332 rc = name_create(&failnodeuuid,
1333 libcfs_nid2str(nid), "");
1337 CDEBUG(D_MGS, "add nid %s for failover uuid %s, "
1338 "client %s\n", libcfs_nid2str(nid),
1339 failnodeuuid, cliname);
1340 rc = record_add_uuid(obd, llh, nid, failnodeuuid);
1343 rc = record_add_conn(obd, llh, cliname, failnodeuuid);
1344 name_destroy(&failnodeuuid);
1345 failnodeuuid = NULL;
1352 static int mgs_write_log_mdc_to_lmv(struct obd_device *obd, struct fs_db *fsdb,
1353 struct mgs_target_info *mti,
1354 char *logname, char *lmvname)
1356 struct llog_handle *llh = NULL;
1357 struct sptlrpc_conf_log *srpc_log;
1358 char *mdcname, *nodeuuid, *mdcuuid, *lmvuuid;
1363 if (mgs_log_is_empty(obd, logname)) {
1364 CERROR("log is empty! Logical error\n");
1368 CDEBUG(D_MGS, "adding mdc for %s to log %s:lmv(%s)\n",
1369 mti->mti_svname, logname, lmvname);
1371 srpc_log = sptlrpc_conf_log_alloc();
1372 if (IS_ERR(srpc_log))
1373 RETURN(PTR_ERR(srpc_log));
1374 srpc_log->scl_part = LUSTRE_SP_CLI;
1376 rc = mgs_get_srpc_conf_log(fsdb, mti->mti_svname,
1377 LUSTRE_SP_CLI, LUSTRE_SP_MDT, srpc_log);
1381 name_create(&nodeuuid, libcfs_nid2str(mti->mti_nids[0]), "");
1382 name_create(&mdcname, mti->mti_svname, "-mdc");
1383 name_create(&mdcuuid, mdcname, "_UUID");
1384 name_create(&lmvuuid, lmvname, "_UUID");
1386 rc = record_start_log(obd, &llh, logname);
1387 rc = record_marker(obd, llh, fsdb, CM_START, mti->mti_svname,
1390 for (i = 0; i < mti->mti_nid_count; i++) {
1391 CDEBUG(D_MGS, "add nid %s for mdt\n",
1392 libcfs_nid2str(mti->mti_nids[i]));
1394 rc = record_add_uuid(obd, llh, mti->mti_nids[i], nodeuuid);
1397 rc = record_attach(obd, llh, mdcname, LUSTRE_MDC_NAME, lmvuuid);
1398 rc = record_setup(obd, llh, mdcname, mti->mti_uuid, nodeuuid, 0, 0);
1399 rc = record_sptlrpc_conf(obd, llh, mdcname, srpc_log);
1400 rc = mgs_write_log_failnids(obd, mti, llh, mdcname);
1401 snprintf(index, sizeof(index), "%d", mti->mti_stripe_index);
1402 rc = record_mdc_add(obd, llh, lmvname, mdcuuid, mti->mti_uuid,
1404 rc = record_marker(obd, llh, fsdb, CM_END, mti->mti_svname,
1406 rc = record_end_log(obd, &llh);
1408 name_destroy(&lmvuuid);
1409 name_destroy(&mdcuuid);
1410 name_destroy(&mdcname);
1411 name_destroy(&nodeuuid);
1413 sptlrpc_conf_log_free(srpc_log);
1417 /* add new mdc to already existent MDS */
1418 static int mgs_write_log_mdc_to_mdt(struct obd_device *obd, struct fs_db *fsdb,
1419 struct mgs_target_info *mti, char *logname)
1421 struct llog_handle *llh = NULL;
1422 struct sptlrpc_conf_log *srpc_log;
1423 char *nodeuuid, *mdcname, *mdcuuid, *mdtuuid;
1424 int idx = mti->mti_stripe_index;
1429 if (mgs_log_is_empty(obd, mti->mti_svname)) {
1430 CERROR("log is empty! Logical error\n");
1434 CDEBUG(D_MGS, "adding mdc index %d to %s\n", idx, logname);
1436 srpc_log = sptlrpc_conf_log_alloc();
1437 if (IS_ERR(srpc_log))
1438 RETURN(PTR_ERR(srpc_log));
1439 srpc_log->scl_part = LUSTRE_SP_MDT;
1441 rc = mgs_get_srpc_conf_log(fsdb, mti->mti_svname,
1442 LUSTRE_SP_MDT, LUSTRE_SP_MDT, srpc_log);
1446 name_create(&nodeuuid, libcfs_nid2str(mti->mti_nids[0]), "");
1447 snprintf(index, sizeof(index), "-mdc%04x", idx);
1448 name_create(&mdcname, logname, index);
1449 name_create(&mdcuuid, mdcname, "_UUID");
1450 name_create(&mdtuuid, logname, "_UUID");
1452 rc = record_start_log(obd, &llh, logname);
1453 rc = record_marker(obd, llh, fsdb, CM_START, mti->mti_svname, "add mdc");
1454 for (i = 0; i < mti->mti_nid_count; i++) {
1455 CDEBUG(D_MGS, "add nid %s for mdt\n",
1456 libcfs_nid2str(mti->mti_nids[i]));
1457 rc = record_add_uuid(obd, llh, mti->mti_nids[i], nodeuuid);
1459 rc = record_attach(obd, llh, mdcname, LUSTRE_MDC_NAME, mdcuuid);
1460 rc = record_setup(obd, llh, mdcname, mti->mti_uuid, nodeuuid, 0, 0);
1461 rc = record_sptlrpc_conf(obd, llh, mdcname, srpc_log);
1462 rc = mgs_write_log_failnids(obd, mti, llh, mdcname);
1463 snprintf(index, sizeof(index), "%d", idx);
1465 rc = record_mdc_add(obd, llh, logname, mdcuuid, mti->mti_uuid,
1467 rc = record_marker(obd, llh, fsdb, CM_END, mti->mti_svname, "add mdc");
1468 rc = record_end_log(obd, &llh);
1470 name_destroy(&mdcuuid);
1471 name_destroy(&mdcname);
1472 name_destroy(&nodeuuid);
1473 name_destroy(&mdtuuid);
1475 sptlrpc_conf_log_free(srpc_log);
1479 static int mgs_write_log_mdt0(struct obd_device *obd, struct fs_db *fsdb,
1480 struct mgs_target_info *mti)
1482 char *log = mti->mti_svname;
1483 struct llog_handle *llh = NULL;
1484 char *uuid, *lovname;
1486 struct sptlrpc_conf_log *srpc_log;
1487 char *ptr = mti->mti_params;
1488 int rc = 0, failout = 0;
1491 srpc_log = sptlrpc_conf_log_alloc();
1492 if (IS_ERR(srpc_log))
1493 RETURN(PTR_ERR(srpc_log));
1494 srpc_log->scl_part = LUSTRE_SP_MDT;
1496 rc = mgs_get_srpc_conf_log(fsdb, mti->mti_svname,
1497 LUSTRE_SP_ANY, LUSTRE_SP_MDT, srpc_log);
1501 OBD_ALLOC(uuid, sizeof(struct obd_uuid));
1503 GOTO(out_srpc, rc = -ENOMEM);
1505 if (class_find_param(ptr, PARAM_FAILMODE, &ptr) == 0)
1506 failout = (strncmp(ptr, "failout", 7) == 0);
1508 name_create(&lovname, log, "-mdtlov");
1509 if (mgs_log_is_empty(obd, log))
1510 rc = mgs_write_log_lov(obd, fsdb, mti, log, lovname);
1512 sprintf(uuid, "%s_UUID", log);
1513 sprintf(mdt_index,"%d",mti->mti_stripe_index);
1515 /* add MDT itself */
1516 rc = record_start_log(obd, &llh, log);
1520 /* FIXME this whole fn should be a single journal transaction */
1521 rc = record_marker(obd, llh, fsdb, CM_START, log, "add mdt");
1522 rc = record_attach(obd, llh, log, LUSTRE_MDT_NAME, uuid);
1523 rc = record_mount_opt(obd, llh, log, lovname, NULL);
1524 rc = record_setup(obd, llh, log, uuid, mdt_index, lovname,
1525 failout ? "n" : "f");
1526 rc = record_sptlrpc_conf(obd, llh, log, srpc_log);
1527 rc = record_marker(obd, llh, fsdb, CM_END, log, "add mdt");
1528 rc = record_end_log(obd, &llh);
1530 name_destroy(&lovname);
1531 OBD_FREE(uuid, sizeof(struct obd_uuid));
1533 sptlrpc_conf_log_free(srpc_log);
1537 /* envelope method for all layers log */
1538 static int mgs_write_log_mdt(struct obd_device *obd, struct fs_db *fsdb,
1539 struct mgs_target_info *mti)
1541 struct llog_handle *llh = NULL;
1543 struct temp_comp comp = { 0 };
1548 CDEBUG(D_MGS, "writing new mdt %s\n", mti->mti_svname);
1552 if (mti->mti_flags & LDD_F_UPGRADE14) {
1553 /* We're starting with an old uuid. Assume old name for lov
1554 as well since the lov entry already exists in the log. */
1555 CDEBUG(D_MGS, "old mds uuid %s\n", mti->mti_uuid);
1556 if (strncmp(mti->mti_uuid, fsdb->fsdb_mdtlov + 4,
1557 strlen(fsdb->fsdb_mdtlov) - 4) != 0) {
1558 CERROR("old mds uuid %s doesn't match log %s (%s)\n",
1559 mti->mti_uuid, fsdb->fsdb_mdtlov,
1560 fsdb->fsdb_mdtlov + 4);
1564 /* end COMPAT_146 */
1566 if (mti->mti_uuid[0] == '\0') {
1567 /* Make up our own uuid */
1568 snprintf(mti->mti_uuid, sizeof(mti->mti_uuid),
1569 "%s_UUID", mti->mti_svname);
1573 rc = mgs_write_log_mdt0(obd, fsdb, mti);
1575 /* Append the mdt info to the client log */
1576 name_create(&cliname, mti->mti_fsname, "-client");
1578 if (mgs_log_is_empty(obd, cliname)) {
1579 /* Start client log */
1580 rc = mgs_write_log_lov(obd, fsdb, mti, cliname,
1582 rc = mgs_write_log_lmv(obd, fsdb, mti, cliname,
1587 #09 L add_uuid nid=uml1@tcp(0x20000c0a80201) 0: 1:uml1_UUID
1588 #10 L attach 0:MDC_uml1_mdsA_MNT_client 1:mdc 2:1d834_MNT_client_03f
1589 #11 L setup 0:MDC_uml1_mdsA_MNT_client 1:mdsA_UUID 2:uml1_UUID
1590 #12 L add_uuid nid=uml2@tcp(0x20000c0a80202) 0: 1:uml2_UUID
1591 #13 L add_conn 0:MDC_uml1_mdsA_MNT_client 1:uml2_UUID
1592 #14 L mount_option 0: 1:client 2:lov1 3:MDC_uml1_mdsA_MNT_client
1597 if (mti->mti_flags & LDD_F_UPGRADE14) {
1598 rc = record_start_log(obd, &llh, cliname);
1602 rc = record_marker(obd, llh, fsdb, CM_START,
1603 mti->mti_svname,"add mdc");
1605 /* Old client log already has MDC entry, but needs mount opt
1606 for new client name (lustre-client) */
1607 /* FIXME Old MDT log already has an old mount opt
1608 which we should remove (currently handled by
1609 class_del_profiles()) */
1610 rc = record_mount_opt(obd, llh, cliname, fsdb->fsdb_clilov,
1612 /* end COMPAT_146 */
1614 rc = record_marker(obd, llh, fsdb, CM_END,
1615 mti->mti_svname, "add mdc");
1619 /* copy client info about lov/lmv */
1620 comp.comp_mti = mti;
1621 comp.comp_fsdb = fsdb;
1623 rc = mgs_steal_llog_for_mdt_from_client(obd, cliname,
1626 rc = mgs_write_log_mdc_to_lmv(obd, fsdb, mti, cliname,
1629 rc = record_start_log(obd, &llh, cliname);
1633 rc = record_marker(obd, llh, fsdb, CM_START, cliname,
1635 rc = record_mount_opt(obd, llh, cliname, fsdb->fsdb_clilov,
1637 rc = record_marker(obd, llh, fsdb, CM_END, cliname,
1641 rc = record_end_log(obd, &llh);
1643 name_destroy(&cliname);
1645 // for_all_existing_mdt except current one
1646 for (i = 0; i < INDEX_MAP_SIZE * 8; i++){
1648 if (i != mti->mti_stripe_index &&
1649 test_bit(i, fsdb->fsdb_mdt_index_map)) {
1650 sprintf(mdt_index,"-MDT%04x",i);
1652 name_create(&mdtname, mti->mti_fsname, mdt_index);
1653 rc = mgs_write_log_mdc_to_mdt(obd, fsdb, mti, mdtname);
1654 name_destroy(&mdtname);
1661 /* Add the ost info to the client/mdt lov */
1662 static int mgs_write_log_osc_to_lov(struct obd_device *obd, struct fs_db *fsdb,
1663 struct mgs_target_info *mti,
1664 char *logname, char *suffix, char *lovname,
1665 enum lustre_sec_part sec_part, int flags)
1667 struct llog_handle *llh = NULL;
1668 struct sptlrpc_conf_log *srpc_log;
1669 char *nodeuuid, *oscname, *oscuuid, *lovuuid, *svname;
1674 CDEBUG(D_INFO, "adding osc for %s to log %s\n",
1675 mti->mti_svname, logname);
1677 srpc_log = sptlrpc_conf_log_alloc();
1678 if (IS_ERR(srpc_log))
1679 RETURN(PTR_ERR(srpc_log));
1680 srpc_log->scl_part = sec_part;
1682 rc = mgs_get_srpc_conf_log(fsdb, mti->mti_svname,
1683 sec_part, LUSTRE_SP_OST, srpc_log);
1687 if (mgs_log_is_empty(obd, logname)) {
1688 /* The first item in the log must be the lov, so we have
1689 somewhere to add our osc. */
1690 rc = mgs_write_log_lov(obd, fsdb, mti, logname, lovname);
1693 name_create(&nodeuuid, libcfs_nid2str(mti->mti_nids[0]), "");
1694 name_create(&svname, mti->mti_svname, "-osc");
1695 name_create(&oscname, svname, suffix);
1696 name_create(&oscuuid, oscname, "_UUID");
1697 name_create(&lovuuid, lovname, "_UUID");
1700 #03 L add_uuid nid=uml1@tcp(0x20000c0a80201) 0: 1:uml1_UUID
1702 #04 L add_uuid nid=1@elan(0x1000000000001) nal=90 0: 1:uml1_UUID
1703 #04 L attach 0:OSC_uml1_ost1_MNT_client 1:osc 2:89070_lov1_a41dff51a
1704 #05 L setup 0:OSC_uml1_ost1_MNT_client 1:ost1_UUID 2:uml1_UUID
1706 #06 L add_uuid nid=uml2@tcp(0x20000c0a80202) 0: 1:uml2_UUID
1707 #07 L add_conn 0:OSC_uml1_ost1_MNT_client 1:uml2_UUID
1708 #08 L lov_modify_tgts add 0:lov1 1:ost1_UUID 2(index):0 3(gen):1
1711 rc = record_start_log(obd, &llh, logname);
1714 /* FIXME these should be a single journal transaction */
1715 rc = record_marker(obd, llh, fsdb, CM_START | flags, mti->mti_svname,
1717 for (i = 0; i < mti->mti_nid_count; i++) {
1718 CDEBUG(D_MGS, "add nid %s\n", libcfs_nid2str(mti->mti_nids[i]));
1719 rc = record_add_uuid(obd, llh, mti->mti_nids[i], nodeuuid);
1721 rc = record_attach(obd, llh, oscname, LUSTRE_OSC_NAME, lovuuid);
1722 rc = record_setup(obd, llh, oscname, mti->mti_uuid, nodeuuid, 0, 0);
1723 rc = record_sptlrpc_conf(obd, llh, oscname, srpc_log);
1724 rc = mgs_write_log_failnids(obd, mti, llh, oscname);
1725 snprintf(index, sizeof(index), "%d", mti->mti_stripe_index);
1726 rc = record_lov_add(obd, llh, lovname, mti->mti_uuid, index, "1");
1727 rc = record_marker(obd, llh, fsdb, CM_END | flags, mti->mti_svname,
1729 rc = record_end_log(obd, &llh);
1731 name_destroy(&lovuuid);
1732 name_destroy(&oscuuid);
1733 name_destroy(&oscname);
1734 name_destroy(&svname);
1735 name_destroy(&nodeuuid);
1737 sptlrpc_conf_log_free(srpc_log);
1741 static int mgs_write_log_ost(struct obd_device *obd, struct fs_db *fsdb,
1742 struct mgs_target_info *mti)
1744 struct llog_handle *llh = NULL;
1745 struct sptlrpc_conf_log *srpc_log;
1746 char *logname, *lovname;
1748 char *ptr = mti->mti_params;
1749 int rc, flags = 0, failout = 0, i;
1752 CDEBUG(D_MGS, "writing new ost %s\n", mti->mti_svname);
1754 /* The ost startup log */
1756 /* If the ost log already exists, that means that someone reformatted
1757 the ost and it called target_add again. */
1758 if (!mgs_log_is_empty(obd, mti->mti_svname)) {
1759 LCONSOLE_ERROR_MSG(0x141, "The config log for %s already "
1760 "exists, yet the server claims it never "
1761 "registered. It may have been reformatted, "
1762 "or the index changed. writeconf the MDT to "
1763 "regenerate all logs.\n", mti->mti_svname);
1767 srpc_log = sptlrpc_conf_log_alloc();
1768 if (IS_ERR(srpc_log))
1769 RETURN(PTR_ERR(srpc_log));
1770 srpc_log->scl_part = LUSTRE_SP_OST;
1772 rc = mgs_get_srpc_conf_log(fsdb, mti->mti_svname,
1773 LUSTRE_SP_ANY, LUSTRE_SP_OST, srpc_log);
1778 attach obdfilter ost1 ost1_UUID
1779 setup /dev/loop2 ldiskfs f|n errors=remount-ro,user_xattr
1781 if (class_find_param(ptr, PARAM_FAILMODE, &ptr) == 0)
1782 failout = (strncmp(ptr, "failout", 7) == 0);
1783 rc = record_start_log(obd, &llh, mti->mti_svname);
1786 /* FIXME these should be a single journal transaction */
1787 rc = record_marker(obd, llh, fsdb, CM_START, mti->mti_svname,"add ost");
1788 if (*mti->mti_uuid == '\0')
1789 snprintf(mti->mti_uuid, sizeof(mti->mti_uuid),
1790 "%s_UUID", mti->mti_svname);
1791 rc = record_attach(obd, llh, mti->mti_svname,
1792 "obdfilter"/*LUSTRE_OST_NAME*/, mti->mti_uuid);
1793 rc = record_setup(obd, llh, mti->mti_svname,
1794 "dev"/*ignored*/, "type"/*ignored*/,
1795 failout ? "n" : "f", 0/*options*/);
1796 rc = record_sptlrpc_conf(obd, llh, mti->mti_svname, srpc_log);
1797 rc = record_marker(obd, llh, fsdb, CM_END, mti->mti_svname, "add ost");
1798 rc = record_end_log(obd, &llh);
1800 /* We also have to update the other logs where this osc is part of
1803 if (fsdb->fsdb_flags & FSDB_OLDLOG14) {
1804 /* If we're upgrading, the old mdt log already has our
1805 entry. Let's do a fake one for fun. */
1806 /* Note that we can't add any new failnids, since we don't
1807 know the old osc names. */
1808 flags = CM_SKIP | CM_UPGRADE146;
1810 } else if ((mti->mti_flags & LDD_F_UPDATE) != LDD_F_UPDATE) {
1811 /* If the update flag isn't set, don't update client/mdt
1814 LCONSOLE_WARN("Client log for %s was not updated; writeconf "
1815 "the MDT first to regenerate it.\n",
1819 // for_all_existing_mdt
1820 for (i = 0; i < INDEX_MAP_SIZE * 8; i++){
1821 if (test_bit(i, fsdb->fsdb_mdt_index_map)) {
1822 sprintf(mdt_index,"-MDT%04x",i);
1823 name_create(&logname, mti->mti_fsname, mdt_index);
1824 name_create(&lovname, logname, "-mdtlov");
1825 mgs_write_log_osc_to_lov(obd, fsdb, mti, logname,
1827 LUSTRE_SP_MDT, flags);
1828 name_destroy(&logname);
1829 name_destroy(&lovname);
1833 /* Append ost info to the client log */
1834 name_create(&logname, mti->mti_fsname, "-client");
1835 mgs_write_log_osc_to_lov(obd, fsdb, mti, logname, "",
1836 fsdb->fsdb_clilov, LUSTRE_SP_CLI, 0);
1837 name_destroy(&logname);
1839 sptlrpc_conf_log_free(srpc_log);
1843 /* Add additional failnids to an existing log.
1844 The mdc/osc must have been added to logs first */
1845 /* tcp nids must be in dotted-quad ascii -
1846 we can't resolve hostnames from the kernel. */
1847 static int mgs_write_log_add_failnid(struct obd_device *obd, struct fs_db *fsdb,
1848 struct mgs_target_info *mti)
1850 char *logname, *cliname;
1851 struct llog_handle *llh = NULL;
1855 /* FIXME how do we delete a failnid? Currently --writeconf is the
1856 only way. Maybe make --erase-params pass a flag to really
1857 erase all params from logs - except it can't erase the failnids
1858 given when a target first registers, since they aren't processed
1861 /* Verify that we know about this target */
1862 if (mgs_log_is_empty(obd, mti->mti_svname)) {
1863 LCONSOLE_ERROR_MSG(0x142, "The target %s has not registered "
1864 "yet. It must be started before failnids "
1865 "can be added.\n", mti->mti_svname);
1869 /* Create mdc/osc client name (e.g. lustre-OST0001-osc) */
1870 if (mti->mti_flags & LDD_F_SV_TYPE_MDT) {
1871 name_create(&cliname, mti->mti_svname, "-mdc");
1872 } else if (mti->mti_flags & LDD_F_SV_TYPE_OST) {
1873 name_create(&cliname, mti->mti_svname, "-osc");
1878 /* Add failover nids to client log */
1879 name_create(&logname, mti->mti_fsname, "-client");
1880 rc = record_start_log(obd, &llh, logname);
1882 /* FIXME this fn should be a single journal transaction */
1883 rc = record_marker(obd, llh, fsdb, CM_START, mti->mti_svname,
1885 rc = mgs_write_log_failnids(obd, mti, llh, cliname);
1886 rc = record_marker(obd, llh, fsdb, CM_END, mti->mti_svname,
1888 rc = record_end_log(obd, &llh);
1890 name_destroy(&logname);
1892 if (mti->mti_flags & LDD_F_SV_TYPE_OST) {
1893 /* Add OST failover nids to the MDT log as well */
1894 name_create(&logname, mti->mti_fsname, "-MDT0000");
1895 rc = record_start_log(obd, &llh, logname);
1897 rc = record_marker(obd, llh, fsdb, CM_START,
1898 mti->mti_svname, "add failnid");
1899 rc = mgs_write_log_failnids(obd, mti, llh, cliname);
1900 rc = record_marker(obd, llh, fsdb, CM_END,
1901 mti->mti_svname, "add failnid");
1902 rc = record_end_log(obd, &llh);
1904 name_destroy(&logname);
1907 name_destroy(&cliname);
1911 static int mgs_wlp_lcfg(struct obd_device *obd, struct fs_db *fsdb,
1912 struct mgs_target_info *mti,
1913 char *logname, struct lustre_cfg_bufs *bufs,
1914 char *tgtname, char *ptr)
1916 char comment[MTI_NAME_MAXLEN];
1918 struct lustre_cfg *lcfg;
1921 /* Erase any old settings of this same parameter */
1922 memcpy(comment, ptr, MTI_NAME_MAXLEN);
1923 comment[MTI_NAME_MAXLEN - 1] = 0;
1924 /* But don't try to match the value. */
1925 if ((tmp = strchr(comment, '=')))
1927 /* FIXME we should skip settings that are the same as old values */
1928 rc = mgs_modify(obd, fsdb, mti, logname, tgtname, comment, CM_SKIP);
1929 LCONSOLE_INFO("%sing parameter %s.%s in log %s\n", rc ?
1930 "Sett" : "Modify", tgtname, comment, logname);
1932 lustre_cfg_bufs_reset(bufs, tgtname);
1933 lustre_cfg_bufs_set_string(bufs, 1, ptr);
1934 lcfg = lustre_cfg_new(LCFG_PARAM, bufs);
1937 rc = mgs_write_log_direct(obd, fsdb, logname, lcfg, tgtname, comment);
1938 lustre_cfg_free(lcfg);
1943 * populate rules which applied to a target device
1945 static int mgs_get_srpc_conf_log(struct fs_db *fsdb, const char *tgt,
1946 enum lustre_sec_part from,
1947 enum lustre_sec_part to,
1948 struct sptlrpc_conf_log *log)
1950 struct mgs_tgt_srpc_conf *tgtconf;
1951 struct sptlrpc_rule_set *tgt_rset;
1952 int found_tgt = 0, rc;
1954 for (tgtconf = fsdb->fsdb_srpc_tgt; tgtconf;
1955 tgtconf = tgtconf->mtsc_next) {
1956 if (!strcmp(tgt, tgtconf->mtsc_tgt)) {
1963 tgt_rset = &tgtconf->mtsc_rset;
1967 rc = sptlrpc_conf_log_populate(&fsdb->fsdb_srpc_gen, tgt_rset,
1968 from, to, fsdb->fsdb_srpc_fl_udesc, log);
1970 CERROR("failed to populate srpc log for %s: %d\n", tgt, rc);
1975 struct mgs_msl_data {
1976 struct obd_device *mmd_obd;
1977 struct fs_db *mmd_fsdb;
1978 struct mgs_target_info *mmd_mti;
1982 enum lustre_sec_part mmd_tgtpart;
1983 char mmd_tgtname[MTI_NAME_MAXLEN];
1986 static void mgs_msl_data_cleanup(struct mgs_msl_data *mmd)
1988 mmd->mmd_attached = 0;
1989 mmd->mmd_tgtname[0] = '\0';
1992 static int mgs_msl_tgt_uuid2name(char *tgtname, char *tgtuuid)
1996 if (tgtuuid == NULL) {
1997 CERROR("missing target UUID???\n");
2001 ptr = strstr(tgtuuid, "_UUID");
2003 CERROR("unrecognized UUID: %s\n", tgtuuid);
2008 strncpy(tgtname, tgtuuid, MTI_NAME_MAXLEN);
2009 tgtname[MTI_NAME_MAXLEN - 1] = '\0';
2014 static int mgs_modify_srpc_log_handler(struct llog_handle *llh,
2015 struct llog_rec_hdr *rec,
2018 struct mgs_msl_data *mmd = (struct mgs_msl_data *)data;
2019 struct cfg_marker *marker;
2020 struct lustre_cfg *lcfg = (struct lustre_cfg *)(rec + 1);
2024 if (rec->lrh_type != OBD_CFG_REC) {
2025 CERROR("unhandled lrh_type: %#x\n", rec->lrh_type);
2029 cfg_len = rec->lrh_len - sizeof(struct llog_rec_hdr) -
2030 sizeof(struct llog_rec_tail);
2032 rc = lustre_cfg_sanity_check(lcfg, cfg_len);
2034 CERROR("Insane cfg\n");
2038 if (lcfg->lcfg_command == LCFG_MARKER) {
2039 marker = lustre_cfg_buf(lcfg, 1);
2041 if (marker->cm_flags & CM_START &&
2042 marker->cm_flags & CM_SKIP)
2044 if (marker->cm_flags & CM_END)
2053 switch (lcfg->lcfg_command) {
2055 mmd->mmd_attached = 1;
2057 if (!strcmp(lustre_cfg_string(lcfg, 1), LUSTRE_OST_NAME)) {
2058 mmd->mmd_server = 1;
2059 mmd->mmd_tgtpart = LUSTRE_SP_OST;
2060 } else if (!strcmp(lustre_cfg_string(lcfg, 1),
2062 mmd->mmd_server = 1;
2063 mmd->mmd_tgtpart = LUSTRE_SP_MDT;
2064 } else if (!strcmp(lustre_cfg_string(lcfg, 1),
2066 mmd->mmd_server = 0;
2067 mmd->mmd_tgtpart = LUSTRE_SP_OST;
2068 } else if (!strcmp(lustre_cfg_string(lcfg, 1),
2070 mmd->mmd_server = 0;
2071 mmd->mmd_tgtpart = LUSTRE_SP_MDT;
2073 mmd->mmd_attached = 0;
2076 if (mmd->mmd_attached && mmd->mmd_server) {
2077 rc = mgs_msl_tgt_uuid2name(mmd->mmd_tgtname,
2078 lustre_cfg_string(lcfg, 2));
2080 mgs_msl_data_cleanup(mmd);
2087 if (!mmd->mmd_attached)
2090 /* already got tgtname at LCFG_ATTACH */
2091 if (mmd->mmd_server)
2094 rc = mgs_msl_tgt_uuid2name(mmd->mmd_tgtname,
2095 lustre_cfg_string(lcfg, 1));
2097 mgs_msl_data_cleanup(mmd);
2102 case LCFG_SPTLRPC_CONF: {
2103 struct sptlrpc_conf_log *log;
2104 enum lustre_sec_part from;
2106 if (!mmd->mmd_attached)
2109 log = sptlrpc_conf_log_extract(lcfg);
2111 CERROR("missing sptlrpc config log???\n");
2112 mgs_msl_data_cleanup(mmd);
2116 if (mmd->mmd_server)
2117 from = LUSTRE_SP_ANY;
2119 from = log->scl_part;
2121 /* cleanup the old log */
2122 sptlrpc_conf_log_cleanup(log);
2124 /* populate new log */
2125 rc = mgs_get_srpc_conf_log(mmd->mmd_fsdb, mmd->mmd_tgtname,
2126 from, mmd->mmd_tgtpart, log);
2128 mgs_msl_data_cleanup(mmd);
2132 /* Overwrite the log */
2133 rec->lrh_len = cfg_len;
2134 rc = llog_write_rec(llh, rec, NULL, 0, (void *)lcfg,
2137 CERROR("overwrite sptlrpc conf log failed: %d\n", rc);
2139 /* append new one */
2140 rc = record_marker(mmd->mmd_obd, llh, mmd->mmd_fsdb, CM_START,
2141 mmd->mmd_mti->mti_svname, "sptlrpc config");
2142 rc = record_sptlrpc_conf(mmd->mmd_obd, llh,
2143 lustre_cfg_string(lcfg, 0), log);
2144 rc = record_marker(mmd->mmd_obd, llh, mmd->mmd_fsdb, CM_END,
2145 mmd->mmd_mti->mti_svname, "sptlrpc config");
2147 mgs_msl_data_cleanup(mmd);
2151 /* ignore all others */
2158 static int mgs_modify_srpc_log(struct obd_device *obd,
2160 struct mgs_target_info *mti,
2163 struct llog_handle *llh;
2164 struct lvfs_run_ctxt saved;
2165 struct llog_ctxt *ctxt;
2166 struct mgs_msl_data *mmd;
2170 CDEBUG(D_MGS, "modify sptlrpc log for %s\n", logname);
2172 push_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
2174 ctxt = llog_get_context(obd, LLOG_CONFIG_ORIG_CTXT);
2175 LASSERT(ctxt != NULL);
2176 rc = llog_create(ctxt, &llh, NULL, logname);
2180 rc = llog_init_handle(llh, LLOG_F_IS_PLAIN, NULL);
2182 GOTO(out_close, rc);
2184 if (llog_get_size(llh) <= 1)
2185 GOTO(out_close, rc = 0);
2189 GOTO(out_close, rc = -ENOMEM);
2192 mmd->mmd_fsdb = fsdb;
2195 rc = llog_process(llh, mgs_modify_srpc_log_handler, (void *) mmd, NULL);
2200 rc2 = llog_close(llh);
2205 pop_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
2206 llog_ctxt_put(ctxt);
2209 CERROR("modify sptlrpc log %s failed %d\n", logname, rc);
2214 * for each of log, remove old conf at first
2216 static int mgs_modify_srpc_log_all(struct obd_device *obd,
2218 struct mgs_target_info *mti)
2225 for (i = 0; i < INDEX_MAP_SIZE * 8; i++){
2226 if (test_bit(i, fsdb->fsdb_mdt_index_map)) {
2227 sprintf(tgt_index,"-MDT%04x",i);
2229 name_create(&logname, mti->mti_fsname, tgt_index);
2230 rc2 = mgs_modify(obd, fsdb, mti, logname,
2231 mti->mti_fsname, "sptlrpc config",
2233 rc2 = mgs_modify_srpc_log(obd, fsdb, mti, logname);
2234 name_destroy(&logname);
2241 for (i = 0; i < INDEX_MAP_SIZE * 8; i++){
2242 if (test_bit(i, fsdb->fsdb_ost_index_map)) {
2243 sprintf(tgt_index,"-OST%04x",i);
2245 name_create(&logname, mti->mti_fsname, tgt_index);
2246 rc2 = mgs_modify(obd, fsdb, mti, logname,
2247 mti->mti_fsname, "sptlrpc config",
2249 rc2 = mgs_modify_srpc_log(obd, fsdb, mti, logname);
2250 name_destroy(&logname);
2257 name_create(&logname, mti->mti_fsname, "-client");
2258 rc2 = mgs_modify(obd, fsdb, mti, logname,
2259 mti->mti_fsname, "sptlrpc config", CM_SKIP);
2260 rc2 = mgs_modify_srpc_log(obd, fsdb, mti, logname);
2261 name_destroy(&logname);
2269 static int mgs_srpc_set_param_disk(struct obd_device *obd,
2271 struct mgs_target_info *mti,
2274 struct llog_handle *llh = NULL;
2276 char *comment, *ptr;
2277 struct lustre_cfg_bufs bufs;
2278 struct lustre_cfg *lcfg;
2283 ptr = strchr(param, '=');
2287 OBD_ALLOC(comment, len + 1);
2288 if (comment == NULL)
2290 strncpy(comment, param, len);
2291 comment[len] = '\0';
2294 lustre_cfg_bufs_reset(&bufs, mti->mti_svname);
2295 lustre_cfg_bufs_set_string(&bufs, 1, param);
2296 lcfg = lustre_cfg_new(0, &bufs);
2298 GOTO(out_comment, rc = -ENOMEM);
2300 /* construct log name */
2301 rc = name_create(&logname, mti->mti_fsname, "-sptlrpc");
2305 if (mgs_log_is_empty(obd, logname)) {
2306 rc = record_start_log(obd, &llh, logname);
2307 record_end_log(obd, &llh);
2312 /* obsolete old one */
2313 mgs_modify(obd, fsdb, mti, logname, mti->mti_svname, comment, CM_SKIP);
2315 /* write the new one */
2316 rc = mgs_write_log_direct(obd, fsdb, logname, lcfg,
2317 mti->mti_svname, comment);
2319 CERROR("err %d writing log %s\n", rc, logname);
2322 name_destroy(&logname);
2324 lustre_cfg_free(lcfg);
2326 OBD_FREE(comment, len + 1);
2330 static int mgs_srpc_set_param_udesc_mem(struct fs_db *fsdb,
2335 /* disable the adjustable udesc parameter for now, i.e. use default
2336 * setting that client always ship udesc to MDT if possible. to enable
2337 * it simply remove the following line */
2340 ptr = strchr(param, '=');
2345 if (strcmp(param, PARAM_SRPC_UDESC))
2348 if (strcmp(ptr, "yes") == 0) {
2349 fsdb->fsdb_srpc_fl_udesc = 1;
2350 CWARN("Enable user descriptor shipping from client to MDT\n");
2351 } else if (strcmp(ptr, "no") == 0) {
2352 fsdb->fsdb_srpc_fl_udesc = 0;
2353 CWARN("Disable user descriptor shipping from client to MDT\n");
2361 CERROR("Invalid param: %s\n", param);
2365 static int mgs_srpc_set_param_mem(struct fs_db *fsdb,
2369 struct sptlrpc_rule rule;
2370 struct sptlrpc_rule_set *rset;
2374 if (strncmp(param, PARAM_SRPC, sizeof(PARAM_SRPC) - 1) != 0) {
2375 CERROR("Invalid sptlrpc parameter: %s\n", param);
2379 if (strncmp(param, PARAM_SRPC_UDESC,
2380 sizeof(PARAM_SRPC_UDESC) - 1) == 0) {
2381 RETURN(mgs_srpc_set_param_udesc_mem(fsdb, param));
2384 if (strncmp(param, PARAM_SRPC_FLVR, sizeof(PARAM_SRPC_FLVR) - 1) != 0) {
2385 CERROR("Invalid sptlrpc flavor parameter: %s\n", param);
2389 param += sizeof(PARAM_SRPC_FLVR) - 1;
2391 rc = sptlrpc_parse_rule(param, &rule);
2395 /* preapre room for this coming rule. svcname format should be:
2396 * - fsname: general rule
2397 * - fsname-tgtname: target-specific rule
2399 if (strchr(svname, '-')) {
2400 struct mgs_tgt_srpc_conf *tgtconf;
2403 for (tgtconf = fsdb->fsdb_srpc_tgt; tgtconf != NULL;
2404 tgtconf = tgtconf->mtsc_next) {
2405 if (!strcmp(tgtconf->mtsc_tgt, svname)) {
2414 OBD_ALLOC_PTR(tgtconf);
2415 if (tgtconf == NULL)
2418 name_len = strlen(svname);
2420 OBD_ALLOC(tgtconf->mtsc_tgt, name_len + 1);
2421 if (tgtconf->mtsc_tgt == NULL) {
2422 OBD_FREE_PTR(tgtconf);
2425 memcpy(tgtconf->mtsc_tgt, svname, name_len);
2427 tgtconf->mtsc_next = fsdb->fsdb_srpc_tgt;
2428 fsdb->fsdb_srpc_tgt = tgtconf;
2431 rset = &tgtconf->mtsc_rset;
2433 rset = &fsdb->fsdb_srpc_gen;
2436 /* limit the maximum number of rules, but allow deletion in any case */
2437 if (rset->srs_nrule >= SPTLRPC_CONF_LOG_MAX / 2 &&
2438 rule.sr_flvr.sf_rpc != SPTLRPC_FLVR_INVALID) {
2439 CERROR("too many (%d) rules already for %s\n",
2440 rset->srs_nrule, svname);
2444 rc = sptlrpc_rule_set_merge(rset, &rule, 1);
2449 static int mgs_srpc_set_param(struct obd_device *obd,
2451 struct mgs_target_info *mti,
2458 /* keep a copy of original param, which could be destroied
2460 copy_size = strlen(param) + 1;
2461 OBD_ALLOC(copy, copy_size);
2464 memcpy(copy, param, copy_size);
2466 rc = mgs_srpc_set_param_mem(fsdb, mti->mti_svname, param);
2470 /* previous steps guaranteed the syntax is correct */
2471 rc = mgs_srpc_set_param_disk(obd, fsdb, mti, copy);
2475 /* now apply the new rules to all existing config logs */
2476 rc = mgs_modify_srpc_log_all(obd, fsdb, mti);
2479 OBD_FREE(copy, copy_size);
2483 struct mgs_srpc_read_data {
2484 struct fs_db *msrd_fsdb;
2488 static int mgs_srpc_read_handler(struct llog_handle *llh,
2489 struct llog_rec_hdr *rec,
2492 struct mgs_srpc_read_data *msrd = (struct mgs_srpc_read_data *) data;
2493 struct cfg_marker *marker;
2494 struct lustre_cfg *lcfg = (struct lustre_cfg *)(rec + 1);
2495 char *svname, *param;
2499 if (rec->lrh_type != OBD_CFG_REC) {
2500 CERROR("unhandled lrh_type: %#x\n", rec->lrh_type);
2504 cfg_len = rec->lrh_len - sizeof(struct llog_rec_hdr) -
2505 sizeof(struct llog_rec_tail);
2507 rc = lustre_cfg_sanity_check(lcfg, cfg_len);
2509 CERROR("Insane cfg\n");
2513 if (lcfg->lcfg_command == LCFG_MARKER) {
2514 marker = lustre_cfg_buf(lcfg, 1);
2516 if (marker->cm_flags & CM_START &&
2517 marker->cm_flags & CM_SKIP)
2518 msrd->msrd_skip = 1;
2519 if (marker->cm_flags & CM_END)
2520 msrd->msrd_skip = 0;
2525 if (msrd->msrd_skip)
2528 if (lcfg->lcfg_command != 0) {
2529 CERROR("invalid command (%x)\n", lcfg->lcfg_command);
2533 svname = lustre_cfg_string(lcfg, 0);
2534 if (svname == NULL) {
2535 CERROR("svname is empty\n");
2539 param = lustre_cfg_string(lcfg, 1);
2540 if (param == NULL) {
2541 CERROR("param is empty\n");
2545 rc = mgs_srpc_set_param_mem(msrd->msrd_fsdb, svname, param);
2547 CERROR("read sptlrpc record error (%d): %s\n", rc, param);
2552 static int mgs_get_fsdb_srpc_from_llog(struct obd_device *obd,
2555 struct llog_handle *llh = NULL;
2556 struct lvfs_run_ctxt saved;
2557 struct llog_ctxt *ctxt;
2559 struct mgs_srpc_read_data msrd;
2563 ctxt = llog_get_context(obd, LLOG_CONFIG_ORIG_CTXT);
2564 LASSERT(ctxt != NULL);
2566 /* construct log name */
2567 rc = name_create(&logname, fsdb->fsdb_name, "-sptlrpc");
2571 if (mgs_log_is_empty(obd, logname))
2574 push_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
2576 rc = llog_create(ctxt, &llh, NULL, logname);
2580 rc = llog_init_handle(llh, LLOG_F_IS_PLAIN, NULL);
2582 GOTO(out_close, rc);
2584 if (llog_get_size(llh) <= 1)
2585 GOTO(out_close, rc = 0);
2587 msrd.msrd_fsdb = fsdb;
2590 rc = llog_process(llh, mgs_srpc_read_handler, (void *) &msrd, NULL);
2595 pop_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
2597 name_destroy(&logname);
2598 llog_ctxt_put(ctxt);
2601 CERROR("failed to read sptlrpc config database: %d\n", rc);
2605 static int mgs_write_log_params(struct obd_device *obd, struct fs_db *fsdb,
2606 struct mgs_target_info *mti)
2608 struct lustre_cfg_bufs bufs;
2609 struct lustre_cfg *lcfg;
2611 char *ptr = mti->mti_params;
2616 if (!mti->mti_params)
2619 /* For various parameter settings, we have to figure out which logs
2620 care about them (e.g. both mdt and client for lov settings) */
2626 endptr = strchr(ptr, ' ');
2629 CDEBUG(D_MGS, "next param '%s'\n", ptr);
2631 /* The params are stored in MOUNT_DATA_FILE and modified
2632 via tunefs.lustre, or set using lctl conf_param */
2634 /* Processed in lustre_start_mgc */
2635 if (class_match_param(ptr, PARAM_MGSNODE, NULL) == 0)
2636 GOTO(end_while, rc);
2638 /* Processed in mgs_write_log_ost */
2639 if (class_match_param(ptr, PARAM_FAILMODE, NULL) == 0) {
2640 if (mti->mti_flags & LDD_F_PARAM) {
2641 LCONSOLE_ERROR_MSG(0x169, "%s can only be "
2642 "changed with tunefs.lustre"
2643 "and --writeconf\n", ptr);
2646 GOTO(end_while, rc);
2649 if (class_match_param(ptr, PARAM_SRPC, NULL) == 0) {
2650 rc = mgs_srpc_set_param(obd, fsdb, mti, ptr);
2651 GOTO(end_while, rc);
2654 if (class_match_param(ptr, PARAM_FAILNODE, NULL) == 0) {
2655 /* Add a failover nidlist */
2657 /* We already processed failovers params for new
2658 targets in mgs_write_log_target */
2659 if (mti->mti_flags & LDD_F_PARAM) {
2660 CDEBUG(D_MGS, "Adding failnode\n");
2661 rc = mgs_write_log_add_failnid(obd, fsdb, mti);
2663 GOTO(end_while, rc);
2666 if (class_match_param(ptr, PARAM_SYS_TIMEOUT, &tmp) == 0) {
2667 /* Change obd timeout */
2669 timeout = simple_strtoul(tmp, NULL, 0);
2671 CDEBUG(D_MGS, "obd timeout %d\n", timeout);
2672 lustre_cfg_bufs_reset(&bufs, NULL);
2673 lcfg = lustre_cfg_new(LCFG_SET_TIMEOUT, &bufs);
2674 lcfg->lcfg_num = timeout;
2675 /* modify all servers and clients */
2676 rc = mgs_write_log_direct_all(obd, fsdb, mti, lcfg,
2679 lustre_cfg_free(lcfg);
2680 GOTO(end_while, rc);
2683 if (class_match_param(ptr, PARAM_OSC""PARAM_ACTIVE, &tmp) == 0) {
2684 /* active=0 means off, anything else means on */
2686 int flag = (*tmp == '0') ? CM_EXCLUDE : 0;
2689 if (!(mti->mti_flags & LDD_F_SV_TYPE_OST)) {
2690 LCONSOLE_ERROR_MSG(0x144, "%s: Only OSCs can "
2691 "be (de)activated.\n",
2696 LCONSOLE_WARN("Permanently %sactivating %s\n",
2697 flag ? "de": "re", mti->mti_svname);
2699 name_create(&logname, mti->mti_fsname, "-client");
2700 rc = mgs_modify(obd, fsdb, mti, logname,
2701 mti->mti_svname, "add osc", flag);
2702 name_destroy(&logname);
2706 /* FIXME add to all MDT logs for CMD */
2707 for (i = 0; i < INDEX_MAP_SIZE * 8; i++) {
2708 if (!test_bit(i, fsdb->fsdb_mdt_index_map))
2710 sprintf(mdt_index,"-MDT%04x", i);
2711 name_create(&logname, mti->mti_fsname, mdt_index);
2712 rc = mgs_modify(obd, fsdb, mti, logname,
2713 mti->mti_svname, "add osc", flag);
2714 name_destroy(&logname);
2720 LCONSOLE_ERROR_MSG(0x145, "Couldn't find %s in"
2721 "log (%d). No permanent "
2722 "changes were made to the "
2724 mti->mti_svname, rc);
2725 if (fsdb->fsdb_flags & FSDB_OLDLOG14)
2726 LCONSOLE_ERROR_MSG(0x146, "This may be"
2731 "update the logs.\n");
2734 /* Fall through to osc proc for deactivating
2735 live OSC on running MDT / clients. */
2737 /* Below here, let obd's XXX_process_config methods handle it */
2739 /* All lov. in proc */
2740 if (class_match_param(ptr, PARAM_LOV, NULL) == 0) {
2744 CDEBUG(D_MGS, "lov param %s\n", ptr);
2745 if (!(mti->mti_flags & LDD_F_SV_TYPE_MDT)) {
2746 LCONSOLE_ERROR_MSG(0x147, "LOV params must be "
2747 "set on the MDT, not %s. "
2755 if (mgs_log_is_empty(obd, mti->mti_svname))
2756 GOTO(end_while, rc = -ENODEV);
2758 sprintf(mdt_index,"-MDT%04x", mti->mti_stripe_index);
2759 name_create(&logname, mti->mti_fsname, mdt_index);
2760 name_create(&mdtlovname, logname, "-mdtlov");
2761 rc = mgs_wlp_lcfg(obd, fsdb, mti, mti->mti_svname,
2762 &bufs, mdtlovname, ptr);
2763 name_destroy(&logname);
2764 name_destroy(&mdtlovname);
2766 GOTO(end_while, rc);
2769 name_create(&logname, mti->mti_fsname, "-client");
2770 rc = mgs_wlp_lcfg(obd, fsdb, mti, logname, &bufs,
2771 fsdb->fsdb_clilov, ptr);
2772 name_destroy(&logname);
2773 GOTO(end_while, rc);
2776 /* All osc., mdc., llite. params in proc */
2777 if ((class_match_param(ptr, PARAM_OSC, NULL) == 0) ||
2778 (class_match_param(ptr, PARAM_MDC, NULL) == 0) ||
2779 (class_match_param(ptr, PARAM_LLITE, NULL) == 0)) {
2781 if (memcmp(ptr, PARAM_LLITE, strlen(PARAM_LLITE)) == 0) {
2782 name_create(&cname, mti->mti_fsname, "-client");
2783 /* Add the client type to match the obdname
2784 in class_config_llog_handler */
2785 } else if (mti->mti_flags & LDD_F_SV_TYPE_MDT) {
2788 name_create(&cname, fsdb->fsdb_mdc, "");
2790 name_create(&cname, mti->mti_svname,
2792 } else if (mti->mti_flags & LDD_F_SV_TYPE_OST) {
2794 if (fsdb->fsdb_flags & FSDB_OLDLOG14) {
2795 LCONSOLE_ERROR_MSG(0x148, "Upgraded "
2796 "client logs for %s"
2798 "modified. Consider"
2800 "configuration with"
2803 /* We don't know the names of all the
2808 name_create(&cname, mti->mti_svname, "-osc");
2814 CDEBUG(D_MGS, "%.3s param %s\n", ptr, ptr + 4);
2817 name_create(&logname, mti->mti_fsname, "-client");
2818 rc = mgs_wlp_lcfg(obd, fsdb, mti, logname, &bufs,
2821 /* osc params affect the MDT as well */
2822 if (!rc && (mti->mti_flags & LDD_F_SV_TYPE_OST)) {
2826 for (i = 0; i < INDEX_MAP_SIZE * 8; i++){
2827 if (!test_bit(i, fsdb->fsdb_mdt_index_map))
2829 name_destroy(&cname);
2830 sprintf(mdt_index, "-osc-MDT%04x", i);
2831 name_create(&cname, mti->mti_svname,
2833 name_destroy(&logname);
2834 sprintf(mdt_index, "-MDT%04x", i);
2835 name_create(&logname, mti->mti_fsname,
2837 if (!mgs_log_is_empty(obd, logname))
2838 rc = mgs_wlp_lcfg(obd, fsdb,
2846 name_destroy(&logname);
2847 name_destroy(&cname);
2848 GOTO(end_while, rc);
2851 /* All mdt., ost. params in proc */
2852 if ((class_match_param(ptr, PARAM_MDT, NULL) == 0) ||
2853 (class_match_param(ptr, PARAM_MDD, NULL) == 0) ||
2854 (class_match_param(ptr, PARAM_OST, NULL) == 0)) {
2855 CDEBUG(D_MGS, "%.3s param %s\n", ptr, ptr + 4);
2856 if (mgs_log_is_empty(obd, mti->mti_svname)) {
2860 rc = mgs_wlp_lcfg(obd, fsdb, mti, mti->mti_svname,
2861 &bufs, mti->mti_svname, ptr);
2862 GOTO(end_while, rc);
2865 LCONSOLE_WARN("Ignoring unrecognized param '%s'\n", ptr);
2869 CERROR("err %d on param '%s\n", rc, ptr);
2884 /* Not implementing automatic failover nid addition at this time. */
2885 int mgs_check_failnid(struct obd_device *obd, struct mgs_target_info *mti)
2892 rc = mgs_find_or_make_fsdb(obd, fsname, &fsdb);
2896 if (mgs_log_is_empty(obd, mti->mti_svname))
2897 /* should never happen */
2900 CDEBUG(D_MGS, "Checking for new failnids for %s\n", mti->mti_svname);
2902 /* FIXME We can just check mti->params to see if we're already in
2903 the failover list. Modify mti->params for rewriting back at
2904 server_register_target(). */
2906 down(&fsdb->fsdb_sem);
2907 rc = mgs_write_log_add_failnid(obd, fsdb, mti);
2908 up(&fsdb->fsdb_sem);
2915 int mgs_write_log_target(struct obd_device *obd,
2916 struct mgs_target_info *mti)
2922 /* set/check the new target index */
2923 rc = mgs_set_index(obd, mti);
2925 CERROR("Can't get index (%d)\n", rc);
2930 if (mti->mti_flags & LDD_F_UPGRADE14) {
2931 if (rc == EALREADY) {
2932 LCONSOLE_INFO("Found index %d for %s 1.4 log, "
2933 "upgrading\n", mti->mti_stripe_index,
2936 LCONSOLE_ERROR_MSG(0x149, "Failed to find %s in the old"
2937 " client log. Apparently it is not "
2938 "part of this filesystem, or the old"
2939 " log is wrong.\nUse 'writeconf' on "
2940 "the MDT to force log regeneration."
2941 "\n", mti->mti_svname);
2942 /* Not in client log? Upgrade anyhow...*/
2943 /* Argument against upgrading: reformat MDT,
2944 upgrade OST, then OST will start but will be SKIPped
2945 in client logs. Maybe error now is better. */
2946 /* RETURN(-EINVAL); */
2948 /* end COMPAT_146 */
2950 if (rc == EALREADY) {
2951 LCONSOLE_WARN("Found index %d for %s, updating log\n",
2952 mti->mti_stripe_index, mti->mti_svname);
2953 /* We would like to mark old log sections as invalid
2954 and add new log sections in the client and mdt logs.
2955 But if we add new sections, then live clients will
2956 get repeat setup instructions for already running
2957 osc's. So don't update the client/mdt logs. */
2958 mti->mti_flags &= ~LDD_F_UPDATE;
2962 rc = mgs_find_or_make_fsdb(obd, mti->mti_fsname, &fsdb);
2964 CERROR("Can't get db for %s\n", mti->mti_fsname);
2968 down(&fsdb->fsdb_sem);
2970 if (mti->mti_flags &
2971 (LDD_F_VIRGIN | LDD_F_UPGRADE14 | LDD_F_WRITECONF)) {
2972 /* Generate a log from scratch */
2973 if (mti->mti_flags & LDD_F_SV_TYPE_MDT) {
2974 rc = mgs_write_log_mdt(obd, fsdb, mti);
2975 } else if (mti->mti_flags & LDD_F_SV_TYPE_OST) {
2976 rc = mgs_write_log_ost(obd, fsdb, mti);
2978 CERROR("Unknown target type %#x, can't create log for "
2979 "%s\n", mti->mti_flags, mti->mti_svname);
2982 CERROR("Can't write logs for %s (%d)\n",
2983 mti->mti_svname, rc);
2987 /* Just update the params from tunefs in mgs_write_log_params */
2988 CDEBUG(D_MGS, "Update params for %s\n", mti->mti_svname);
2989 mti->mti_flags |= LDD_F_PARAM;
2992 rc = mgs_write_log_params(obd, fsdb, mti);
2995 up(&fsdb->fsdb_sem);
3000 /* verify that we can handle the old config logs */
3001 int mgs_upgrade_sv_14(struct obd_device *obd, struct mgs_target_info *mti)
3007 /* Create ost log normally, as servers register. Servers
3008 register with their old uuids (from last_rcvd), so old
3009 (MDT and client) logs should work.
3010 - new MDT won't know about old OSTs, only the ones that have
3011 registered, so we need the old MDT log to get the LOV right
3012 in order for old clients to work.
3013 - Old clients connect to the MDT, not the MGS, for their logs, and
3014 will therefore receive the old client log from the MDT /LOGS dir.
3015 - Old clients can continue to use and connect to old or new OSTs
3016 - New clients will contact the MGS for their log
3019 LCONSOLE_INFO("upgrading server %s from pre-1.6\n", mti->mti_svname);
3020 server_mti_print("upgrade", mti);
3022 rc = mgs_find_or_make_fsdb(obd, mti->mti_fsname, &fsdb);
3026 if (fsdb->fsdb_flags & FSDB_LOG_EMPTY) {
3027 LCONSOLE_ERROR_MSG(0x14a, "The old client log %s-client is "
3028 "missing. Was tunefs.lustre successful?\n",
3033 if (fsdb->fsdb_gen == 0) {
3034 /* There were no markers in the client log, meaning we have
3035 not updated the logs for this fs */
3036 CDEBUG(D_MGS, "found old, unupdated client log\n");
3039 if (mti->mti_flags & LDD_F_SV_TYPE_MDT) {
3040 if (mgs_log_is_empty(obd, mti->mti_svname)) {
3041 LCONSOLE_ERROR_MSG(0x14b, "The old MDT log %s is "
3042 "missing. Was tunefs.lustre "
3047 /* We're starting with an old uuid. Assume old name for lov
3048 as well since the lov entry already exists in the log. */
3049 CDEBUG(D_MGS, "old mds uuid %s\n", mti->mti_uuid);
3050 if (strncmp(mti->mti_uuid, fsdb->fsdb_mdtlov + 4,
3051 strlen(fsdb->fsdb_mdtlov) - 4) != 0) {
3052 CERROR("old mds uuid %s doesn't match log %s (%s)\n",
3053 mti->mti_uuid, fsdb->fsdb_mdtlov,
3054 fsdb->fsdb_mdtlov + 4);
3059 if (!(fsdb->fsdb_flags & FSDB_OLDLOG14)) {
3060 LCONSOLE_ERROR_MSG(0x14c, "%s-client is supposedly an old "
3061 "log, but no old LOV or MDT was found. "
3062 "Consider updating the configuration with"
3063 " --writeconf.\n", mti->mti_fsname);
3068 /* end COMPAT_146 */
3070 int mgs_erase_log(struct obd_device *obd, char *name)
3072 struct lvfs_run_ctxt saved;
3073 struct llog_ctxt *ctxt;
3074 struct llog_handle *llh;
3077 ctxt = llog_get_context(obd, LLOG_CONFIG_ORIG_CTXT);
3078 LASSERT(ctxt != NULL);
3080 push_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
3081 rc = llog_create(ctxt, &llh, NULL, name);
3083 llog_init_handle(llh, LLOG_F_IS_PLAIN, NULL);
3084 rc = llog_destroy(llh);
3085 llog_free_handle(llh);
3087 pop_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
3088 llog_ctxt_put(ctxt);
3091 CERROR("failed to clear log %s: %d\n", name, rc);
3096 /* erase all logs for the given fs */
3097 int mgs_erase_logs(struct obd_device *obd, char *fsname)
3099 struct mgs_obd *mgs = &obd->u.mgs;
3100 static struct fs_db *fsdb;
3101 struct list_head dentry_list;
3102 struct l_linux_dirent *dirent, *n;
3103 int rc, len = strlen(fsname);
3106 /* Find all the logs in the CONFIGS directory */
3107 rc = class_dentry_readdir(obd, mgs->mgs_configs_dir,
3108 mgs->mgs_vfsmnt, &dentry_list);
3110 CERROR("Can't read %s dir\n", MOUNT_CONFIGS_DIR);
3114 down(&mgs->mgs_sem);
3116 /* Delete the fs db */
3117 fsdb = mgs_find_fsdb(obd, fsname);
3119 mgs_free_fsdb(obd, fsdb);
3121 list_for_each_entry_safe(dirent, n, &dentry_list, lld_list) {
3122 list_del(&dirent->lld_list);
3123 if (strncmp(fsname, dirent->lld_name, len) == 0) {
3124 CDEBUG(D_MGS, "Removing log %s\n", dirent->lld_name);
3125 mgs_erase_log(obd, dirent->lld_name);
3127 OBD_FREE(dirent, sizeof(*dirent));
3135 /* from llog_swab */
3136 static void print_lustre_cfg(struct lustre_cfg *lcfg)
3141 CDEBUG(D_MGS, "lustre_cfg: %p\n", lcfg);
3142 CDEBUG(D_MGS, "\tlcfg->lcfg_version: %#x\n", lcfg->lcfg_version);
3144 CDEBUG(D_MGS, "\tlcfg->lcfg_command: %#x\n", lcfg->lcfg_command);
3145 CDEBUG(D_MGS, "\tlcfg->lcfg_num: %#x\n", lcfg->lcfg_num);
3146 CDEBUG(D_MGS, "\tlcfg->lcfg_flags: %#x\n", lcfg->lcfg_flags);
3147 CDEBUG(D_MGS, "\tlcfg->lcfg_nid: %s\n", libcfs_nid2str(lcfg->lcfg_nid));
3149 CDEBUG(D_MGS, "\tlcfg->lcfg_bufcount: %d\n", lcfg->lcfg_bufcount);
3150 if (lcfg->lcfg_bufcount < LUSTRE_CFG_MAX_BUFCOUNT)
3151 for (i = 0; i < lcfg->lcfg_bufcount; i++) {
3152 CDEBUG(D_MGS, "\tlcfg->lcfg_buflens[%d]: %d %s\n",
3153 i, lcfg->lcfg_buflens[i],
3154 lustre_cfg_string(lcfg, i));
3159 /* Set a permanent (config log) param for a target or fs */
3160 int mgs_setparam(struct obd_device *obd, struct lustre_cfg *lcfg, char *fsname)
3163 struct mgs_target_info *mti;
3164 char *devname, *param;
3170 print_lustre_cfg(lcfg);
3172 /* lustre, lustre-mdtlov, lustre-client, lustre-MDT0000 */
3173 devname = lustre_cfg_string(lcfg, 0);
3174 param = lustre_cfg_string(lcfg, 1);
3176 /* Assume device name embedded in param:
3177 lustre-OST0000.osc.max_dirty_mb=32 */
3178 ptr = strchr(param, '.');
3186 LCONSOLE_ERROR_MSG(0x14d, "No target specified: %s\n", param);
3190 /* Extract fsname */
3191 ptr = strrchr(devname, '-');
3192 memset(fsname, 0, MTI_NAME_MAXLEN);
3193 if (ptr && (server_name2index(ptr, &index, NULL) >= 0)) {
3194 strncpy(fsname, devname, ptr - devname);
3196 /* assume devname is the fsname */
3197 strncpy(fsname, devname, MTI_NAME_MAXLEN);
3199 fsname[MTI_NAME_MAXLEN - 1] = 0;
3200 CDEBUG(D_MGS, "setparam on fs %s device %s\n", fsname, devname);
3202 rc = mgs_find_or_make_fsdb(obd, fsname, &fsdb);
3205 if (fsdb->fsdb_flags & FSDB_LOG_EMPTY) {
3206 CERROR("No filesystem targets for %s. cfg_device from lctl "
3207 "is '%s'\n", fsname, devname);
3208 mgs_free_fsdb(obd, fsdb);
3212 /* Create a fake mti to hold everything */
3215 GOTO(out, rc = -ENOMEM);
3216 strncpy(mti->mti_fsname, fsname, MTI_NAME_MAXLEN);
3217 strncpy(mti->mti_svname, devname, MTI_NAME_MAXLEN);
3218 strncpy(mti->mti_params, param, sizeof(mti->mti_params));
3219 rc = server_name2index(mti->mti_svname, &mti->mti_stripe_index, &tmp);
3221 /* Not a valid server; may be only fsname */
3224 /* Strip -osc or -mdc suffix from svname */
3225 if (server_make_name(rc, mti->mti_stripe_index, mti->mti_fsname,
3227 GOTO(out, rc = -EINVAL);
3229 mti->mti_flags = rc | LDD_F_PARAM;
3231 down(&fsdb->fsdb_sem);
3232 rc = mgs_write_log_params(obd, fsdb, mti);
3233 up(&fsdb->fsdb_sem);
3240 static int mgs_write_log_pool(struct obd_device *obd, char *logname,
3241 struct fs_db *fsdb, char *lovname,
3242 enum lcfg_command_type cmd,
3243 char *poolname, char *fsname,
3244 char *ostname, char *comment)
3246 struct llog_handle *llh = NULL;
3249 rc = record_start_log(obd, &llh, logname);
3252 rc = record_marker(obd, llh, fsdb, CM_START, lovname, comment);
3253 record_base(obd, llh, lovname, 0, cmd, poolname, fsname, ostname, 0);
3254 rc = record_marker(obd, llh, fsdb, CM_END, lovname, comment);
3255 rc = record_end_log(obd, &llh);
3260 int mgs_pool_cmd(struct obd_device *obd, enum lcfg_command_type cmd,
3261 char *fsname, char *poolname, char *ostname)
3267 char *label = NULL, *canceled_label = NULL;
3269 struct mgs_target_info *mti = NULL;
3273 rc = mgs_find_or_make_fsdb(obd, fsname, &fsdb);
3275 CERROR("Can't get db for %s\n", fsname);
3278 if (fsdb->fsdb_flags & FSDB_LOG_EMPTY) {
3279 CERROR("%s is not defined\n", fsname);
3280 mgs_free_fsdb(obd, fsdb);
3284 label_sz = 10 + strlen(fsname) + strlen(poolname);
3286 /* check if ostname match fsname */
3287 if (ostname != NULL) {
3290 ptr = strrchr(ostname, '-');
3291 if ((ptr == NULL) ||
3292 (strncmp(fsname, ostname, ptr-ostname) != 0))
3294 label_sz += strlen(ostname);
3297 OBD_ALLOC(label, label_sz);
3299 GOTO(out, rc = -ENOMEM);
3302 case LCFG_POOL_NEW: {
3304 "new %s.%s", fsname, poolname);
3307 case LCFG_POOL_ADD: {
3309 "add %s.%s.%s", fsname, poolname, ostname);
3312 case LCFG_POOL_REM: {
3313 OBD_ALLOC(canceled_label, label_sz);
3314 if (canceled_label == NULL)
3315 GOTO(out, rc = -ENOMEM);
3317 "rem %s.%s.%s", fsname, poolname, ostname);
3318 sprintf(canceled_label,
3319 "add %s.%s.%s", fsname, poolname, ostname);
3322 case LCFG_POOL_DEL: {
3323 OBD_ALLOC(canceled_label, label_sz);
3324 if (canceled_label == NULL)
3325 GOTO(out, rc = -ENOMEM);
3327 "del %s.%s", fsname, poolname);
3328 sprintf(canceled_label,
3329 "new %s.%s", fsname, poolname);
3337 down(&fsdb->fsdb_sem);
3339 if (canceled_label != NULL) {
3342 GOTO(out, rc = -ENOMEM);
3345 /* loop on all potential MDT */
3346 for (i = 0; i < INDEX_MAP_SIZE * 8; i++) {
3347 if (test_bit(i, fsdb->fsdb_mdt_index_map)) {
3348 sprintf(mdt_index, "-MDT%04x", i);
3349 name_create(&logname, fsname, mdt_index);
3350 name_create(&lovname, logname, "-mdtlov");
3352 if (canceled_label != NULL) {
3353 strcpy(mti->mti_svname, "lov pool");
3354 mgs_modify(obd, fsdb, mti, logname, lovname,
3355 canceled_label, CM_SKIP);
3358 mgs_write_log_pool(obd, logname, fsdb, lovname,
3359 cmd, fsname, poolname, ostname,
3361 name_destroy(&logname);
3362 name_destroy(&lovname);
3366 name_create(&logname, fsname, "-client");
3367 if (canceled_label != NULL)
3368 mgs_modify(obd, fsdb, mti, logname, fsdb->fsdb_clilov,
3369 canceled_label, CM_SKIP);
3371 mgs_write_log_pool(obd, logname, fsdb, fsdb->fsdb_clilov,
3372 cmd, fsname, poolname, ostname, label);
3373 name_destroy(&logname);
3375 up(&fsdb->fsdb_sem);
3380 OBD_FREE(label, label_sz);
3382 if (canceled_label != NULL)
3383 OBD_FREE(canceled_label, label_sz);
3392 /******************** unused *********************/
3393 static int mgs_backup_llog(struct obd_device *obd, char* fsname)
3395 struct file *filp, *bak_filp;
3396 struct lvfs_run_ctxt saved;
3397 char *logname, *buf;
3398 loff_t soff = 0 , doff = 0;
3399 int count = 4096, len;
3402 OBD_ALLOC(logname, PATH_MAX);
3403 if (logname == NULL)
3406 OBD_ALLOC(buf, count);
3408 GOTO(out , rc = -ENOMEM);
3410 len = snprintf(logname, PATH_MAX, "%s/%s.bak",
3411 MOUNT_CONFIGS_DIR, fsname);
3413 if (len >= PATH_MAX - 1) {
3414 GOTO(out, -ENAMETOOLONG);
3417 push_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
3419 bak_filp = l_filp_open(logname, O_RDWR|O_CREAT|O_TRUNC, 0660);
3420 if (IS_ERR(bak_filp)) {
3421 rc = PTR_ERR(bak_filp);
3422 CERROR("backup logfile open %s: %d\n", logname, rc);
3425 sprintf(logname, "%s/%s", MOUNT_CONFIGS_DIR, fsname);
3426 filp = l_filp_open(logname, O_RDONLY, 0);
3429 CERROR("logfile open %s: %d\n", logname, rc);
3433 while ((rc = lustre_fread(filp, buf, count, &soff)) > 0) {
3434 rc = lustre_fwrite(bak_filp, buf, count, &doff);
3438 filp_close(filp, 0);
3440 filp_close(bak_filp, 0);
3442 pop_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
3445 OBD_FREE(buf, count);
3446 OBD_FREE(logname, PATH_MAX);