1 /* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*-
2 * vim:expandtab:shiftwidth=8:tabstop=8:
4 * lustre/mgs/mgs_llog.c
5 * Lustre Management Server (mgs) config llog creation
7 * Copyright (C) 2006 Cluster File Systems, Inc.
8 * Author: Nathan Rutman <nathan@clusterfs.com>
10 * This file is part of Lustre, http://www.lustre.org.
12 * Lustre is free software; you can redistribute it and/or
13 * modify it under the terms of version 2 of the GNU General Public
14 * License as published by the Free Software Foundation.
16 * Lustre is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU General Public License for more details.
21 * You should have received a copy of the GNU General Public License
22 * along with Lustre; if not, write to the Free Software
23 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
29 #define DEBUG_SUBSYSTEM S_MGS
30 #define D_MGS D_CONFIG /*|D_WARNING*/
33 #include <linux/module.h>
34 #include <linux/pagemap.h>
40 #include <obd_class.h>
41 #include <lustre_log.h>
43 #include <libcfs/list.h>
44 #include <linux/lvfs.h>
45 #include <lustre_fsfilt.h>
46 #include <lustre_disk.h>
47 #include <lustre_param.h>
48 #include <lustre_sec.h>
49 #include "mgs_internal.h"
51 static int mgs_get_fsdb_srpc_from_llog(struct obd_device *obd,
53 static int mgs_get_srpc_conf_log(struct fs_db *fsdb, const char *tgt,
54 enum lustre_sec_part from,
55 enum lustre_sec_part to,
56 struct sptlrpc_conf_log *log);
58 /********************** Class functions ********************/
60 /* Caller must list_del and OBD_FREE each dentry from the list */
61 int class_dentry_readdir(struct obd_device *obd, struct dentry *dir,
62 struct vfsmount *inmnt,
63 struct list_head *dentry_list){
64 /* see mds_cleanup_pending */
65 struct lvfs_run_ctxt saved;
67 struct dentry *dentry;
72 push_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
75 GOTO(out_pop, rc = PTR_ERR(dentry));
79 GOTO(out_pop, rc = PTR_ERR(mnt));
82 file = dentry_open(dentry, mnt, O_RDONLY);
84 /* dentry_open_it() drops the dentry, mnt refs */
85 GOTO(out_pop, rc = PTR_ERR(file));
87 INIT_LIST_HEAD(dentry_list);
88 rc = l_readdir(file, dentry_list);
90 /* filp_close->fput() drops the dentry, mnt refs */
93 pop_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
97 /******************** DB functions *********************/
99 static inline int name_create(char **newname, char *prefix, char *suffix)
102 OBD_ALLOC(*newname, strlen(prefix) + strlen(suffix) + 1);
105 sprintf(*newname, "%s%s", prefix, suffix);
109 static inline void name_destroy(char **name)
112 OBD_FREE(*name, strlen(*name) + 1);
116 /* from the (client) config log, figure out:
117 1. which ost's/mdt's are configured (by index)
118 2. what the last config step is
119 3. COMPAT_146 lov name
120 4. COMPAT_146 mdt lov name
121 5. COMPAT_146 mdc name
123 /* It might be better to have a separate db file, instead of parsing the info
124 out of the client log. This is slow and potentially error-prone. */
125 static int mgs_fsdb_handler(struct llog_handle *llh, struct llog_rec_hdr *rec,
128 struct fs_db *fsdb = (struct fs_db *)data;
129 int cfg_len = rec->lrh_len;
130 char *cfg_buf = (char*) (rec + 1);
131 struct lustre_cfg *lcfg;
136 if (rec->lrh_type != OBD_CFG_REC) {
137 CERROR("unhandled lrh_type: %#x\n", rec->lrh_type);
141 rc = lustre_cfg_sanity_check(cfg_buf, cfg_len);
143 CERROR("Insane cfg\n");
147 lcfg = (struct lustre_cfg *)cfg_buf;
149 CDEBUG(D_INFO, "cmd %x %s %s\n", lcfg->lcfg_command,
150 lustre_cfg_string(lcfg, 0), lustre_cfg_string(lcfg, 1));
152 /* Figure out ost indicies */
153 /* lov_modify_tgts add 0:lov1 1:ost1_UUID 2(index):0 3(gen):1 */
154 if (lcfg->lcfg_command == LCFG_LOV_ADD_OBD ||
155 lcfg->lcfg_command == LCFG_LOV_DEL_OBD) {
156 index = simple_strtoul(lustre_cfg_string(lcfg, 2),
158 CDEBUG(D_MGS, "OST index for %s is %u (%s)\n",
159 lustre_cfg_string(lcfg, 1), index,
160 lustre_cfg_string(lcfg, 2));
161 set_bit(index, fsdb->fsdb_ost_index_map);
164 /* Figure out mdt indicies */
165 /* attach 0:MDC_uml1_mdsA_MNT_client 1:mdc 2:1d834_MNT_client_03f */
166 if ((lcfg->lcfg_command == LCFG_ATTACH) &&
167 (strcmp(lustre_cfg_string(lcfg, 1), LUSTRE_MDC_NAME) == 0)) {
168 rc = server_name2index(lustre_cfg_string(lcfg, 0),
170 if (rc != LDD_F_SV_TYPE_MDT) {
171 CWARN("Unparsable MDC name %s, assuming index 0\n",
172 lustre_cfg_string(lcfg, 0));
176 CDEBUG(D_MGS, "MDT index is %u\n", index);
177 set_bit(index, fsdb->fsdb_mdt_index_map);
181 /* figure out the old LOV name. fsdb_gen = 0 means old log */
182 /* #01 L attach 0:lov_mdsA 1:lov 2:cdbe9_lov_mdsA_dc8cf7f3bb */
183 if ((fsdb->fsdb_gen == 0) && (lcfg->lcfg_command == LCFG_ATTACH) &&
184 (strcmp(lustre_cfg_string(lcfg, 1), LUSTRE_LOV_NAME) == 0)) {
185 fsdb->fsdb_flags |= FSDB_OLDLOG14;
186 name_destroy(&fsdb->fsdb_clilov);
187 rc = name_create(&fsdb->fsdb_clilov,
188 lustre_cfg_string(lcfg, 0), "");
191 CDEBUG(D_MGS, "client lov name is %s\n", fsdb->fsdb_clilov);
194 /* figure out the old MDT lov name from the MDT uuid */
195 if ((fsdb->fsdb_gen == 0) && (lcfg->lcfg_command == LCFG_SETUP) &&
196 (strncmp(lustre_cfg_string(lcfg, 0), "MDC_", 4) == 0)) {
198 fsdb->fsdb_flags |= FSDB_OLDLOG14;
199 ptr = strstr(lustre_cfg_string(lcfg, 1), "_UUID");
201 CERROR("Can't parse MDT uuid %s\n",
202 lustre_cfg_string(lcfg, 1));
206 name_destroy(&fsdb->fsdb_mdtlov);
207 rc = name_create(&fsdb->fsdb_mdtlov,
208 "lov_", lustre_cfg_string(lcfg, 1));
211 name_destroy(&fsdb->fsdb_mdc);
212 rc = name_create(&fsdb->fsdb_mdc,
213 lustre_cfg_string(lcfg, 0), "");
216 CDEBUG(D_MGS, "MDT lov name is %s\n", fsdb->fsdb_mdtlov);
220 /* Keep track of the latest marker step */
221 if (lcfg->lcfg_command == LCFG_MARKER) {
222 struct cfg_marker *marker;
223 marker = lustre_cfg_buf(lcfg, 1);
224 fsdb->fsdb_gen = max(fsdb->fsdb_gen, marker->cm_step);
230 /* fsdb->fsdb_sem is already held in mgs_find_or_make_fsdb*/
231 static int mgs_get_fsdb_from_llog(struct obd_device *obd, struct fs_db *fsdb)
234 struct llog_handle *loghandle;
235 struct lvfs_run_ctxt saved;
239 name_create(&logname, fsdb->fsdb_name, "-client");
240 down(&fsdb->fsdb_sem);
241 push_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
243 rc = llog_create(llog_get_context(obd, LLOG_CONFIG_ORIG_CTXT),
244 &loghandle, NULL, logname);
248 rc = llog_init_handle(loghandle, LLOG_F_IS_PLAIN, NULL);
252 if (llog_get_size(loghandle) <= 1)
253 fsdb->fsdb_flags |= FSDB_LOG_EMPTY;
255 rc = llog_process(loghandle, mgs_fsdb_handler, (void *)fsdb, NULL);
256 CDEBUG(D_INFO, "get_db = %d\n", rc);
258 rc2 = llog_close(loghandle);
263 pop_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
265 name_destroy(&logname);
270 static void mgs_free_fsdb_srpc(struct fs_db *fsdb)
272 struct mgs_tgt_srpc_conf *tgtconf;
274 /* free target-specific rules */
275 while (fsdb->fsdb_srpc_tgt) {
276 tgtconf = fsdb->fsdb_srpc_tgt;
277 fsdb->fsdb_srpc_tgt = tgtconf->mtsc_next;
279 LASSERT(tgtconf->mtsc_tgt);
281 sptlrpc_rule_set_free(&tgtconf->mtsc_rset);
282 OBD_FREE(tgtconf->mtsc_tgt, strlen(tgtconf->mtsc_tgt) + 1);
283 OBD_FREE_PTR(tgtconf);
286 /* free general rules */
287 sptlrpc_rule_set_free(&fsdb->fsdb_srpc_gen);
290 static struct fs_db *mgs_find_fsdb(struct obd_device *obd, char *fsname)
292 struct mgs_obd *mgs = &obd->u.mgs;
294 struct list_head *tmp;
296 list_for_each(tmp, &mgs->mgs_fs_db_list) {
297 fsdb = list_entry(tmp, struct fs_db, fsdb_list);
298 if (strcmp(fsdb->fsdb_name, fsname) == 0)
304 /* caller must hold the mgs->mgs_fs_db_lock */
305 static struct fs_db *mgs_new_fsdb(struct obd_device *obd, char *fsname)
307 struct mgs_obd *mgs = &obd->u.mgs;
316 OBD_ALLOC(fsdb->fsdb_ost_index_map, INDEX_MAP_SIZE);
317 OBD_ALLOC(fsdb->fsdb_mdt_index_map, INDEX_MAP_SIZE);
318 if (!fsdb->fsdb_ost_index_map || !fsdb->fsdb_mdt_index_map) {
319 CERROR("No memory for index maps\n");
323 strncpy(fsdb->fsdb_name, fsname, sizeof(fsdb->fsdb_name));
324 fsdb->fsdb_name[sizeof(fsdb->fsdb_name) - 1] = 0;
325 rc = name_create(&fsdb->fsdb_mdtlov, fsname, "-mdtlov");
328 rc = name_create(&fsdb->fsdb_mdtlmv, fsname, "-mdtlmv");
331 rc = name_create(&fsdb->fsdb_clilov, fsname, "-clilov");
335 rc = name_create(&fsdb->fsdb_clilmv, fsname, "-clilmv");
339 fsdb->fsdb_srpc_fl_udesc = 1;
340 sema_init(&fsdb->fsdb_sem, 1);
341 list_add(&fsdb->fsdb_list, &mgs->mgs_fs_db_list);
342 lproc_mgs_add_live(obd, fsdb);
346 if (fsdb->fsdb_ost_index_map)
347 OBD_FREE(fsdb->fsdb_ost_index_map, INDEX_MAP_SIZE);
348 if (fsdb->fsdb_mdt_index_map)
349 OBD_FREE(fsdb->fsdb_mdt_index_map, INDEX_MAP_SIZE);
350 name_destroy(&fsdb->fsdb_clilov);
351 name_destroy(&fsdb->fsdb_clilmv);
352 name_destroy(&fsdb->fsdb_mdtlov);
353 name_destroy(&fsdb->fsdb_mdtlmv);
358 static void mgs_free_fsdb(struct obd_device *obd, struct fs_db *fsdb)
360 /* wait for anyone with the sem */
361 down(&fsdb->fsdb_sem);
362 lproc_mgs_del_live(obd, fsdb);
363 list_del(&fsdb->fsdb_list);
364 OBD_FREE(fsdb->fsdb_ost_index_map, INDEX_MAP_SIZE);
365 OBD_FREE(fsdb->fsdb_mdt_index_map, INDEX_MAP_SIZE);
366 name_destroy(&fsdb->fsdb_clilov);
367 name_destroy(&fsdb->fsdb_clilmv);
368 name_destroy(&fsdb->fsdb_mdtlov);
369 name_destroy(&fsdb->fsdb_mdtlmv);
370 name_destroy(&fsdb->fsdb_mdc);
371 mgs_free_fsdb_srpc(fsdb);
375 int mgs_init_fsdb_list(struct obd_device *obd)
377 struct mgs_obd *mgs = &obd->u.mgs;
378 INIT_LIST_HEAD(&mgs->mgs_fs_db_list);
382 int mgs_cleanup_fsdb_list(struct obd_device *obd)
384 struct mgs_obd *mgs = &obd->u.mgs;
386 struct list_head *tmp, *tmp2;
388 list_for_each_safe(tmp, tmp2, &mgs->mgs_fs_db_list) {
389 fsdb = list_entry(tmp, struct fs_db, fsdb_list);
390 mgs_free_fsdb(obd, fsdb);
396 static int mgs_find_or_make_fsdb(struct obd_device *obd, char *name,
399 struct mgs_obd *mgs = &obd->u.mgs;
404 fsdb = mgs_find_fsdb(obd, name);
411 CDEBUG(D_MGS, "Creating new db\n");
412 fsdb = mgs_new_fsdb(obd, name);
417 /* populate the db from the client llog */
418 rc = mgs_get_fsdb_from_llog(obd, fsdb);
420 CERROR("Can't get db from client log %d\n", rc);
421 mgs_free_fsdb(obd, fsdb);
425 /* populate srpc rules from params llog */
426 rc = mgs_get_fsdb_srpc_from_llog(obd, fsdb);
428 CERROR("Can't get db from params log %d\n", rc);
429 mgs_free_fsdb(obd, fsdb);
440 -1= empty client log */
441 int mgs_check_index(struct obd_device *obd, struct mgs_target_info *mti)
448 LASSERT(!(mti->mti_flags & LDD_F_NEED_INDEX));
450 rc = mgs_find_or_make_fsdb(obd, mti->mti_fsname, &fsdb);
452 CERROR("Can't get db for %s\n", mti->mti_fsname);
456 if (fsdb->fsdb_flags & FSDB_LOG_EMPTY)
459 if (mti->mti_flags & LDD_F_SV_TYPE_OST)
460 imap = fsdb->fsdb_ost_index_map;
461 else if (mti->mti_flags & LDD_F_SV_TYPE_MDT)
462 imap = fsdb->fsdb_mdt_index_map;
466 if (test_bit(mti->mti_stripe_index, imap))
471 static __inline__ int next_index(void *index_map, int map_len)
474 for (i = 0; i < map_len * 8; i++)
475 if (!test_bit(i, index_map)) {
478 CERROR("max index %d exceeded.\n", i);
483 0 newly marked as in use
485 +EALREADY for update of an old index */
486 int mgs_set_index(struct obd_device *obd, struct mgs_target_info *mti)
493 rc = mgs_find_or_make_fsdb(obd, mti->mti_fsname, &fsdb);
495 CERROR("Can't get db for %s\n", mti->mti_fsname);
499 if (mti->mti_flags & LDD_F_SV_TYPE_OST)
500 imap = fsdb->fsdb_ost_index_map;
501 else if (mti->mti_flags & LDD_F_SV_TYPE_MDT)
502 imap = fsdb->fsdb_mdt_index_map;
506 if (mti->mti_flags & LDD_F_NEED_INDEX) {
507 rc = next_index(imap, INDEX_MAP_SIZE);
510 mti->mti_stripe_index = rc;
513 if (mti->mti_stripe_index >= INDEX_MAP_SIZE * 8) {
514 LCONSOLE_ERROR_MSG(0x13f, "Server %s requested index %d, "
515 "but the max index is %d.\n",
516 mti->mti_svname, mti->mti_stripe_index,
521 if (test_bit(mti->mti_stripe_index, imap)) {
522 if (mti->mti_flags & LDD_F_VIRGIN) {
523 LCONSOLE_ERROR_MSG(0x140, "Server %s requested index "
524 "%d, but that index is already in "
525 "use\n", mti->mti_svname,
526 mti->mti_stripe_index);
529 CDEBUG(D_MGS, "Server %s updating index %d\n",
530 mti->mti_svname, mti->mti_stripe_index);
535 set_bit(mti->mti_stripe_index, imap);
536 fsdb->fsdb_flags &= ~FSDB_LOG_EMPTY;
537 server_make_name(mti->mti_flags, mti->mti_stripe_index,
538 mti->mti_fsname, mti->mti_svname);
540 CDEBUG(D_MGS, "Set index for %s to %d\n", mti->mti_svname,
541 mti->mti_stripe_index);
546 struct mgs_modify_lookup {
547 struct cfg_marker mml_marker;
551 static int mgs_modify_handler(struct llog_handle *llh, struct llog_rec_hdr *rec,
554 struct mgs_modify_lookup *mml = (struct mgs_modify_lookup *)data;
555 struct cfg_marker *marker;
556 struct lustre_cfg *lcfg = (struct lustre_cfg *)(rec + 1);
557 int cfg_len = rec->lrh_len - sizeof(struct llog_rec_hdr) -
558 sizeof(struct llog_rec_tail);
562 if (rec->lrh_type != OBD_CFG_REC) {
563 CERROR("unhandled lrh_type: %#x\n", rec->lrh_type);
567 rc = lustre_cfg_sanity_check(lcfg, cfg_len);
569 CERROR("Insane cfg\n");
573 /* We only care about markers */
574 if (lcfg->lcfg_command != LCFG_MARKER)
577 marker = lustre_cfg_buf(lcfg, 1);
578 if ((strcmp(mml->mml_marker.cm_comment, marker->cm_comment) == 0) &&
579 (strcmp(mml->mml_marker.cm_tgtname, marker->cm_tgtname) == 0) &&
580 !(marker->cm_flags & CM_SKIP)) {
581 /* Found a non-skipped marker match */
582 CDEBUG(D_MGS, "Changing rec %u marker %d %x->%x: %s %s\n",
583 rec->lrh_index, marker->cm_step,
584 marker->cm_flags, mml->mml_marker.cm_flags,
585 marker->cm_tgtname, marker->cm_comment);
586 /* Overwrite the old marker llog entry */
587 marker->cm_flags &= ~CM_EXCLUDE; /* in case we're unexcluding */
588 marker->cm_flags |= mml->mml_marker.cm_flags;
589 marker->cm_canceltime = mml->mml_marker.cm_canceltime;
590 /* Header and tail are added back to lrh_len in
591 llog_lvfs_write_rec */
592 rec->lrh_len = cfg_len;
593 rc = llog_write_rec(llh, rec, NULL, 0, (void *)lcfg,
602 /* Modify an existing config log record (for CM_SKIP or CM_EXCLUDE) */
603 static int mgs_modify(struct obd_device *obd, struct fs_db *fsdb,
604 struct mgs_target_info *mti, char *logname,
605 char *devname, char *comment, int flags)
607 struct llog_handle *loghandle;
608 struct lvfs_run_ctxt saved;
609 struct mgs_modify_lookup *mml;
613 CDEBUG(D_MGS, "modify %s/%s/%s\n", logname, devname, comment);
615 push_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
617 rc = llog_create(llog_get_context(obd, LLOG_CONFIG_ORIG_CTXT),
618 &loghandle, NULL, logname);
622 rc = llog_init_handle(loghandle, LLOG_F_IS_PLAIN, NULL);
626 if (llog_get_size(loghandle) <= 1)
627 GOTO(out_close, rc = 0);
631 GOTO(out_close, rc = -ENOMEM);
632 strcpy(mml->mml_marker.cm_comment, comment);
633 strcpy(mml->mml_marker.cm_tgtname, devname);
634 /* Modify mostly means cancel */
635 mml->mml_marker.cm_flags = flags;
636 mml->mml_marker.cm_canceltime = flags ? cfs_time_current_sec() : 0;
637 mml->mml_modified = 0;
638 rc = llog_process(loghandle, mgs_modify_handler, (void *)mml, NULL);
639 if (!rc && !mml->mml_modified)
644 rc2 = llog_close(loghandle);
649 pop_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
650 if (rc && rc != -ENODEV)
651 CERROR("modify %s/%s failed %d\n",
652 mti->mti_svname, comment, rc);
657 /******************** config log recording functions *********************/
659 static int record_lcfg(struct obd_device *obd, struct llog_handle *llh,
660 struct lustre_cfg *lcfg)
662 struct lvfs_run_ctxt saved;
663 struct llog_rec_hdr rec;
669 LASSERT(llh->lgh_ctxt);
671 buflen = lustre_cfg_len(lcfg->lcfg_bufcount,
673 rec.lrh_len = llog_data_len(buflen);
674 rec.lrh_type = OBD_CFG_REC;
676 push_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
677 /* idx = -1 means append */
678 rc = llog_write_rec(llh, &rec, NULL, 0, (void *)lcfg, -1);
679 pop_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
681 CERROR("failed %d\n", rc);
685 static int record_base(struct obd_device *obd, struct llog_handle *llh,
686 char *cfgname, lnet_nid_t nid, int cmd,
687 char *s1, char *s2, char *s3, char *s4)
689 struct lustre_cfg_bufs bufs;
690 struct lustre_cfg *lcfg;
693 CDEBUG(D_MGS, "lcfg %s %#x %s %s %s %s\n", cfgname,
694 cmd, s1, s2, s3, s4);
696 lustre_cfg_bufs_reset(&bufs, cfgname);
698 lustre_cfg_bufs_set_string(&bufs, 1, s1);
700 lustre_cfg_bufs_set_string(&bufs, 2, s2);
702 lustre_cfg_bufs_set_string(&bufs, 3, s3);
704 lustre_cfg_bufs_set_string(&bufs, 4, s4);
706 lcfg = lustre_cfg_new(cmd, &bufs);
709 lcfg->lcfg_nid = nid;
711 rc = record_lcfg(obd, llh, lcfg);
713 lustre_cfg_free(lcfg);
716 CERROR("error %d: lcfg %s %#x %s %s %s %s\n", rc, cfgname,
717 cmd, s1, s2, s3, s4);
723 static inline int record_add_uuid(struct obd_device *obd,
724 struct llog_handle *llh,
725 uint64_t nid, char *uuid)
727 return record_base(obd,llh,NULL,nid,LCFG_ADD_UUID,uuid,0,0,0);
731 static inline int record_add_conn(struct obd_device *obd,
732 struct llog_handle *llh,
736 return record_base(obd,llh,devname,0,LCFG_ADD_CONN,uuid,0,0,0);
739 static inline int record_attach(struct obd_device *obd, struct llog_handle *llh,
740 char *devname, char *type, char *uuid)
742 return record_base(obd,llh,devname,0,LCFG_ATTACH,type,uuid,0,0);
745 static inline int record_setup(struct obd_device *obd, struct llog_handle *llh,
747 char *s1, char *s2, char *s3, char *s4)
749 return record_base(obd,llh,devname,0,LCFG_SETUP,s1,s2,s3,s4);
752 static inline int record_sptlrpc_conf(struct obd_device *obd,
753 struct llog_handle *llh,
755 struct sptlrpc_conf_log *srpc_log)
757 struct lustre_cfg_bufs bufs;
758 struct lustre_cfg *lcfg;
761 lustre_cfg_bufs_reset(&bufs, devname);
762 lustre_cfg_bufs_set(&bufs, 1, srpc_log, sizeof(*srpc_log));
763 lcfg = lustre_cfg_new(LCFG_SPTLRPC_CONF, &bufs);
765 rc = record_lcfg(obd, llh, lcfg);
767 lustre_cfg_free(lcfg);
771 static int record_lov_setup(struct obd_device *obd, struct llog_handle *llh,
772 char *devname, struct lov_desc *desc)
774 struct lustre_cfg_bufs bufs;
775 struct lustre_cfg *lcfg;
778 lustre_cfg_bufs_reset(&bufs, devname);
779 lustre_cfg_bufs_set(&bufs, 1, desc, sizeof(*desc));
780 lcfg = lustre_cfg_new(LCFG_SETUP, &bufs);
783 rc = record_lcfg(obd, llh, lcfg);
785 lustre_cfg_free(lcfg);
789 static int record_lmv_setup(struct obd_device *obd, struct llog_handle *llh,
790 char *devname, struct lmv_desc *desc)
792 struct lustre_cfg_bufs bufs;
793 struct lustre_cfg *lcfg;
796 lustre_cfg_bufs_reset(&bufs, devname);
797 lustre_cfg_bufs_set(&bufs, 1, desc, sizeof(*desc));
798 lcfg = lustre_cfg_new(LCFG_SETUP, &bufs);
800 rc = record_lcfg(obd, llh, lcfg);
802 lustre_cfg_free(lcfg);
806 static inline int record_mdc_add(struct obd_device *obd,
807 struct llog_handle *llh,
808 char *logname, char *mdcuuid,
809 char *mdtuuid, char *index,
812 return record_base(obd,llh,logname,0,LCFG_ADD_MDC,
813 mdtuuid,index,gen,mdcuuid);
816 static inline int record_lov_add(struct obd_device *obd,
817 struct llog_handle *llh,
818 char *lov_name, char *ost_uuid,
819 char *index, char *gen)
821 return record_base(obd,llh,lov_name,0,LCFG_LOV_ADD_OBD,
822 ost_uuid,index,gen,0);
825 static inline int record_mount_opt(struct obd_device *obd,
826 struct llog_handle *llh,
827 char *profile, char *lov_name,
830 return record_base(obd,llh,NULL,0,LCFG_MOUNTOPT,
831 profile,lov_name,mdc_name,0);
834 static int record_marker(struct obd_device *obd, struct llog_handle *llh,
835 struct fs_db *fsdb, __u32 flags,
836 char *tgtname, char *comment)
838 struct cfg_marker marker;
839 struct lustre_cfg_bufs bufs;
840 struct lustre_cfg *lcfg;
843 if (flags & CM_START)
845 marker.cm_step = fsdb->fsdb_gen;
846 marker.cm_flags = flags;
847 marker.cm_vers = LUSTRE_VERSION_CODE;
848 strncpy(marker.cm_tgtname, tgtname, sizeof(marker.cm_tgtname));
849 strncpy(marker.cm_comment, comment, sizeof(marker.cm_comment));
850 marker.cm_createtime = cfs_time_current_sec();
851 marker.cm_canceltime = 0;
852 lustre_cfg_bufs_reset(&bufs, NULL);
853 lustre_cfg_bufs_set(&bufs, 1, &marker, sizeof(marker));
854 lcfg = lustre_cfg_new(LCFG_MARKER, &bufs);
857 rc = record_lcfg(obd, llh, lcfg);
859 lustre_cfg_free(lcfg);
863 static int record_start_log(struct obd_device *obd,
864 struct llog_handle **llh, char *name)
866 static struct obd_uuid cfg_uuid = { .uuid = "config_uuid" };
867 struct lvfs_run_ctxt saved;
871 GOTO(out, rc = -EBUSY);
874 push_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
876 rc = llog_create(llog_get_context(obd, LLOG_CONFIG_ORIG_CTXT),
879 llog_init_handle(*llh, LLOG_F_IS_PLAIN, &cfg_uuid);
883 pop_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
887 CERROR("Can't start log %s: %d\n", name, rc);
892 static int record_end_log(struct obd_device *obd, struct llog_handle **llh)
894 struct lvfs_run_ctxt saved;
897 push_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
899 rc = llog_close(*llh);
902 pop_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
906 static int mgs_log_is_empty(struct obd_device *obd, char *name)
908 struct lvfs_run_ctxt saved;
909 struct llog_handle *llh;
912 push_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
913 rc = llog_create(llog_get_context(obd, LLOG_CONFIG_ORIG_CTXT),
916 llog_init_handle(llh, LLOG_F_IS_PLAIN, NULL);
917 rc = llog_get_size(llh);
920 pop_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
921 /* header is record 1 */
925 /******************** config "macros" *********************/
927 /* write an lcfg directly into a log (with markers) */
928 static int mgs_write_log_direct(struct obd_device *obd, struct fs_db *fsdb,
929 char *logname, struct lustre_cfg *lcfg,
930 char *devname, char *comment)
932 struct llog_handle *llh = NULL;
939 rc = record_start_log(obd, &llh, logname);
943 /* FIXME These should be a single journal transaction */
944 rc = record_marker(obd, llh, fsdb, CM_START, devname, comment);
946 rc = record_lcfg(obd, llh, lcfg);
948 rc = record_marker(obd, llh, fsdb, CM_END, devname, comment);
949 rc = record_end_log(obd, &llh);
954 /* write the lcfg in all logs for the given fs */
955 int mgs_write_log_direct_all(struct obd_device *obd, struct fs_db *fsdb,
956 struct mgs_target_info *mti,
957 struct lustre_cfg *lcfg,
958 char *devname, char *comment)
960 struct mgs_obd *mgs = &obd->u.mgs;
961 struct list_head dentry_list;
962 struct l_linux_dirent *dirent, *n;
963 char *fsname = mti->mti_fsname;
965 int rc = 0, len = strlen(fsname);
968 /* We need to set params for any future logs
969 as well. FIXME Append this file to every new log.
970 Actually, we should store as params (text), not llogs. Or
972 name_create(&logname, fsname, "-params");
973 if (mgs_log_is_empty(obd, logname)) {
974 struct llog_handle *llh = NULL;
975 rc = record_start_log(obd, &llh, logname);
976 record_end_log(obd, &llh);
978 name_destroy(&logname);
982 /* Find all the logs in the CONFIGS directory */
983 rc = class_dentry_readdir(obd, mgs->mgs_configs_dir,
984 mgs->mgs_vfsmnt, &dentry_list);
986 CERROR("Can't read %s dir\n", MOUNT_CONFIGS_DIR);
990 /* Could use fsdb index maps instead of directory listing */
991 list_for_each_entry_safe(dirent, n, &dentry_list, lld_list) {
992 list_del(&dirent->lld_list);
993 /* don't write to sptlrpc rule log */
994 if (strncmp(fsname, dirent->lld_name, len) == 0 &&
995 strstr(dirent->lld_name, "-sptlrpc") == NULL) {
996 CDEBUG(D_MGS, "Changing log %s\n", dirent->lld_name);
997 /* Erase any old settings of this same parameter */
998 mgs_modify(obd, fsdb, mti, dirent->lld_name, devname,
1000 /* Write the new one */
1001 rc = mgs_write_log_direct(obd, fsdb, dirent->lld_name,
1002 lcfg, devname, comment);
1004 CERROR("err %d writing log %s\n", rc,
1007 OBD_FREE(dirent, sizeof(*dirent));
1015 struct mgs_target_info *comp_tmti;
1016 struct mgs_target_info *comp_mti;
1017 struct fs_db *comp_fsdb;
1018 struct obd_device *comp_obd;
1021 static int mgs_write_log_mdc_to_mdt(struct obd_device *, struct fs_db *,
1022 struct mgs_target_info *, char *);
1024 static int mgs_steal_llog_handler(struct llog_handle *llh,
1025 struct llog_rec_hdr *rec,
1028 struct obd_device * obd;
1029 struct mgs_target_info *mti, *tmti;
1031 int cfg_len = rec->lrh_len;
1032 char *cfg_buf = (char*) (rec + 1);
1033 struct lustre_cfg *lcfg;
1035 struct llog_handle *mdt_llh = NULL;
1036 static int got_an_osc_or_mdc = 0;
1037 /* 0: not found any osc/mdc;
1041 static int last_step = -1;
1045 mti = ((struct temp_comp*)data)->comp_mti;
1046 tmti = ((struct temp_comp*)data)->comp_tmti;
1047 fsdb = ((struct temp_comp*)data)->comp_fsdb;
1048 obd = ((struct temp_comp*)data)->comp_obd;
1050 if (rec->lrh_type != OBD_CFG_REC) {
1051 CERROR("unhandled lrh_type: %#x\n", rec->lrh_type);
1055 rc = lustre_cfg_sanity_check(cfg_buf, cfg_len);
1057 CERROR("Insane cfg\n");
1061 lcfg = (struct lustre_cfg *)cfg_buf;
1063 if (lcfg->lcfg_command == LCFG_MARKER) {
1064 struct cfg_marker *marker;
1065 marker = lustre_cfg_buf(lcfg, 1);
1066 if (!strncmp(marker->cm_comment,"add osc",7) &&
1067 (marker->cm_flags & CM_START)){
1068 got_an_osc_or_mdc = 1;
1069 rc = record_start_log(obd, &mdt_llh, mti->mti_svname);
1070 rc = record_marker(obd, mdt_llh, fsdb, CM_START,
1071 mti->mti_svname,"add osc(copied)");
1072 rc = record_end_log(obd, &mdt_llh);
1073 last_step = marker->cm_step;
1076 if (!strncmp(marker->cm_comment,"add osc",7) &&
1077 (marker->cm_flags & CM_END)){
1078 LASSERT(last_step == marker->cm_step);
1080 got_an_osc_or_mdc = 0;
1081 rc = record_start_log(obd, &mdt_llh, mti->mti_svname);
1082 rc = record_marker(obd, mdt_llh, fsdb, CM_END,
1083 mti->mti_svname,"add osc(copied)");
1084 rc = record_end_log(obd, &mdt_llh);
1087 if (!strncmp(marker->cm_comment,"add mdc",7) &&
1088 (marker->cm_flags & CM_START)){
1089 got_an_osc_or_mdc = 2;
1090 last_step = marker->cm_step;
1091 memcpy(tmti->mti_svname, marker->cm_tgtname,
1092 strlen(marker->cm_tgtname));
1096 if (!strncmp(marker->cm_comment,"add mdc",7) &&
1097 (marker->cm_flags & CM_END)){
1098 LASSERT(last_step == marker->cm_step);
1100 got_an_osc_or_mdc = 0;
1105 if (got_an_osc_or_mdc == 0 || last_step < 0)
1108 if (lcfg->lcfg_command == LCFG_ADD_UUID) {
1110 nodenid = lcfg->lcfg_nid;
1112 tmti->mti_nids[tmti->mti_nid_count] = nodenid;
1113 tmti->mti_nid_count++;
1118 if (lcfg->lcfg_command == LCFG_SETUP) {
1121 target = lustre_cfg_string(lcfg, 1);
1122 memcpy(tmti->mti_uuid, target, strlen(target));
1126 /* ignore client side sptlrpc_conf_log */
1127 if (lcfg->lcfg_command == LCFG_SPTLRPC_CONF)
1130 if (lcfg->lcfg_command == LCFG_ADD_MDC) {
1133 if (sscanf(lustre_cfg_buf(lcfg, 2), "%d", &index) != 1)
1136 memcpy(tmti->mti_fsname, mti->mti_fsname,
1137 strlen(mti->mti_fsname));
1138 tmti->mti_stripe_index = index;
1140 mgs_write_log_mdc_to_mdt(obd, fsdb, tmti, mti->mti_svname);
1141 memset(tmti, 0, sizeof(*tmti));
1147 /* fsdb->fsdb_sem is already held in mgs_write_log_target*/
1148 /* stealed from mgs_get_fsdb_from_llog*/
1149 static int mgs_steal_llog_for_mdt_from_client(struct obd_device *obd,
1151 struct temp_comp* comp)
1153 struct llog_handle *loghandle;
1154 struct lvfs_run_ctxt saved;
1155 struct mgs_target_info *tmti;
1159 OBD_ALLOC_PTR(tmti);
1163 comp->comp_tmti = tmti;
1164 comp->comp_obd = obd;
1166 push_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
1168 rc = llog_create(llog_get_context(obd, LLOG_CONFIG_ORIG_CTXT),
1169 &loghandle, NULL, client_name);
1173 rc = llog_init_handle(loghandle, LLOG_F_IS_PLAIN, NULL);
1175 GOTO(out_close, rc);
1177 rc = llog_process(loghandle, mgs_steal_llog_handler, (void *)comp, NULL);
1178 CDEBUG(D_MGS, "steal llog re = %d\n", rc);
1180 rc2 = llog_close(loghandle);
1184 pop_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
1189 /* lmv is the second thing for client logs */
1190 /* copied from mgs_write_log_lov. Please refer to that. */
1191 static int mgs_write_log_lmv(struct obd_device *obd, struct fs_db *fsdb,
1192 struct mgs_target_info *mti,
1193 char *logname, char *lmvname)
1195 struct llog_handle *llh = NULL;
1196 struct lmv_desc *lmvdesc;
1201 CDEBUG(D_MGS, "Writing lmv(%s) log for %s\n", lmvname,logname);
1203 OBD_ALLOC(lmvdesc, sizeof(*lmvdesc));
1204 if (lmvdesc == NULL)
1206 lmvdesc->ld_active_tgt_count = 0;
1207 lmvdesc->ld_tgt_count = 0;
1208 sprintf((char*)lmvdesc->ld_uuid.uuid, "%s_UUID", lmvname);
1209 uuid = (char *)lmvdesc->ld_uuid.uuid;
1211 rc = record_start_log(obd, &llh, logname);
1212 rc = record_marker(obd, llh, fsdb, CM_START, lmvname, "lmv setup");
1213 rc = record_attach(obd, llh, lmvname, "lmv", uuid);
1214 rc = record_lmv_setup(obd, llh, lmvname, lmvdesc);
1215 rc = record_marker(obd, llh, fsdb, CM_END, lmvname, "lmv setup");
1216 rc = record_end_log(obd, &llh);
1218 OBD_FREE(lmvdesc, sizeof(*lmvdesc));
1221 /***************************************END PROTO**********************/
1223 /* lov is the first thing in the mdt and client logs */
1224 static int mgs_write_log_lov(struct obd_device *obd, struct fs_db *fsdb,
1225 struct mgs_target_info *mti,
1226 char *logname, char *lovname)
1228 struct llog_handle *llh = NULL;
1229 struct lov_desc *lovdesc;
1234 CDEBUG(D_MGS, "Writing lov(%s) log for %s\n", lovname, logname);
1237 #01 L attach 0:lov_mdsA 1:lov 2:71ccb_lov_mdsA_19f961a9e1
1238 #02 L lov_setup 0:lov_mdsA 1:(struct lov_desc)
1239 uuid=lov1_UUID, stripe count=1, size=1048576, offset=0, pattern=0
1242 /* FIXME just make lov_setup accept empty desc (put uuid in buf 2) */
1243 OBD_ALLOC(lovdesc, sizeof(*lovdesc));
1244 if (lovdesc == NULL)
1246 lovdesc->ld_magic = LOV_DESC_MAGIC;
1247 lovdesc->ld_tgt_count = 0;
1248 /* Defaults. Can be changed later by lcfg config_param */
1249 lovdesc->ld_default_stripe_count = 1;
1250 lovdesc->ld_pattern = LOV_PATTERN_RAID0;
1251 lovdesc->ld_default_stripe_size = 1024 * 1024;
1252 lovdesc->ld_default_stripe_offset = 0;
1253 lovdesc->ld_qos_maxage = QOS_DEFAULT_MAXAGE;
1254 sprintf((char*)lovdesc->ld_uuid.uuid, "%s_UUID", lovname);
1255 /* can these be the same? */
1256 uuid = (char *)lovdesc->ld_uuid.uuid;
1258 /* This should always be the first entry in a log.
1259 rc = mgs_clear_log(obd, logname); */
1260 rc = record_start_log(obd, &llh, logname);
1263 /* FIXME these should be a single journal transaction */
1264 rc = record_marker(obd, llh, fsdb, CM_START, lovname, "lov setup");
1265 rc = record_attach(obd, llh, lovname, "lov", uuid);
1266 rc = record_lov_setup(obd, llh, lovname, lovdesc);
1267 rc = record_marker(obd, llh, fsdb, CM_END, lovname, "lov setup");
1268 rc = record_end_log(obd, &llh);
1270 OBD_FREE(lovdesc, sizeof(*lovdesc));
1274 /* add failnids to open log */
1275 static int mgs_write_log_failnids(struct obd_device *obd,
1276 struct mgs_target_info *mti,
1277 struct llog_handle *llh,
1280 char *failnodeuuid = NULL;
1281 char *ptr = mti->mti_params;
1286 #03 L add_uuid nid=uml1@tcp(0x20000c0a80201) nal=90 0: 1:uml1_UUID
1287 #04 L add_uuid nid=1@elan(0x1000000000001) nal=90 0: 1:uml1_UUID
1288 #05 L setup 0:OSC_uml1_ost1_mdsA 1:ost1_UUID 2:uml1_UUID
1289 #06 L add_uuid nid=uml2@tcp(0x20000c0a80202) nal=90 0: 1:uml2_UUID
1290 #0x L add_uuid nid=2@elan(0x1000000000002) nal=90 0: 1:uml2_UUID
1291 #07 L add_conn 0:OSC_uml1_ost1_mdsA 1:uml2_UUID
1294 /* Pull failnid info out of params string */
1295 while (class_find_param(ptr, PARAM_FAILNODE, &ptr) == 0) {
1296 while (class_parse_nid(ptr, &nid, &ptr) == 0) {
1297 if (failnodeuuid == NULL) {
1298 /* We don't know the failover node name,
1299 so just use the first nid as the uuid */
1300 rc = name_create(&failnodeuuid,
1301 libcfs_nid2str(nid), "");
1305 CDEBUG(D_MGS, "add nid %s for failover uuid %s, "
1306 "client %s\n", libcfs_nid2str(nid),
1307 failnodeuuid, cliname);
1308 rc = record_add_uuid(obd, llh, nid, failnodeuuid);
1311 rc = record_add_conn(obd, llh, cliname, failnodeuuid);
1312 name_destroy(&failnodeuuid);
1313 failnodeuuid = NULL;
1320 static int mgs_write_log_mdc_to_lmv(struct obd_device *obd, struct fs_db *fsdb,
1321 struct mgs_target_info *mti,
1322 char *logname, char *lmvname)
1324 struct llog_handle *llh = NULL;
1325 struct sptlrpc_conf_log *srpc_log;
1326 char *mdcname, *nodeuuid, *mdcuuid, *lmvuuid;
1331 if (mgs_log_is_empty(obd, logname)) {
1332 CERROR("log is empty! Logical error\n");
1336 CDEBUG(D_MGS, "adding mdc for %s to log %s:lmv(%s)\n",
1337 mti->mti_svname, logname, lmvname);
1339 srpc_log = sptlrpc_conf_log_alloc();
1340 if (IS_ERR(srpc_log))
1341 RETURN(PTR_ERR(srpc_log));
1342 srpc_log->scl_part = LUSTRE_SP_CLI;
1344 rc = mgs_get_srpc_conf_log(fsdb, mti->mti_svname,
1345 LUSTRE_SP_CLI, LUSTRE_SP_MDT, srpc_log);
1349 name_create(&nodeuuid, libcfs_nid2str(mti->mti_nids[0]), "");
1350 name_create(&mdcname, mti->mti_svname, "-mdc");
1351 name_create(&mdcuuid, mdcname, "_UUID");
1352 name_create(&lmvuuid, lmvname, "_UUID");
1354 rc = record_start_log(obd, &llh, logname);
1355 rc = record_marker(obd, llh, fsdb, CM_START, mti->mti_svname,
1358 for (i = 0; i < mti->mti_nid_count; i++) {
1359 CDEBUG(D_MGS, "add nid %s for mdt\n",
1360 libcfs_nid2str(mti->mti_nids[i]));
1362 rc = record_add_uuid(obd, llh, mti->mti_nids[i], nodeuuid);
1365 rc = record_attach(obd, llh, mdcname, LUSTRE_MDC_NAME, lmvuuid);
1366 rc = record_setup(obd, llh, mdcname, mti->mti_uuid, nodeuuid, 0, 0);
1367 rc = record_sptlrpc_conf(obd, llh, mdcname, srpc_log);
1368 rc = mgs_write_log_failnids(obd, mti, llh, mdcname);
1369 snprintf(index, sizeof(index), "%d", mti->mti_stripe_index);
1370 rc = record_mdc_add(obd, llh, lmvname, mdcuuid, mti->mti_uuid,
1372 rc = record_marker(obd, llh, fsdb, CM_END, mti->mti_svname,
1374 rc = record_end_log(obd, &llh);
1376 name_destroy(&lmvuuid);
1377 name_destroy(&mdcuuid);
1378 name_destroy(&mdcname);
1379 name_destroy(&nodeuuid);
1381 sptlrpc_conf_log_free(srpc_log);
1385 /* add new mdc to already existent MDS */
1386 static int mgs_write_log_mdc_to_mdt(struct obd_device *obd, struct fs_db *fsdb,
1387 struct mgs_target_info *mti, char *logname)
1389 struct llog_handle *llh = NULL;
1390 struct sptlrpc_conf_log *srpc_log;
1391 char *nodeuuid, *mdcname, *mdcuuid, *mdtuuid;
1392 int idx = mti->mti_stripe_index;
1397 if (mgs_log_is_empty(obd, mti->mti_svname)) {
1398 CERROR("log is empty! Logical error\n");
1402 CDEBUG(D_MGS, "adding mdc index %d to %s\n", idx, logname);
1404 srpc_log = sptlrpc_conf_log_alloc();
1405 if (IS_ERR(srpc_log))
1406 RETURN(PTR_ERR(srpc_log));
1407 srpc_log->scl_part = LUSTRE_SP_MDT;
1409 rc = mgs_get_srpc_conf_log(fsdb, mti->mti_svname,
1410 LUSTRE_SP_MDT, LUSTRE_SP_MDT, srpc_log);
1414 name_create(&nodeuuid, libcfs_nid2str(mti->mti_nids[0]), "");
1415 snprintf(index, sizeof(index), "-mdc%04x", idx);
1416 name_create(&mdcname, logname, index);
1417 name_create(&mdcuuid, mdcname, "_UUID");
1418 name_create(&mdtuuid, logname, "_UUID");
1420 rc = record_start_log(obd, &llh, logname);
1421 rc = record_marker(obd, llh, fsdb, CM_START, mti->mti_svname, "add mdc");
1422 for (i = 0; i < mti->mti_nid_count; i++) {
1423 CDEBUG(D_MGS, "add nid %s for mdt\n",
1424 libcfs_nid2str(mti->mti_nids[i]));
1425 rc = record_add_uuid(obd, llh, mti->mti_nids[i], nodeuuid);
1427 rc = record_attach(obd, llh, mdcname, LUSTRE_MDC_NAME, mdcuuid);
1428 rc = record_setup(obd, llh, mdcname, mti->mti_uuid, nodeuuid, 0, 0);
1429 rc = record_sptlrpc_conf(obd, llh, mdcname, srpc_log);
1430 rc = mgs_write_log_failnids(obd, mti, llh, mdcname);
1431 snprintf(index, sizeof(index), "%d", idx);
1433 rc = record_mdc_add(obd, llh, logname, mdcuuid, mti->mti_uuid,
1435 rc = record_marker(obd, llh, fsdb, CM_END, mti->mti_svname, "add mdc");
1436 rc = record_end_log(obd, &llh);
1438 name_destroy(&mdcuuid);
1439 name_destroy(&mdcname);
1440 name_destroy(&nodeuuid);
1441 name_destroy(&mdtuuid);
1443 sptlrpc_conf_log_free(srpc_log);
1447 static int mgs_write_log_mdt0(struct obd_device *obd, struct fs_db *fsdb,
1448 struct mgs_target_info *mti)
1450 char *log = mti->mti_svname;
1451 struct llog_handle *llh = NULL;
1452 char *uuid, *lovname;
1454 struct sptlrpc_conf_log *srpc_log;
1455 char *ptr = mti->mti_params;
1456 int rc = 0, failout = 0;
1459 srpc_log = sptlrpc_conf_log_alloc();
1460 if (IS_ERR(srpc_log))
1461 RETURN(PTR_ERR(srpc_log));
1462 srpc_log->scl_part = LUSTRE_SP_MDT;
1464 rc = mgs_get_srpc_conf_log(fsdb, mti->mti_svname,
1465 LUSTRE_SP_ANY, LUSTRE_SP_MDT, srpc_log);
1469 OBD_ALLOC(uuid, sizeof(struct obd_uuid));
1471 GOTO(out_srpc, rc = -ENOMEM);
1473 if (class_find_param(ptr, PARAM_FAILMODE, &ptr) == 0)
1474 failout = (strncmp(ptr, "failout", 7) == 0);
1476 name_create(&lovname, log, "-mdtlov");
1477 if (mgs_log_is_empty(obd, log))
1478 rc = mgs_write_log_lov(obd, fsdb, mti, log, lovname);
1480 sprintf(uuid, "%s_UUID", log);
1481 sprintf(mdt_index,"%d",mti->mti_stripe_index);
1483 /* add MDT itself */
1484 rc = record_start_log(obd, &llh, log);
1488 /* FIXME this whole fn should be a single journal transaction */
1489 rc = record_marker(obd, llh, fsdb, CM_START, log, "add mdt");
1490 rc = record_attach(obd, llh, log, LUSTRE_MDT_NAME, uuid);
1491 rc = record_mount_opt(obd, llh, log, lovname, NULL);
1492 rc = record_setup(obd, llh, log, uuid, mdt_index, lovname,
1493 failout ? "n" : "f");
1494 rc = record_sptlrpc_conf(obd, llh, log, srpc_log);
1495 rc = record_marker(obd, llh, fsdb, CM_END, log, "add mdt");
1496 rc = record_end_log(obd, &llh);
1498 name_destroy(&lovname);
1499 OBD_FREE(uuid, sizeof(struct obd_uuid));
1501 sptlrpc_conf_log_free(srpc_log);
1505 /* envelope method for all layers log */
1506 static int mgs_write_log_mdt(struct obd_device *obd, struct fs_db *fsdb,
1507 struct mgs_target_info *mti)
1509 struct llog_handle *llh = NULL;
1511 struct temp_comp comp = { 0 };
1516 CDEBUG(D_MGS, "writing new mdt %s\n", mti->mti_svname);
1520 if (mti->mti_flags & LDD_F_UPGRADE14) {
1521 /* We're starting with an old uuid. Assume old name for lov
1522 as well since the lov entry already exists in the log. */
1523 CDEBUG(D_MGS, "old mds uuid %s\n", mti->mti_uuid);
1524 if (strncmp(mti->mti_uuid, fsdb->fsdb_mdtlov + 4,
1525 strlen(fsdb->fsdb_mdtlov) - 4) != 0) {
1526 CERROR("old mds uuid %s doesn't match log %s (%s)\n",
1527 mti->mti_uuid, fsdb->fsdb_mdtlov,
1528 fsdb->fsdb_mdtlov + 4);
1532 /* end COMPAT_146 */
1534 if (mti->mti_uuid[0] == '\0') {
1535 /* Make up our own uuid */
1536 snprintf(mti->mti_uuid, sizeof(mti->mti_uuid),
1537 "%s_UUID", mti->mti_svname);
1541 rc = mgs_write_log_mdt0(obd, fsdb, mti);
1543 /* Append the mdt info to the client log */
1544 name_create(&cliname, mti->mti_fsname, "-client");
1546 if (mgs_log_is_empty(obd, cliname)) {
1547 /* Start client log */
1548 rc = mgs_write_log_lov(obd, fsdb, mti, cliname,
1550 rc = mgs_write_log_lmv(obd, fsdb, mti, cliname,
1555 #09 L add_uuid nid=uml1@tcp(0x20000c0a80201) 0: 1:uml1_UUID
1556 #10 L attach 0:MDC_uml1_mdsA_MNT_client 1:mdc 2:1d834_MNT_client_03f
1557 #11 L setup 0:MDC_uml1_mdsA_MNT_client 1:mdsA_UUID 2:uml1_UUID
1558 #12 L add_uuid nid=uml2@tcp(0x20000c0a80202) 0: 1:uml2_UUID
1559 #13 L add_conn 0:MDC_uml1_mdsA_MNT_client 1:uml2_UUID
1560 #14 L mount_option 0: 1:client 2:lov1 3:MDC_uml1_mdsA_MNT_client
1565 if (mti->mti_flags & LDD_F_UPGRADE14) {
1566 rc = record_start_log(obd, &llh, cliname);
1570 rc = record_marker(obd, llh, fsdb, CM_START,
1571 mti->mti_svname,"add mdc");
1573 /* Old client log already has MDC entry, but needs mount opt
1574 for new client name (lustre-client) */
1575 /* FIXME Old MDT log already has an old mount opt
1576 which we should remove (currently handled by
1577 class_del_profiles()) */
1578 rc = record_mount_opt(obd, llh, cliname, fsdb->fsdb_clilov,
1580 /* end COMPAT_146 */
1582 rc = record_marker(obd, llh, fsdb, CM_END,
1583 mti->mti_svname, "add mdc");
1587 /* copy client info about lov/lmv */
1588 comp.comp_mti = mti;
1589 comp.comp_fsdb = fsdb;
1591 rc = mgs_steal_llog_for_mdt_from_client(obd, cliname,
1594 rc = mgs_write_log_mdc_to_lmv(obd, fsdb, mti, cliname,
1597 rc = record_start_log(obd, &llh, cliname);
1601 rc = record_marker(obd, llh, fsdb, CM_START, cliname,
1603 rc = record_mount_opt(obd, llh, cliname, fsdb->fsdb_clilov,
1605 rc = record_marker(obd, llh, fsdb, CM_END, cliname,
1609 rc = record_end_log(obd, &llh);
1611 name_destroy(&cliname);
1613 // for_all_existing_mdt except current one
1614 for (i = 0; i < INDEX_MAP_SIZE * 8; i++){
1616 if (i != mti->mti_stripe_index &&
1617 test_bit(i, fsdb->fsdb_mdt_index_map)) {
1618 sprintf(mdt_index,"-MDT%04x",i);
1620 name_create(&mdtname, mti->mti_fsname, mdt_index);
1621 rc = mgs_write_log_mdc_to_mdt(obd, fsdb, mti, mdtname);
1622 name_destroy(&mdtname);
1629 /* Add the ost info to the client/mdt lov */
1630 static int mgs_write_log_osc_to_lov(struct obd_device *obd, struct fs_db *fsdb,
1631 struct mgs_target_info *mti,
1632 char *logname, char *suffix, char *lovname,
1633 enum lustre_sec_part sec_part, int flags)
1635 struct llog_handle *llh = NULL;
1636 struct sptlrpc_conf_log *srpc_log;
1637 char *nodeuuid, *oscname, *oscuuid, *lovuuid, *svname;
1642 CDEBUG(D_INFO, "adding osc for %s to log %s\n",
1643 mti->mti_svname, logname);
1645 srpc_log = sptlrpc_conf_log_alloc();
1646 if (IS_ERR(srpc_log))
1647 RETURN(PTR_ERR(srpc_log));
1648 srpc_log->scl_part = sec_part;
1650 rc = mgs_get_srpc_conf_log(fsdb, mti->mti_svname,
1651 sec_part, LUSTRE_SP_OST, srpc_log);
1655 if (mgs_log_is_empty(obd, logname)) {
1656 /* The first item in the log must be the lov, so we have
1657 somewhere to add our osc. */
1658 rc = mgs_write_log_lov(obd, fsdb, mti, logname, lovname);
1661 name_create(&nodeuuid, libcfs_nid2str(mti->mti_nids[0]), "");
1662 name_create(&svname, mti->mti_svname, "-osc");
1663 name_create(&oscname, svname, suffix);
1664 name_create(&oscuuid, oscname, "_UUID");
1665 name_create(&lovuuid, lovname, "_UUID");
1668 #03 L add_uuid nid=uml1@tcp(0x20000c0a80201) 0: 1:uml1_UUID
1670 #04 L add_uuid nid=1@elan(0x1000000000001) nal=90 0: 1:uml1_UUID
1671 #04 L attach 0:OSC_uml1_ost1_MNT_client 1:osc 2:89070_lov1_a41dff51a
1672 #05 L setup 0:OSC_uml1_ost1_MNT_client 1:ost1_UUID 2:uml1_UUID
1674 #06 L add_uuid nid=uml2@tcp(0x20000c0a80202) 0: 1:uml2_UUID
1675 #07 L add_conn 0:OSC_uml1_ost1_MNT_client 1:uml2_UUID
1676 #08 L lov_modify_tgts add 0:lov1 1:ost1_UUID 2(index):0 3(gen):1
1679 rc = record_start_log(obd, &llh, logname);
1682 /* FIXME these should be a single journal transaction */
1683 rc = record_marker(obd, llh, fsdb, CM_START | flags, mti->mti_svname,
1685 for (i = 0; i < mti->mti_nid_count; i++) {
1686 CDEBUG(D_MGS, "add nid %s\n", libcfs_nid2str(mti->mti_nids[i]));
1687 rc = record_add_uuid(obd, llh, mti->mti_nids[i], nodeuuid);
1689 rc = record_attach(obd, llh, oscname, LUSTRE_OSC_NAME, lovuuid);
1690 rc = record_setup(obd, llh, oscname, mti->mti_uuid, nodeuuid, 0, 0);
1691 rc = record_sptlrpc_conf(obd, llh, oscname, srpc_log);
1692 rc = mgs_write_log_failnids(obd, mti, llh, oscname);
1693 snprintf(index, sizeof(index), "%d", mti->mti_stripe_index);
1694 rc = record_lov_add(obd, llh, lovname, mti->mti_uuid, index, "1");
1695 rc = record_marker(obd, llh, fsdb, CM_END | flags, mti->mti_svname,
1697 rc = record_end_log(obd, &llh);
1699 name_destroy(&lovuuid);
1700 name_destroy(&oscuuid);
1701 name_destroy(&oscname);
1702 name_destroy(&svname);
1703 name_destroy(&nodeuuid);
1705 sptlrpc_conf_log_free(srpc_log);
1709 static int mgs_write_log_ost(struct obd_device *obd, struct fs_db *fsdb,
1710 struct mgs_target_info *mti)
1712 struct llog_handle *llh = NULL;
1713 struct sptlrpc_conf_log *srpc_log;
1714 char *logname, *lovname;
1716 char *ptr = mti->mti_params;
1717 int rc, flags = 0, failout = 0, i;
1720 CDEBUG(D_MGS, "writing new ost %s\n", mti->mti_svname);
1722 /* The ost startup log */
1724 /* If the ost log already exists, that means that someone reformatted
1725 the ost and it called target_add again. */
1726 if (!mgs_log_is_empty(obd, mti->mti_svname)) {
1727 LCONSOLE_ERROR_MSG(0x141, "The config log for %s already "
1728 "exists, yet the server claims it never "
1729 "registered. It may have been reformatted, "
1730 "or the index changed. writeconf the MDT to "
1731 "regenerate all logs.\n", mti->mti_svname);
1735 srpc_log = sptlrpc_conf_log_alloc();
1736 if (IS_ERR(srpc_log))
1737 RETURN(PTR_ERR(srpc_log));
1738 srpc_log->scl_part = LUSTRE_SP_OST;
1740 rc = mgs_get_srpc_conf_log(fsdb, mti->mti_svname,
1741 LUSTRE_SP_ANY, LUSTRE_SP_OST, srpc_log);
1746 attach obdfilter ost1 ost1_UUID
1747 setup /dev/loop2 ldiskfs f|n errors=remount-ro,user_xattr
1749 if (class_find_param(ptr, PARAM_FAILMODE, &ptr) == 0)
1750 failout = (strncmp(ptr, "failout", 7) == 0);
1751 rc = record_start_log(obd, &llh, mti->mti_svname);
1754 /* FIXME these should be a single journal transaction */
1755 rc = record_marker(obd, llh, fsdb, CM_START, mti->mti_svname,"add ost");
1756 if (*mti->mti_uuid == '\0')
1757 snprintf(mti->mti_uuid, sizeof(mti->mti_uuid),
1758 "%s_UUID", mti->mti_svname);
1759 rc = record_attach(obd, llh, mti->mti_svname,
1760 "obdfilter"/*LUSTRE_OST_NAME*/, mti->mti_uuid);
1761 rc = record_setup(obd, llh, mti->mti_svname,
1762 "dev"/*ignored*/, "type"/*ignored*/,
1763 failout ? "n" : "f", 0/*options*/);
1764 rc = record_sptlrpc_conf(obd, llh, mti->mti_svname, srpc_log);
1765 rc = record_marker(obd, llh, fsdb, CM_END, mti->mti_svname, "add ost");
1766 rc = record_end_log(obd, &llh);
1768 /* We also have to update the other logs where this osc is part of
1771 if (fsdb->fsdb_flags & FSDB_OLDLOG14) {
1772 /* If we're upgrading, the old mdt log already has our
1773 entry. Let's do a fake one for fun. */
1774 /* Note that we can't add any new failnids, since we don't
1775 know the old osc names. */
1776 flags = CM_SKIP | CM_UPGRADE146;
1778 } else if ((mti->mti_flags & LDD_F_UPDATE) != LDD_F_UPDATE) {
1779 /* If the update flag isn't set, don't update client/mdt
1782 LCONSOLE_WARN("Client log for %s was not updated; writeconf "
1783 "the MDT first to regenerate it.\n",
1787 // for_all_existing_mdt
1788 for (i = 0; i < INDEX_MAP_SIZE * 8; i++){
1789 if (test_bit(i, fsdb->fsdb_mdt_index_map)) {
1790 sprintf(mdt_index,"-MDT%04x",i);
1791 name_create(&logname, mti->mti_fsname, mdt_index);
1792 name_create(&lovname, logname, "-mdtlov");
1793 mgs_write_log_osc_to_lov(obd, fsdb, mti, logname,
1795 LUSTRE_SP_MDT, flags);
1796 name_destroy(&logname);
1797 name_destroy(&lovname);
1801 /* Append ost info to the client log */
1802 name_create(&logname, mti->mti_fsname, "-client");
1803 mgs_write_log_osc_to_lov(obd, fsdb, mti, logname, "",
1804 fsdb->fsdb_clilov, LUSTRE_SP_CLI, 0);
1805 name_destroy(&logname);
1807 sptlrpc_conf_log_free(srpc_log);
1811 /* Add additional failnids to an existing log.
1812 The mdc/osc must have been added to logs first */
1813 /* tcp nids must be in dotted-quad ascii -
1814 we can't resolve hostnames from the kernel. */
1815 static int mgs_write_log_add_failnid(struct obd_device *obd, struct fs_db *fsdb,
1816 struct mgs_target_info *mti)
1818 char *logname, *cliname;
1819 struct llog_handle *llh = NULL;
1823 /* FIXME how do we delete a failnid? Currently --writeconf is the
1824 only way. Maybe make --erase-params pass a flag to really
1825 erase all params from logs - except it can't erase the failnids
1826 given when a target first registers, since they aren't processed
1829 /* Verify that we know about this target */
1830 if (mgs_log_is_empty(obd, mti->mti_svname)) {
1831 LCONSOLE_ERROR_MSG(0x142, "The target %s has not registered "
1832 "yet. It must be started before failnids "
1833 "can be added.\n", mti->mti_svname);
1837 /* Create mdc/osc client name (e.g. lustre-OST0001-osc) */
1838 if (mti->mti_flags & LDD_F_SV_TYPE_MDT) {
1839 name_create(&cliname, mti->mti_svname, "-mdc");
1840 } else if (mti->mti_flags & LDD_F_SV_TYPE_OST) {
1841 name_create(&cliname, mti->mti_svname, "-osc");
1846 /* Add failover nids to client log */
1847 name_create(&logname, mti->mti_fsname, "-client");
1848 rc = record_start_log(obd, &llh, logname);
1850 /* FIXME this fn should be a single journal transaction */
1851 rc = record_marker(obd, llh, fsdb, CM_START, mti->mti_svname,
1853 rc = mgs_write_log_failnids(obd, mti, llh, cliname);
1854 rc = record_marker(obd, llh, fsdb, CM_END, mti->mti_svname,
1856 rc = record_end_log(obd, &llh);
1858 name_destroy(&logname);
1860 if (mti->mti_flags & LDD_F_SV_TYPE_OST) {
1861 /* Add OST failover nids to the MDT log as well */
1862 name_create(&logname, mti->mti_fsname, "-MDT0000");
1863 rc = record_start_log(obd, &llh, logname);
1865 rc = record_marker(obd, llh, fsdb, CM_START,
1866 mti->mti_svname, "add failnid");
1867 rc = mgs_write_log_failnids(obd, mti, llh, cliname);
1868 rc = record_marker(obd, llh, fsdb, CM_END,
1869 mti->mti_svname, "add failnid");
1870 rc = record_end_log(obd, &llh);
1872 name_destroy(&logname);
1875 name_destroy(&cliname);
1879 static int mgs_wlp_lcfg(struct obd_device *obd, struct fs_db *fsdb,
1880 struct mgs_target_info *mti,
1881 char *logname, struct lustre_cfg_bufs *bufs,
1882 char *tgtname, char *ptr)
1884 char comment[MTI_NAME_MAXLEN];
1886 struct lustre_cfg *lcfg;
1889 /* Erase any old settings of this same parameter */
1890 memcpy(comment, ptr, MTI_NAME_MAXLEN);
1891 comment[MTI_NAME_MAXLEN - 1] = 0;
1892 /* But don't try to match the value. */
1893 if ((tmp = strchr(comment, '=')))
1895 /* FIXME we should skip settings that are the same as old values */
1896 rc = mgs_modify(obd, fsdb, mti, logname, tgtname, comment, CM_SKIP);
1897 LCONSOLE_INFO("%sing parameter %s.%s in log %s\n", rc ?
1898 "Sett" : "Modify", tgtname, comment, logname);
1900 lustre_cfg_bufs_reset(bufs, tgtname);
1901 lustre_cfg_bufs_set_string(bufs, 1, ptr);
1902 lcfg = lustre_cfg_new(LCFG_PARAM, bufs);
1905 rc = mgs_write_log_direct(obd, fsdb, logname, lcfg, tgtname, comment);
1906 lustre_cfg_free(lcfg);
1911 * populate rules which applied to a target device
1913 static int mgs_get_srpc_conf_log(struct fs_db *fsdb, const char *tgt,
1914 enum lustre_sec_part from,
1915 enum lustre_sec_part to,
1916 struct sptlrpc_conf_log *log)
1918 struct mgs_tgt_srpc_conf *tgtconf;
1919 struct sptlrpc_rule_set *tgt_rset;
1920 int found_tgt = 0, rc;
1922 for (tgtconf = fsdb->fsdb_srpc_tgt; tgtconf;
1923 tgtconf = tgtconf->mtsc_next) {
1924 if (!strcmp(tgt, tgtconf->mtsc_tgt)) {
1931 tgt_rset = &tgtconf->mtsc_rset;
1935 rc = sptlrpc_conf_log_populate(&fsdb->fsdb_srpc_gen, tgt_rset,
1936 from, to, fsdb->fsdb_srpc_fl_udesc, log);
1938 CERROR("failed to populate srpc log for %s: %d\n", tgt, rc);
1943 struct mgs_msl_data {
1944 struct obd_device *mmd_obd;
1945 struct fs_db *mmd_fsdb;
1946 struct mgs_target_info *mmd_mti;
1950 enum lustre_sec_part mmd_tgtpart;
1951 char mmd_tgtname[MTI_NAME_MAXLEN];
1954 static void mgs_msl_data_cleanup(struct mgs_msl_data *mmd)
1956 mmd->mmd_attached = 0;
1957 mmd->mmd_tgtname[0] = '\0';
1960 static int mgs_msl_tgt_uuid2name(char *tgtname, char *tgtuuid)
1964 if (tgtuuid == NULL) {
1965 CERROR("missing target UUID???\n");
1969 ptr = strstr(tgtuuid, "_UUID");
1971 CERROR("unrecognized UUID: %s\n", tgtuuid);
1976 strncpy(tgtname, tgtuuid, MTI_NAME_MAXLEN);
1977 tgtname[MTI_NAME_MAXLEN - 1] = '\0';
1982 static int mgs_modify_srpc_log_handler(struct llog_handle *llh,
1983 struct llog_rec_hdr *rec,
1986 struct mgs_msl_data *mmd = (struct mgs_msl_data *)data;
1987 struct cfg_marker *marker;
1988 struct lustre_cfg *lcfg = (struct lustre_cfg *)(rec + 1);
1992 if (rec->lrh_type != OBD_CFG_REC) {
1993 CERROR("unhandled lrh_type: %#x\n", rec->lrh_type);
1997 cfg_len = rec->lrh_len - sizeof(struct llog_rec_hdr) -
1998 sizeof(struct llog_rec_tail);
2000 rc = lustre_cfg_sanity_check(lcfg, cfg_len);
2002 CERROR("Insane cfg\n");
2006 if (lcfg->lcfg_command == LCFG_MARKER) {
2007 marker = lustre_cfg_buf(lcfg, 1);
2009 if (marker->cm_flags & CM_START &&
2010 marker->cm_flags & CM_SKIP)
2012 if (marker->cm_flags & CM_END)
2021 switch (lcfg->lcfg_command) {
2023 mmd->mmd_attached = 1;
2025 if (!strcmp(lustre_cfg_string(lcfg, 1), LUSTRE_OST_NAME)) {
2026 mmd->mmd_server = 1;
2027 mmd->mmd_tgtpart = LUSTRE_SP_OST;
2028 } else if (!strcmp(lustre_cfg_string(lcfg, 1),
2030 mmd->mmd_server = 1;
2031 mmd->mmd_tgtpart = LUSTRE_SP_MDT;
2032 } else if (!strcmp(lustre_cfg_string(lcfg, 1),
2034 mmd->mmd_server = 0;
2035 mmd->mmd_tgtpart = LUSTRE_SP_OST;
2036 } else if (!strcmp(lustre_cfg_string(lcfg, 1),
2038 mmd->mmd_server = 0;
2039 mmd->mmd_tgtpart = LUSTRE_SP_MDT;
2041 mmd->mmd_attached = 0;
2044 if (mmd->mmd_attached && mmd->mmd_server) {
2045 rc = mgs_msl_tgt_uuid2name(mmd->mmd_tgtname,
2046 lustre_cfg_string(lcfg, 2));
2048 mgs_msl_data_cleanup(mmd);
2055 if (!mmd->mmd_attached)
2058 /* already got tgtname at LCFG_ATTACH */
2059 if (mmd->mmd_server)
2062 rc = mgs_msl_tgt_uuid2name(mmd->mmd_tgtname,
2063 lustre_cfg_string(lcfg, 1));
2065 mgs_msl_data_cleanup(mmd);
2070 case LCFG_SPTLRPC_CONF: {
2071 struct sptlrpc_conf_log *log;
2072 enum lustre_sec_part from;
2074 if (!mmd->mmd_attached)
2077 log = sptlrpc_conf_log_extract(lcfg);
2079 CERROR("missing sptlrpc config log???\n");
2080 mgs_msl_data_cleanup(mmd);
2084 if (mmd->mmd_server)
2085 from = LUSTRE_SP_ANY;
2087 from = log->scl_part;
2089 /* cleanup the old log */
2090 sptlrpc_conf_log_cleanup(log);
2092 /* populate new log */
2093 rc = mgs_get_srpc_conf_log(mmd->mmd_fsdb, mmd->mmd_tgtname,
2094 from, mmd->mmd_tgtpart, log);
2096 mgs_msl_data_cleanup(mmd);
2100 /* Overwrite the log */
2101 rec->lrh_len = cfg_len;
2102 rc = llog_write_rec(llh, rec, NULL, 0, (void *)lcfg,
2105 CERROR("overwrite sptlrpc conf log failed: %d\n", rc);
2107 /* append new one */
2108 rc = record_marker(mmd->mmd_obd, llh, mmd->mmd_fsdb, CM_START,
2109 mmd->mmd_mti->mti_svname, "sptlrpc config");
2110 rc = record_sptlrpc_conf(mmd->mmd_obd, llh,
2111 lustre_cfg_string(lcfg, 0), log);
2112 rc = record_marker(mmd->mmd_obd, llh, mmd->mmd_fsdb, CM_END,
2113 mmd->mmd_mti->mti_svname, "sptlrpc config");
2115 mgs_msl_data_cleanup(mmd);
2119 /* ignore all others */
2126 static int mgs_modify_srpc_log(struct obd_device *obd,
2128 struct mgs_target_info *mti,
2131 struct llog_handle *llh;
2132 struct lvfs_run_ctxt saved;
2133 struct mgs_msl_data *mmd;
2137 CDEBUG(D_MGS, "modify sptlrpc log for %s\n", logname);
2139 push_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
2141 rc = llog_create(llog_get_context(obd, LLOG_CONFIG_ORIG_CTXT),
2142 &llh, NULL, logname);
2146 rc = llog_init_handle(llh, LLOG_F_IS_PLAIN, NULL);
2148 GOTO(out_close, rc);
2150 if (llog_get_size(llh) <= 1)
2151 GOTO(out_close, rc = 0);
2155 GOTO(out_close, rc = -ENOMEM);
2158 mmd->mmd_fsdb = fsdb;
2161 rc = llog_process(llh, mgs_modify_srpc_log_handler, (void *) mmd, NULL);
2166 rc2 = llog_close(llh);
2171 pop_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
2173 CERROR("modify sptlrpc log %s failed %d\n", logname, rc);
2179 * for each of log, remove old conf at first
2181 static int mgs_modify_srpc_log_all(struct obd_device *obd,
2183 struct mgs_target_info *mti)
2190 for (i = 0; i < INDEX_MAP_SIZE * 8; i++){
2191 if (test_bit(i, fsdb->fsdb_mdt_index_map)) {
2192 sprintf(tgt_index,"-MDT%04x",i);
2194 name_create(&logname, mti->mti_fsname, tgt_index);
2195 rc2 = mgs_modify(obd, fsdb, mti, logname,
2196 mti->mti_fsname, "sptlrpc config",
2198 rc2 = mgs_modify_srpc_log(obd, fsdb, mti, logname);
2199 name_destroy(&logname);
2206 for (i = 0; i < INDEX_MAP_SIZE * 8; i++){
2207 if (test_bit(i, fsdb->fsdb_ost_index_map)) {
2208 sprintf(tgt_index,"-OST%04x",i);
2210 name_create(&logname, mti->mti_fsname, tgt_index);
2211 rc2 = mgs_modify(obd, fsdb, mti, logname,
2212 mti->mti_fsname, "sptlrpc config",
2214 rc2 = mgs_modify_srpc_log(obd, fsdb, mti, logname);
2215 name_destroy(&logname);
2222 name_create(&logname, mti->mti_fsname, "-client");
2223 rc2 = mgs_modify(obd, fsdb, mti, logname,
2224 mti->mti_fsname, "sptlrpc config", CM_SKIP);
2225 rc2 = mgs_modify_srpc_log(obd, fsdb, mti, logname);
2226 name_destroy(&logname);
2234 static int mgs_srpc_set_param_disk(struct obd_device *obd,
2236 struct mgs_target_info *mti,
2239 struct llog_handle *llh = NULL;
2241 char *comment, *ptr;
2242 struct lustre_cfg_bufs bufs;
2243 struct lustre_cfg *lcfg;
2248 ptr = strchr(param, '=');
2252 OBD_ALLOC(comment, len + 1);
2253 if (comment == NULL)
2255 strncpy(comment, param, len);
2256 comment[len] = '\0';
2259 lustre_cfg_bufs_reset(&bufs, mti->mti_svname);
2260 lustre_cfg_bufs_set_string(&bufs, 1, param);
2261 lcfg = lustre_cfg_new(0, &bufs);
2263 GOTO(out_comment, rc = -ENOMEM);
2265 /* construct log name */
2266 rc = name_create(&logname, mti->mti_fsname, "-sptlrpc");
2270 if (mgs_log_is_empty(obd, logname)) {
2271 rc = record_start_log(obd, &llh, logname);
2272 record_end_log(obd, &llh);
2277 /* obsolete old one */
2278 mgs_modify(obd, fsdb, mti, logname, mti->mti_svname, comment, CM_SKIP);
2280 /* write the new one */
2281 rc = mgs_write_log_direct(obd, fsdb, logname, lcfg,
2282 mti->mti_svname, comment);
2284 CERROR("err %d writing log %s\n", rc, logname);
2287 name_destroy(&logname);
2289 lustre_cfg_free(lcfg);
2291 OBD_FREE(comment, len + 1);
2295 static int mgs_srpc_set_param_udesc_mem(struct fs_db *fsdb,
2300 /* disable the adjustable udesc parameter for now, i.e. use default
2301 * setting that client always ship udesc to MDT if possible. to enable
2302 * it simply remove the following line */
2305 ptr = strchr(param, '=');
2310 if (strcmp(param, PARAM_SRPC_UDESC))
2313 if (strcmp(ptr, "yes") == 0) {
2314 fsdb->fsdb_srpc_fl_udesc = 1;
2315 CWARN("Enable user descriptor shipping from client to MDT\n");
2316 } else if (strcmp(ptr, "no") == 0) {
2317 fsdb->fsdb_srpc_fl_udesc = 0;
2318 CWARN("Disable user descriptor shipping from client to MDT\n");
2326 CERROR("Invalid param: %s\n", param);
2330 static int mgs_srpc_set_param_mem(struct fs_db *fsdb,
2334 struct sptlrpc_rule rule;
2335 struct sptlrpc_rule_set *rset;
2339 if (strncmp(param, PARAM_SRPC, sizeof(PARAM_SRPC) - 1) != 0) {
2340 CERROR("Invalid sptlrpc parameter: %s\n", param);
2344 if (strncmp(param, PARAM_SRPC_UDESC,
2345 sizeof(PARAM_SRPC_UDESC) - 1) == 0) {
2346 RETURN(mgs_srpc_set_param_udesc_mem(fsdb, param));
2349 if (strncmp(param, PARAM_SRPC_FLVR, sizeof(PARAM_SRPC_FLVR) - 1) != 0) {
2350 CERROR("Invalid sptlrpc flavor parameter: %s\n", param);
2354 param += sizeof(PARAM_SRPC_FLVR) - 1;
2356 rc = sptlrpc_parse_rule(param, &rule);
2360 /* preapre room for this coming rule. svcname format should be:
2361 * - fsname: general rule
2362 * - fsname-tgtname: target-specific rule
2364 if (strchr(svname, '-')) {
2365 struct mgs_tgt_srpc_conf *tgtconf;
2368 for (tgtconf = fsdb->fsdb_srpc_tgt; tgtconf != NULL;
2369 tgtconf = tgtconf->mtsc_next) {
2370 if (!strcmp(tgtconf->mtsc_tgt, svname)) {
2379 OBD_ALLOC_PTR(tgtconf);
2380 if (tgtconf == NULL)
2383 name_len = strlen(svname);
2385 OBD_ALLOC(tgtconf->mtsc_tgt, name_len + 1);
2386 if (tgtconf->mtsc_tgt == NULL) {
2387 OBD_FREE_PTR(tgtconf);
2390 memcpy(tgtconf->mtsc_tgt, svname, name_len);
2392 tgtconf->mtsc_next = fsdb->fsdb_srpc_tgt;
2393 fsdb->fsdb_srpc_tgt = tgtconf;
2396 rset = &tgtconf->mtsc_rset;
2398 rset = &fsdb->fsdb_srpc_gen;
2401 /* limit the maximum number of rules, but allow deletion in any case */
2402 if (rset->srs_nrule >= SPTLRPC_CONF_LOG_MAX / 2 &&
2403 rule.sr_flvr.sf_rpc != SPTLRPC_FLVR_INVALID) {
2404 CERROR("too many (%d) rules already for %s\n",
2405 rset->srs_nrule, svname);
2409 rc = sptlrpc_rule_set_merge(rset, &rule, 1);
2414 static int mgs_srpc_set_param(struct obd_device *obd,
2416 struct mgs_target_info *mti,
2423 /* keep a copy of original param, which could be destroied
2425 copy_size = strlen(param) + 1;
2426 OBD_ALLOC(copy, copy_size);
2429 memcpy(copy, param, copy_size);
2431 rc = mgs_srpc_set_param_mem(fsdb, mti->mti_svname, param);
2435 /* previous steps guaranteed the syntax is correct */
2436 rc = mgs_srpc_set_param_disk(obd, fsdb, mti, copy);
2440 /* now apply the new rules to all existing config logs */
2441 rc = mgs_modify_srpc_log_all(obd, fsdb, mti);
2444 OBD_FREE(copy, copy_size);
2448 struct mgs_srpc_read_data {
2449 struct fs_db *msrd_fsdb;
2453 static int mgs_srpc_read_handler(struct llog_handle *llh,
2454 struct llog_rec_hdr *rec,
2457 struct mgs_srpc_read_data *msrd = (struct mgs_srpc_read_data *) data;
2458 struct cfg_marker *marker;
2459 struct lustre_cfg *lcfg = (struct lustre_cfg *)(rec + 1);
2460 char *svname, *param;
2464 if (rec->lrh_type != OBD_CFG_REC) {
2465 CERROR("unhandled lrh_type: %#x\n", rec->lrh_type);
2469 cfg_len = rec->lrh_len - sizeof(struct llog_rec_hdr) -
2470 sizeof(struct llog_rec_tail);
2472 rc = lustre_cfg_sanity_check(lcfg, cfg_len);
2474 CERROR("Insane cfg\n");
2478 if (lcfg->lcfg_command == LCFG_MARKER) {
2479 marker = lustre_cfg_buf(lcfg, 1);
2481 if (marker->cm_flags & CM_START &&
2482 marker->cm_flags & CM_SKIP)
2483 msrd->msrd_skip = 1;
2484 if (marker->cm_flags & CM_END)
2485 msrd->msrd_skip = 0;
2490 if (msrd->msrd_skip)
2493 if (lcfg->lcfg_command != 0) {
2494 CERROR("invalid command (%x)\n", lcfg->lcfg_command);
2498 svname = lustre_cfg_string(lcfg, 0);
2499 if (svname == NULL) {
2500 CERROR("svname is empty\n");
2504 param = lustre_cfg_string(lcfg, 1);
2505 if (param == NULL) {
2506 CERROR("param is empty\n");
2510 rc = mgs_srpc_set_param_mem(msrd->msrd_fsdb, svname, param);
2512 CERROR("read sptlrpc record error (%d): %s\n", rc, param);
2517 static int mgs_get_fsdb_srpc_from_llog(struct obd_device *obd,
2520 struct llog_handle *llh = NULL;
2521 struct lvfs_run_ctxt saved;
2523 struct mgs_srpc_read_data msrd;
2527 /* construct log name */
2528 rc = name_create(&logname, fsdb->fsdb_name, "-sptlrpc");
2532 if (mgs_log_is_empty(obd, logname))
2535 push_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
2537 rc = llog_create(llog_get_context(obd, LLOG_CONFIG_ORIG_CTXT),
2538 &llh, NULL, logname);
2542 rc = llog_init_handle(llh, LLOG_F_IS_PLAIN, NULL);
2544 GOTO(out_close, rc);
2546 if (llog_get_size(llh) <= 1)
2547 GOTO(out_close, rc = 0);
2549 msrd.msrd_fsdb = fsdb;
2552 rc = llog_process(llh, mgs_srpc_read_handler, (void *) &msrd, NULL);
2557 pop_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
2559 name_destroy(&logname);
2562 CERROR("failed to read sptlrpc config database: %d\n", rc);
2566 static int mgs_write_log_params(struct obd_device *obd, struct fs_db *fsdb,
2567 struct mgs_target_info *mti)
2569 struct lustre_cfg_bufs bufs;
2570 struct lustre_cfg *lcfg;
2572 char *ptr = mti->mti_params;
2577 if (!mti->mti_params)
2580 /* For various parameter settings, we have to figure out which logs
2581 care about them (e.g. both mdt and client for lov settings) */
2587 endptr = strchr(ptr, ' ');
2590 CDEBUG(D_MGS, "next param '%s'\n", ptr);
2592 /* The params are stored in MOUNT_DATA_FILE and modified
2593 via tunefs.lustre */
2595 /* Processed in lustre_start_mgc */
2596 if (class_match_param(ptr, PARAM_MGSNODE, NULL) == 0)
2597 GOTO(end_while, rc);
2599 /* Processed in mgs_write_log_ost */
2600 if (class_match_param(ptr, PARAM_FAILMODE, NULL) == 0) {
2601 if (mti->mti_flags & LDD_F_PARAM) {
2602 LCONSOLE_ERROR_MSG(0x169, "%s can only be "
2603 "changed with tunefs.lustre"
2604 "and --writeconf\n", ptr);
2607 GOTO(end_while, rc);
2610 if (class_match_param(ptr, PARAM_SRPC, NULL) == 0) {
2611 rc = mgs_srpc_set_param(obd, fsdb, mti, ptr);
2612 GOTO(end_while, rc);
2615 if (class_match_param(ptr, PARAM_FAILNODE, NULL) == 0) {
2616 /* Add a failover nidlist */
2618 /* We already processed failovers params for new
2619 targets in mgs_write_log_target */
2620 if (mti->mti_flags & LDD_F_PARAM) {
2621 CDEBUG(D_MGS, "Adding failnode\n");
2622 rc = mgs_write_log_add_failnid(obd, fsdb, mti);
2624 GOTO(end_while, rc);
2627 if (class_match_param(ptr, PARAM_SYS_TIMEOUT, &tmp) == 0) {
2628 /* Change obd timeout */
2630 timeout = simple_strtoul(tmp, NULL, 0);
2632 CDEBUG(D_MGS, "obd timeout %d\n", timeout);
2633 lustre_cfg_bufs_reset(&bufs, NULL);
2634 lcfg = lustre_cfg_new(LCFG_SET_TIMEOUT, &bufs);
2635 lcfg->lcfg_num = timeout;
2636 /* modify all servers and clients */
2637 rc = mgs_write_log_direct_all(obd, fsdb, mti, lcfg,
2640 lustre_cfg_free(lcfg);
2641 GOTO(end_while, rc);
2644 if (class_match_param(ptr, PARAM_OSC""PARAM_ACTIVE, &tmp) == 0) {
2645 /* active=0 means off, anything else means on */
2647 int flag = (*tmp == '0') ? CM_EXCLUDE : 0;
2650 if (!(mti->mti_flags & LDD_F_SV_TYPE_OST)) {
2651 LCONSOLE_ERROR_MSG(0x144, "%s: Only OSCs can "
2652 "be (de)activated.\n",
2657 LCONSOLE_WARN("Permanently %sactivating %s\n",
2658 flag ? "de": "re", mti->mti_svname);
2660 name_create(&logname, mti->mti_fsname, "-client");
2661 rc = mgs_modify(obd, fsdb, mti, logname,
2662 mti->mti_svname, "add osc", flag);
2663 name_destroy(&logname);
2667 /* FIXME add to all MDT logs for CMD */
2668 for (i = 0; i < INDEX_MAP_SIZE * 8; i++) {
2669 if (!test_bit(i, fsdb->fsdb_mdt_index_map))
2671 sprintf(mdt_index,"-MDT%04x", i);
2672 name_create(&logname, mti->mti_fsname, mdt_index);
2673 rc = mgs_modify(obd, fsdb, mti, logname,
2674 mti->mti_svname, "add osc", flag);
2675 name_destroy(&logname);
2681 LCONSOLE_ERROR_MSG(0x145, "Couldn't find %s in"
2682 "log (%d). No permanent "
2683 "changes were made to the "
2685 mti->mti_svname, rc);
2686 if (fsdb->fsdb_flags & FSDB_OLDLOG14)
2687 LCONSOLE_ERROR_MSG(0x146, "This may be"
2692 "update the logs.\n");
2695 /* Fall through to osc proc for deactivating
2696 live OSC on running MDT / clients. */
2698 /* Below here, let obd's XXX_process_config methods handle it */
2700 /* All lov. in proc */
2701 if (class_match_param(ptr, PARAM_LOV, NULL) == 0) {
2705 CDEBUG(D_MGS, "lov param %s\n", ptr);
2706 if (!(mti->mti_flags & LDD_F_SV_TYPE_MDT)) {
2707 LCONSOLE_ERROR_MSG(0x147, "LOV params must be "
2708 "set on the MDT, not %s. "
2716 if (mgs_log_is_empty(obd, mti->mti_svname))
2717 GOTO(end_while, rc = -ENODEV);
2719 sprintf(mdt_index,"-MDT%04x", mti->mti_stripe_index);
2720 name_create(&logname, mti->mti_fsname, mdt_index);
2721 name_create(&mdtlovname, logname, "-mdtlov");
2722 rc = mgs_wlp_lcfg(obd, fsdb, mti, mti->mti_svname,
2723 &bufs, mdtlovname, ptr);
2724 name_destroy(&logname);
2725 name_destroy(&mdtlovname);
2727 GOTO(end_while, rc);
2730 name_create(&logname, mti->mti_fsname, "-client");
2731 rc = mgs_wlp_lcfg(obd, fsdb, mti, logname, &bufs,
2732 fsdb->fsdb_clilov, ptr);
2733 name_destroy(&logname);
2734 GOTO(end_while, rc);
2737 /* All osc., mdc., llite. params in proc */
2738 if ((class_match_param(ptr, PARAM_OSC, NULL) == 0) ||
2739 (class_match_param(ptr, PARAM_MDC, NULL) == 0) ||
2740 (class_match_param(ptr, PARAM_LLITE, NULL) == 0)) {
2742 if (memcmp(ptr, PARAM_LLITE, strlen(PARAM_LLITE)) == 0) {
2743 name_create(&cname, mti->mti_fsname, "-client");
2744 /* Add the client type to match the obdname
2745 in class_config_llog_handler */
2746 } else if (mti->mti_flags & LDD_F_SV_TYPE_MDT) {
2749 name_create(&cname, fsdb->fsdb_mdc, "");
2751 name_create(&cname, mti->mti_svname,
2753 } else if (mti->mti_flags & LDD_F_SV_TYPE_OST) {
2755 if (fsdb->fsdb_flags & FSDB_OLDLOG14) {
2756 LCONSOLE_ERROR_MSG(0x148, "Upgraded "
2757 "client logs for %s"
2759 "modified. Consider"
2761 "configuration with"
2764 /* We don't know the names of all the
2769 name_create(&cname, mti->mti_svname, "-osc");
2775 CDEBUG(D_MGS, "%.3s param %s\n", ptr, ptr + 4);
2778 name_create(&logname, mti->mti_fsname, "-client");
2779 rc = mgs_wlp_lcfg(obd, fsdb, mti, logname, &bufs,
2782 /* osc params affect the MDT as well */
2783 if (!rc && (mti->mti_flags & LDD_F_SV_TYPE_OST)) {
2787 for (i = 0; i < INDEX_MAP_SIZE * 8; i++){
2788 if (!test_bit(i, fsdb->fsdb_mdt_index_map))
2790 name_destroy(&cname);
2791 sprintf(mdt_index, "-osc-MDT%04x", i);
2792 name_create(&cname, mti->mti_svname,
2794 name_destroy(&logname);
2795 sprintf(mdt_index, "-MDT%04x", i);
2796 name_create(&logname, mti->mti_fsname,
2798 if (!mgs_log_is_empty(obd, logname))
2799 rc = mgs_wlp_lcfg(obd, fsdb,
2807 name_destroy(&logname);
2808 name_destroy(&cname);
2809 GOTO(end_while, rc);
2812 /* All mdt., ost. params in proc */
2813 if ((class_match_param(ptr, PARAM_MDT, NULL) == 0) ||
2814 (class_match_param(ptr, PARAM_OST, NULL) == 0)) {
2815 CDEBUG(D_MGS, "%.3s param %s\n", ptr, ptr + 4);
2816 if (mgs_log_is_empty(obd, mti->mti_svname)) {
2820 rc = mgs_wlp_lcfg(obd, fsdb, mti, mti->mti_svname,
2821 &bufs, mti->mti_svname, ptr);
2822 GOTO(end_while, rc);
2825 LCONSOLE_WARN("Ignoring unrecognized param '%s'\n", ptr);
2829 CERROR("err %d on param '%s\n", rc, ptr);
2844 /* Not implementing automatic failover nid addition at this time. */
2845 int mgs_check_failnid(struct obd_device *obd, struct mgs_target_info *mti)
2852 rc = mgs_find_or_make_fsdb(obd, fsname, &fsdb);
2856 if (mgs_log_is_empty(obd, mti->mti_svname))
2857 /* should never happen */
2860 CDEBUG(D_MGS, "Checking for new failnids for %s\n", mti->mti_svname);
2862 /* FIXME We can just check mti->params to see if we're already in
2863 the failover list. Modify mti->params for rewriting back at
2864 server_register_target(). */
2866 down(&fsdb->fsdb_sem);
2867 rc = mgs_write_log_add_failnid(obd, fsdb, mti);
2868 up(&fsdb->fsdb_sem);
2875 int mgs_write_log_target(struct obd_device *obd,
2876 struct mgs_target_info *mti)
2882 /* set/check the new target index */
2883 rc = mgs_set_index(obd, mti);
2885 CERROR("Can't get index (%d)\n", rc);
2890 if (mti->mti_flags & LDD_F_UPGRADE14) {
2891 if (rc == EALREADY) {
2892 LCONSOLE_INFO("Found index %d for %s 1.4 log, "
2893 "upgrading\n", mti->mti_stripe_index,
2896 LCONSOLE_ERROR_MSG(0x149, "Failed to find %s in the old"
2897 " client log. Apparently it is not "
2898 "part of this filesystem, or the old"
2899 " log is wrong.\nUse 'writeconf' on "
2900 "the MDT to force log regeneration."
2901 "\n", mti->mti_svname);
2902 /* Not in client log? Upgrade anyhow...*/
2903 /* Argument against upgrading: reformat MDT,
2904 upgrade OST, then OST will start but will be SKIPped
2905 in client logs. Maybe error now is better. */
2906 /* RETURN(-EINVAL); */
2908 /* end COMPAT_146 */
2910 if (rc == EALREADY) {
2911 LCONSOLE_WARN("Found index %d for %s, updating log\n",
2912 mti->mti_stripe_index, mti->mti_svname);
2913 /* We would like to mark old log sections as invalid
2914 and add new log sections in the client and mdt logs.
2915 But if we add new sections, then live clients will
2916 get repeat setup instructions for already running
2917 osc's. So don't update the client/mdt logs. */
2918 mti->mti_flags &= ~LDD_F_UPDATE;
2922 rc = mgs_find_or_make_fsdb(obd, mti->mti_fsname, &fsdb);
2924 CERROR("Can't get db for %s\n", mti->mti_fsname);
2928 down(&fsdb->fsdb_sem);
2930 if (mti->mti_flags &
2931 (LDD_F_VIRGIN | LDD_F_UPGRADE14 | LDD_F_WRITECONF)) {
2932 /* Generate a log from scratch */
2933 if (mti->mti_flags & LDD_F_SV_TYPE_MDT) {
2934 rc = mgs_write_log_mdt(obd, fsdb, mti);
2935 } else if (mti->mti_flags & LDD_F_SV_TYPE_OST) {
2936 rc = mgs_write_log_ost(obd, fsdb, mti);
2938 CERROR("Unknown target type %#x, can't create log for "
2939 "%s\n", mti->mti_flags, mti->mti_svname);
2942 CERROR("Can't write logs for %s (%d)\n",
2943 mti->mti_svname, rc);
2947 /* Just update the params from tunefs in mgs_write_log_params */
2948 CDEBUG(D_MGS, "Update params for %s\n", mti->mti_svname);
2949 mti->mti_flags |= LDD_F_PARAM;
2952 rc = mgs_write_log_params(obd, fsdb, mti);
2955 up(&fsdb->fsdb_sem);
2960 /* verify that we can handle the old config logs */
2961 int mgs_upgrade_sv_14(struct obd_device *obd, struct mgs_target_info *mti)
2967 /* Create ost log normally, as servers register. Servers
2968 register with their old uuids (from last_rcvd), so old
2969 (MDT and client) logs should work.
2970 - new MDT won't know about old OSTs, only the ones that have
2971 registered, so we need the old MDT log to get the LOV right
2972 in order for old clients to work.
2973 - Old clients connect to the MDT, not the MGS, for their logs, and
2974 will therefore receive the old client log from the MDT /LOGS dir.
2975 - Old clients can continue to use and connect to old or new OSTs
2976 - New clients will contact the MGS for their log
2979 LCONSOLE_INFO("upgrading server %s from pre-1.6\n", mti->mti_svname);
2980 server_mti_print("upgrade", mti);
2982 rc = mgs_find_or_make_fsdb(obd, mti->mti_fsname, &fsdb);
2986 if (fsdb->fsdb_flags & FSDB_LOG_EMPTY) {
2987 LCONSOLE_ERROR_MSG(0x14a, "The old client log %s-client is "
2988 "missing. Was tunefs.lustre successful?\n",
2993 if (fsdb->fsdb_gen == 0) {
2994 /* There were no markers in the client log, meaning we have
2995 not updated the logs for this fs */
2996 CDEBUG(D_MGS, "found old, unupdated client log\n");
2999 if (mti->mti_flags & LDD_F_SV_TYPE_MDT) {
3000 if (mgs_log_is_empty(obd, mti->mti_svname)) {
3001 LCONSOLE_ERROR_MSG(0x14b, "The old MDT log %s is "
3002 "missing. Was tunefs.lustre "
3007 /* We're starting with an old uuid. Assume old name for lov
3008 as well since the lov entry already exists in the log. */
3009 CDEBUG(D_MGS, "old mds uuid %s\n", mti->mti_uuid);
3010 if (strncmp(mti->mti_uuid, fsdb->fsdb_mdtlov + 4,
3011 strlen(fsdb->fsdb_mdtlov) - 4) != 0) {
3012 CERROR("old mds uuid %s doesn't match log %s (%s)\n",
3013 mti->mti_uuid, fsdb->fsdb_mdtlov,
3014 fsdb->fsdb_mdtlov + 4);
3019 if (!(fsdb->fsdb_flags & FSDB_OLDLOG14)) {
3020 LCONSOLE_ERROR_MSG(0x14c, "%s-client is supposedly an old "
3021 "log, but no old LOV or MDT was found. "
3022 "Consider updating the configuration with"
3023 " --writeconf.\n", mti->mti_fsname);
3028 /* end COMPAT_146 */
3030 int mgs_erase_log(struct obd_device *obd, char *name)
3032 struct lvfs_run_ctxt saved;
3033 struct llog_handle *llh;
3036 push_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
3037 rc = llog_create(llog_get_context(obd, LLOG_CONFIG_ORIG_CTXT),
3040 llog_init_handle(llh, LLOG_F_IS_PLAIN, NULL);
3041 rc = llog_destroy(llh);
3042 llog_free_handle(llh);
3044 pop_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
3047 CERROR("failed to clear log %s: %d\n", name, rc);
3052 /* erase all logs for the given fs */
3053 int mgs_erase_logs(struct obd_device *obd, char *fsname)
3055 struct mgs_obd *mgs = &obd->u.mgs;
3056 static struct fs_db *fsdb;
3057 struct list_head dentry_list;
3058 struct l_linux_dirent *dirent, *n;
3059 int rc, len = strlen(fsname);
3062 /* Find all the logs in the CONFIGS directory */
3063 rc = class_dentry_readdir(obd, mgs->mgs_configs_dir,
3064 mgs->mgs_vfsmnt, &dentry_list);
3066 CERROR("Can't read %s dir\n", MOUNT_CONFIGS_DIR);
3070 down(&mgs->mgs_sem);
3072 /* Delete the fs db */
3073 fsdb = mgs_find_fsdb(obd, fsname);
3075 mgs_free_fsdb(obd, fsdb);
3077 list_for_each_entry_safe(dirent, n, &dentry_list, lld_list) {
3078 list_del(&dirent->lld_list);
3079 if (strncmp(fsname, dirent->lld_name, len) == 0) {
3080 CDEBUG(D_MGS, "Removing log %s\n", dirent->lld_name);
3081 mgs_erase_log(obd, dirent->lld_name);
3083 OBD_FREE(dirent, sizeof(*dirent));
3091 /* from llog_swab */
3092 static void print_lustre_cfg(struct lustre_cfg *lcfg)
3097 CDEBUG(D_MGS, "lustre_cfg: %p\n", lcfg);
3098 CDEBUG(D_MGS, "\tlcfg->lcfg_version: %#x\n", lcfg->lcfg_version);
3100 CDEBUG(D_MGS, "\tlcfg->lcfg_command: %#x\n", lcfg->lcfg_command);
3101 CDEBUG(D_MGS, "\tlcfg->lcfg_num: %#x\n", lcfg->lcfg_num);
3102 CDEBUG(D_MGS, "\tlcfg->lcfg_flags: %#x\n", lcfg->lcfg_flags);
3103 CDEBUG(D_MGS, "\tlcfg->lcfg_nid: %s\n", libcfs_nid2str(lcfg->lcfg_nid));
3105 CDEBUG(D_MGS, "\tlcfg->lcfg_bufcount: %d\n", lcfg->lcfg_bufcount);
3106 if (lcfg->lcfg_bufcount < LUSTRE_CFG_MAX_BUFCOUNT)
3107 for (i = 0; i < lcfg->lcfg_bufcount; i++) {
3108 CDEBUG(D_MGS, "\tlcfg->lcfg_buflens[%d]: %d %s\n",
3109 i, lcfg->lcfg_buflens[i],
3110 lustre_cfg_string(lcfg, i));
3115 /* Set a permanent (config log) param for a target or fs */
3116 int mgs_setparam(struct obd_device *obd, struct lustre_cfg *lcfg, char *fsname)
3119 struct mgs_target_info *mti;
3120 char *devname, *param;
3126 print_lustre_cfg(lcfg);
3128 /* lustre, lustre-mdtlov, lustre-client, lustre-MDT0000 */
3129 devname = lustre_cfg_string(lcfg, 0);
3130 param = lustre_cfg_string(lcfg, 1);
3132 /* Assume device name embedded in param:
3133 lustre-OST0000.osc.max_dirty_mb=32 */
3134 ptr = strchr(param, '.');
3142 LCONSOLE_ERROR_MSG(0x14d, "No target specified: %s\n", param);
3146 /* Extract fsname */
3147 ptr = strrchr(devname, '-');
3148 memset(fsname, 0, MTI_NAME_MAXLEN);
3149 if (ptr && (server_name2index(ptr, &index, NULL) >= 0)) {
3150 strncpy(fsname, devname, ptr - devname);
3152 /* assume devname is the fsname */
3153 strncpy(fsname, devname, MTI_NAME_MAXLEN);
3155 fsname[MTI_NAME_MAXLEN - 1] = 0;
3156 CDEBUG(D_MGS, "setparam on fs %s device %s\n", fsname, devname);
3158 rc = mgs_find_or_make_fsdb(obd, fsname, &fsdb);
3161 if (fsdb->fsdb_flags & FSDB_LOG_EMPTY) {
3162 CERROR("No filesystem targets for %s. cfg_device from lctl "
3163 "is '%s'\n", fsname, devname);
3164 mgs_free_fsdb(obd, fsdb);
3168 /* Create a fake mti to hold everything */
3171 GOTO(out, rc = -ENOMEM);
3172 strncpy(mti->mti_fsname, fsname, MTI_NAME_MAXLEN);
3173 strncpy(mti->mti_svname, devname, MTI_NAME_MAXLEN);
3174 strncpy(mti->mti_params, param, sizeof(mti->mti_params));
3175 rc = server_name2index(mti->mti_svname, &mti->mti_stripe_index, &tmp);
3177 /* Not a valid server; may be only fsname */
3180 /* Strip -osc or -mdc suffix from svname */
3181 if (server_make_name(rc, mti->mti_stripe_index, mti->mti_fsname,
3183 GOTO(out, rc = -EINVAL);
3185 mti->mti_flags = rc | LDD_F_PARAM;
3187 down(&fsdb->fsdb_sem);
3188 rc = mgs_write_log_params(obd, fsdb, mti);
3189 up(&fsdb->fsdb_sem);
3197 /******************** unused *********************/
3198 static int mgs_backup_llog(struct obd_device *obd, char* fsname)
3200 struct file *filp, *bak_filp;
3201 struct lvfs_run_ctxt saved;
3202 char *logname, *buf;
3203 loff_t soff = 0 , doff = 0;
3204 int count = 4096, len;
3207 OBD_ALLOC(logname, PATH_MAX);
3208 if (logname == NULL)
3211 OBD_ALLOC(buf, count);
3213 GOTO(out , rc = -ENOMEM);
3215 len = snprintf(logname, PATH_MAX, "%s/%s.bak",
3216 MOUNT_CONFIGS_DIR, fsname);
3218 if (len >= PATH_MAX - 1) {
3219 GOTO(out, -ENAMETOOLONG);
3222 push_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
3224 bak_filp = l_filp_open(logname, O_RDWR|O_CREAT|O_TRUNC, 0660);
3225 if (IS_ERR(bak_filp)) {
3226 rc = PTR_ERR(bak_filp);
3227 CERROR("backup logfile open %s: %d\n", logname, rc);
3230 sprintf(logname, "%s/%s", MOUNT_CONFIGS_DIR, fsname);
3231 filp = l_filp_open(logname, O_RDONLY, 0);
3234 CERROR("logfile open %s: %d\n", logname, rc);
3238 while ((rc = lustre_fread(filp, buf, count, &soff)) > 0) {
3239 rc = lustre_fwrite(bak_filp, buf, count, &doff);
3243 filp_close(filp, 0);
3245 filp_close(bak_filp, 0);
3247 pop_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
3250 OBD_FREE(buf, count);
3251 OBD_FREE(logname, PATH_MAX);