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 /********************** Class functions ********************/
70 /* Caller must list_del and OBD_FREE each dentry from the list */
71 int class_dentry_readdir(struct obd_device *obd, struct dentry *dir,
72 struct vfsmount *inmnt,
73 struct list_head *dentry_list){
74 /* see mds_cleanup_pending */
75 struct lvfs_run_ctxt saved;
77 struct dentry *dentry;
82 push_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
85 GOTO(out_pop, rc = PTR_ERR(dentry));
89 GOTO(out_pop, rc = PTR_ERR(mnt));
92 file = dentry_open(dentry, mnt, O_RDONLY);
94 /* dentry_open_it() drops the dentry, mnt refs */
95 GOTO(out_pop, rc = PTR_ERR(file));
97 CFS_INIT_LIST_HEAD(dentry_list);
98 rc = l_readdir(file, dentry_list);
100 /* filp_close->fput() drops the dentry, mnt refs */
103 pop_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
107 /******************** DB functions *********************/
109 static inline int name_create(char **newname, char *prefix, char *suffix)
112 OBD_ALLOC(*newname, strlen(prefix) + strlen(suffix) + 1);
115 sprintf(*newname, "%s%s", prefix, suffix);
119 static inline void name_destroy(char **name)
122 OBD_FREE(*name, strlen(*name) + 1);
126 /* from the (client) config log, figure out:
127 1. which ost's/mdt's are configured (by index)
128 2. what the last config step is
129 3. COMPAT_146 lov name
130 4. COMPAT_146 mdt lov name
131 5. COMPAT_146 mdc name
133 /* It might be better to have a separate db file, instead of parsing the info
134 out of the client log. This is slow and potentially error-prone. */
135 static int mgs_fsdb_handler(struct llog_handle *llh, struct llog_rec_hdr *rec,
138 struct fs_db *fsdb = (struct fs_db *)data;
139 int cfg_len = rec->lrh_len;
140 char *cfg_buf = (char*) (rec + 1);
141 struct lustre_cfg *lcfg;
146 if (rec->lrh_type != OBD_CFG_REC) {
147 CERROR("unhandled lrh_type: %#x\n", rec->lrh_type);
151 rc = lustre_cfg_sanity_check(cfg_buf, cfg_len);
153 CERROR("Insane cfg\n");
157 lcfg = (struct lustre_cfg *)cfg_buf;
159 CDEBUG(D_INFO, "cmd %x %s %s\n", lcfg->lcfg_command,
160 lustre_cfg_string(lcfg, 0), lustre_cfg_string(lcfg, 1));
162 /* Figure out ost indicies */
163 /* lov_modify_tgts add 0:lov1 1:ost1_UUID 2(index):0 3(gen):1 */
164 if (lcfg->lcfg_command == LCFG_LOV_ADD_OBD ||
165 lcfg->lcfg_command == LCFG_LOV_DEL_OBD) {
166 index = simple_strtoul(lustre_cfg_string(lcfg, 2),
168 CDEBUG(D_MGS, "OST index for %s is %u (%s)\n",
169 lustre_cfg_string(lcfg, 1), index,
170 lustre_cfg_string(lcfg, 2));
171 set_bit(index, fsdb->fsdb_ost_index_map);
174 /* Figure out mdt indicies */
175 /* attach 0:MDC_uml1_mdsA_MNT_client 1:mdc 2:1d834_MNT_client_03f */
176 if ((lcfg->lcfg_command == LCFG_ATTACH) &&
177 (strcmp(lustre_cfg_string(lcfg, 1), LUSTRE_MDC_NAME) == 0)) {
178 rc = server_name2index(lustre_cfg_string(lcfg, 0),
180 if (rc != LDD_F_SV_TYPE_MDT) {
181 CWARN("Unparsable MDC name %s, assuming index 0\n",
182 lustre_cfg_string(lcfg, 0));
186 CDEBUG(D_MGS, "MDT index is %u\n", index);
187 set_bit(index, fsdb->fsdb_mdt_index_map);
191 /* figure out the old LOV name. fsdb_gen = 0 means old log */
192 /* #01 L attach 0:lov_mdsA 1:lov 2:cdbe9_lov_mdsA_dc8cf7f3bb */
193 if ((fsdb->fsdb_gen == 0) && (lcfg->lcfg_command == LCFG_ATTACH) &&
194 (strcmp(lustre_cfg_string(lcfg, 1), LUSTRE_LOV_NAME) == 0)) {
195 fsdb->fsdb_flags |= FSDB_OLDLOG14;
196 name_destroy(&fsdb->fsdb_clilov);
197 rc = name_create(&fsdb->fsdb_clilov,
198 lustre_cfg_string(lcfg, 0), "");
201 CDEBUG(D_MGS, "client lov name is %s\n", fsdb->fsdb_clilov);
204 /* figure out the old MDT lov name from the MDT uuid */
205 if ((fsdb->fsdb_gen == 0) && (lcfg->lcfg_command == LCFG_SETUP) &&
206 (strncmp(lustre_cfg_string(lcfg, 0), "MDC_", 4) == 0)) {
208 fsdb->fsdb_flags |= FSDB_OLDLOG14;
209 ptr = strstr(lustre_cfg_string(lcfg, 1), "_UUID");
211 CERROR("Can't parse MDT uuid %s\n",
212 lustre_cfg_string(lcfg, 1));
216 name_destroy(&fsdb->fsdb_mdtlov);
217 rc = name_create(&fsdb->fsdb_mdtlov,
218 "lov_", lustre_cfg_string(lcfg, 1));
221 name_destroy(&fsdb->fsdb_mdc);
222 rc = name_create(&fsdb->fsdb_mdc,
223 lustre_cfg_string(lcfg, 0), "");
226 CDEBUG(D_MGS, "MDT lov name is %s\n", fsdb->fsdb_mdtlov);
230 /* Keep track of the latest marker step */
231 if (lcfg->lcfg_command == LCFG_MARKER) {
232 struct cfg_marker *marker;
233 marker = lustre_cfg_buf(lcfg, 1);
234 fsdb->fsdb_gen = max(fsdb->fsdb_gen, marker->cm_step);
240 /* fsdb->fsdb_sem is already held in mgs_find_or_make_fsdb*/
241 static int mgs_get_fsdb_from_llog(struct obd_device *obd, struct fs_db *fsdb)
244 struct llog_handle *loghandle;
245 struct lvfs_run_ctxt saved;
246 struct llog_ctxt *ctxt;
250 ctxt = llog_get_context(obd, LLOG_CONFIG_ORIG_CTXT);
251 LASSERT(ctxt != NULL);
252 name_create(&logname, fsdb->fsdb_name, "-client");
253 down(&fsdb->fsdb_sem);
254 push_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
255 rc = llog_create(ctxt, &loghandle, NULL, logname);
259 rc = llog_init_handle(loghandle, LLOG_F_IS_PLAIN, NULL);
263 if (llog_get_size(loghandle) <= 1)
264 fsdb->fsdb_flags |= FSDB_LOG_EMPTY;
266 rc = llog_process(loghandle, mgs_fsdb_handler, (void *)fsdb, NULL);
267 CDEBUG(D_INFO, "get_db = %d\n", rc);
269 rc2 = llog_close(loghandle);
273 pop_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
275 name_destroy(&logname);
281 static void mgs_free_fsdb_srpc(struct fs_db *fsdb)
283 struct mgs_tgt_srpc_conf *tgtconf;
285 /* free target-specific rules */
286 while (fsdb->fsdb_srpc_tgt) {
287 tgtconf = fsdb->fsdb_srpc_tgt;
288 fsdb->fsdb_srpc_tgt = tgtconf->mtsc_next;
290 LASSERT(tgtconf->mtsc_tgt);
292 sptlrpc_rule_set_free(&tgtconf->mtsc_rset);
293 OBD_FREE(tgtconf->mtsc_tgt, strlen(tgtconf->mtsc_tgt) + 1);
294 OBD_FREE_PTR(tgtconf);
297 /* free general rules */
298 sptlrpc_rule_set_free(&fsdb->fsdb_srpc_gen);
301 static struct fs_db *mgs_find_fsdb(struct obd_device *obd, char *fsname)
303 struct mgs_obd *mgs = &obd->u.mgs;
305 struct list_head *tmp;
307 list_for_each(tmp, &mgs->mgs_fs_db_list) {
308 fsdb = list_entry(tmp, struct fs_db, fsdb_list);
309 if (strcmp(fsdb->fsdb_name, fsname) == 0)
315 /* caller must hold the mgs->mgs_fs_db_lock */
316 static struct fs_db *mgs_new_fsdb(struct obd_device *obd, char *fsname)
318 struct mgs_obd *mgs = &obd->u.mgs;
323 if (strlen(fsname) >= sizeof(fsdb->fsdb_name)) {
324 CERROR("fsname %s is too long\n", fsname);
332 strcpy(fsdb->fsdb_name, fsname);
333 sema_init(&fsdb->fsdb_sem, 1);
334 fsdb->fsdb_fl_udesc = 1;
336 if (strcmp(fsname, MGSSELF_NAME) == 0) {
337 fsdb->fsdb_fl_mgsself = 1;
339 OBD_ALLOC(fsdb->fsdb_ost_index_map, INDEX_MAP_SIZE);
340 OBD_ALLOC(fsdb->fsdb_mdt_index_map, INDEX_MAP_SIZE);
341 if (!fsdb->fsdb_ost_index_map || !fsdb->fsdb_mdt_index_map) {
342 CERROR("No memory for index maps\n");
346 rc = name_create(&fsdb->fsdb_mdtlov, fsname, "-mdtlov");
349 rc = name_create(&fsdb->fsdb_mdtlmv, fsname, "-mdtlmv");
352 rc = name_create(&fsdb->fsdb_clilov, fsname, "-clilov");
355 rc = name_create(&fsdb->fsdb_clilmv, fsname, "-clilmv");
359 lproc_mgs_add_live(obd, fsdb);
362 list_add(&fsdb->fsdb_list, &mgs->mgs_fs_db_list);
366 if (fsdb->fsdb_ost_index_map)
367 OBD_FREE(fsdb->fsdb_ost_index_map, INDEX_MAP_SIZE);
368 if (fsdb->fsdb_mdt_index_map)
369 OBD_FREE(fsdb->fsdb_mdt_index_map, INDEX_MAP_SIZE);
370 name_destroy(&fsdb->fsdb_clilov);
371 name_destroy(&fsdb->fsdb_clilmv);
372 name_destroy(&fsdb->fsdb_mdtlov);
373 name_destroy(&fsdb->fsdb_mdtlmv);
378 static void mgs_free_fsdb(struct obd_device *obd, struct fs_db *fsdb)
380 /* wait for anyone with the sem */
381 down(&fsdb->fsdb_sem);
382 lproc_mgs_del_live(obd, fsdb);
383 list_del(&fsdb->fsdb_list);
384 if (fsdb->fsdb_ost_index_map)
385 OBD_FREE(fsdb->fsdb_ost_index_map, INDEX_MAP_SIZE);
386 if (fsdb->fsdb_mdt_index_map)
387 OBD_FREE(fsdb->fsdb_mdt_index_map, INDEX_MAP_SIZE);
388 name_destroy(&fsdb->fsdb_clilov);
389 name_destroy(&fsdb->fsdb_clilmv);
390 name_destroy(&fsdb->fsdb_mdtlov);
391 name_destroy(&fsdb->fsdb_mdtlmv);
392 name_destroy(&fsdb->fsdb_mdc);
393 mgs_free_fsdb_srpc(fsdb);
397 int mgs_init_fsdb_list(struct obd_device *obd)
399 struct mgs_obd *mgs = &obd->u.mgs;
400 CFS_INIT_LIST_HEAD(&mgs->mgs_fs_db_list);
404 int mgs_cleanup_fsdb_list(struct obd_device *obd)
406 struct mgs_obd *mgs = &obd->u.mgs;
408 struct list_head *tmp, *tmp2;
410 list_for_each_safe(tmp, tmp2, &mgs->mgs_fs_db_list) {
411 fsdb = list_entry(tmp, struct fs_db, fsdb_list);
412 mgs_free_fsdb(obd, fsdb);
418 int mgs_find_or_make_fsdb(struct obd_device *obd, char *name,
421 struct mgs_obd *mgs = &obd->u.mgs;
426 fsdb = mgs_find_fsdb(obd, name);
433 CDEBUG(D_MGS, "Creating new db\n");
434 fsdb = mgs_new_fsdb(obd, name);
439 if (!fsdb->fsdb_fl_mgsself) {
440 /* populate the db from the client llog */
441 rc = mgs_get_fsdb_from_llog(obd, fsdb);
443 CERROR("Can't get db from client log %d\n", rc);
444 mgs_free_fsdb(obd, fsdb);
449 /* populate srpc rules from params llog */
450 rc = mgs_get_fsdb_srpc_from_llog(obd, fsdb);
452 CERROR("Can't get db from params log %d\n", rc);
453 mgs_free_fsdb(obd, fsdb);
464 -1= empty client log */
465 int mgs_check_index(struct obd_device *obd, struct mgs_target_info *mti)
472 LASSERT(!(mti->mti_flags & LDD_F_NEED_INDEX));
474 rc = mgs_find_or_make_fsdb(obd, mti->mti_fsname, &fsdb);
476 CERROR("Can't get db for %s\n", mti->mti_fsname);
480 if (fsdb->fsdb_flags & FSDB_LOG_EMPTY)
483 if (mti->mti_flags & LDD_F_SV_TYPE_OST)
484 imap = fsdb->fsdb_ost_index_map;
485 else if (mti->mti_flags & LDD_F_SV_TYPE_MDT)
486 imap = fsdb->fsdb_mdt_index_map;
490 if (test_bit(mti->mti_stripe_index, imap))
495 static __inline__ int next_index(void *index_map, int map_len)
498 for (i = 0; i < map_len * 8; i++)
499 if (!test_bit(i, index_map)) {
502 CERROR("max index %d exceeded.\n", i);
507 0 newly marked as in use
509 +EALREADY for update of an old index */
510 static int mgs_set_index(struct fs_db *fsdb, struct mgs_target_info *mti)
516 if (mti->mti_flags & LDD_F_SV_TYPE_OST)
517 imap = fsdb->fsdb_ost_index_map;
518 else if (mti->mti_flags & LDD_F_SV_TYPE_MDT)
519 imap = fsdb->fsdb_mdt_index_map;
523 if (mti->mti_flags & LDD_F_NEED_INDEX) {
524 rc = next_index(imap, INDEX_MAP_SIZE);
527 mti->mti_stripe_index = rc;
530 if (mti->mti_stripe_index >= INDEX_MAP_SIZE * 8) {
531 LCONSOLE_ERROR_MSG(0x13f, "Server %s requested index %d, "
532 "but the max index is %d.\n",
533 mti->mti_svname, mti->mti_stripe_index,
538 if (test_bit(mti->mti_stripe_index, imap)) {
539 if ((mti->mti_flags & LDD_F_VIRGIN) &&
540 !(mti->mti_flags & LDD_F_WRITECONF)) {
541 LCONSOLE_ERROR_MSG(0x140, "Server %s requested index "
542 "%d, but that index is already in "
543 "use. Use --writeconf to force\n",
545 mti->mti_stripe_index);
548 CDEBUG(D_MGS, "Server %s updating index %d\n",
549 mti->mti_svname, mti->mti_stripe_index);
554 set_bit(mti->mti_stripe_index, imap);
555 fsdb->fsdb_flags &= ~FSDB_LOG_EMPTY;
556 server_make_name(mti->mti_flags, mti->mti_stripe_index,
557 mti->mti_fsname, mti->mti_svname);
559 CDEBUG(D_MGS, "Set index for %s to %d\n", mti->mti_svname,
560 mti->mti_stripe_index);
565 struct mgs_modify_lookup {
566 struct cfg_marker mml_marker;
570 static int mgs_modify_handler(struct llog_handle *llh, struct llog_rec_hdr *rec,
573 struct mgs_modify_lookup *mml = (struct mgs_modify_lookup *)data;
574 struct cfg_marker *marker;
575 struct lustre_cfg *lcfg = (struct lustre_cfg *)(rec + 1);
576 int cfg_len = rec->lrh_len - sizeof(struct llog_rec_hdr) -
577 sizeof(struct llog_rec_tail);
581 if (rec->lrh_type != OBD_CFG_REC) {
582 CERROR("unhandled lrh_type: %#x\n", rec->lrh_type);
586 rc = lustre_cfg_sanity_check(lcfg, cfg_len);
588 CERROR("Insane cfg\n");
592 /* We only care about markers */
593 if (lcfg->lcfg_command != LCFG_MARKER)
596 marker = lustre_cfg_buf(lcfg, 1);
597 if ((strcmp(mml->mml_marker.cm_comment, marker->cm_comment) == 0) &&
598 (strcmp(mml->mml_marker.cm_tgtname, marker->cm_tgtname) == 0) &&
599 !(marker->cm_flags & CM_SKIP)) {
600 /* Found a non-skipped marker match */
601 CDEBUG(D_MGS, "Changing rec %u marker %d %x->%x: %s %s\n",
602 rec->lrh_index, marker->cm_step,
603 marker->cm_flags, mml->mml_marker.cm_flags,
604 marker->cm_tgtname, marker->cm_comment);
605 /* Overwrite the old marker llog entry */
606 marker->cm_flags &= ~CM_EXCLUDE; /* in case we're unexcluding */
607 marker->cm_flags |= mml->mml_marker.cm_flags;
608 marker->cm_canceltime = mml->mml_marker.cm_canceltime;
609 /* Header and tail are added back to lrh_len in
610 llog_lvfs_write_rec */
611 rec->lrh_len = cfg_len;
612 rc = llog_write_rec(llh, rec, NULL, 0, (void *)lcfg,
621 /* Modify an existing config log record (for CM_SKIP or CM_EXCLUDE) */
622 static int mgs_modify(struct obd_device *obd, struct fs_db *fsdb,
623 struct mgs_target_info *mti, char *logname,
624 char *devname, char *comment, int flags)
626 struct llog_handle *loghandle;
627 struct lvfs_run_ctxt saved;
628 struct llog_ctxt *ctxt;
629 struct mgs_modify_lookup *mml;
633 CDEBUG(D_MGS, "modify %s/%s/%s\n", logname, devname, comment);
635 push_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
637 ctxt = llog_get_context(obd, LLOG_CONFIG_ORIG_CTXT);
638 LASSERT(ctxt != NULL);
639 rc = llog_create(ctxt, &loghandle, NULL, logname);
643 rc = llog_init_handle(loghandle, LLOG_F_IS_PLAIN, NULL);
647 if (llog_get_size(loghandle) <= 1)
648 GOTO(out_close, rc = 0);
652 GOTO(out_close, rc = -ENOMEM);
653 strcpy(mml->mml_marker.cm_comment, comment);
654 strcpy(mml->mml_marker.cm_tgtname, devname);
655 /* Modify mostly means cancel */
656 mml->mml_marker.cm_flags = flags;
657 mml->mml_marker.cm_canceltime = flags ? cfs_time_current_sec() : 0;
658 mml->mml_modified = 0;
659 rc = llog_process(loghandle, mgs_modify_handler, (void *)mml, NULL);
660 if (!rc && !mml->mml_modified)
665 rc2 = llog_close(loghandle);
669 pop_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
670 if (rc && rc != -ENODEV)
671 CERROR("modify %s/%s failed %d\n",
672 mti->mti_svname, comment, rc);
677 /******************** config log recording functions *********************/
679 static int record_lcfg(struct obd_device *obd, struct llog_handle *llh,
680 struct lustre_cfg *lcfg)
682 struct lvfs_run_ctxt saved;
683 struct llog_rec_hdr rec;
689 LASSERT(llh->lgh_ctxt);
691 buflen = lustre_cfg_len(lcfg->lcfg_bufcount,
693 rec.lrh_len = llog_data_len(buflen);
694 rec.lrh_type = OBD_CFG_REC;
696 push_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
697 /* idx = -1 means append */
698 rc = llog_write_rec(llh, &rec, NULL, 0, (void *)lcfg, -1);
699 pop_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
701 CERROR("failed %d\n", rc);
705 static int record_base(struct obd_device *obd, struct llog_handle *llh,
706 char *cfgname, lnet_nid_t nid, int cmd,
707 char *s1, char *s2, char *s3, char *s4)
709 struct lustre_cfg_bufs bufs;
710 struct lustre_cfg *lcfg;
713 CDEBUG(D_MGS, "lcfg %s %#x %s %s %s %s\n", cfgname,
714 cmd, s1, s2, s3, s4);
716 lustre_cfg_bufs_reset(&bufs, cfgname);
718 lustre_cfg_bufs_set_string(&bufs, 1, s1);
720 lustre_cfg_bufs_set_string(&bufs, 2, s2);
722 lustre_cfg_bufs_set_string(&bufs, 3, s3);
724 lustre_cfg_bufs_set_string(&bufs, 4, s4);
726 lcfg = lustre_cfg_new(cmd, &bufs);
729 lcfg->lcfg_nid = nid;
731 rc = record_lcfg(obd, llh, lcfg);
733 lustre_cfg_free(lcfg);
736 CERROR("error %d: lcfg %s %#x %s %s %s %s\n", rc, cfgname,
737 cmd, s1, s2, s3, s4);
743 static inline int record_add_uuid(struct obd_device *obd,
744 struct llog_handle *llh,
745 uint64_t nid, char *uuid)
747 return record_base(obd,llh,NULL,nid,LCFG_ADD_UUID,uuid,0,0,0);
751 static inline int record_add_conn(struct obd_device *obd,
752 struct llog_handle *llh,
756 return record_base(obd,llh,devname,0,LCFG_ADD_CONN,uuid,0,0,0);
759 static inline int record_attach(struct obd_device *obd, struct llog_handle *llh,
760 char *devname, char *type, char *uuid)
762 return record_base(obd,llh,devname,0,LCFG_ATTACH,type,uuid,0,0);
765 static inline int record_setup(struct obd_device *obd, struct llog_handle *llh,
767 char *s1, char *s2, char *s3, char *s4)
769 return record_base(obd,llh,devname,0,LCFG_SETUP,s1,s2,s3,s4);
772 static int record_lov_setup(struct obd_device *obd, struct llog_handle *llh,
773 char *devname, struct lov_desc *desc)
775 struct lustre_cfg_bufs bufs;
776 struct lustre_cfg *lcfg;
779 lustre_cfg_bufs_reset(&bufs, devname);
780 lustre_cfg_bufs_set(&bufs, 1, desc, sizeof(*desc));
781 lcfg = lustre_cfg_new(LCFG_SETUP, &bufs);
784 rc = record_lcfg(obd, llh, lcfg);
786 lustre_cfg_free(lcfg);
790 static int record_lmv_setup(struct obd_device *obd, struct llog_handle *llh,
791 char *devname, struct lmv_desc *desc)
793 struct lustre_cfg_bufs bufs;
794 struct lustre_cfg *lcfg;
797 lustre_cfg_bufs_reset(&bufs, devname);
798 lustre_cfg_bufs_set(&bufs, 1, desc, sizeof(*desc));
799 lcfg = lustre_cfg_new(LCFG_SETUP, &bufs);
801 rc = record_lcfg(obd, llh, lcfg);
803 lustre_cfg_free(lcfg);
807 static inline int record_mdc_add(struct obd_device *obd,
808 struct llog_handle *llh,
809 char *logname, char *mdcuuid,
810 char *mdtuuid, char *index,
813 return record_base(obd,llh,logname,0,LCFG_ADD_MDC,
814 mdtuuid,index,gen,mdcuuid);
817 static inline int record_lov_add(struct obd_device *obd,
818 struct llog_handle *llh,
819 char *lov_name, char *ost_uuid,
820 char *index, char *gen)
822 return record_base(obd,llh,lov_name,0,LCFG_LOV_ADD_OBD,
823 ost_uuid,index,gen,0);
826 static inline int record_mount_opt(struct obd_device *obd,
827 struct llog_handle *llh,
828 char *profile, char *lov_name,
831 return record_base(obd,llh,NULL,0,LCFG_MOUNTOPT,
832 profile,lov_name,mdc_name,0);
835 static int record_marker(struct obd_device *obd, struct llog_handle *llh,
836 struct fs_db *fsdb, __u32 flags,
837 char *tgtname, char *comment)
839 struct cfg_marker marker;
840 struct lustre_cfg_bufs bufs;
841 struct lustre_cfg *lcfg;
844 if (flags & CM_START)
846 marker.cm_step = fsdb->fsdb_gen;
847 marker.cm_flags = flags;
848 marker.cm_vers = LUSTRE_VERSION_CODE;
849 strncpy(marker.cm_tgtname, tgtname, sizeof(marker.cm_tgtname));
850 strncpy(marker.cm_comment, comment, sizeof(marker.cm_comment));
851 marker.cm_createtime = cfs_time_current_sec();
852 marker.cm_canceltime = 0;
853 lustre_cfg_bufs_reset(&bufs, NULL);
854 lustre_cfg_bufs_set(&bufs, 1, &marker, sizeof(marker));
855 lcfg = lustre_cfg_new(LCFG_MARKER, &bufs);
858 rc = record_lcfg(obd, llh, lcfg);
860 lustre_cfg_free(lcfg);
864 static int record_start_log(struct obd_device *obd,
865 struct llog_handle **llh, char *name)
867 static struct obd_uuid cfg_uuid = { .uuid = "config_uuid" };
868 struct lvfs_run_ctxt saved;
869 struct llog_ctxt *ctxt;
873 GOTO(out, rc = -EBUSY);
875 ctxt = llog_get_context(obd, LLOG_CONFIG_ORIG_CTXT);
877 GOTO(out, rc = -ENODEV);
879 push_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
880 rc = llog_create(ctxt, llh, NULL, name);
882 llog_init_handle(*llh, LLOG_F_IS_PLAIN, &cfg_uuid);
886 pop_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
891 CERROR("Can't start log %s: %d\n", name, rc);
896 static int record_end_log(struct obd_device *obd, struct llog_handle **llh)
898 struct lvfs_run_ctxt saved;
901 push_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
903 rc = llog_close(*llh);
906 pop_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
910 static int mgs_log_is_empty(struct obd_device *obd, char *name)
912 struct lvfs_run_ctxt saved;
913 struct llog_handle *llh;
914 struct llog_ctxt *ctxt;
917 ctxt = llog_get_context(obd, LLOG_CONFIG_ORIG_CTXT);
918 LASSERT(ctxt != NULL);
919 push_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
920 rc = llog_create(ctxt, &llh, NULL, name);
922 llog_init_handle(llh, LLOG_F_IS_PLAIN, NULL);
923 rc = llog_get_size(llh);
926 pop_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
928 /* header is record 1 */
932 /******************** config "macros" *********************/
934 /* write an lcfg directly into a log (with markers) */
935 static int mgs_write_log_direct(struct obd_device *obd, struct fs_db *fsdb,
936 char *logname, struct lustre_cfg *lcfg,
937 char *devname, char *comment)
939 struct llog_handle *llh = NULL;
946 rc = record_start_log(obd, &llh, logname);
950 /* FIXME These should be a single journal transaction */
951 rc = record_marker(obd, llh, fsdb, CM_START, devname, comment);
953 rc = record_lcfg(obd, llh, lcfg);
955 rc = record_marker(obd, llh, fsdb, CM_END, devname, comment);
956 rc = record_end_log(obd, &llh);
961 /* write the lcfg in all logs for the given fs */
962 int mgs_write_log_direct_all(struct obd_device *obd, struct fs_db *fsdb,
963 struct mgs_target_info *mti,
964 struct lustre_cfg *lcfg,
965 char *devname, char *comment)
967 struct mgs_obd *mgs = &obd->u.mgs;
968 struct list_head dentry_list;
969 struct l_linux_dirent *dirent, *n;
970 char *fsname = mti->mti_fsname;
972 int rc = 0, len = strlen(fsname);
975 /* We need to set params for any future logs
976 as well. FIXME Append this file to every new log.
977 Actually, we should store as params (text), not llogs. Or
979 name_create(&logname, fsname, "-params");
980 if (mgs_log_is_empty(obd, logname)) {
981 struct llog_handle *llh = NULL;
982 rc = record_start_log(obd, &llh, logname);
983 record_end_log(obd, &llh);
985 name_destroy(&logname);
989 /* Find all the logs in the CONFIGS directory */
990 rc = class_dentry_readdir(obd, mgs->mgs_configs_dir,
991 mgs->mgs_vfsmnt, &dentry_list);
993 CERROR("Can't read %s dir\n", MOUNT_CONFIGS_DIR);
997 /* Could use fsdb index maps instead of directory listing */
998 list_for_each_entry_safe(dirent, n, &dentry_list, lld_list) {
999 list_del(&dirent->lld_list);
1000 /* don't write to sptlrpc rule log */
1001 if (strncmp(fsname, dirent->lld_name, len) == 0 &&
1002 strstr(dirent->lld_name, "-sptlrpc") == NULL) {
1003 CDEBUG(D_MGS, "Changing log %s\n", dirent->lld_name);
1004 /* Erase any old settings of this same parameter */
1005 mgs_modify(obd, fsdb, mti, dirent->lld_name, devname,
1007 /* Write the new one */
1008 rc = mgs_write_log_direct(obd, fsdb, dirent->lld_name,
1009 lcfg, devname, comment);
1011 CERROR("err %d writing log %s\n", rc,
1014 OBD_FREE(dirent, sizeof(*dirent));
1022 struct mgs_target_info *comp_tmti;
1023 struct mgs_target_info *comp_mti;
1024 struct fs_db *comp_fsdb;
1025 struct obd_device *comp_obd;
1028 static int mgs_write_log_mdc_to_mdt(struct obd_device *, struct fs_db *,
1029 struct mgs_target_info *, char *);
1031 static int mgs_steal_llog_handler(struct llog_handle *llh,
1032 struct llog_rec_hdr *rec,
1035 struct obd_device * obd;
1036 struct mgs_target_info *mti, *tmti;
1038 int cfg_len = rec->lrh_len;
1039 char *cfg_buf = (char*) (rec + 1);
1040 struct lustre_cfg *lcfg;
1042 struct llog_handle *mdt_llh = NULL;
1043 static int got_an_osc_or_mdc = 0;
1044 /* 0: not found any osc/mdc;
1048 static int last_step = -1;
1052 mti = ((struct temp_comp*)data)->comp_mti;
1053 tmti = ((struct temp_comp*)data)->comp_tmti;
1054 fsdb = ((struct temp_comp*)data)->comp_fsdb;
1055 obd = ((struct temp_comp*)data)->comp_obd;
1057 if (rec->lrh_type != OBD_CFG_REC) {
1058 CERROR("unhandled lrh_type: %#x\n", rec->lrh_type);
1062 rc = lustre_cfg_sanity_check(cfg_buf, cfg_len);
1064 CERROR("Insane cfg\n");
1068 lcfg = (struct lustre_cfg *)cfg_buf;
1070 if (lcfg->lcfg_command == LCFG_MARKER) {
1071 struct cfg_marker *marker;
1072 marker = lustre_cfg_buf(lcfg, 1);
1073 if (!strncmp(marker->cm_comment,"add osc",7) &&
1074 (marker->cm_flags & CM_START)){
1075 got_an_osc_or_mdc = 1;
1076 rc = record_start_log(obd, &mdt_llh, mti->mti_svname);
1077 rc = record_marker(obd, mdt_llh, fsdb, CM_START,
1078 mti->mti_svname,"add osc(copied)");
1079 rc = record_end_log(obd, &mdt_llh);
1080 last_step = marker->cm_step;
1083 if (!strncmp(marker->cm_comment,"add osc",7) &&
1084 (marker->cm_flags & CM_END)){
1085 LASSERT(last_step == marker->cm_step);
1087 got_an_osc_or_mdc = 0;
1088 rc = record_start_log(obd, &mdt_llh, mti->mti_svname);
1089 rc = record_marker(obd, mdt_llh, fsdb, CM_END,
1090 mti->mti_svname,"add osc(copied)");
1091 rc = record_end_log(obd, &mdt_llh);
1094 if (!strncmp(marker->cm_comment,"add mdc",7) &&
1095 (marker->cm_flags & CM_START)){
1096 got_an_osc_or_mdc = 2;
1097 last_step = marker->cm_step;
1098 memcpy(tmti->mti_svname, marker->cm_tgtname,
1099 strlen(marker->cm_tgtname));
1103 if (!strncmp(marker->cm_comment,"add mdc",7) &&
1104 (marker->cm_flags & CM_END)){
1105 LASSERT(last_step == marker->cm_step);
1107 got_an_osc_or_mdc = 0;
1112 if (got_an_osc_or_mdc == 0 || last_step < 0)
1115 if (lcfg->lcfg_command == LCFG_ADD_UUID) {
1117 nodenid = lcfg->lcfg_nid;
1119 tmti->mti_nids[tmti->mti_nid_count] = nodenid;
1120 tmti->mti_nid_count++;
1125 if (lcfg->lcfg_command == LCFG_SETUP) {
1128 target = lustre_cfg_string(lcfg, 1);
1129 memcpy(tmti->mti_uuid, target, strlen(target));
1133 /* ignore client side sptlrpc_conf_log */
1134 if (lcfg->lcfg_command == LCFG_SPTLRPC_CONF)
1137 if (lcfg->lcfg_command == LCFG_ADD_MDC) {
1140 if (sscanf(lustre_cfg_buf(lcfg, 2), "%d", &index) != 1)
1143 memcpy(tmti->mti_fsname, mti->mti_fsname,
1144 strlen(mti->mti_fsname));
1145 tmti->mti_stripe_index = index;
1147 mgs_write_log_mdc_to_mdt(obd, fsdb, tmti, mti->mti_svname);
1148 memset(tmti, 0, sizeof(*tmti));
1154 /* fsdb->fsdb_sem is already held in mgs_write_log_target*/
1155 /* stealed from mgs_get_fsdb_from_llog*/
1156 static int mgs_steal_llog_for_mdt_from_client(struct obd_device *obd,
1158 struct temp_comp* comp)
1160 struct llog_handle *loghandle;
1161 struct lvfs_run_ctxt saved;
1162 struct mgs_target_info *tmti;
1163 struct llog_ctxt *ctxt;
1167 ctxt = llog_get_context(obd, LLOG_CONFIG_ORIG_CTXT);
1168 LASSERT(ctxt != NULL);
1170 OBD_ALLOC_PTR(tmti);
1174 comp->comp_tmti = tmti;
1175 comp->comp_obd = obd;
1177 push_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
1179 rc = llog_create(ctxt, &loghandle, NULL, client_name);
1183 rc = llog_init_handle(loghandle, LLOG_F_IS_PLAIN, NULL);
1185 GOTO(out_close, rc);
1187 rc = llog_process(loghandle, mgs_steal_llog_handler, (void *)comp, NULL);
1188 CDEBUG(D_MGS, "steal llog re = %d\n", rc);
1190 rc2 = llog_close(loghandle);
1194 pop_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
1196 llog_ctxt_put(ctxt);
1200 /* lmv is the second thing for client logs */
1201 /* copied from mgs_write_log_lov. Please refer to that. */
1202 static int mgs_write_log_lmv(struct obd_device *obd, struct fs_db *fsdb,
1203 struct mgs_target_info *mti,
1204 char *logname, char *lmvname)
1206 struct llog_handle *llh = NULL;
1207 struct lmv_desc *lmvdesc;
1212 CDEBUG(D_MGS, "Writing lmv(%s) log for %s\n", lmvname,logname);
1214 OBD_ALLOC_PTR(lmvdesc);
1215 if (lmvdesc == NULL)
1217 lmvdesc->ld_active_tgt_count = 0;
1218 lmvdesc->ld_tgt_count = 0;
1219 sprintf((char*)lmvdesc->ld_uuid.uuid, "%s_UUID", lmvname);
1220 uuid = (char *)lmvdesc->ld_uuid.uuid;
1222 rc = record_start_log(obd, &llh, logname);
1223 rc = record_marker(obd, llh, fsdb, CM_START, lmvname, "lmv setup");
1224 rc = record_attach(obd, llh, lmvname, "lmv", uuid);
1225 rc = record_lmv_setup(obd, llh, lmvname, lmvdesc);
1226 rc = record_marker(obd, llh, fsdb, CM_END, lmvname, "lmv setup");
1227 rc = record_end_log(obd, &llh);
1229 OBD_FREE_PTR(lmvdesc);
1233 /* lov is the first thing in the mdt and client logs */
1234 static int mgs_write_log_lov(struct obd_device *obd, struct fs_db *fsdb,
1235 struct mgs_target_info *mti,
1236 char *logname, char *lovname)
1238 struct llog_handle *llh = NULL;
1239 struct lov_desc *lovdesc;
1244 CDEBUG(D_MGS, "Writing lov(%s) log for %s\n", lovname, logname);
1247 #01 L attach 0:lov_mdsA 1:lov 2:71ccb_lov_mdsA_19f961a9e1
1248 #02 L lov_setup 0:lov_mdsA 1:(struct lov_desc)
1249 uuid=lov1_UUID, stripe count=1, size=1048576, offset=0, pattern=0
1252 /* FIXME just make lov_setup accept empty desc (put uuid in buf 2) */
1253 OBD_ALLOC_PTR(lovdesc);
1254 if (lovdesc == NULL)
1256 lovdesc->ld_magic = LOV_DESC_MAGIC;
1257 lovdesc->ld_tgt_count = 0;
1258 /* Defaults. Can be changed later by lcfg config_param */
1259 lovdesc->ld_default_stripe_count = 1;
1260 lovdesc->ld_pattern = LOV_PATTERN_RAID0;
1261 lovdesc->ld_default_stripe_size = 1024 * 1024;
1262 lovdesc->ld_default_stripe_offset = 0;
1263 lovdesc->ld_qos_maxage = QOS_DEFAULT_MAXAGE;
1264 sprintf((char*)lovdesc->ld_uuid.uuid, "%s_UUID", lovname);
1265 /* can these be the same? */
1266 uuid = (char *)lovdesc->ld_uuid.uuid;
1268 /* This should always be the first entry in a log.
1269 rc = mgs_clear_log(obd, logname); */
1270 rc = record_start_log(obd, &llh, logname);
1273 /* FIXME these should be a single journal transaction */
1274 rc = record_marker(obd, llh, fsdb, CM_START, lovname, "lov setup");
1275 rc = record_attach(obd, llh, lovname, "lov", uuid);
1276 rc = record_lov_setup(obd, llh, lovname, lovdesc);
1277 rc = record_marker(obd, llh, fsdb, CM_END, lovname, "lov setup");
1278 rc = record_end_log(obd, &llh);
1282 OBD_FREE_PTR(lovdesc);
1286 /* add failnids to open log */
1287 static int mgs_write_log_failnids(struct obd_device *obd,
1288 struct mgs_target_info *mti,
1289 struct llog_handle *llh,
1292 char *failnodeuuid = NULL;
1293 char *ptr = mti->mti_params;
1298 #03 L add_uuid nid=uml1@tcp(0x20000c0a80201) nal=90 0: 1:uml1_UUID
1299 #04 L add_uuid nid=1@elan(0x1000000000001) nal=90 0: 1:uml1_UUID
1300 #05 L setup 0:OSC_uml1_ost1_mdsA 1:ost1_UUID 2:uml1_UUID
1301 #06 L add_uuid nid=uml2@tcp(0x20000c0a80202) nal=90 0: 1:uml2_UUID
1302 #0x L add_uuid nid=2@elan(0x1000000000002) nal=90 0: 1:uml2_UUID
1303 #07 L add_conn 0:OSC_uml1_ost1_mdsA 1:uml2_UUID
1306 /* Pull failnid info out of params string */
1307 while (class_find_param(ptr, PARAM_FAILNODE, &ptr) == 0) {
1308 while (class_parse_nid(ptr, &nid, &ptr) == 0) {
1309 if (failnodeuuid == NULL) {
1310 /* We don't know the failover node name,
1311 so just use the first nid as the uuid */
1312 rc = name_create(&failnodeuuid,
1313 libcfs_nid2str(nid), "");
1317 CDEBUG(D_MGS, "add nid %s for failover uuid %s, "
1318 "client %s\n", libcfs_nid2str(nid),
1319 failnodeuuid, cliname);
1320 rc = record_add_uuid(obd, llh, nid, failnodeuuid);
1323 rc = record_add_conn(obd, llh, cliname, failnodeuuid);
1324 name_destroy(&failnodeuuid);
1325 failnodeuuid = NULL;
1332 static int mgs_write_log_mdc_to_lmv(struct obd_device *obd, struct fs_db *fsdb,
1333 struct mgs_target_info *mti,
1334 char *logname, char *lmvname)
1336 struct llog_handle *llh = NULL;
1337 char *mdcname, *nodeuuid, *mdcuuid, *lmvuuid;
1342 if (mgs_log_is_empty(obd, logname)) {
1343 CERROR("log is empty! Logical error\n");
1347 CDEBUG(D_MGS, "adding mdc for %s to log %s:lmv(%s)\n",
1348 mti->mti_svname, logname, lmvname);
1350 name_create(&nodeuuid, libcfs_nid2str(mti->mti_nids[0]), "");
1351 name_create(&mdcname, mti->mti_svname, "-mdc");
1352 name_create(&mdcuuid, mdcname, "_UUID");
1353 name_create(&lmvuuid, lmvname, "_UUID");
1355 rc = record_start_log(obd, &llh, logname);
1356 rc = record_marker(obd, llh, fsdb, CM_START, mti->mti_svname,
1359 for (i = 0; i < mti->mti_nid_count; i++) {
1360 CDEBUG(D_MGS, "add nid %s for mdt\n",
1361 libcfs_nid2str(mti->mti_nids[i]));
1363 rc = record_add_uuid(obd, llh, mti->mti_nids[i], nodeuuid);
1366 rc = record_attach(obd, llh, mdcname, LUSTRE_MDC_NAME, lmvuuid);
1367 rc = record_setup(obd, llh, mdcname, mti->mti_uuid, nodeuuid, 0, 0);
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);
1383 /* add new mdc to already existent MDS */
1384 static int mgs_write_log_mdc_to_mdt(struct obd_device *obd, struct fs_db *fsdb,
1385 struct mgs_target_info *mti, char *logname)
1387 struct llog_handle *llh = NULL;
1388 char *nodeuuid, *mdcname, *mdcuuid, *mdtuuid;
1389 int idx = mti->mti_stripe_index;
1394 if (mgs_log_is_empty(obd, mti->mti_svname)) {
1395 CERROR("log is empty! Logical error\n");
1399 CDEBUG(D_MGS, "adding mdc index %d to %s\n", idx, logname);
1401 name_create(&nodeuuid, libcfs_nid2str(mti->mti_nids[0]), "");
1402 snprintf(index, sizeof(index), "-mdc%04x", idx);
1403 name_create(&mdcname, logname, index);
1404 name_create(&mdcuuid, mdcname, "_UUID");
1405 name_create(&mdtuuid, logname, "_UUID");
1407 rc = record_start_log(obd, &llh, logname);
1408 rc = record_marker(obd, llh, fsdb, CM_START, mti->mti_svname, "add mdc");
1409 for (i = 0; i < mti->mti_nid_count; i++) {
1410 CDEBUG(D_MGS, "add nid %s for mdt\n",
1411 libcfs_nid2str(mti->mti_nids[i]));
1412 rc = record_add_uuid(obd, llh, mti->mti_nids[i], nodeuuid);
1414 rc = record_attach(obd, llh, mdcname, LUSTRE_MDC_NAME, mdcuuid);
1415 rc = record_setup(obd, llh, mdcname, mti->mti_uuid, nodeuuid, 0, 0);
1416 rc = mgs_write_log_failnids(obd, mti, llh, mdcname);
1417 snprintf(index, sizeof(index), "%d", idx);
1419 rc = record_mdc_add(obd, llh, logname, mdcuuid, mti->mti_uuid,
1421 rc = record_marker(obd, llh, fsdb, CM_END, mti->mti_svname, "add mdc");
1422 rc = record_end_log(obd, &llh);
1424 name_destroy(&mdcuuid);
1425 name_destroy(&mdcname);
1426 name_destroy(&nodeuuid);
1427 name_destroy(&mdtuuid);
1431 static int mgs_write_log_mdt0(struct obd_device *obd, struct fs_db *fsdb,
1432 struct mgs_target_info *mti)
1434 char *log = mti->mti_svname;
1435 struct llog_handle *llh = NULL;
1436 char *uuid, *lovname;
1438 char *ptr = mti->mti_params;
1439 int rc = 0, failout = 0;
1442 OBD_ALLOC(uuid, sizeof(struct obd_uuid));
1446 if (class_find_param(ptr, PARAM_FAILMODE, &ptr) == 0)
1447 failout = (strncmp(ptr, "failout", 7) == 0);
1449 name_create(&lovname, log, "-mdtlov");
1450 if (mgs_log_is_empty(obd, log))
1451 rc = mgs_write_log_lov(obd, fsdb, mti, log, lovname);
1453 sprintf(uuid, "%s_UUID", log);
1454 sprintf(mdt_index,"%d",mti->mti_stripe_index);
1456 /* add MDT itself */
1457 rc = record_start_log(obd, &llh, log);
1461 /* FIXME this whole fn should be a single journal transaction */
1462 rc = record_marker(obd, llh, fsdb, CM_START, log, "add mdt");
1463 rc = record_attach(obd, llh, log, LUSTRE_MDT_NAME, uuid);
1464 rc = record_mount_opt(obd, llh, log, lovname, NULL);
1465 rc = record_setup(obd, llh, log, uuid, mdt_index, lovname,
1466 failout ? "n" : "f");
1467 rc = record_marker(obd, llh, fsdb, CM_END, log, "add mdt");
1468 rc = record_end_log(obd, &llh);
1470 name_destroy(&lovname);
1471 OBD_FREE(uuid, sizeof(struct obd_uuid));
1475 /* envelope method for all layers log */
1476 static int mgs_write_log_mdt(struct obd_device *obd, struct fs_db *fsdb,
1477 struct mgs_target_info *mti)
1479 struct llog_handle *llh = NULL;
1481 struct temp_comp comp = { 0 };
1486 CDEBUG(D_MGS, "writing new mdt %s\n", mti->mti_svname);
1490 if (mti->mti_flags & LDD_F_UPGRADE14) {
1491 /* We're starting with an old uuid. Assume old name for lov
1492 as well since the lov entry already exists in the log. */
1493 CDEBUG(D_MGS, "old mds uuid %s\n", mti->mti_uuid);
1494 if (strncmp(mti->mti_uuid, fsdb->fsdb_mdtlov + 4,
1495 strlen(fsdb->fsdb_mdtlov) - 4) != 0) {
1496 CERROR("old mds uuid %s doesn't match log %s (%s)\n",
1497 mti->mti_uuid, fsdb->fsdb_mdtlov,
1498 fsdb->fsdb_mdtlov + 4);
1502 /* end COMPAT_146 */
1504 if (mti->mti_uuid[0] == '\0') {
1505 /* Make up our own uuid */
1506 snprintf(mti->mti_uuid, sizeof(mti->mti_uuid),
1507 "%s_UUID", mti->mti_svname);
1511 rc = mgs_write_log_mdt0(obd, fsdb, mti);
1513 /* Append the mdt info to the client log */
1514 name_create(&cliname, mti->mti_fsname, "-client");
1516 if (mgs_log_is_empty(obd, cliname)) {
1517 /* Start client log */
1518 rc = mgs_write_log_lov(obd, fsdb, mti, cliname,
1520 rc = mgs_write_log_lmv(obd, fsdb, mti, cliname,
1525 #09 L add_uuid nid=uml1@tcp(0x20000c0a80201) 0: 1:uml1_UUID
1526 #10 L attach 0:MDC_uml1_mdsA_MNT_client 1:mdc 2:1d834_MNT_client_03f
1527 #11 L setup 0:MDC_uml1_mdsA_MNT_client 1:mdsA_UUID 2:uml1_UUID
1528 #12 L add_uuid nid=uml2@tcp(0x20000c0a80202) 0: 1:uml2_UUID
1529 #13 L add_conn 0:MDC_uml1_mdsA_MNT_client 1:uml2_UUID
1530 #14 L mount_option 0: 1:client 2:lov1 3:MDC_uml1_mdsA_MNT_client
1535 if (mti->mti_flags & LDD_F_UPGRADE14) {
1536 rc = record_start_log(obd, &llh, cliname);
1540 rc = record_marker(obd, llh, fsdb, CM_START,
1541 mti->mti_svname,"add mdc");
1543 /* Old client log already has MDC entry, but needs mount opt
1544 for new client name (lustre-client) */
1545 /* FIXME Old MDT log already has an old mount opt
1546 which we should remove (currently handled by
1547 class_del_profiles()) */
1548 rc = record_mount_opt(obd, llh, cliname, fsdb->fsdb_clilov,
1550 /* end COMPAT_146 */
1552 rc = record_marker(obd, llh, fsdb, CM_END,
1553 mti->mti_svname, "add mdc");
1557 /* copy client info about lov/lmv */
1558 comp.comp_mti = mti;
1559 comp.comp_fsdb = fsdb;
1561 rc = mgs_steal_llog_for_mdt_from_client(obd, cliname,
1564 rc = mgs_write_log_mdc_to_lmv(obd, fsdb, mti, cliname,
1567 rc = record_start_log(obd, &llh, cliname);
1571 rc = record_marker(obd, llh, fsdb, CM_START, cliname,
1573 rc = record_mount_opt(obd, llh, cliname, fsdb->fsdb_clilov,
1575 rc = record_marker(obd, llh, fsdb, CM_END, cliname,
1579 rc = record_end_log(obd, &llh);
1581 name_destroy(&cliname);
1583 // for_all_existing_mdt except current one
1584 for (i = 0; i < INDEX_MAP_SIZE * 8; i++){
1586 if (i != mti->mti_stripe_index &&
1587 test_bit(i, fsdb->fsdb_mdt_index_map)) {
1588 sprintf(mdt_index,"-MDT%04x",i);
1590 name_create(&mdtname, mti->mti_fsname, mdt_index);
1591 rc = mgs_write_log_mdc_to_mdt(obd, fsdb, mti, mdtname);
1592 name_destroy(&mdtname);
1599 /* Add the ost info to the client/mdt lov */
1600 static int mgs_write_log_osc_to_lov(struct obd_device *obd, struct fs_db *fsdb,
1601 struct mgs_target_info *mti,
1602 char *logname, char *suffix, char *lovname,
1603 enum lustre_sec_part sec_part, int flags)
1605 struct llog_handle *llh = NULL;
1606 char *nodeuuid, *oscname, *oscuuid, *lovuuid, *svname;
1611 CDEBUG(D_INFO, "adding osc for %s to log %s\n",
1612 mti->mti_svname, logname);
1614 if (mgs_log_is_empty(obd, logname)) {
1615 /* The first item in the log must be the lov, so we have
1616 somewhere to add our osc. */
1617 rc = mgs_write_log_lov(obd, fsdb, mti, logname, lovname);
1620 name_create(&nodeuuid, libcfs_nid2str(mti->mti_nids[0]), "");
1621 name_create(&svname, mti->mti_svname, "-osc");
1622 name_create(&oscname, svname, suffix);
1623 name_create(&oscuuid, oscname, "_UUID");
1624 name_create(&lovuuid, lovname, "_UUID");
1627 #03 L add_uuid nid=uml1@tcp(0x20000c0a80201) 0: 1:uml1_UUID
1629 #04 L add_uuid nid=1@elan(0x1000000000001) nal=90 0: 1:uml1_UUID
1630 #04 L attach 0:OSC_uml1_ost1_MNT_client 1:osc 2:89070_lov1_a41dff51a
1631 #05 L setup 0:OSC_uml1_ost1_MNT_client 1:ost1_UUID 2:uml1_UUID
1633 #06 L add_uuid nid=uml2@tcp(0x20000c0a80202) 0: 1:uml2_UUID
1634 #07 L add_conn 0:OSC_uml1_ost1_MNT_client 1:uml2_UUID
1635 #08 L lov_modify_tgts add 0:lov1 1:ost1_UUID 2(index):0 3(gen):1
1638 rc = record_start_log(obd, &llh, logname);
1641 /* FIXME these should be a single journal transaction */
1642 rc = record_marker(obd, llh, fsdb, CM_START | flags, mti->mti_svname,
1644 for (i = 0; i < mti->mti_nid_count; i++) {
1645 CDEBUG(D_MGS, "add nid %s\n", libcfs_nid2str(mti->mti_nids[i]));
1646 rc = record_add_uuid(obd, llh, mti->mti_nids[i], nodeuuid);
1648 rc = record_attach(obd, llh, oscname, LUSTRE_OSC_NAME, lovuuid);
1649 rc = record_setup(obd, llh, oscname, mti->mti_uuid, nodeuuid, 0, 0);
1650 rc = mgs_write_log_failnids(obd, mti, llh, oscname);
1651 snprintf(index, sizeof(index), "%d", mti->mti_stripe_index);
1652 rc = record_lov_add(obd, llh, lovname, mti->mti_uuid, index, "1");
1653 rc = record_marker(obd, llh, fsdb, CM_END | flags, mti->mti_svname,
1655 rc = record_end_log(obd, &llh);
1657 name_destroy(&lovuuid);
1658 name_destroy(&oscuuid);
1659 name_destroy(&oscname);
1660 name_destroy(&svname);
1661 name_destroy(&nodeuuid);
1665 static int mgs_write_log_ost(struct obd_device *obd, struct fs_db *fsdb,
1666 struct mgs_target_info *mti)
1668 struct llog_handle *llh = NULL;
1669 char *logname, *lovname;
1671 char *ptr = mti->mti_params;
1672 int rc, flags = 0, failout = 0, i;
1675 CDEBUG(D_MGS, "writing new ost %s\n", mti->mti_svname);
1677 /* The ost startup log */
1679 /* If the ost log already exists, that means that someone reformatted
1680 the ost and it called target_add again. */
1681 if (!mgs_log_is_empty(obd, mti->mti_svname)) {
1682 LCONSOLE_ERROR_MSG(0x141, "The config log for %s already "
1683 "exists, yet the server claims it never "
1684 "registered. It may have been reformatted, "
1685 "or the index changed. writeconf the MDT to "
1686 "regenerate all logs.\n", mti->mti_svname);
1691 attach obdfilter ost1 ost1_UUID
1692 setup /dev/loop2 ldiskfs f|n errors=remount-ro,user_xattr
1694 if (class_find_param(ptr, PARAM_FAILMODE, &ptr) == 0)
1695 failout = (strncmp(ptr, "failout", 7) == 0);
1696 rc = record_start_log(obd, &llh, mti->mti_svname);
1699 /* FIXME these should be a single journal transaction */
1700 rc = record_marker(obd, llh, fsdb, CM_START, mti->mti_svname,"add ost");
1701 if (*mti->mti_uuid == '\0')
1702 snprintf(mti->mti_uuid, sizeof(mti->mti_uuid),
1703 "%s_UUID", mti->mti_svname);
1704 rc = record_attach(obd, llh, mti->mti_svname,
1705 "obdfilter"/*LUSTRE_OST_NAME*/, mti->mti_uuid);
1706 rc = record_setup(obd, llh, mti->mti_svname,
1707 "dev"/*ignored*/, "type"/*ignored*/,
1708 failout ? "n" : "f", 0/*options*/);
1709 rc = record_marker(obd, llh, fsdb, CM_END, mti->mti_svname, "add ost");
1710 rc = record_end_log(obd, &llh);
1712 /* We also have to update the other logs where this osc is part of
1715 if (fsdb->fsdb_flags & FSDB_OLDLOG14) {
1716 /* If we're upgrading, the old mdt log already has our
1717 entry. Let's do a fake one for fun. */
1718 /* Note that we can't add any new failnids, since we don't
1719 know the old osc names. */
1720 flags = CM_SKIP | CM_UPGRADE146;
1722 } else if ((mti->mti_flags & LDD_F_UPDATE) != LDD_F_UPDATE) {
1723 /* If the update flag isn't set, don't update client/mdt
1726 LCONSOLE_WARN("Client log for %s was not updated; writeconf "
1727 "the MDT first to regenerate it.\n",
1731 // for_all_existing_mdt
1732 for (i = 0; i < INDEX_MAP_SIZE * 8; i++){
1733 if (test_bit(i, fsdb->fsdb_mdt_index_map)) {
1734 sprintf(mdt_index,"-MDT%04x",i);
1735 name_create(&logname, mti->mti_fsname, mdt_index);
1736 name_create(&lovname, logname, "-mdtlov");
1737 mgs_write_log_osc_to_lov(obd, fsdb, mti, logname,
1739 LUSTRE_SP_MDT, flags);
1740 name_destroy(&logname);
1741 name_destroy(&lovname);
1745 /* Append ost info to the client log */
1746 name_create(&logname, mti->mti_fsname, "-client");
1747 mgs_write_log_osc_to_lov(obd, fsdb, mti, logname, "",
1748 fsdb->fsdb_clilov, LUSTRE_SP_CLI, 0);
1749 name_destroy(&logname);
1753 /* Add additional failnids to an existing log.
1754 The mdc/osc must have been added to logs first */
1755 /* tcp nids must be in dotted-quad ascii -
1756 we can't resolve hostnames from the kernel. */
1757 static int mgs_write_log_add_failnid(struct obd_device *obd, struct fs_db *fsdb,
1758 struct mgs_target_info *mti)
1760 char *logname, *cliname;
1761 struct llog_handle *llh = NULL;
1765 /* FIXME how do we delete a failnid? Currently --writeconf is the
1766 only way. Maybe make --erase-params pass a flag to really
1767 erase all params from logs - except it can't erase the failnids
1768 given when a target first registers, since they aren't processed
1771 /* Verify that we know about this target */
1772 if (mgs_log_is_empty(obd, mti->mti_svname)) {
1773 LCONSOLE_ERROR_MSG(0x142, "The target %s has not registered "
1774 "yet. It must be started before failnids "
1775 "can be added.\n", mti->mti_svname);
1779 /* Create mdc/osc client name (e.g. lustre-OST0001-osc) */
1780 if (mti->mti_flags & LDD_F_SV_TYPE_MDT) {
1781 name_create(&cliname, mti->mti_svname, "-mdc");
1782 } else if (mti->mti_flags & LDD_F_SV_TYPE_OST) {
1783 name_create(&cliname, mti->mti_svname, "-osc");
1788 /* Add failover nids to client log */
1789 name_create(&logname, mti->mti_fsname, "-client");
1790 rc = record_start_log(obd, &llh, logname);
1792 /* FIXME this fn should be a single journal transaction */
1793 rc = record_marker(obd, llh, fsdb, CM_START, mti->mti_svname,
1795 rc = mgs_write_log_failnids(obd, mti, llh, cliname);
1796 rc = record_marker(obd, llh, fsdb, CM_END, mti->mti_svname,
1798 rc = record_end_log(obd, &llh);
1800 name_destroy(&logname);
1802 if (mti->mti_flags & LDD_F_SV_TYPE_OST) {
1803 /* Add OST failover nids to the MDT log as well */
1804 name_create(&logname, mti->mti_fsname, "-MDT0000");
1805 rc = record_start_log(obd, &llh, logname);
1807 rc = record_marker(obd, llh, fsdb, CM_START,
1808 mti->mti_svname, "add failnid");
1809 rc = mgs_write_log_failnids(obd, mti, llh, cliname);
1810 rc = record_marker(obd, llh, fsdb, CM_END,
1811 mti->mti_svname, "add failnid");
1812 rc = record_end_log(obd, &llh);
1814 name_destroy(&logname);
1817 name_destroy(&cliname);
1821 static int mgs_wlp_lcfg(struct obd_device *obd, struct fs_db *fsdb,
1822 struct mgs_target_info *mti,
1823 char *logname, struct lustre_cfg_bufs *bufs,
1824 char *tgtname, char *ptr)
1826 char comment[MTI_NAME_MAXLEN];
1828 struct lustre_cfg *lcfg;
1831 /* Erase any old settings of this same parameter */
1832 memcpy(comment, ptr, MTI_NAME_MAXLEN);
1833 comment[MTI_NAME_MAXLEN - 1] = 0;
1834 /* But don't try to match the value. */
1835 if ((tmp = strchr(comment, '=')))
1837 /* FIXME we should skip settings that are the same as old values */
1838 rc = mgs_modify(obd, fsdb, mti, logname, tgtname, comment, CM_SKIP);
1839 LCONSOLE_INFO("%sing parameter %s.%s in log %s\n", rc ?
1840 "Sett" : "Modify", tgtname, comment, logname);
1842 lustre_cfg_bufs_reset(bufs, tgtname);
1843 lustre_cfg_bufs_set_string(bufs, 1, ptr);
1844 lcfg = lustre_cfg_new(LCFG_PARAM, bufs);
1847 rc = mgs_write_log_direct(obd, fsdb, logname, lcfg, tgtname, comment);
1848 lustre_cfg_free(lcfg);
1852 /* write global variable settings into log */
1853 static int mgs_write_log_sys(struct obd_device *obd, struct fs_db *fsdb,
1854 struct mgs_target_info *mti, char *sys, char *ptr)
1856 struct lustre_cfg_bufs bufs;
1857 struct lustre_cfg *lcfg;
1862 if (class_match_param(ptr, PARAM_TIMEOUT, &tmp) == 0)
1863 cmd = LCFG_SET_TIMEOUT;
1864 else if (class_match_param(ptr, PARAM_LDLM_TIMEOUT, &tmp) == 0)
1865 cmd = LCFG_SET_LDLM_TIMEOUT;
1866 /* Check for known params here so we can return error to lctl */
1867 else if ((class_match_param(ptr, PARAM_AT_MIN, &tmp) == 0)
1868 || (class_match_param(ptr, PARAM_AT_MAX, &tmp) == 0)
1869 || (class_match_param(ptr, PARAM_AT_EXTRA, &tmp) == 0)
1870 || (class_match_param(ptr, PARAM_AT_EARLY_MARGIN, &tmp) == 0)
1871 || (class_match_param(ptr, PARAM_AT_HISTORY, &tmp) == 0))
1876 val = simple_strtoul(tmp, NULL, 0);
1877 CDEBUG(D_MGS, "global %s = %d\n", ptr, val);
1879 lustre_cfg_bufs_reset(&bufs, NULL);
1880 lustre_cfg_bufs_set_string(&bufs, 1, sys);
1881 lcfg = lustre_cfg_new(cmd, &bufs);
1882 lcfg->lcfg_num = val;
1883 /* modify all servers and clients */
1884 rc = mgs_write_log_direct_all(obd, fsdb, mti, lcfg, mti->mti_fsname,
1886 lustre_cfg_free(lcfg);
1890 static int mgs_srpc_set_param_disk(struct obd_device *obd,
1892 struct mgs_target_info *mti,
1895 struct llog_handle *llh = NULL;
1897 char *comment, *ptr;
1898 struct lustre_cfg_bufs bufs;
1899 struct lustre_cfg *lcfg;
1904 ptr = strchr(param, '=');
1908 OBD_ALLOC(comment, len + 1);
1909 if (comment == NULL)
1911 strncpy(comment, param, len);
1912 comment[len] = '\0';
1915 lustre_cfg_bufs_reset(&bufs, mti->mti_svname);
1916 lustre_cfg_bufs_set_string(&bufs, 1, param);
1917 lcfg = lustre_cfg_new(LCFG_SPTLRPC_CONF, &bufs);
1919 GOTO(out_comment, rc = -ENOMEM);
1921 /* construct log name */
1922 rc = name_create(&logname, mti->mti_fsname, "-sptlrpc");
1926 if (mgs_log_is_empty(obd, logname)) {
1927 rc = record_start_log(obd, &llh, logname);
1928 record_end_log(obd, &llh);
1933 /* obsolete old one */
1934 mgs_modify(obd, fsdb, mti, logname, mti->mti_svname, comment, CM_SKIP);
1936 /* write the new one */
1937 rc = mgs_write_log_direct(obd, fsdb, logname, lcfg,
1938 mti->mti_svname, comment);
1940 CERROR("err %d writing log %s\n", rc, logname);
1943 name_destroy(&logname);
1945 lustre_cfg_free(lcfg);
1947 OBD_FREE(comment, len + 1);
1951 static int mgs_srpc_set_param_udesc_mem(struct fs_db *fsdb,
1956 /* disable the adjustable udesc parameter for now, i.e. use default
1957 * setting that client always ship udesc to MDT if possible. to enable
1958 * it simply remove the following line */
1961 ptr = strchr(param, '=');
1966 if (strcmp(param, PARAM_SRPC_UDESC))
1969 if (strcmp(ptr, "yes") == 0) {
1970 fsdb->fsdb_fl_udesc = 1;
1971 CWARN("Enable user descriptor shipping from client to MDT\n");
1972 } else if (strcmp(ptr, "no") == 0) {
1973 fsdb->fsdb_fl_udesc = 0;
1974 CWARN("Disable user descriptor shipping from client to MDT\n");
1982 CERROR("Invalid param: %s\n", param);
1986 static int mgs_srpc_set_param_mem(struct fs_db *fsdb,
1990 struct sptlrpc_rule rule;
1991 struct sptlrpc_rule_set *rset;
1995 if (strncmp(param, PARAM_SRPC, sizeof(PARAM_SRPC) - 1) != 0) {
1996 CERROR("Invalid sptlrpc parameter: %s\n", param);
2000 if (strncmp(param, PARAM_SRPC_UDESC,
2001 sizeof(PARAM_SRPC_UDESC) - 1) == 0) {
2002 RETURN(mgs_srpc_set_param_udesc_mem(fsdb, param));
2005 if (strncmp(param, PARAM_SRPC_FLVR, sizeof(PARAM_SRPC_FLVR) - 1) != 0) {
2006 CERROR("Invalid sptlrpc flavor parameter: %s\n", param);
2010 param += sizeof(PARAM_SRPC_FLVR) - 1;
2012 rc = sptlrpc_parse_rule(param, &rule);
2016 /* mgs rules implies must be mgc->mgs */
2017 if (fsdb->fsdb_fl_mgsself) {
2018 if ((rule.sr_from != LUSTRE_SP_MGC &&
2019 rule.sr_from != LUSTRE_SP_ANY) ||
2020 (rule.sr_to != LUSTRE_SP_MGS &&
2021 rule.sr_to != LUSTRE_SP_ANY))
2025 /* preapre room for this coming rule. svcname format should be:
2026 * - fsname: general rule
2027 * - fsname-tgtname: target-specific rule
2029 if (strchr(svname, '-')) {
2030 struct mgs_tgt_srpc_conf *tgtconf;
2033 for (tgtconf = fsdb->fsdb_srpc_tgt; tgtconf != NULL;
2034 tgtconf = tgtconf->mtsc_next) {
2035 if (!strcmp(tgtconf->mtsc_tgt, svname)) {
2044 OBD_ALLOC_PTR(tgtconf);
2045 if (tgtconf == NULL)
2048 name_len = strlen(svname);
2050 OBD_ALLOC(tgtconf->mtsc_tgt, name_len + 1);
2051 if (tgtconf->mtsc_tgt == NULL) {
2052 OBD_FREE_PTR(tgtconf);
2055 memcpy(tgtconf->mtsc_tgt, svname, name_len);
2057 tgtconf->mtsc_next = fsdb->fsdb_srpc_tgt;
2058 fsdb->fsdb_srpc_tgt = tgtconf;
2061 rset = &tgtconf->mtsc_rset;
2063 rset = &fsdb->fsdb_srpc_gen;
2066 rc = sptlrpc_rule_set_merge(rset, &rule);
2071 static int mgs_srpc_set_param(struct obd_device *obd,
2073 struct mgs_target_info *mti,
2083 /* keep a copy of original param, which could be destroied
2085 copy_size = strlen(param) + 1;
2086 OBD_ALLOC(copy, copy_size);
2089 memcpy(copy, param, copy_size);
2091 rc = mgs_srpc_set_param_mem(fsdb, mti->mti_svname, param);
2095 /* previous steps guaranteed the syntax is correct */
2096 rc = mgs_srpc_set_param_disk(obd, fsdb, mti, copy);
2100 if (fsdb->fsdb_fl_mgsself) {
2102 * for mgs rules, make them effective immediately.
2104 LASSERT(fsdb->fsdb_srpc_tgt == NULL);
2105 sptlrpc_target_update_exp_flavor(obd, &fsdb->fsdb_srpc_gen);
2109 OBD_FREE(copy, copy_size);
2113 struct mgs_srpc_read_data {
2114 struct fs_db *msrd_fsdb;
2118 static int mgs_srpc_read_handler(struct llog_handle *llh,
2119 struct llog_rec_hdr *rec,
2122 struct mgs_srpc_read_data *msrd = (struct mgs_srpc_read_data *) data;
2123 struct cfg_marker *marker;
2124 struct lustre_cfg *lcfg = (struct lustre_cfg *)(rec + 1);
2125 char *svname, *param;
2129 if (rec->lrh_type != OBD_CFG_REC) {
2130 CERROR("unhandled lrh_type: %#x\n", rec->lrh_type);
2134 cfg_len = rec->lrh_len - sizeof(struct llog_rec_hdr) -
2135 sizeof(struct llog_rec_tail);
2137 rc = lustre_cfg_sanity_check(lcfg, cfg_len);
2139 CERROR("Insane cfg\n");
2143 if (lcfg->lcfg_command == LCFG_MARKER) {
2144 marker = lustre_cfg_buf(lcfg, 1);
2146 if (marker->cm_flags & CM_START &&
2147 marker->cm_flags & CM_SKIP)
2148 msrd->msrd_skip = 1;
2149 if (marker->cm_flags & CM_END)
2150 msrd->msrd_skip = 0;
2155 if (msrd->msrd_skip)
2158 if (lcfg->lcfg_command != LCFG_SPTLRPC_CONF) {
2159 CERROR("invalid command (%x)\n", lcfg->lcfg_command);
2163 svname = lustre_cfg_string(lcfg, 0);
2164 if (svname == NULL) {
2165 CERROR("svname is empty\n");
2169 param = lustre_cfg_string(lcfg, 1);
2170 if (param == NULL) {
2171 CERROR("param is empty\n");
2175 rc = mgs_srpc_set_param_mem(msrd->msrd_fsdb, svname, param);
2177 CERROR("read sptlrpc record error (%d): %s\n", rc, param);
2182 int mgs_get_fsdb_srpc_from_llog(struct obd_device *obd,
2185 struct llog_handle *llh = NULL;
2186 struct lvfs_run_ctxt saved;
2187 struct llog_ctxt *ctxt;
2189 struct mgs_srpc_read_data msrd;
2193 /* construct log name */
2194 rc = name_create(&logname, fsdb->fsdb_name, "-sptlrpc");
2198 ctxt = llog_get_context(obd, LLOG_CONFIG_ORIG_CTXT);
2199 LASSERT(ctxt != NULL);
2201 if (mgs_log_is_empty(obd, logname))
2204 push_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
2206 rc = llog_create(ctxt, &llh, NULL, logname);
2210 rc = llog_init_handle(llh, LLOG_F_IS_PLAIN, NULL);
2212 GOTO(out_close, rc);
2214 if (llog_get_size(llh) <= 1)
2215 GOTO(out_close, rc = 0);
2217 msrd.msrd_fsdb = fsdb;
2220 rc = llog_process(llh, mgs_srpc_read_handler, (void *) &msrd, NULL);
2225 pop_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
2227 llog_ctxt_put(ctxt);
2228 name_destroy(&logname);
2231 CERROR("failed to read sptlrpc config database: %d\n", rc);
2235 static int mgs_write_log_param(struct obd_device *obd, struct fs_db *fsdb,
2236 struct mgs_target_info *mti, char *ptr)
2238 struct lustre_cfg_bufs bufs;
2244 /* For various parameter settings, we have to figure out which logs
2245 care about them (e.g. both mdt and client for lov settings) */
2246 CDEBUG(D_MGS, "next param '%s'\n", ptr);
2248 /* The params are stored in MOUNT_DATA_FILE and modified via
2249 tunefs.lustre, or set using lctl conf_param */
2251 /* Processed in lustre_start_mgc */
2252 if (class_match_param(ptr, PARAM_MGSNODE, NULL) == 0)
2255 /* Processed in mgs_write_log_ost */
2256 if (class_match_param(ptr, PARAM_FAILMODE, NULL) == 0) {
2257 if (mti->mti_flags & LDD_F_PARAM) {
2258 LCONSOLE_ERROR_MSG(0x169, "%s can only be "
2259 "changed with tunefs.lustre"
2260 "and --writeconf\n", ptr);
2266 if (class_match_param(ptr, PARAM_SRPC, NULL) == 0) {
2267 rc = mgs_srpc_set_param(obd, fsdb, mti, ptr);
2271 if (class_match_param(ptr, PARAM_FAILNODE, NULL) == 0) {
2272 /* Add a failover nidlist */
2274 /* We already processed failovers params for new
2275 targets in mgs_write_log_target */
2276 if (mti->mti_flags & LDD_F_PARAM) {
2277 CDEBUG(D_MGS, "Adding failnode\n");
2278 rc = mgs_write_log_add_failnid(obd, fsdb, mti);
2283 if (class_match_param(ptr, PARAM_SYS, &tmp) == 0) {
2284 rc = mgs_write_log_sys(obd, fsdb, mti, ptr, tmp);
2288 if (class_match_param(ptr, PARAM_OSC""PARAM_ACTIVE, &tmp) == 0) {
2289 /* active=0 means off, anything else means on */
2291 int flag = (*tmp == '0') ? CM_EXCLUDE : 0;
2294 if (!(mti->mti_flags & LDD_F_SV_TYPE_OST)) {
2295 LCONSOLE_ERROR_MSG(0x144, "%s: Only OSCs can "
2296 "be (de)activated.\n",
2298 GOTO(end, rc = -EINVAL);
2300 LCONSOLE_WARN("Permanently %sactivating %s\n",
2301 flag ? "de": "re", mti->mti_svname);
2303 name_create(&logname, mti->mti_fsname, "-client");
2304 rc = mgs_modify(obd, fsdb, mti, logname,
2305 mti->mti_svname, "add osc", flag);
2306 name_destroy(&logname);
2310 /* FIXME add to all MDT logs for CMD */
2311 for (i = 0; i < INDEX_MAP_SIZE * 8; i++) {
2312 if (!test_bit(i, fsdb->fsdb_mdt_index_map))
2314 sprintf(mdt_index,"-MDT%04x", i);
2315 name_create(&logname, mti->mti_fsname, mdt_index);
2316 rc = mgs_modify(obd, fsdb, mti, logname,
2317 mti->mti_svname, "add osc", flag);
2318 name_destroy(&logname);
2324 LCONSOLE_ERROR_MSG(0x145, "Couldn't find %s in"
2325 "log (%d). No permanent "
2326 "changes were made to the "
2328 mti->mti_svname, rc);
2329 if (fsdb->fsdb_flags & FSDB_OLDLOG14)
2330 LCONSOLE_ERROR_MSG(0x146, "This may be"
2335 "update the logs.\n");
2338 /* Fall through to osc proc for deactivating live OSC
2339 on running MDT / clients. */
2341 /* Below here, let obd's XXX_process_config methods handle it */
2343 /* All lov. in proc */
2344 if (class_match_param(ptr, PARAM_LOV, NULL) == 0) {
2348 CDEBUG(D_MGS, "lov param %s\n", ptr);
2349 if (!(mti->mti_flags & LDD_F_SV_TYPE_MDT)) {
2350 LCONSOLE_ERROR_MSG(0x147, "LOV params must be "
2351 "set on the MDT, not %s. "
2358 if (mgs_log_is_empty(obd, mti->mti_svname))
2359 GOTO(end, rc = -ENODEV);
2361 sprintf(mdt_index,"-MDT%04x", mti->mti_stripe_index);
2362 name_create(&logname, mti->mti_fsname, mdt_index);
2363 name_create(&mdtlovname, logname, "-mdtlov");
2364 rc = mgs_wlp_lcfg(obd, fsdb, mti, mti->mti_svname,
2365 &bufs, mdtlovname, ptr);
2366 name_destroy(&logname);
2367 name_destroy(&mdtlovname);
2372 name_create(&logname, mti->mti_fsname, "-client");
2373 rc = mgs_wlp_lcfg(obd, fsdb, mti, logname, &bufs,
2374 fsdb->fsdb_clilov, ptr);
2375 name_destroy(&logname);
2379 /* All osc., mdc., llite. params in proc */
2380 if ((class_match_param(ptr, PARAM_OSC, NULL) == 0) ||
2381 (class_match_param(ptr, PARAM_MDC, NULL) == 0) ||
2382 (class_match_param(ptr, PARAM_LLITE, NULL) == 0)) {
2384 if (memcmp(ptr, PARAM_LLITE, strlen(PARAM_LLITE)) == 0) {
2385 name_create(&cname, mti->mti_fsname, "-client");
2386 /* Add the client type to match the obdname in
2387 class_config_llog_handler */
2388 } else if (mti->mti_flags & LDD_F_SV_TYPE_MDT) {
2391 name_create(&cname, fsdb->fsdb_mdc, "");
2393 name_create(&cname, mti->mti_svname,
2395 } else if (mti->mti_flags & LDD_F_SV_TYPE_OST) {
2397 if (fsdb->fsdb_flags & FSDB_OLDLOG14) {
2398 LCONSOLE_ERROR_MSG(0x148, "Upgraded "
2399 "client logs for %s"
2401 "modified. Consider"
2403 "configuration with"
2406 /* We don't know the names of all the
2408 GOTO(end, rc = -EINVAL);
2410 name_create(&cname, mti->mti_svname, "-osc");
2412 GOTO(end, rc = -EINVAL);
2415 CDEBUG(D_MGS, "%.3s param %s\n", ptr, ptr + 4);
2418 name_create(&logname, mti->mti_fsname, "-client");
2419 rc = mgs_wlp_lcfg(obd, fsdb, mti, logname, &bufs,
2422 /* osc params affect the MDT as well */
2423 if (!rc && (mti->mti_flags & LDD_F_SV_TYPE_OST)) {
2427 for (i = 0; i < INDEX_MAP_SIZE * 8; i++){
2428 if (!test_bit(i, fsdb->fsdb_mdt_index_map))
2430 name_destroy(&cname);
2431 sprintf(mdt_index, "-osc-MDT%04x", i);
2432 name_create(&cname, mti->mti_svname,
2434 name_destroy(&logname);
2435 sprintf(mdt_index, "-MDT%04x", i);
2436 name_create(&logname, mti->mti_fsname,
2438 if (!mgs_log_is_empty(obd, logname))
2439 rc = mgs_wlp_lcfg(obd, fsdb,
2447 name_destroy(&logname);
2448 name_destroy(&cname);
2452 /* All mdt. params in proc */
2453 if (class_match_param(ptr, PARAM_MDT, NULL) == 0) {
2458 CDEBUG(D_MGS, "%.3s param %s\n", ptr, ptr + 4);
2459 if (strncmp(mti->mti_svname, mti->mti_fsname,
2460 MTI_NAME_MAXLEN) == 0)
2461 /* device is unspecified completely? */
2462 rc = LDD_F_SV_TYPE_MDT | LDD_F_SV_ALL;
2464 rc = server_name2index(mti->mti_svname, &idx, NULL);
2467 if ((rc & LDD_F_SV_TYPE_MDT) == 0)
2469 if (rc & LDD_F_SV_ALL) {
2470 for (i = 0; i < INDEX_MAP_SIZE * 8; i++) {
2472 fsdb->fsdb_mdt_index_map))
2474 sprintf(mdt_index,"-MDT%04x", i);
2475 name_create(&logname, mti->mti_fsname,
2477 rc = mgs_wlp_lcfg(obd, fsdb, mti,
2480 name_destroy(&logname);
2485 rc = mgs_wlp_lcfg(obd, fsdb, mti,
2486 mti->mti_svname, &bufs,
2487 mti->mti_svname, ptr);
2494 /* All mdd., ost. params in proc */
2495 if ((class_match_param(ptr, PARAM_MDD, NULL) == 0) ||
2496 (class_match_param(ptr, PARAM_OST, NULL) == 0)) {
2497 CDEBUG(D_MGS, "%.3s param %s\n", ptr, ptr + 4);
2498 if (mgs_log_is_empty(obd, mti->mti_svname))
2499 GOTO(end, rc = -ENODEV);
2501 rc = mgs_wlp_lcfg(obd, fsdb, mti, mti->mti_svname,
2502 &bufs, mti->mti_svname, ptr);
2506 LCONSOLE_WARN("Ignoring unrecognized param '%s'\n", ptr);
2510 CERROR("err %d on param '%s'\n", rc, ptr);
2515 /* Not implementing automatic failover nid addition at this time. */
2516 int mgs_check_failnid(struct obd_device *obd, struct mgs_target_info *mti)
2523 rc = mgs_find_or_make_fsdb(obd, fsname, &fsdb);
2527 if (mgs_log_is_empty(obd, mti->mti_svname))
2528 /* should never happen */
2531 CDEBUG(D_MGS, "Checking for new failnids for %s\n", mti->mti_svname);
2533 /* FIXME We can just check mti->params to see if we're already in
2534 the failover list. Modify mti->params for rewriting back at
2535 server_register_target(). */
2537 down(&fsdb->fsdb_sem);
2538 rc = mgs_write_log_add_failnid(obd, fsdb, mti);
2539 up(&fsdb->fsdb_sem);
2546 int mgs_write_log_target(struct obd_device *obd,
2547 struct mgs_target_info *mti)
2554 rc = mgs_find_or_make_fsdb(obd, mti->mti_fsname, &fsdb);
2556 CERROR("Can't get db for %s\n", mti->mti_fsname);
2560 down(&fsdb->fsdb_sem);
2562 /* set/check the new target index */
2563 rc = mgs_set_index(fsdb, mti);
2565 CERROR("Can't get index (%d)\n", rc);
2570 if (mti->mti_flags & LDD_F_UPGRADE14) {
2571 if (rc == EALREADY) {
2572 LCONSOLE_INFO("Found index %d for %s 1.4 log, "
2573 "upgrading\n", mti->mti_stripe_index,
2576 LCONSOLE_ERROR_MSG(0x149, "Failed to find %s in the old"
2577 " client log. Apparently it is not "
2578 "part of this filesystem, or the old"
2579 " log is wrong.\nUse 'writeconf' on "
2580 "the MDT to force log regeneration."
2581 "\n", mti->mti_svname);
2582 /* Not in client log? Upgrade anyhow...*/
2583 /* Argument against upgrading: reformat MDT,
2584 upgrade OST, then OST will start but will be SKIPped
2585 in client logs. Maybe error now is better. */
2586 /* RETURN(-EINVAL); */
2588 /* end COMPAT_146 */
2590 if (rc == EALREADY) {
2591 LCONSOLE_WARN("Found index %d for %s, updating log\n",
2592 mti->mti_stripe_index, mti->mti_svname);
2593 /* We would like to mark old log sections as invalid
2594 and add new log sections in the client and mdt logs.
2595 But if we add new sections, then live clients will
2596 get repeat setup instructions for already running
2597 osc's. So don't update the client/mdt logs. */
2598 mti->mti_flags &= ~LDD_F_UPDATE;
2602 if (mti->mti_flags &
2603 (LDD_F_VIRGIN | LDD_F_UPGRADE14 | LDD_F_WRITECONF)) {
2604 /* Generate a log from scratch */
2605 if (mti->mti_flags & LDD_F_SV_TYPE_MDT) {
2606 rc = mgs_write_log_mdt(obd, fsdb, mti);
2607 } else if (mti->mti_flags & LDD_F_SV_TYPE_OST) {
2608 rc = mgs_write_log_ost(obd, fsdb, mti);
2610 CERROR("Unknown target type %#x, can't create log for "
2611 "%s\n", mti->mti_flags, mti->mti_svname);
2614 CERROR("Can't write logs for %s (%d)\n",
2615 mti->mti_svname, rc);
2619 /* Just update the params from tunefs in mgs_write_log_params */
2620 CDEBUG(D_MGS, "Update params for %s\n", mti->mti_svname);
2621 mti->mti_flags |= LDD_F_PARAM;
2624 /* allocate temporary buffer, where class_get_next_param will
2625 make copy of a current parameter */
2626 OBD_ALLOC(buf, strlen(mti->mti_params) + 1);
2628 GOTO(out_up, rc = -ENOMEM);
2629 params = mti->mti_params;
2630 while (params != NULL) {
2631 rc = class_get_next_param(¶ms, buf);
2634 /* there is no next parameter, that is
2639 CDEBUG(D_MGS, "remaining string: '%s', param: '%s'\n",
2641 rc = mgs_write_log_param(obd, fsdb, mti, buf);
2646 OBD_FREE(buf, strlen(mti->mti_params) + 1);
2649 up(&fsdb->fsdb_sem);
2654 /* verify that we can handle the old config logs */
2655 int mgs_upgrade_sv_14(struct obd_device *obd, struct mgs_target_info *mti)
2661 /* Create ost log normally, as servers register. Servers
2662 register with their old uuids (from last_rcvd), so old
2663 (MDT and client) logs should work.
2664 - new MDT won't know about old OSTs, only the ones that have
2665 registered, so we need the old MDT log to get the LOV right
2666 in order for old clients to work.
2667 - Old clients connect to the MDT, not the MGS, for their logs, and
2668 will therefore receive the old client log from the MDT /LOGS dir.
2669 - Old clients can continue to use and connect to old or new OSTs
2670 - New clients will contact the MGS for their log
2673 LCONSOLE_INFO("upgrading server %s from pre-1.6\n", mti->mti_svname);
2674 server_mti_print("upgrade", mti);
2676 rc = mgs_find_or_make_fsdb(obd, mti->mti_fsname, &fsdb);
2680 if (fsdb->fsdb_flags & FSDB_LOG_EMPTY) {
2681 LCONSOLE_ERROR_MSG(0x14a, "The old client log %s-client is "
2682 "missing. Was tunefs.lustre successful?\n",
2687 if (fsdb->fsdb_gen == 0) {
2688 /* There were no markers in the client log, meaning we have
2689 not updated the logs for this fs */
2690 CDEBUG(D_MGS, "found old, unupdated client log\n");
2693 if (mti->mti_flags & LDD_F_SV_TYPE_MDT) {
2694 if (mgs_log_is_empty(obd, mti->mti_svname)) {
2695 LCONSOLE_ERROR_MSG(0x14b, "The old MDT log %s is "
2696 "missing. Was tunefs.lustre "
2701 /* We're starting with an old uuid. Assume old name for lov
2702 as well since the lov entry already exists in the log. */
2703 CDEBUG(D_MGS, "old mds uuid %s\n", mti->mti_uuid);
2704 if (strncmp(mti->mti_uuid, fsdb->fsdb_mdtlov + 4,
2705 strlen(fsdb->fsdb_mdtlov) - 4) != 0) {
2706 CERROR("old mds uuid %s doesn't match log %s (%s)\n",
2707 mti->mti_uuid, fsdb->fsdb_mdtlov,
2708 fsdb->fsdb_mdtlov + 4);
2713 if (!(fsdb->fsdb_flags & FSDB_OLDLOG14)) {
2714 LCONSOLE_ERROR_MSG(0x14c, "%s-client is supposedly an old "
2715 "log, but no old LOV or MDT was found. "
2716 "Consider updating the configuration with"
2717 " --writeconf.\n", mti->mti_fsname);
2722 /* end COMPAT_146 */
2724 int mgs_erase_log(struct obd_device *obd, char *name)
2726 struct lvfs_run_ctxt saved;
2727 struct llog_ctxt *ctxt;
2728 struct llog_handle *llh;
2731 ctxt = llog_get_context(obd, LLOG_CONFIG_ORIG_CTXT);
2732 LASSERT(ctxt != NULL);
2734 push_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
2735 rc = llog_create(ctxt, &llh, NULL, name);
2737 llog_init_handle(llh, LLOG_F_IS_PLAIN, NULL);
2738 rc = llog_destroy(llh);
2739 llog_free_handle(llh);
2741 pop_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
2742 llog_ctxt_put(ctxt);
2745 CERROR("failed to clear log %s: %d\n", name, rc);
2750 /* erase all logs for the given fs */
2751 int mgs_erase_logs(struct obd_device *obd, char *fsname)
2753 struct mgs_obd *mgs = &obd->u.mgs;
2754 static struct fs_db *fsdb;
2755 struct list_head dentry_list;
2756 struct l_linux_dirent *dirent, *n;
2757 int rc, len = strlen(fsname);
2760 /* Find all the logs in the CONFIGS directory */
2761 rc = class_dentry_readdir(obd, mgs->mgs_configs_dir,
2762 mgs->mgs_vfsmnt, &dentry_list);
2764 CERROR("Can't read %s dir\n", MOUNT_CONFIGS_DIR);
2768 down(&mgs->mgs_sem);
2770 /* Delete the fs db */
2771 fsdb = mgs_find_fsdb(obd, fsname);
2773 mgs_free_fsdb(obd, fsdb);
2775 list_for_each_entry_safe(dirent, n, &dentry_list, lld_list) {
2776 list_del(&dirent->lld_list);
2777 if (strncmp(fsname, dirent->lld_name, len) == 0) {
2778 CDEBUG(D_MGS, "Removing log %s\n", dirent->lld_name);
2779 mgs_erase_log(obd, dirent->lld_name);
2781 OBD_FREE(dirent, sizeof(*dirent));
2789 /* from llog_swab */
2790 static void print_lustre_cfg(struct lustre_cfg *lcfg)
2795 CDEBUG(D_MGS, "lustre_cfg: %p\n", lcfg);
2796 CDEBUG(D_MGS, "\tlcfg->lcfg_version: %#x\n", lcfg->lcfg_version);
2798 CDEBUG(D_MGS, "\tlcfg->lcfg_command: %#x\n", lcfg->lcfg_command);
2799 CDEBUG(D_MGS, "\tlcfg->lcfg_num: %#x\n", lcfg->lcfg_num);
2800 CDEBUG(D_MGS, "\tlcfg->lcfg_flags: %#x\n", lcfg->lcfg_flags);
2801 CDEBUG(D_MGS, "\tlcfg->lcfg_nid: %s\n", libcfs_nid2str(lcfg->lcfg_nid));
2803 CDEBUG(D_MGS, "\tlcfg->lcfg_bufcount: %d\n", lcfg->lcfg_bufcount);
2804 if (lcfg->lcfg_bufcount < LUSTRE_CFG_MAX_BUFCOUNT)
2805 for (i = 0; i < lcfg->lcfg_bufcount; i++) {
2806 CDEBUG(D_MGS, "\tlcfg->lcfg_buflens[%d]: %d %s\n",
2807 i, lcfg->lcfg_buflens[i],
2808 lustre_cfg_string(lcfg, i));
2813 /* Set a permanent (config log) param for a target or fs */
2814 int mgs_setparam(struct obd_device *obd, struct lustre_cfg *lcfg, char *fsname)
2817 struct mgs_target_info *mti;
2818 char *devname, *param;
2824 print_lustre_cfg(lcfg);
2826 /* lustre, lustre-mdtlov, lustre-client, lustre-MDT0000 */
2827 devname = lustre_cfg_string(lcfg, 0);
2828 param = lustre_cfg_string(lcfg, 1);
2830 /* Assume device name embedded in param:
2831 lustre-OST0000.osc.max_dirty_mb=32 */
2832 ptr = strchr(param, '.');
2840 LCONSOLE_ERROR_MSG(0x14d, "No target specified: %s\n", param);
2844 /* Extract fsname */
2845 ptr = strrchr(devname, '-');
2846 memset(fsname, 0, MTI_NAME_MAXLEN);
2847 if (ptr && (server_name2index(ptr, &index, NULL) >= 0)) {
2848 /* param related to llite isn't allowed to set by OST or MDT */
2849 if (strncmp(param, PARAM_LLITE, sizeof(PARAM_LLITE)) == 0)
2852 strncpy(fsname, devname, ptr - devname);
2854 /* assume devname is the fsname */
2855 strncpy(fsname, devname, MTI_NAME_MAXLEN);
2857 fsname[MTI_NAME_MAXLEN - 1] = 0;
2858 CDEBUG(D_MGS, "setparam on fs %s device %s\n", fsname, devname);
2860 rc = mgs_find_or_make_fsdb(obd, fsname, &fsdb);
2863 if (!fsdb->fsdb_fl_mgsself && fsdb->fsdb_flags & FSDB_LOG_EMPTY) {
2864 CERROR("No filesystem targets for %s. cfg_device from lctl "
2865 "is '%s'\n", fsname, devname);
2866 mgs_free_fsdb(obd, fsdb);
2870 /* Create a fake mti to hold everything */
2873 GOTO(out, rc = -ENOMEM);
2874 strncpy(mti->mti_fsname, fsname, MTI_NAME_MAXLEN);
2875 strncpy(mti->mti_svname, devname, MTI_NAME_MAXLEN);
2876 strncpy(mti->mti_params, param, sizeof(mti->mti_params));
2877 rc = server_name2index(mti->mti_svname, &mti->mti_stripe_index, &tmp);
2879 /* Not a valid server; may be only fsname */
2882 /* Strip -osc or -mdc suffix from svname */
2883 if (server_make_name(rc, mti->mti_stripe_index, mti->mti_fsname,
2885 GOTO(out, rc = -EINVAL);
2887 mti->mti_flags = rc | LDD_F_PARAM;
2889 down(&fsdb->fsdb_sem);
2890 /* this is lctl conf_param's single param path, there is not
2891 need to loop through parameters */
2892 rc = mgs_write_log_param(obd, fsdb, mti, mti->mti_params);
2893 up(&fsdb->fsdb_sem);
2900 static int mgs_write_log_pool(struct obd_device *obd, char *logname,
2901 struct fs_db *fsdb, char *lovname,
2902 enum lcfg_command_type cmd,
2903 char *poolname, char *fsname,
2904 char *ostname, char *comment)
2906 struct llog_handle *llh = NULL;
2909 rc = record_start_log(obd, &llh, logname);
2912 rc = record_marker(obd, llh, fsdb, CM_START, lovname, comment);
2913 record_base(obd, llh, lovname, 0, cmd, poolname, fsname, ostname, 0);
2914 rc = record_marker(obd, llh, fsdb, CM_END, lovname, comment);
2915 rc = record_end_log(obd, &llh);
2920 int mgs_pool_cmd(struct obd_device *obd, enum lcfg_command_type cmd,
2921 char *fsname, char *poolname, char *ostname)
2927 char *label = NULL, *canceled_label = NULL;
2929 struct mgs_target_info *mti = NULL;
2933 rc = mgs_find_or_make_fsdb(obd, fsname, &fsdb);
2935 CERROR("Can't get db for %s\n", fsname);
2938 if (fsdb->fsdb_flags & FSDB_LOG_EMPTY) {
2939 CERROR("%s is not defined\n", fsname);
2940 mgs_free_fsdb(obd, fsdb);
2944 label_sz = 10 + strlen(fsname) + strlen(poolname);
2946 /* check if ostname match fsname */
2947 if (ostname != NULL) {
2950 ptr = strrchr(ostname, '-');
2951 if ((ptr == NULL) ||
2952 (strncmp(fsname, ostname, ptr-ostname) != 0))
2954 label_sz += strlen(ostname);
2957 OBD_ALLOC(label, label_sz);
2959 GOTO(out, rc = -ENOMEM);
2962 case LCFG_POOL_NEW: {
2964 "new %s.%s", fsname, poolname);
2967 case LCFG_POOL_ADD: {
2969 "add %s.%s.%s", fsname, poolname, ostname);
2972 case LCFG_POOL_REM: {
2973 OBD_ALLOC(canceled_label, label_sz);
2974 if (canceled_label == NULL)
2975 GOTO(out, rc = -ENOMEM);
2977 "rem %s.%s.%s", fsname, poolname, ostname);
2978 sprintf(canceled_label,
2979 "add %s.%s.%s", fsname, poolname, ostname);
2982 case LCFG_POOL_DEL: {
2983 OBD_ALLOC(canceled_label, label_sz);
2984 if (canceled_label == NULL)
2985 GOTO(out, rc = -ENOMEM);
2987 "del %s.%s", fsname, poolname);
2988 sprintf(canceled_label,
2989 "new %s.%s", fsname, poolname);
2997 down(&fsdb->fsdb_sem);
2999 if (canceled_label != NULL) {
3002 GOTO(out, rc = -ENOMEM);
3005 /* loop on all potential MDT */
3006 for (i = 0; i < INDEX_MAP_SIZE * 8; i++) {
3007 if (test_bit(i, fsdb->fsdb_mdt_index_map)) {
3008 sprintf(mdt_index, "-MDT%04x", i);
3009 name_create(&logname, fsname, mdt_index);
3010 name_create(&lovname, logname, "-mdtlov");
3012 if (canceled_label != NULL) {
3013 strcpy(mti->mti_svname, "lov pool");
3014 mgs_modify(obd, fsdb, mti, logname, lovname,
3015 canceled_label, CM_SKIP);
3018 mgs_write_log_pool(obd, logname, fsdb, lovname,
3019 cmd, fsname, poolname, ostname,
3021 name_destroy(&logname);
3022 name_destroy(&lovname);
3026 name_create(&logname, fsname, "-client");
3027 if (canceled_label != NULL)
3028 mgs_modify(obd, fsdb, mti, logname, fsdb->fsdb_clilov,
3029 canceled_label, CM_SKIP);
3031 mgs_write_log_pool(obd, logname, fsdb, fsdb->fsdb_clilov,
3032 cmd, fsname, poolname, ostname, label);
3033 name_destroy(&logname);
3035 up(&fsdb->fsdb_sem);
3040 OBD_FREE(label, label_sz);
3042 if (canceled_label != NULL)
3043 OBD_FREE(canceled_label, label_sz);
3052 /******************** unused *********************/
3053 static int mgs_backup_llog(struct obd_device *obd, char* fsname)
3055 struct file *filp, *bak_filp;
3056 struct lvfs_run_ctxt saved;
3057 char *logname, *buf;
3058 loff_t soff = 0 , doff = 0;
3059 int count = 4096, len;
3062 OBD_ALLOC(logname, PATH_MAX);
3063 if (logname == NULL)
3066 OBD_ALLOC(buf, count);
3068 GOTO(out , rc = -ENOMEM);
3070 len = snprintf(logname, PATH_MAX, "%s/%s.bak",
3071 MOUNT_CONFIGS_DIR, fsname);
3073 if (len >= PATH_MAX - 1) {
3074 GOTO(out, -ENAMETOOLONG);
3077 push_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
3079 bak_filp = l_filp_open(logname, O_RDWR|O_CREAT|O_TRUNC, 0660);
3080 if (IS_ERR(bak_filp)) {
3081 rc = PTR_ERR(bak_filp);
3082 CERROR("backup logfile open %s: %d\n", logname, rc);
3085 sprintf(logname, "%s/%s", MOUNT_CONFIGS_DIR, fsname);
3086 filp = l_filp_open(logname, O_RDONLY, 0);
3089 CERROR("logfile open %s: %d\n", logname, rc);
3093 while ((rc = lustre_fread(filp, buf, count, &soff)) > 0) {
3094 rc = lustre_fwrite(bak_filp, buf, count, &doff);
3098 filp_close(filp, 0);
3100 filp_close(bak_filp, 0);
3102 pop_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
3105 OBD_FREE(buf, count);
3106 OBD_FREE(logname, PATH_MAX);