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 int mgs_set_index(struct obd_device *obd, struct mgs_target_info *mti)
517 rc = mgs_find_or_make_fsdb(obd, mti->mti_fsname, &fsdb);
519 CERROR("Can't get db for %s\n", mti->mti_fsname);
523 if (mti->mti_flags & LDD_F_SV_TYPE_OST)
524 imap = fsdb->fsdb_ost_index_map;
525 else if (mti->mti_flags & LDD_F_SV_TYPE_MDT)
526 imap = fsdb->fsdb_mdt_index_map;
530 if (mti->mti_flags & LDD_F_NEED_INDEX) {
531 rc = next_index(imap, INDEX_MAP_SIZE);
534 mti->mti_stripe_index = rc;
537 if (mti->mti_stripe_index >= INDEX_MAP_SIZE * 8) {
538 LCONSOLE_ERROR_MSG(0x13f, "Server %s requested index %d, "
539 "but the max index is %d.\n",
540 mti->mti_svname, mti->mti_stripe_index,
545 if (test_bit(mti->mti_stripe_index, imap)) {
546 if ((mti->mti_flags & LDD_F_VIRGIN) &&
547 !(mti->mti_flags & LDD_F_WRITECONF)) {
548 LCONSOLE_ERROR_MSG(0x140, "Server %s requested index "
549 "%d, but that index is already in "
550 "use. Use --writeconf to force\n",
552 mti->mti_stripe_index);
555 CDEBUG(D_MGS, "Server %s updating index %d\n",
556 mti->mti_svname, mti->mti_stripe_index);
561 set_bit(mti->mti_stripe_index, imap);
562 fsdb->fsdb_flags &= ~FSDB_LOG_EMPTY;
563 server_make_name(mti->mti_flags, mti->mti_stripe_index,
564 mti->mti_fsname, mti->mti_svname);
566 CDEBUG(D_MGS, "Set index for %s to %d\n", mti->mti_svname,
567 mti->mti_stripe_index);
572 struct mgs_modify_lookup {
573 struct cfg_marker mml_marker;
577 static int mgs_modify_handler(struct llog_handle *llh, struct llog_rec_hdr *rec,
580 struct mgs_modify_lookup *mml = (struct mgs_modify_lookup *)data;
581 struct cfg_marker *marker;
582 struct lustre_cfg *lcfg = (struct lustre_cfg *)(rec + 1);
583 int cfg_len = rec->lrh_len - sizeof(struct llog_rec_hdr) -
584 sizeof(struct llog_rec_tail);
588 if (rec->lrh_type != OBD_CFG_REC) {
589 CERROR("unhandled lrh_type: %#x\n", rec->lrh_type);
593 rc = lustre_cfg_sanity_check(lcfg, cfg_len);
595 CERROR("Insane cfg\n");
599 /* We only care about markers */
600 if (lcfg->lcfg_command != LCFG_MARKER)
603 marker = lustre_cfg_buf(lcfg, 1);
604 if ((strcmp(mml->mml_marker.cm_comment, marker->cm_comment) == 0) &&
605 (strcmp(mml->mml_marker.cm_tgtname, marker->cm_tgtname) == 0) &&
606 !(marker->cm_flags & CM_SKIP)) {
607 /* Found a non-skipped marker match */
608 CDEBUG(D_MGS, "Changing rec %u marker %d %x->%x: %s %s\n",
609 rec->lrh_index, marker->cm_step,
610 marker->cm_flags, mml->mml_marker.cm_flags,
611 marker->cm_tgtname, marker->cm_comment);
612 /* Overwrite the old marker llog entry */
613 marker->cm_flags &= ~CM_EXCLUDE; /* in case we're unexcluding */
614 marker->cm_flags |= mml->mml_marker.cm_flags;
615 marker->cm_canceltime = mml->mml_marker.cm_canceltime;
616 /* Header and tail are added back to lrh_len in
617 llog_lvfs_write_rec */
618 rec->lrh_len = cfg_len;
619 rc = llog_write_rec(llh, rec, NULL, 0, (void *)lcfg,
628 /* Modify an existing config log record (for CM_SKIP or CM_EXCLUDE) */
629 static int mgs_modify(struct obd_device *obd, struct fs_db *fsdb,
630 struct mgs_target_info *mti, char *logname,
631 char *devname, char *comment, int flags)
633 struct llog_handle *loghandle;
634 struct lvfs_run_ctxt saved;
635 struct llog_ctxt *ctxt;
636 struct mgs_modify_lookup *mml;
640 CDEBUG(D_MGS, "modify %s/%s/%s\n", logname, devname, comment);
642 push_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
644 ctxt = llog_get_context(obd, LLOG_CONFIG_ORIG_CTXT);
645 LASSERT(ctxt != NULL);
646 rc = llog_create(ctxt, &loghandle, NULL, logname);
650 rc = llog_init_handle(loghandle, LLOG_F_IS_PLAIN, NULL);
654 if (llog_get_size(loghandle) <= 1)
655 GOTO(out_close, rc = 0);
659 GOTO(out_close, rc = -ENOMEM);
660 strcpy(mml->mml_marker.cm_comment, comment);
661 strcpy(mml->mml_marker.cm_tgtname, devname);
662 /* Modify mostly means cancel */
663 mml->mml_marker.cm_flags = flags;
664 mml->mml_marker.cm_canceltime = flags ? cfs_time_current_sec() : 0;
665 mml->mml_modified = 0;
666 rc = llog_process(loghandle, mgs_modify_handler, (void *)mml, NULL);
667 if (!rc && !mml->mml_modified)
672 rc2 = llog_close(loghandle);
676 pop_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
677 if (rc && rc != -ENODEV)
678 CERROR("modify %s/%s failed %d\n",
679 mti->mti_svname, comment, rc);
684 /******************** config log recording functions *********************/
686 static int record_lcfg(struct obd_device *obd, struct llog_handle *llh,
687 struct lustre_cfg *lcfg)
689 struct lvfs_run_ctxt saved;
690 struct llog_rec_hdr rec;
696 LASSERT(llh->lgh_ctxt);
698 buflen = lustre_cfg_len(lcfg->lcfg_bufcount,
700 rec.lrh_len = llog_data_len(buflen);
701 rec.lrh_type = OBD_CFG_REC;
703 push_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
704 /* idx = -1 means append */
705 rc = llog_write_rec(llh, &rec, NULL, 0, (void *)lcfg, -1);
706 pop_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
708 CERROR("failed %d\n", rc);
712 static int record_base(struct obd_device *obd, struct llog_handle *llh,
713 char *cfgname, lnet_nid_t nid, int cmd,
714 char *s1, char *s2, char *s3, char *s4)
716 struct lustre_cfg_bufs bufs;
717 struct lustre_cfg *lcfg;
720 CDEBUG(D_MGS, "lcfg %s %#x %s %s %s %s\n", cfgname,
721 cmd, s1, s2, s3, s4);
723 lustre_cfg_bufs_reset(&bufs, cfgname);
725 lustre_cfg_bufs_set_string(&bufs, 1, s1);
727 lustre_cfg_bufs_set_string(&bufs, 2, s2);
729 lustre_cfg_bufs_set_string(&bufs, 3, s3);
731 lustre_cfg_bufs_set_string(&bufs, 4, s4);
733 lcfg = lustre_cfg_new(cmd, &bufs);
736 lcfg->lcfg_nid = nid;
738 rc = record_lcfg(obd, llh, lcfg);
740 lustre_cfg_free(lcfg);
743 CERROR("error %d: lcfg %s %#x %s %s %s %s\n", rc, cfgname,
744 cmd, s1, s2, s3, s4);
750 static inline int record_add_uuid(struct obd_device *obd,
751 struct llog_handle *llh,
752 uint64_t nid, char *uuid)
754 return record_base(obd,llh,NULL,nid,LCFG_ADD_UUID,uuid,0,0,0);
758 static inline int record_add_conn(struct obd_device *obd,
759 struct llog_handle *llh,
763 return record_base(obd,llh,devname,0,LCFG_ADD_CONN,uuid,0,0,0);
766 static inline int record_attach(struct obd_device *obd, struct llog_handle *llh,
767 char *devname, char *type, char *uuid)
769 return record_base(obd,llh,devname,0,LCFG_ATTACH,type,uuid,0,0);
772 static inline int record_setup(struct obd_device *obd, struct llog_handle *llh,
774 char *s1, char *s2, char *s3, char *s4)
776 return record_base(obd,llh,devname,0,LCFG_SETUP,s1,s2,s3,s4);
779 static int record_lov_setup(struct obd_device *obd, struct llog_handle *llh,
780 char *devname, struct lov_desc *desc)
782 struct lustre_cfg_bufs bufs;
783 struct lustre_cfg *lcfg;
786 lustre_cfg_bufs_reset(&bufs, devname);
787 lustre_cfg_bufs_set(&bufs, 1, desc, sizeof(*desc));
788 lcfg = lustre_cfg_new(LCFG_SETUP, &bufs);
791 rc = record_lcfg(obd, llh, lcfg);
793 lustre_cfg_free(lcfg);
797 static int record_lmv_setup(struct obd_device *obd, struct llog_handle *llh,
798 char *devname, struct lmv_desc *desc)
800 struct lustre_cfg_bufs bufs;
801 struct lustre_cfg *lcfg;
804 lustre_cfg_bufs_reset(&bufs, devname);
805 lustre_cfg_bufs_set(&bufs, 1, desc, sizeof(*desc));
806 lcfg = lustre_cfg_new(LCFG_SETUP, &bufs);
808 rc = record_lcfg(obd, llh, lcfg);
810 lustre_cfg_free(lcfg);
814 static inline int record_mdc_add(struct obd_device *obd,
815 struct llog_handle *llh,
816 char *logname, char *mdcuuid,
817 char *mdtuuid, char *index,
820 return record_base(obd,llh,logname,0,LCFG_ADD_MDC,
821 mdtuuid,index,gen,mdcuuid);
824 static inline int record_lov_add(struct obd_device *obd,
825 struct llog_handle *llh,
826 char *lov_name, char *ost_uuid,
827 char *index, char *gen)
829 return record_base(obd,llh,lov_name,0,LCFG_LOV_ADD_OBD,
830 ost_uuid,index,gen,0);
833 static inline int record_mount_opt(struct obd_device *obd,
834 struct llog_handle *llh,
835 char *profile, char *lov_name,
838 return record_base(obd,llh,NULL,0,LCFG_MOUNTOPT,
839 profile,lov_name,mdc_name,0);
842 static int record_marker(struct obd_device *obd, struct llog_handle *llh,
843 struct fs_db *fsdb, __u32 flags,
844 char *tgtname, char *comment)
846 struct cfg_marker marker;
847 struct lustre_cfg_bufs bufs;
848 struct lustre_cfg *lcfg;
851 if (flags & CM_START)
853 marker.cm_step = fsdb->fsdb_gen;
854 marker.cm_flags = flags;
855 marker.cm_vers = LUSTRE_VERSION_CODE;
856 strncpy(marker.cm_tgtname, tgtname, sizeof(marker.cm_tgtname));
857 strncpy(marker.cm_comment, comment, sizeof(marker.cm_comment));
858 marker.cm_createtime = cfs_time_current_sec();
859 marker.cm_canceltime = 0;
860 lustre_cfg_bufs_reset(&bufs, NULL);
861 lustre_cfg_bufs_set(&bufs, 1, &marker, sizeof(marker));
862 lcfg = lustre_cfg_new(LCFG_MARKER, &bufs);
865 rc = record_lcfg(obd, llh, lcfg);
867 lustre_cfg_free(lcfg);
871 static int record_start_log(struct obd_device *obd,
872 struct llog_handle **llh, char *name)
874 static struct obd_uuid cfg_uuid = { .uuid = "config_uuid" };
875 struct lvfs_run_ctxt saved;
876 struct llog_ctxt *ctxt;
880 GOTO(out, rc = -EBUSY);
882 ctxt = llog_get_context(obd, LLOG_CONFIG_ORIG_CTXT);
884 GOTO(out, rc = -ENODEV);
886 push_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
887 rc = llog_create(ctxt, llh, NULL, name);
889 llog_init_handle(*llh, LLOG_F_IS_PLAIN, &cfg_uuid);
893 pop_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
898 CERROR("Can't start log %s: %d\n", name, rc);
903 static int record_end_log(struct obd_device *obd, struct llog_handle **llh)
905 struct lvfs_run_ctxt saved;
908 push_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
910 rc = llog_close(*llh);
913 pop_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
917 static int mgs_log_is_empty(struct obd_device *obd, char *name)
919 struct lvfs_run_ctxt saved;
920 struct llog_handle *llh;
921 struct llog_ctxt *ctxt;
924 ctxt = llog_get_context(obd, LLOG_CONFIG_ORIG_CTXT);
925 LASSERT(ctxt != NULL);
926 push_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
927 rc = llog_create(ctxt, &llh, NULL, name);
929 llog_init_handle(llh, LLOG_F_IS_PLAIN, NULL);
930 rc = llog_get_size(llh);
933 pop_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
935 /* header is record 1 */
939 /******************** config "macros" *********************/
941 /* write an lcfg directly into a log (with markers) */
942 static int mgs_write_log_direct(struct obd_device *obd, struct fs_db *fsdb,
943 char *logname, struct lustre_cfg *lcfg,
944 char *devname, char *comment)
946 struct llog_handle *llh = NULL;
953 rc = record_start_log(obd, &llh, logname);
957 /* FIXME These should be a single journal transaction */
958 rc = record_marker(obd, llh, fsdb, CM_START, devname, comment);
960 rc = record_lcfg(obd, llh, lcfg);
962 rc = record_marker(obd, llh, fsdb, CM_END, devname, comment);
963 rc = record_end_log(obd, &llh);
968 /* write the lcfg in all logs for the given fs */
969 int mgs_write_log_direct_all(struct obd_device *obd, struct fs_db *fsdb,
970 struct mgs_target_info *mti,
971 struct lustre_cfg *lcfg,
972 char *devname, char *comment)
974 struct mgs_obd *mgs = &obd->u.mgs;
975 struct list_head dentry_list;
976 struct l_linux_dirent *dirent, *n;
977 char *fsname = mti->mti_fsname;
979 int rc = 0, len = strlen(fsname);
982 /* We need to set params for any future logs
983 as well. FIXME Append this file to every new log.
984 Actually, we should store as params (text), not llogs. Or
986 name_create(&logname, fsname, "-params");
987 if (mgs_log_is_empty(obd, logname)) {
988 struct llog_handle *llh = NULL;
989 rc = record_start_log(obd, &llh, logname);
990 record_end_log(obd, &llh);
992 name_destroy(&logname);
996 /* Find all the logs in the CONFIGS directory */
997 rc = class_dentry_readdir(obd, mgs->mgs_configs_dir,
998 mgs->mgs_vfsmnt, &dentry_list);
1000 CERROR("Can't read %s dir\n", MOUNT_CONFIGS_DIR);
1004 /* Could use fsdb index maps instead of directory listing */
1005 list_for_each_entry_safe(dirent, n, &dentry_list, lld_list) {
1006 list_del(&dirent->lld_list);
1007 /* don't write to sptlrpc rule log */
1008 if (strncmp(fsname, dirent->lld_name, len) == 0 &&
1009 strstr(dirent->lld_name, "-sptlrpc") == NULL) {
1010 CDEBUG(D_MGS, "Changing log %s\n", dirent->lld_name);
1011 /* Erase any old settings of this same parameter */
1012 mgs_modify(obd, fsdb, mti, dirent->lld_name, devname,
1014 /* Write the new one */
1015 rc = mgs_write_log_direct(obd, fsdb, dirent->lld_name,
1016 lcfg, devname, comment);
1018 CERROR("err %d writing log %s\n", rc,
1021 OBD_FREE(dirent, sizeof(*dirent));
1029 struct mgs_target_info *comp_tmti;
1030 struct mgs_target_info *comp_mti;
1031 struct fs_db *comp_fsdb;
1032 struct obd_device *comp_obd;
1035 static int mgs_write_log_mdc_to_mdt(struct obd_device *, struct fs_db *,
1036 struct mgs_target_info *, char *);
1038 static int mgs_steal_llog_handler(struct llog_handle *llh,
1039 struct llog_rec_hdr *rec,
1042 struct obd_device * obd;
1043 struct mgs_target_info *mti, *tmti;
1045 int cfg_len = rec->lrh_len;
1046 char *cfg_buf = (char*) (rec + 1);
1047 struct lustre_cfg *lcfg;
1049 struct llog_handle *mdt_llh = NULL;
1050 static int got_an_osc_or_mdc = 0;
1051 /* 0: not found any osc/mdc;
1055 static int last_step = -1;
1059 mti = ((struct temp_comp*)data)->comp_mti;
1060 tmti = ((struct temp_comp*)data)->comp_tmti;
1061 fsdb = ((struct temp_comp*)data)->comp_fsdb;
1062 obd = ((struct temp_comp*)data)->comp_obd;
1064 if (rec->lrh_type != OBD_CFG_REC) {
1065 CERROR("unhandled lrh_type: %#x\n", rec->lrh_type);
1069 rc = lustre_cfg_sanity_check(cfg_buf, cfg_len);
1071 CERROR("Insane cfg\n");
1075 lcfg = (struct lustre_cfg *)cfg_buf;
1077 if (lcfg->lcfg_command == LCFG_MARKER) {
1078 struct cfg_marker *marker;
1079 marker = lustre_cfg_buf(lcfg, 1);
1080 if (!strncmp(marker->cm_comment,"add osc",7) &&
1081 (marker->cm_flags & CM_START)){
1082 got_an_osc_or_mdc = 1;
1083 rc = record_start_log(obd, &mdt_llh, mti->mti_svname);
1084 rc = record_marker(obd, mdt_llh, fsdb, CM_START,
1085 mti->mti_svname,"add osc(copied)");
1086 rc = record_end_log(obd, &mdt_llh);
1087 last_step = marker->cm_step;
1090 if (!strncmp(marker->cm_comment,"add osc",7) &&
1091 (marker->cm_flags & CM_END)){
1092 LASSERT(last_step == marker->cm_step);
1094 got_an_osc_or_mdc = 0;
1095 rc = record_start_log(obd, &mdt_llh, mti->mti_svname);
1096 rc = record_marker(obd, mdt_llh, fsdb, CM_END,
1097 mti->mti_svname,"add osc(copied)");
1098 rc = record_end_log(obd, &mdt_llh);
1101 if (!strncmp(marker->cm_comment,"add mdc",7) &&
1102 (marker->cm_flags & CM_START)){
1103 got_an_osc_or_mdc = 2;
1104 last_step = marker->cm_step;
1105 memcpy(tmti->mti_svname, marker->cm_tgtname,
1106 strlen(marker->cm_tgtname));
1110 if (!strncmp(marker->cm_comment,"add mdc",7) &&
1111 (marker->cm_flags & CM_END)){
1112 LASSERT(last_step == marker->cm_step);
1114 got_an_osc_or_mdc = 0;
1119 if (got_an_osc_or_mdc == 0 || last_step < 0)
1122 if (lcfg->lcfg_command == LCFG_ADD_UUID) {
1124 nodenid = lcfg->lcfg_nid;
1126 tmti->mti_nids[tmti->mti_nid_count] = nodenid;
1127 tmti->mti_nid_count++;
1132 if (lcfg->lcfg_command == LCFG_SETUP) {
1135 target = lustre_cfg_string(lcfg, 1);
1136 memcpy(tmti->mti_uuid, target, strlen(target));
1140 /* ignore client side sptlrpc_conf_log */
1141 if (lcfg->lcfg_command == LCFG_SPTLRPC_CONF)
1144 if (lcfg->lcfg_command == LCFG_ADD_MDC) {
1147 if (sscanf(lustre_cfg_buf(lcfg, 2), "%d", &index) != 1)
1150 memcpy(tmti->mti_fsname, mti->mti_fsname,
1151 strlen(mti->mti_fsname));
1152 tmti->mti_stripe_index = index;
1154 mgs_write_log_mdc_to_mdt(obd, fsdb, tmti, mti->mti_svname);
1155 memset(tmti, 0, sizeof(*tmti));
1161 /* fsdb->fsdb_sem is already held in mgs_write_log_target*/
1162 /* stealed from mgs_get_fsdb_from_llog*/
1163 static int mgs_steal_llog_for_mdt_from_client(struct obd_device *obd,
1165 struct temp_comp* comp)
1167 struct llog_handle *loghandle;
1168 struct lvfs_run_ctxt saved;
1169 struct mgs_target_info *tmti;
1170 struct llog_ctxt *ctxt;
1174 ctxt = llog_get_context(obd, LLOG_CONFIG_ORIG_CTXT);
1175 LASSERT(ctxt != NULL);
1177 OBD_ALLOC_PTR(tmti);
1181 comp->comp_tmti = tmti;
1182 comp->comp_obd = obd;
1184 push_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
1186 rc = llog_create(ctxt, &loghandle, NULL, client_name);
1190 rc = llog_init_handle(loghandle, LLOG_F_IS_PLAIN, NULL);
1192 GOTO(out_close, rc);
1194 rc = llog_process(loghandle, mgs_steal_llog_handler, (void *)comp, NULL);
1195 CDEBUG(D_MGS, "steal llog re = %d\n", rc);
1197 rc2 = llog_close(loghandle);
1201 pop_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
1203 llog_ctxt_put(ctxt);
1207 /* lmv is the second thing for client logs */
1208 /* copied from mgs_write_log_lov. Please refer to that. */
1209 static int mgs_write_log_lmv(struct obd_device *obd, struct fs_db *fsdb,
1210 struct mgs_target_info *mti,
1211 char *logname, char *lmvname)
1213 struct llog_handle *llh = NULL;
1214 struct lmv_desc *lmvdesc;
1219 CDEBUG(D_MGS, "Writing lmv(%s) log for %s\n", lmvname,logname);
1221 OBD_ALLOC_PTR(lmvdesc);
1222 if (lmvdesc == NULL)
1224 lmvdesc->ld_active_tgt_count = 0;
1225 lmvdesc->ld_tgt_count = 0;
1226 sprintf((char*)lmvdesc->ld_uuid.uuid, "%s_UUID", lmvname);
1227 uuid = (char *)lmvdesc->ld_uuid.uuid;
1229 rc = record_start_log(obd, &llh, logname);
1230 rc = record_marker(obd, llh, fsdb, CM_START, lmvname, "lmv setup");
1231 rc = record_attach(obd, llh, lmvname, "lmv", uuid);
1232 rc = record_lmv_setup(obd, llh, lmvname, lmvdesc);
1233 rc = record_marker(obd, llh, fsdb, CM_END, lmvname, "lmv setup");
1234 rc = record_end_log(obd, &llh);
1236 OBD_FREE_PTR(lmvdesc);
1240 /* lov is the first thing in the mdt and client logs */
1241 static int mgs_write_log_lov(struct obd_device *obd, struct fs_db *fsdb,
1242 struct mgs_target_info *mti,
1243 char *logname, char *lovname)
1245 struct llog_handle *llh = NULL;
1246 struct lov_desc *lovdesc;
1251 CDEBUG(D_MGS, "Writing lov(%s) log for %s\n", lovname, logname);
1254 #01 L attach 0:lov_mdsA 1:lov 2:71ccb_lov_mdsA_19f961a9e1
1255 #02 L lov_setup 0:lov_mdsA 1:(struct lov_desc)
1256 uuid=lov1_UUID, stripe count=1, size=1048576, offset=0, pattern=0
1259 /* FIXME just make lov_setup accept empty desc (put uuid in buf 2) */
1260 OBD_ALLOC_PTR(lovdesc);
1261 if (lovdesc == NULL)
1263 lovdesc->ld_magic = LOV_DESC_MAGIC;
1264 lovdesc->ld_tgt_count = 0;
1265 /* Defaults. Can be changed later by lcfg config_param */
1266 lovdesc->ld_default_stripe_count = 1;
1267 lovdesc->ld_pattern = LOV_PATTERN_RAID0;
1268 lovdesc->ld_default_stripe_size = 1024 * 1024;
1269 lovdesc->ld_default_stripe_offset = 0;
1270 lovdesc->ld_qos_maxage = QOS_DEFAULT_MAXAGE;
1271 sprintf((char*)lovdesc->ld_uuid.uuid, "%s_UUID", lovname);
1272 /* can these be the same? */
1273 uuid = (char *)lovdesc->ld_uuid.uuid;
1275 /* This should always be the first entry in a log.
1276 rc = mgs_clear_log(obd, logname); */
1277 rc = record_start_log(obd, &llh, logname);
1280 /* FIXME these should be a single journal transaction */
1281 rc = record_marker(obd, llh, fsdb, CM_START, lovname, "lov setup");
1282 rc = record_attach(obd, llh, lovname, "lov", uuid);
1283 rc = record_lov_setup(obd, llh, lovname, lovdesc);
1284 rc = record_marker(obd, llh, fsdb, CM_END, lovname, "lov setup");
1285 rc = record_end_log(obd, &llh);
1289 OBD_FREE_PTR(lovdesc);
1293 /* add failnids to open log */
1294 static int mgs_write_log_failnids(struct obd_device *obd,
1295 struct mgs_target_info *mti,
1296 struct llog_handle *llh,
1299 char *failnodeuuid = NULL;
1300 char *ptr = mti->mti_params;
1305 #03 L add_uuid nid=uml1@tcp(0x20000c0a80201) nal=90 0: 1:uml1_UUID
1306 #04 L add_uuid nid=1@elan(0x1000000000001) nal=90 0: 1:uml1_UUID
1307 #05 L setup 0:OSC_uml1_ost1_mdsA 1:ost1_UUID 2:uml1_UUID
1308 #06 L add_uuid nid=uml2@tcp(0x20000c0a80202) nal=90 0: 1:uml2_UUID
1309 #0x L add_uuid nid=2@elan(0x1000000000002) nal=90 0: 1:uml2_UUID
1310 #07 L add_conn 0:OSC_uml1_ost1_mdsA 1:uml2_UUID
1313 /* Pull failnid info out of params string */
1314 while (class_find_param(ptr, PARAM_FAILNODE, &ptr) == 0) {
1315 while (class_parse_nid(ptr, &nid, &ptr) == 0) {
1316 if (failnodeuuid == NULL) {
1317 /* We don't know the failover node name,
1318 so just use the first nid as the uuid */
1319 rc = name_create(&failnodeuuid,
1320 libcfs_nid2str(nid), "");
1324 CDEBUG(D_MGS, "add nid %s for failover uuid %s, "
1325 "client %s\n", libcfs_nid2str(nid),
1326 failnodeuuid, cliname);
1327 rc = record_add_uuid(obd, llh, nid, failnodeuuid);
1330 rc = record_add_conn(obd, llh, cliname, failnodeuuid);
1331 name_destroy(&failnodeuuid);
1332 failnodeuuid = NULL;
1339 static int mgs_write_log_mdc_to_lmv(struct obd_device *obd, struct fs_db *fsdb,
1340 struct mgs_target_info *mti,
1341 char *logname, char *lmvname)
1343 struct llog_handle *llh = NULL;
1344 char *mdcname, *nodeuuid, *mdcuuid, *lmvuuid;
1349 if (mgs_log_is_empty(obd, logname)) {
1350 CERROR("log is empty! Logical error\n");
1354 CDEBUG(D_MGS, "adding mdc for %s to log %s:lmv(%s)\n",
1355 mti->mti_svname, logname, lmvname);
1357 name_create(&nodeuuid, libcfs_nid2str(mti->mti_nids[0]), "");
1358 name_create(&mdcname, mti->mti_svname, "-mdc");
1359 name_create(&mdcuuid, mdcname, "_UUID");
1360 name_create(&lmvuuid, lmvname, "_UUID");
1362 rc = record_start_log(obd, &llh, logname);
1363 rc = record_marker(obd, llh, fsdb, CM_START, mti->mti_svname,
1366 for (i = 0; i < mti->mti_nid_count; i++) {
1367 CDEBUG(D_MGS, "add nid %s for mdt\n",
1368 libcfs_nid2str(mti->mti_nids[i]));
1370 rc = record_add_uuid(obd, llh, mti->mti_nids[i], nodeuuid);
1373 rc = record_attach(obd, llh, mdcname, LUSTRE_MDC_NAME, lmvuuid);
1374 rc = record_setup(obd, llh, mdcname, mti->mti_uuid, nodeuuid, 0, 0);
1375 rc = mgs_write_log_failnids(obd, mti, llh, mdcname);
1376 snprintf(index, sizeof(index), "%d", mti->mti_stripe_index);
1377 rc = record_mdc_add(obd, llh, lmvname, mdcuuid, mti->mti_uuid,
1379 rc = record_marker(obd, llh, fsdb, CM_END, mti->mti_svname,
1381 rc = record_end_log(obd, &llh);
1383 name_destroy(&lmvuuid);
1384 name_destroy(&mdcuuid);
1385 name_destroy(&mdcname);
1386 name_destroy(&nodeuuid);
1390 /* add new mdc to already existent MDS */
1391 static int mgs_write_log_mdc_to_mdt(struct obd_device *obd, struct fs_db *fsdb,
1392 struct mgs_target_info *mti, char *logname)
1394 struct llog_handle *llh = NULL;
1395 char *nodeuuid, *mdcname, *mdcuuid, *mdtuuid;
1396 int idx = mti->mti_stripe_index;
1401 if (mgs_log_is_empty(obd, mti->mti_svname)) {
1402 CERROR("log is empty! Logical error\n");
1406 CDEBUG(D_MGS, "adding mdc index %d to %s\n", idx, logname);
1408 name_create(&nodeuuid, libcfs_nid2str(mti->mti_nids[0]), "");
1409 snprintf(index, sizeof(index), "-mdc%04x", idx);
1410 name_create(&mdcname, logname, index);
1411 name_create(&mdcuuid, mdcname, "_UUID");
1412 name_create(&mdtuuid, logname, "_UUID");
1414 rc = record_start_log(obd, &llh, logname);
1415 rc = record_marker(obd, llh, fsdb, CM_START, mti->mti_svname, "add mdc");
1416 for (i = 0; i < mti->mti_nid_count; i++) {
1417 CDEBUG(D_MGS, "add nid %s for mdt\n",
1418 libcfs_nid2str(mti->mti_nids[i]));
1419 rc = record_add_uuid(obd, llh, mti->mti_nids[i], nodeuuid);
1421 rc = record_attach(obd, llh, mdcname, LUSTRE_MDC_NAME, mdcuuid);
1422 rc = record_setup(obd, llh, mdcname, mti->mti_uuid, nodeuuid, 0, 0);
1423 rc = mgs_write_log_failnids(obd, mti, llh, mdcname);
1424 snprintf(index, sizeof(index), "%d", idx);
1426 rc = record_mdc_add(obd, llh, logname, mdcuuid, mti->mti_uuid,
1428 rc = record_marker(obd, llh, fsdb, CM_END, mti->mti_svname, "add mdc");
1429 rc = record_end_log(obd, &llh);
1431 name_destroy(&mdcuuid);
1432 name_destroy(&mdcname);
1433 name_destroy(&nodeuuid);
1434 name_destroy(&mdtuuid);
1438 static int mgs_write_log_mdt0(struct obd_device *obd, struct fs_db *fsdb,
1439 struct mgs_target_info *mti)
1441 char *log = mti->mti_svname;
1442 struct llog_handle *llh = NULL;
1443 char *uuid, *lovname;
1445 char *ptr = mti->mti_params;
1446 int rc = 0, failout = 0;
1449 OBD_ALLOC(uuid, sizeof(struct obd_uuid));
1453 if (class_find_param(ptr, PARAM_FAILMODE, &ptr) == 0)
1454 failout = (strncmp(ptr, "failout", 7) == 0);
1456 name_create(&lovname, log, "-mdtlov");
1457 if (mgs_log_is_empty(obd, log))
1458 rc = mgs_write_log_lov(obd, fsdb, mti, log, lovname);
1460 sprintf(uuid, "%s_UUID", log);
1461 sprintf(mdt_index,"%d",mti->mti_stripe_index);
1463 /* add MDT itself */
1464 rc = record_start_log(obd, &llh, log);
1468 /* FIXME this whole fn should be a single journal transaction */
1469 rc = record_marker(obd, llh, fsdb, CM_START, log, "add mdt");
1470 rc = record_attach(obd, llh, log, LUSTRE_MDT_NAME, uuid);
1471 rc = record_mount_opt(obd, llh, log, lovname, NULL);
1472 rc = record_setup(obd, llh, log, uuid, mdt_index, lovname,
1473 failout ? "n" : "f");
1474 rc = record_marker(obd, llh, fsdb, CM_END, log, "add mdt");
1475 rc = record_end_log(obd, &llh);
1477 name_destroy(&lovname);
1478 OBD_FREE(uuid, sizeof(struct obd_uuid));
1482 /* envelope method for all layers log */
1483 static int mgs_write_log_mdt(struct obd_device *obd, struct fs_db *fsdb,
1484 struct mgs_target_info *mti)
1486 struct llog_handle *llh = NULL;
1488 struct temp_comp comp = { 0 };
1493 CDEBUG(D_MGS, "writing new mdt %s\n", mti->mti_svname);
1497 if (mti->mti_flags & LDD_F_UPGRADE14) {
1498 /* We're starting with an old uuid. Assume old name for lov
1499 as well since the lov entry already exists in the log. */
1500 CDEBUG(D_MGS, "old mds uuid %s\n", mti->mti_uuid);
1501 if (strncmp(mti->mti_uuid, fsdb->fsdb_mdtlov + 4,
1502 strlen(fsdb->fsdb_mdtlov) - 4) != 0) {
1503 CERROR("old mds uuid %s doesn't match log %s (%s)\n",
1504 mti->mti_uuid, fsdb->fsdb_mdtlov,
1505 fsdb->fsdb_mdtlov + 4);
1509 /* end COMPAT_146 */
1511 if (mti->mti_uuid[0] == '\0') {
1512 /* Make up our own uuid */
1513 snprintf(mti->mti_uuid, sizeof(mti->mti_uuid),
1514 "%s_UUID", mti->mti_svname);
1518 rc = mgs_write_log_mdt0(obd, fsdb, mti);
1520 /* Append the mdt info to the client log */
1521 name_create(&cliname, mti->mti_fsname, "-client");
1523 if (mgs_log_is_empty(obd, cliname)) {
1524 /* Start client log */
1525 rc = mgs_write_log_lov(obd, fsdb, mti, cliname,
1527 rc = mgs_write_log_lmv(obd, fsdb, mti, cliname,
1532 #09 L add_uuid nid=uml1@tcp(0x20000c0a80201) 0: 1:uml1_UUID
1533 #10 L attach 0:MDC_uml1_mdsA_MNT_client 1:mdc 2:1d834_MNT_client_03f
1534 #11 L setup 0:MDC_uml1_mdsA_MNT_client 1:mdsA_UUID 2:uml1_UUID
1535 #12 L add_uuid nid=uml2@tcp(0x20000c0a80202) 0: 1:uml2_UUID
1536 #13 L add_conn 0:MDC_uml1_mdsA_MNT_client 1:uml2_UUID
1537 #14 L mount_option 0: 1:client 2:lov1 3:MDC_uml1_mdsA_MNT_client
1542 if (mti->mti_flags & LDD_F_UPGRADE14) {
1543 rc = record_start_log(obd, &llh, cliname);
1547 rc = record_marker(obd, llh, fsdb, CM_START,
1548 mti->mti_svname,"add mdc");
1550 /* Old client log already has MDC entry, but needs mount opt
1551 for new client name (lustre-client) */
1552 /* FIXME Old MDT log already has an old mount opt
1553 which we should remove (currently handled by
1554 class_del_profiles()) */
1555 rc = record_mount_opt(obd, llh, cliname, fsdb->fsdb_clilov,
1557 /* end COMPAT_146 */
1559 rc = record_marker(obd, llh, fsdb, CM_END,
1560 mti->mti_svname, "add mdc");
1564 /* copy client info about lov/lmv */
1565 comp.comp_mti = mti;
1566 comp.comp_fsdb = fsdb;
1568 rc = mgs_steal_llog_for_mdt_from_client(obd, cliname,
1571 rc = mgs_write_log_mdc_to_lmv(obd, fsdb, mti, cliname,
1574 rc = record_start_log(obd, &llh, cliname);
1578 rc = record_marker(obd, llh, fsdb, CM_START, cliname,
1580 rc = record_mount_opt(obd, llh, cliname, fsdb->fsdb_clilov,
1582 rc = record_marker(obd, llh, fsdb, CM_END, cliname,
1586 rc = record_end_log(obd, &llh);
1588 name_destroy(&cliname);
1590 // for_all_existing_mdt except current one
1591 for (i = 0; i < INDEX_MAP_SIZE * 8; i++){
1593 if (i != mti->mti_stripe_index &&
1594 test_bit(i, fsdb->fsdb_mdt_index_map)) {
1595 sprintf(mdt_index,"-MDT%04x",i);
1597 name_create(&mdtname, mti->mti_fsname, mdt_index);
1598 rc = mgs_write_log_mdc_to_mdt(obd, fsdb, mti, mdtname);
1599 name_destroy(&mdtname);
1606 /* Add the ost info to the client/mdt lov */
1607 static int mgs_write_log_osc_to_lov(struct obd_device *obd, struct fs_db *fsdb,
1608 struct mgs_target_info *mti,
1609 char *logname, char *suffix, char *lovname,
1610 enum lustre_sec_part sec_part, int flags)
1612 struct llog_handle *llh = NULL;
1613 char *nodeuuid, *oscname, *oscuuid, *lovuuid, *svname;
1618 CDEBUG(D_INFO, "adding osc for %s to log %s\n",
1619 mti->mti_svname, logname);
1621 if (mgs_log_is_empty(obd, logname)) {
1622 /* The first item in the log must be the lov, so we have
1623 somewhere to add our osc. */
1624 rc = mgs_write_log_lov(obd, fsdb, mti, logname, lovname);
1627 name_create(&nodeuuid, libcfs_nid2str(mti->mti_nids[0]), "");
1628 name_create(&svname, mti->mti_svname, "-osc");
1629 name_create(&oscname, svname, suffix);
1630 name_create(&oscuuid, oscname, "_UUID");
1631 name_create(&lovuuid, lovname, "_UUID");
1634 #03 L add_uuid nid=uml1@tcp(0x20000c0a80201) 0: 1:uml1_UUID
1636 #04 L add_uuid nid=1@elan(0x1000000000001) nal=90 0: 1:uml1_UUID
1637 #04 L attach 0:OSC_uml1_ost1_MNT_client 1:osc 2:89070_lov1_a41dff51a
1638 #05 L setup 0:OSC_uml1_ost1_MNT_client 1:ost1_UUID 2:uml1_UUID
1640 #06 L add_uuid nid=uml2@tcp(0x20000c0a80202) 0: 1:uml2_UUID
1641 #07 L add_conn 0:OSC_uml1_ost1_MNT_client 1:uml2_UUID
1642 #08 L lov_modify_tgts add 0:lov1 1:ost1_UUID 2(index):0 3(gen):1
1645 rc = record_start_log(obd, &llh, logname);
1648 /* FIXME these should be a single journal transaction */
1649 rc = record_marker(obd, llh, fsdb, CM_START | flags, mti->mti_svname,
1651 for (i = 0; i < mti->mti_nid_count; i++) {
1652 CDEBUG(D_MGS, "add nid %s\n", libcfs_nid2str(mti->mti_nids[i]));
1653 rc = record_add_uuid(obd, llh, mti->mti_nids[i], nodeuuid);
1655 rc = record_attach(obd, llh, oscname, LUSTRE_OSC_NAME, lovuuid);
1656 rc = record_setup(obd, llh, oscname, mti->mti_uuid, nodeuuid, 0, 0);
1657 rc = mgs_write_log_failnids(obd, mti, llh, oscname);
1658 snprintf(index, sizeof(index), "%d", mti->mti_stripe_index);
1659 rc = record_lov_add(obd, llh, lovname, mti->mti_uuid, index, "1");
1660 rc = record_marker(obd, llh, fsdb, CM_END | flags, mti->mti_svname,
1662 rc = record_end_log(obd, &llh);
1664 name_destroy(&lovuuid);
1665 name_destroy(&oscuuid);
1666 name_destroy(&oscname);
1667 name_destroy(&svname);
1668 name_destroy(&nodeuuid);
1672 static int mgs_write_log_ost(struct obd_device *obd, struct fs_db *fsdb,
1673 struct mgs_target_info *mti)
1675 struct llog_handle *llh = NULL;
1676 char *logname, *lovname;
1678 char *ptr = mti->mti_params;
1679 int rc, flags = 0, failout = 0, i;
1682 CDEBUG(D_MGS, "writing new ost %s\n", mti->mti_svname);
1684 /* The ost startup log */
1686 /* If the ost log already exists, that means that someone reformatted
1687 the ost and it called target_add again. */
1688 if (!mgs_log_is_empty(obd, mti->mti_svname)) {
1689 LCONSOLE_ERROR_MSG(0x141, "The config log for %s already "
1690 "exists, yet the server claims it never "
1691 "registered. It may have been reformatted, "
1692 "or the index changed. writeconf the MDT to "
1693 "regenerate all logs.\n", mti->mti_svname);
1698 attach obdfilter ost1 ost1_UUID
1699 setup /dev/loop2 ldiskfs f|n errors=remount-ro,user_xattr
1701 if (class_find_param(ptr, PARAM_FAILMODE, &ptr) == 0)
1702 failout = (strncmp(ptr, "failout", 7) == 0);
1703 rc = record_start_log(obd, &llh, mti->mti_svname);
1706 /* FIXME these should be a single journal transaction */
1707 rc = record_marker(obd, llh, fsdb, CM_START, mti->mti_svname,"add ost");
1708 if (*mti->mti_uuid == '\0')
1709 snprintf(mti->mti_uuid, sizeof(mti->mti_uuid),
1710 "%s_UUID", mti->mti_svname);
1711 rc = record_attach(obd, llh, mti->mti_svname,
1712 "obdfilter"/*LUSTRE_OST_NAME*/, mti->mti_uuid);
1713 rc = record_setup(obd, llh, mti->mti_svname,
1714 "dev"/*ignored*/, "type"/*ignored*/,
1715 failout ? "n" : "f", 0/*options*/);
1716 rc = record_marker(obd, llh, fsdb, CM_END, mti->mti_svname, "add ost");
1717 rc = record_end_log(obd, &llh);
1719 /* We also have to update the other logs where this osc is part of
1722 if (fsdb->fsdb_flags & FSDB_OLDLOG14) {
1723 /* If we're upgrading, the old mdt log already has our
1724 entry. Let's do a fake one for fun. */
1725 /* Note that we can't add any new failnids, since we don't
1726 know the old osc names. */
1727 flags = CM_SKIP | CM_UPGRADE146;
1729 } else if ((mti->mti_flags & LDD_F_UPDATE) != LDD_F_UPDATE) {
1730 /* If the update flag isn't set, don't update client/mdt
1733 LCONSOLE_WARN("Client log for %s was not updated; writeconf "
1734 "the MDT first to regenerate it.\n",
1738 // for_all_existing_mdt
1739 for (i = 0; i < INDEX_MAP_SIZE * 8; i++){
1740 if (test_bit(i, fsdb->fsdb_mdt_index_map)) {
1741 sprintf(mdt_index,"-MDT%04x",i);
1742 name_create(&logname, mti->mti_fsname, mdt_index);
1743 name_create(&lovname, logname, "-mdtlov");
1744 mgs_write_log_osc_to_lov(obd, fsdb, mti, logname,
1746 LUSTRE_SP_MDT, flags);
1747 name_destroy(&logname);
1748 name_destroy(&lovname);
1752 /* Append ost info to the client log */
1753 name_create(&logname, mti->mti_fsname, "-client");
1754 mgs_write_log_osc_to_lov(obd, fsdb, mti, logname, "",
1755 fsdb->fsdb_clilov, LUSTRE_SP_CLI, 0);
1756 name_destroy(&logname);
1760 /* Add additional failnids to an existing log.
1761 The mdc/osc must have been added to logs first */
1762 /* tcp nids must be in dotted-quad ascii -
1763 we can't resolve hostnames from the kernel. */
1764 static int mgs_write_log_add_failnid(struct obd_device *obd, struct fs_db *fsdb,
1765 struct mgs_target_info *mti)
1767 char *logname, *cliname;
1768 struct llog_handle *llh = NULL;
1772 /* FIXME how do we delete a failnid? Currently --writeconf is the
1773 only way. Maybe make --erase-params pass a flag to really
1774 erase all params from logs - except it can't erase the failnids
1775 given when a target first registers, since they aren't processed
1778 /* Verify that we know about this target */
1779 if (mgs_log_is_empty(obd, mti->mti_svname)) {
1780 LCONSOLE_ERROR_MSG(0x142, "The target %s has not registered "
1781 "yet. It must be started before failnids "
1782 "can be added.\n", mti->mti_svname);
1786 /* Create mdc/osc client name (e.g. lustre-OST0001-osc) */
1787 if (mti->mti_flags & LDD_F_SV_TYPE_MDT) {
1788 name_create(&cliname, mti->mti_svname, "-mdc");
1789 } else if (mti->mti_flags & LDD_F_SV_TYPE_OST) {
1790 name_create(&cliname, mti->mti_svname, "-osc");
1795 /* Add failover nids to client log */
1796 name_create(&logname, mti->mti_fsname, "-client");
1797 rc = record_start_log(obd, &llh, logname);
1799 /* FIXME this fn should be a single journal transaction */
1800 rc = record_marker(obd, llh, fsdb, CM_START, mti->mti_svname,
1802 rc = mgs_write_log_failnids(obd, mti, llh, cliname);
1803 rc = record_marker(obd, llh, fsdb, CM_END, mti->mti_svname,
1805 rc = record_end_log(obd, &llh);
1807 name_destroy(&logname);
1809 if (mti->mti_flags & LDD_F_SV_TYPE_OST) {
1810 /* Add OST failover nids to the MDT log as well */
1811 name_create(&logname, mti->mti_fsname, "-MDT0000");
1812 rc = record_start_log(obd, &llh, logname);
1814 rc = record_marker(obd, llh, fsdb, CM_START,
1815 mti->mti_svname, "add failnid");
1816 rc = mgs_write_log_failnids(obd, mti, llh, cliname);
1817 rc = record_marker(obd, llh, fsdb, CM_END,
1818 mti->mti_svname, "add failnid");
1819 rc = record_end_log(obd, &llh);
1821 name_destroy(&logname);
1824 name_destroy(&cliname);
1828 static int mgs_wlp_lcfg(struct obd_device *obd, struct fs_db *fsdb,
1829 struct mgs_target_info *mti,
1830 char *logname, struct lustre_cfg_bufs *bufs,
1831 char *tgtname, char *ptr)
1833 char comment[MTI_NAME_MAXLEN];
1835 struct lustre_cfg *lcfg;
1838 /* Erase any old settings of this same parameter */
1839 memcpy(comment, ptr, MTI_NAME_MAXLEN);
1840 comment[MTI_NAME_MAXLEN - 1] = 0;
1841 /* But don't try to match the value. */
1842 if ((tmp = strchr(comment, '=')))
1844 /* FIXME we should skip settings that are the same as old values */
1845 rc = mgs_modify(obd, fsdb, mti, logname, tgtname, comment, CM_SKIP);
1846 LCONSOLE_INFO("%sing parameter %s.%s in log %s\n", rc ?
1847 "Sett" : "Modify", tgtname, comment, logname);
1849 lustre_cfg_bufs_reset(bufs, tgtname);
1850 lustre_cfg_bufs_set_string(bufs, 1, ptr);
1851 lcfg = lustre_cfg_new(LCFG_PARAM, bufs);
1854 rc = mgs_write_log_direct(obd, fsdb, logname, lcfg, tgtname, comment);
1855 lustre_cfg_free(lcfg);
1859 /* write global variable settings into log */
1860 static int mgs_write_log_sys(struct obd_device *obd, struct fs_db *fsdb,
1861 struct mgs_target_info *mti, char *sys, char *ptr)
1863 struct lustre_cfg_bufs bufs;
1864 struct lustre_cfg *lcfg;
1869 if (class_match_param(ptr, PARAM_TIMEOUT, &tmp) == 0)
1870 cmd = LCFG_SET_TIMEOUT;
1871 else if (class_match_param(ptr, PARAM_LDLM_TIMEOUT, &tmp) == 0)
1872 cmd = LCFG_SET_LDLM_TIMEOUT;
1873 /* Check for known params here so we can return error to lctl */
1874 else if ((class_match_param(ptr, PARAM_AT_MIN, &tmp) == 0)
1875 || (class_match_param(ptr, PARAM_AT_MAX, &tmp) == 0)
1876 || (class_match_param(ptr, PARAM_AT_EXTRA, &tmp) == 0)
1877 || (class_match_param(ptr, PARAM_AT_EARLY_MARGIN, &tmp) == 0)
1878 || (class_match_param(ptr, PARAM_AT_HISTORY, &tmp) == 0))
1883 val = simple_strtoul(tmp, NULL, 0);
1884 CDEBUG(D_MGS, "global %s = %d\n", ptr, val);
1886 lustre_cfg_bufs_reset(&bufs, NULL);
1887 lustre_cfg_bufs_set_string(&bufs, 1, sys);
1888 lcfg = lustre_cfg_new(cmd, &bufs);
1889 lcfg->lcfg_num = val;
1890 /* modify all servers and clients */
1891 rc = mgs_write_log_direct_all(obd, fsdb, mti, lcfg, mti->mti_fsname,
1893 lustre_cfg_free(lcfg);
1897 static int mgs_srpc_set_param_disk(struct obd_device *obd,
1899 struct mgs_target_info *mti,
1902 struct llog_handle *llh = NULL;
1904 char *comment, *ptr;
1905 struct lustre_cfg_bufs bufs;
1906 struct lustre_cfg *lcfg;
1911 ptr = strchr(param, '=');
1915 OBD_ALLOC(comment, len + 1);
1916 if (comment == NULL)
1918 strncpy(comment, param, len);
1919 comment[len] = '\0';
1922 lustre_cfg_bufs_reset(&bufs, mti->mti_svname);
1923 lustre_cfg_bufs_set_string(&bufs, 1, param);
1924 lcfg = lustre_cfg_new(LCFG_SPTLRPC_CONF, &bufs);
1926 GOTO(out_comment, rc = -ENOMEM);
1928 /* construct log name */
1929 rc = name_create(&logname, mti->mti_fsname, "-sptlrpc");
1933 if (mgs_log_is_empty(obd, logname)) {
1934 rc = record_start_log(obd, &llh, logname);
1935 record_end_log(obd, &llh);
1940 /* obsolete old one */
1941 mgs_modify(obd, fsdb, mti, logname, mti->mti_svname, comment, CM_SKIP);
1943 /* write the new one */
1944 rc = mgs_write_log_direct(obd, fsdb, logname, lcfg,
1945 mti->mti_svname, comment);
1947 CERROR("err %d writing log %s\n", rc, logname);
1950 name_destroy(&logname);
1952 lustre_cfg_free(lcfg);
1954 OBD_FREE(comment, len + 1);
1958 static int mgs_srpc_set_param_udesc_mem(struct fs_db *fsdb,
1963 /* disable the adjustable udesc parameter for now, i.e. use default
1964 * setting that client always ship udesc to MDT if possible. to enable
1965 * it simply remove the following line */
1968 ptr = strchr(param, '=');
1973 if (strcmp(param, PARAM_SRPC_UDESC))
1976 if (strcmp(ptr, "yes") == 0) {
1977 fsdb->fsdb_fl_udesc = 1;
1978 CWARN("Enable user descriptor shipping from client to MDT\n");
1979 } else if (strcmp(ptr, "no") == 0) {
1980 fsdb->fsdb_fl_udesc = 0;
1981 CWARN("Disable user descriptor shipping from client to MDT\n");
1989 CERROR("Invalid param: %s\n", param);
1993 static int mgs_srpc_set_param_mem(struct fs_db *fsdb,
1997 struct sptlrpc_rule rule;
1998 struct sptlrpc_rule_set *rset;
2002 if (strncmp(param, PARAM_SRPC, sizeof(PARAM_SRPC) - 1) != 0) {
2003 CERROR("Invalid sptlrpc parameter: %s\n", param);
2007 if (strncmp(param, PARAM_SRPC_UDESC,
2008 sizeof(PARAM_SRPC_UDESC) - 1) == 0) {
2009 RETURN(mgs_srpc_set_param_udesc_mem(fsdb, param));
2012 if (strncmp(param, PARAM_SRPC_FLVR, sizeof(PARAM_SRPC_FLVR) - 1) != 0) {
2013 CERROR("Invalid sptlrpc flavor parameter: %s\n", param);
2017 param += sizeof(PARAM_SRPC_FLVR) - 1;
2019 rc = sptlrpc_parse_rule(param, &rule);
2023 /* mgs rules implies must be mgc->mgs */
2024 if (fsdb->fsdb_fl_mgsself) {
2025 if ((rule.sr_from != LUSTRE_SP_MGC &&
2026 rule.sr_from != LUSTRE_SP_ANY) ||
2027 (rule.sr_to != LUSTRE_SP_MGS &&
2028 rule.sr_to != LUSTRE_SP_ANY))
2032 /* preapre room for this coming rule. svcname format should be:
2033 * - fsname: general rule
2034 * - fsname-tgtname: target-specific rule
2036 if (strchr(svname, '-')) {
2037 struct mgs_tgt_srpc_conf *tgtconf;
2040 for (tgtconf = fsdb->fsdb_srpc_tgt; tgtconf != NULL;
2041 tgtconf = tgtconf->mtsc_next) {
2042 if (!strcmp(tgtconf->mtsc_tgt, svname)) {
2051 OBD_ALLOC_PTR(tgtconf);
2052 if (tgtconf == NULL)
2055 name_len = strlen(svname);
2057 OBD_ALLOC(tgtconf->mtsc_tgt, name_len + 1);
2058 if (tgtconf->mtsc_tgt == NULL) {
2059 OBD_FREE_PTR(tgtconf);
2062 memcpy(tgtconf->mtsc_tgt, svname, name_len);
2064 tgtconf->mtsc_next = fsdb->fsdb_srpc_tgt;
2065 fsdb->fsdb_srpc_tgt = tgtconf;
2068 rset = &tgtconf->mtsc_rset;
2070 rset = &fsdb->fsdb_srpc_gen;
2073 rc = sptlrpc_rule_set_merge(rset, &rule);
2078 static int mgs_srpc_set_param(struct obd_device *obd,
2080 struct mgs_target_info *mti,
2090 /* keep a copy of original param, which could be destroied
2092 copy_size = strlen(param) + 1;
2093 OBD_ALLOC(copy, copy_size);
2096 memcpy(copy, param, copy_size);
2098 rc = mgs_srpc_set_param_mem(fsdb, mti->mti_svname, param);
2102 /* previous steps guaranteed the syntax is correct */
2103 rc = mgs_srpc_set_param_disk(obd, fsdb, mti, copy);
2107 if (fsdb->fsdb_fl_mgsself) {
2109 * for mgs rules, make them effective immediately.
2111 LASSERT(fsdb->fsdb_srpc_tgt == NULL);
2112 sptlrpc_target_update_exp_flavor(obd, &fsdb->fsdb_srpc_gen);
2116 OBD_FREE(copy, copy_size);
2120 struct mgs_srpc_read_data {
2121 struct fs_db *msrd_fsdb;
2125 static int mgs_srpc_read_handler(struct llog_handle *llh,
2126 struct llog_rec_hdr *rec,
2129 struct mgs_srpc_read_data *msrd = (struct mgs_srpc_read_data *) data;
2130 struct cfg_marker *marker;
2131 struct lustre_cfg *lcfg = (struct lustre_cfg *)(rec + 1);
2132 char *svname, *param;
2136 if (rec->lrh_type != OBD_CFG_REC) {
2137 CERROR("unhandled lrh_type: %#x\n", rec->lrh_type);
2141 cfg_len = rec->lrh_len - sizeof(struct llog_rec_hdr) -
2142 sizeof(struct llog_rec_tail);
2144 rc = lustre_cfg_sanity_check(lcfg, cfg_len);
2146 CERROR("Insane cfg\n");
2150 if (lcfg->lcfg_command == LCFG_MARKER) {
2151 marker = lustre_cfg_buf(lcfg, 1);
2153 if (marker->cm_flags & CM_START &&
2154 marker->cm_flags & CM_SKIP)
2155 msrd->msrd_skip = 1;
2156 if (marker->cm_flags & CM_END)
2157 msrd->msrd_skip = 0;
2162 if (msrd->msrd_skip)
2165 if (lcfg->lcfg_command != LCFG_SPTLRPC_CONF) {
2166 CERROR("invalid command (%x)\n", lcfg->lcfg_command);
2170 svname = lustre_cfg_string(lcfg, 0);
2171 if (svname == NULL) {
2172 CERROR("svname is empty\n");
2176 param = lustre_cfg_string(lcfg, 1);
2177 if (param == NULL) {
2178 CERROR("param is empty\n");
2182 rc = mgs_srpc_set_param_mem(msrd->msrd_fsdb, svname, param);
2184 CERROR("read sptlrpc record error (%d): %s\n", rc, param);
2189 int mgs_get_fsdb_srpc_from_llog(struct obd_device *obd,
2192 struct llog_handle *llh = NULL;
2193 struct lvfs_run_ctxt saved;
2194 struct llog_ctxt *ctxt;
2196 struct mgs_srpc_read_data msrd;
2200 /* construct log name */
2201 rc = name_create(&logname, fsdb->fsdb_name, "-sptlrpc");
2205 ctxt = llog_get_context(obd, LLOG_CONFIG_ORIG_CTXT);
2206 LASSERT(ctxt != NULL);
2208 if (mgs_log_is_empty(obd, logname))
2211 push_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
2213 rc = llog_create(ctxt, &llh, NULL, logname);
2217 rc = llog_init_handle(llh, LLOG_F_IS_PLAIN, NULL);
2219 GOTO(out_close, rc);
2221 if (llog_get_size(llh) <= 1)
2222 GOTO(out_close, rc = 0);
2224 msrd.msrd_fsdb = fsdb;
2227 rc = llog_process(llh, mgs_srpc_read_handler, (void *) &msrd, NULL);
2232 pop_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
2234 llog_ctxt_put(ctxt);
2235 name_destroy(&logname);
2238 CERROR("failed to read sptlrpc config database: %d\n", rc);
2242 static int mgs_write_log_param(struct obd_device *obd, struct fs_db *fsdb,
2243 struct mgs_target_info *mti, char *ptr)
2245 struct lustre_cfg_bufs bufs;
2251 /* For various parameter settings, we have to figure out which logs
2252 care about them (e.g. both mdt and client for lov settings) */
2253 CDEBUG(D_MGS, "next param '%s'\n", ptr);
2255 /* The params are stored in MOUNT_DATA_FILE and modified via
2256 tunefs.lustre, or set using lctl conf_param */
2258 /* Processed in lustre_start_mgc */
2259 if (class_match_param(ptr, PARAM_MGSNODE, NULL) == 0)
2262 /* Processed in mgs_write_log_ost */
2263 if (class_match_param(ptr, PARAM_FAILMODE, NULL) == 0) {
2264 if (mti->mti_flags & LDD_F_PARAM) {
2265 LCONSOLE_ERROR_MSG(0x169, "%s can only be "
2266 "changed with tunefs.lustre"
2267 "and --writeconf\n", ptr);
2273 if (class_match_param(ptr, PARAM_SRPC, NULL) == 0) {
2274 rc = mgs_srpc_set_param(obd, fsdb, mti, ptr);
2278 if (class_match_param(ptr, PARAM_FAILNODE, NULL) == 0) {
2279 /* Add a failover nidlist */
2281 /* We already processed failovers params for new
2282 targets in mgs_write_log_target */
2283 if (mti->mti_flags & LDD_F_PARAM) {
2284 CDEBUG(D_MGS, "Adding failnode\n");
2285 rc = mgs_write_log_add_failnid(obd, fsdb, mti);
2290 if (class_match_param(ptr, PARAM_SYS, &tmp) == 0) {
2291 rc = mgs_write_log_sys(obd, fsdb, mti, ptr, tmp);
2295 if (class_match_param(ptr, PARAM_OSC""PARAM_ACTIVE, &tmp) == 0) {
2296 /* active=0 means off, anything else means on */
2298 int flag = (*tmp == '0') ? CM_EXCLUDE : 0;
2301 if (!(mti->mti_flags & LDD_F_SV_TYPE_OST)) {
2302 LCONSOLE_ERROR_MSG(0x144, "%s: Only OSCs can "
2303 "be (de)activated.\n",
2305 GOTO(end, rc = -EINVAL);
2307 LCONSOLE_WARN("Permanently %sactivating %s\n",
2308 flag ? "de": "re", mti->mti_svname);
2310 name_create(&logname, mti->mti_fsname, "-client");
2311 rc = mgs_modify(obd, fsdb, mti, logname,
2312 mti->mti_svname, "add osc", flag);
2313 name_destroy(&logname);
2317 /* FIXME add to all MDT logs for CMD */
2318 for (i = 0; i < INDEX_MAP_SIZE * 8; i++) {
2319 if (!test_bit(i, fsdb->fsdb_mdt_index_map))
2321 sprintf(mdt_index,"-MDT%04x", i);
2322 name_create(&logname, mti->mti_fsname, mdt_index);
2323 rc = mgs_modify(obd, fsdb, mti, logname,
2324 mti->mti_svname, "add osc", flag);
2325 name_destroy(&logname);
2331 LCONSOLE_ERROR_MSG(0x145, "Couldn't find %s in"
2332 "log (%d). No permanent "
2333 "changes were made to the "
2335 mti->mti_svname, rc);
2336 if (fsdb->fsdb_flags & FSDB_OLDLOG14)
2337 LCONSOLE_ERROR_MSG(0x146, "This may be"
2342 "update the logs.\n");
2345 /* Fall through to osc proc for deactivating live OSC
2346 on running MDT / clients. */
2348 /* Below here, let obd's XXX_process_config methods handle it */
2350 /* All lov. in proc */
2351 if (class_match_param(ptr, PARAM_LOV, NULL) == 0) {
2355 CDEBUG(D_MGS, "lov param %s\n", ptr);
2356 if (!(mti->mti_flags & LDD_F_SV_TYPE_MDT)) {
2357 LCONSOLE_ERROR_MSG(0x147, "LOV params must be "
2358 "set on the MDT, not %s. "
2365 if (mgs_log_is_empty(obd, mti->mti_svname))
2366 GOTO(end, rc = -ENODEV);
2368 sprintf(mdt_index,"-MDT%04x", mti->mti_stripe_index);
2369 name_create(&logname, mti->mti_fsname, mdt_index);
2370 name_create(&mdtlovname, logname, "-mdtlov");
2371 rc = mgs_wlp_lcfg(obd, fsdb, mti, mti->mti_svname,
2372 &bufs, mdtlovname, ptr);
2373 name_destroy(&logname);
2374 name_destroy(&mdtlovname);
2379 name_create(&logname, mti->mti_fsname, "-client");
2380 rc = mgs_wlp_lcfg(obd, fsdb, mti, logname, &bufs,
2381 fsdb->fsdb_clilov, ptr);
2382 name_destroy(&logname);
2386 /* All osc., mdc., llite. params in proc */
2387 if ((class_match_param(ptr, PARAM_OSC, NULL) == 0) ||
2388 (class_match_param(ptr, PARAM_MDC, NULL) == 0) ||
2389 (class_match_param(ptr, PARAM_LLITE, NULL) == 0)) {
2391 if (memcmp(ptr, PARAM_LLITE, strlen(PARAM_LLITE)) == 0) {
2392 name_create(&cname, mti->mti_fsname, "-client");
2393 /* Add the client type to match the obdname in
2394 class_config_llog_handler */
2395 } else if (mti->mti_flags & LDD_F_SV_TYPE_MDT) {
2398 name_create(&cname, fsdb->fsdb_mdc, "");
2400 name_create(&cname, mti->mti_svname,
2402 } else if (mti->mti_flags & LDD_F_SV_TYPE_OST) {
2404 if (fsdb->fsdb_flags & FSDB_OLDLOG14) {
2405 LCONSOLE_ERROR_MSG(0x148, "Upgraded "
2406 "client logs for %s"
2408 "modified. Consider"
2410 "configuration with"
2413 /* We don't know the names of all the
2415 GOTO(end, rc = -EINVAL);
2417 name_create(&cname, mti->mti_svname, "-osc");
2419 GOTO(end, rc = -EINVAL);
2422 CDEBUG(D_MGS, "%.3s param %s\n", ptr, ptr + 4);
2425 name_create(&logname, mti->mti_fsname, "-client");
2426 rc = mgs_wlp_lcfg(obd, fsdb, mti, logname, &bufs,
2429 /* osc params affect the MDT as well */
2430 if (!rc && (mti->mti_flags & LDD_F_SV_TYPE_OST)) {
2434 for (i = 0; i < INDEX_MAP_SIZE * 8; i++){
2435 if (!test_bit(i, fsdb->fsdb_mdt_index_map))
2437 name_destroy(&cname);
2438 sprintf(mdt_index, "-osc-MDT%04x", i);
2439 name_create(&cname, mti->mti_svname,
2441 name_destroy(&logname);
2442 sprintf(mdt_index, "-MDT%04x", i);
2443 name_create(&logname, mti->mti_fsname,
2445 if (!mgs_log_is_empty(obd, logname))
2446 rc = mgs_wlp_lcfg(obd, fsdb,
2454 name_destroy(&logname);
2455 name_destroy(&cname);
2459 /* All mdt. params in proc */
2460 if (class_match_param(ptr, PARAM_MDT, NULL) == 0) {
2465 CDEBUG(D_MGS, "%.3s param %s\n", ptr, ptr + 4);
2466 if (strncmp(mti->mti_svname, mti->mti_fsname,
2467 MTI_NAME_MAXLEN) == 0)
2468 /* device is unspecified completely? */
2469 rc = LDD_F_SV_TYPE_MDT | LDD_F_SV_ALL;
2471 rc = server_name2index(mti->mti_svname, &idx, NULL);
2474 if ((rc & LDD_F_SV_TYPE_MDT) == 0)
2476 if (rc & LDD_F_SV_ALL) {
2477 for (i = 0; i < INDEX_MAP_SIZE * 8; i++) {
2479 fsdb->fsdb_mdt_index_map))
2481 sprintf(mdt_index,"-MDT%04x", i);
2482 name_create(&logname, mti->mti_fsname,
2484 rc = mgs_wlp_lcfg(obd, fsdb, mti,
2487 name_destroy(&logname);
2492 rc = mgs_wlp_lcfg(obd, fsdb, mti,
2493 mti->mti_svname, &bufs,
2494 mti->mti_svname, ptr);
2501 /* All mdd., ost. params in proc */
2502 if ((class_match_param(ptr, PARAM_MDD, NULL) == 0) ||
2503 (class_match_param(ptr, PARAM_OST, NULL) == 0)) {
2504 CDEBUG(D_MGS, "%.3s param %s\n", ptr, ptr + 4);
2505 if (mgs_log_is_empty(obd, mti->mti_svname))
2506 GOTO(end, rc = -ENODEV);
2508 rc = mgs_wlp_lcfg(obd, fsdb, mti, mti->mti_svname,
2509 &bufs, mti->mti_svname, ptr);
2513 LCONSOLE_WARN("Ignoring unrecognized param '%s'\n", ptr);
2517 CERROR("err %d on param '%s'\n", rc, ptr);
2522 /* Not implementing automatic failover nid addition at this time. */
2523 int mgs_check_failnid(struct obd_device *obd, struct mgs_target_info *mti)
2530 rc = mgs_find_or_make_fsdb(obd, fsname, &fsdb);
2534 if (mgs_log_is_empty(obd, mti->mti_svname))
2535 /* should never happen */
2538 CDEBUG(D_MGS, "Checking for new failnids for %s\n", mti->mti_svname);
2540 /* FIXME We can just check mti->params to see if we're already in
2541 the failover list. Modify mti->params for rewriting back at
2542 server_register_target(). */
2544 down(&fsdb->fsdb_sem);
2545 rc = mgs_write_log_add_failnid(obd, fsdb, mti);
2546 up(&fsdb->fsdb_sem);
2553 int mgs_write_log_target(struct obd_device *obd,
2554 struct mgs_target_info *mti)
2561 /* set/check the new target index */
2562 rc = mgs_set_index(obd, mti);
2564 CERROR("Can't get index (%d)\n", rc);
2569 if (mti->mti_flags & LDD_F_UPGRADE14) {
2570 if (rc == EALREADY) {
2571 LCONSOLE_INFO("Found index %d for %s 1.4 log, "
2572 "upgrading\n", mti->mti_stripe_index,
2575 LCONSOLE_ERROR_MSG(0x149, "Failed to find %s in the old"
2576 " client log. Apparently it is not "
2577 "part of this filesystem, or the old"
2578 " log is wrong.\nUse 'writeconf' on "
2579 "the MDT to force log regeneration."
2580 "\n", mti->mti_svname);
2581 /* Not in client log? Upgrade anyhow...*/
2582 /* Argument against upgrading: reformat MDT,
2583 upgrade OST, then OST will start but will be SKIPped
2584 in client logs. Maybe error now is better. */
2585 /* RETURN(-EINVAL); */
2587 /* end COMPAT_146 */
2589 if (rc == EALREADY) {
2590 LCONSOLE_WARN("Found index %d for %s, updating log\n",
2591 mti->mti_stripe_index, mti->mti_svname);
2592 /* We would like to mark old log sections as invalid
2593 and add new log sections in the client and mdt logs.
2594 But if we add new sections, then live clients will
2595 get repeat setup instructions for already running
2596 osc's. So don't update the client/mdt logs. */
2597 mti->mti_flags &= ~LDD_F_UPDATE;
2601 rc = mgs_find_or_make_fsdb(obd, mti->mti_fsname, &fsdb);
2603 CERROR("Can't get db for %s\n", mti->mti_fsname);
2607 down(&fsdb->fsdb_sem);
2609 if (mti->mti_flags &
2610 (LDD_F_VIRGIN | LDD_F_UPGRADE14 | LDD_F_WRITECONF)) {
2611 /* Generate a log from scratch */
2612 if (mti->mti_flags & LDD_F_SV_TYPE_MDT) {
2613 rc = mgs_write_log_mdt(obd, fsdb, mti);
2614 } else if (mti->mti_flags & LDD_F_SV_TYPE_OST) {
2615 rc = mgs_write_log_ost(obd, fsdb, mti);
2617 CERROR("Unknown target type %#x, can't create log for "
2618 "%s\n", mti->mti_flags, mti->mti_svname);
2621 CERROR("Can't write logs for %s (%d)\n",
2622 mti->mti_svname, rc);
2626 /* Just update the params from tunefs in mgs_write_log_params */
2627 CDEBUG(D_MGS, "Update params for %s\n", mti->mti_svname);
2628 mti->mti_flags |= LDD_F_PARAM;
2631 /* allocate temporary buffer, where class_get_next_param will
2632 make copy of a current parameter */
2633 OBD_ALLOC(buf, strlen(mti->mti_params) + 1);
2635 GOTO(out_up, rc = -ENOMEM);
2636 params = mti->mti_params;
2637 while (params != NULL) {
2638 rc = class_get_next_param(¶ms, buf);
2641 /* there is no next parameter, that is
2646 CDEBUG(D_MGS, "remaining string: '%s', param: '%s'\n",
2648 rc = mgs_write_log_param(obd, fsdb, mti, buf);
2653 OBD_FREE(buf, strlen(mti->mti_params) + 1);
2656 up(&fsdb->fsdb_sem);
2661 /* verify that we can handle the old config logs */
2662 int mgs_upgrade_sv_14(struct obd_device *obd, struct mgs_target_info *mti)
2668 /* Create ost log normally, as servers register. Servers
2669 register with their old uuids (from last_rcvd), so old
2670 (MDT and client) logs should work.
2671 - new MDT won't know about old OSTs, only the ones that have
2672 registered, so we need the old MDT log to get the LOV right
2673 in order for old clients to work.
2674 - Old clients connect to the MDT, not the MGS, for their logs, and
2675 will therefore receive the old client log from the MDT /LOGS dir.
2676 - Old clients can continue to use and connect to old or new OSTs
2677 - New clients will contact the MGS for their log
2680 LCONSOLE_INFO("upgrading server %s from pre-1.6\n", mti->mti_svname);
2681 server_mti_print("upgrade", mti);
2683 rc = mgs_find_or_make_fsdb(obd, mti->mti_fsname, &fsdb);
2687 if (fsdb->fsdb_flags & FSDB_LOG_EMPTY) {
2688 LCONSOLE_ERROR_MSG(0x14a, "The old client log %s-client is "
2689 "missing. Was tunefs.lustre successful?\n",
2694 if (fsdb->fsdb_gen == 0) {
2695 /* There were no markers in the client log, meaning we have
2696 not updated the logs for this fs */
2697 CDEBUG(D_MGS, "found old, unupdated client log\n");
2700 if (mti->mti_flags & LDD_F_SV_TYPE_MDT) {
2701 if (mgs_log_is_empty(obd, mti->mti_svname)) {
2702 LCONSOLE_ERROR_MSG(0x14b, "The old MDT log %s is "
2703 "missing. Was tunefs.lustre "
2708 /* We're starting with an old uuid. Assume old name for lov
2709 as well since the lov entry already exists in the log. */
2710 CDEBUG(D_MGS, "old mds uuid %s\n", mti->mti_uuid);
2711 if (strncmp(mti->mti_uuid, fsdb->fsdb_mdtlov + 4,
2712 strlen(fsdb->fsdb_mdtlov) - 4) != 0) {
2713 CERROR("old mds uuid %s doesn't match log %s (%s)\n",
2714 mti->mti_uuid, fsdb->fsdb_mdtlov,
2715 fsdb->fsdb_mdtlov + 4);
2720 if (!(fsdb->fsdb_flags & FSDB_OLDLOG14)) {
2721 LCONSOLE_ERROR_MSG(0x14c, "%s-client is supposedly an old "
2722 "log, but no old LOV or MDT was found. "
2723 "Consider updating the configuration with"
2724 " --writeconf.\n", mti->mti_fsname);
2729 /* end COMPAT_146 */
2731 int mgs_erase_log(struct obd_device *obd, char *name)
2733 struct lvfs_run_ctxt saved;
2734 struct llog_ctxt *ctxt;
2735 struct llog_handle *llh;
2738 ctxt = llog_get_context(obd, LLOG_CONFIG_ORIG_CTXT);
2739 LASSERT(ctxt != NULL);
2741 push_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
2742 rc = llog_create(ctxt, &llh, NULL, name);
2744 llog_init_handle(llh, LLOG_F_IS_PLAIN, NULL);
2745 rc = llog_destroy(llh);
2746 llog_free_handle(llh);
2748 pop_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
2749 llog_ctxt_put(ctxt);
2752 CERROR("failed to clear log %s: %d\n", name, rc);
2757 /* erase all logs for the given fs */
2758 int mgs_erase_logs(struct obd_device *obd, char *fsname)
2760 struct mgs_obd *mgs = &obd->u.mgs;
2761 static struct fs_db *fsdb;
2762 struct list_head dentry_list;
2763 struct l_linux_dirent *dirent, *n;
2764 int rc, len = strlen(fsname);
2767 /* Find all the logs in the CONFIGS directory */
2768 rc = class_dentry_readdir(obd, mgs->mgs_configs_dir,
2769 mgs->mgs_vfsmnt, &dentry_list);
2771 CERROR("Can't read %s dir\n", MOUNT_CONFIGS_DIR);
2775 down(&mgs->mgs_sem);
2777 /* Delete the fs db */
2778 fsdb = mgs_find_fsdb(obd, fsname);
2780 mgs_free_fsdb(obd, fsdb);
2782 list_for_each_entry_safe(dirent, n, &dentry_list, lld_list) {
2783 list_del(&dirent->lld_list);
2784 if (strncmp(fsname, dirent->lld_name, len) == 0) {
2785 CDEBUG(D_MGS, "Removing log %s\n", dirent->lld_name);
2786 mgs_erase_log(obd, dirent->lld_name);
2788 OBD_FREE(dirent, sizeof(*dirent));
2796 /* from llog_swab */
2797 static void print_lustre_cfg(struct lustre_cfg *lcfg)
2802 CDEBUG(D_MGS, "lustre_cfg: %p\n", lcfg);
2803 CDEBUG(D_MGS, "\tlcfg->lcfg_version: %#x\n", lcfg->lcfg_version);
2805 CDEBUG(D_MGS, "\tlcfg->lcfg_command: %#x\n", lcfg->lcfg_command);
2806 CDEBUG(D_MGS, "\tlcfg->lcfg_num: %#x\n", lcfg->lcfg_num);
2807 CDEBUG(D_MGS, "\tlcfg->lcfg_flags: %#x\n", lcfg->lcfg_flags);
2808 CDEBUG(D_MGS, "\tlcfg->lcfg_nid: %s\n", libcfs_nid2str(lcfg->lcfg_nid));
2810 CDEBUG(D_MGS, "\tlcfg->lcfg_bufcount: %d\n", lcfg->lcfg_bufcount);
2811 if (lcfg->lcfg_bufcount < LUSTRE_CFG_MAX_BUFCOUNT)
2812 for (i = 0; i < lcfg->lcfg_bufcount; i++) {
2813 CDEBUG(D_MGS, "\tlcfg->lcfg_buflens[%d]: %d %s\n",
2814 i, lcfg->lcfg_buflens[i],
2815 lustre_cfg_string(lcfg, i));
2820 /* Set a permanent (config log) param for a target or fs */
2821 int mgs_setparam(struct obd_device *obd, struct lustre_cfg *lcfg, char *fsname)
2824 struct mgs_target_info *mti;
2825 char *devname, *param;
2831 print_lustre_cfg(lcfg);
2833 /* lustre, lustre-mdtlov, lustre-client, lustre-MDT0000 */
2834 devname = lustre_cfg_string(lcfg, 0);
2835 param = lustre_cfg_string(lcfg, 1);
2837 /* Assume device name embedded in param:
2838 lustre-OST0000.osc.max_dirty_mb=32 */
2839 ptr = strchr(param, '.');
2847 LCONSOLE_ERROR_MSG(0x14d, "No target specified: %s\n", param);
2851 /* Extract fsname */
2852 ptr = strrchr(devname, '-');
2853 memset(fsname, 0, MTI_NAME_MAXLEN);
2854 if (ptr && (server_name2index(ptr, &index, NULL) >= 0)) {
2855 /* param related to llite isn't allowed to set by OST or MDT */
2856 if (strncmp(param, PARAM_LLITE, sizeof(PARAM_LLITE)) == 0)
2859 strncpy(fsname, devname, ptr - devname);
2861 /* assume devname is the fsname */
2862 strncpy(fsname, devname, MTI_NAME_MAXLEN);
2864 fsname[MTI_NAME_MAXLEN - 1] = 0;
2865 CDEBUG(D_MGS, "setparam on fs %s device %s\n", fsname, devname);
2867 rc = mgs_find_or_make_fsdb(obd, fsname, &fsdb);
2870 if (!fsdb->fsdb_fl_mgsself && fsdb->fsdb_flags & FSDB_LOG_EMPTY) {
2871 CERROR("No filesystem targets for %s. cfg_device from lctl "
2872 "is '%s'\n", fsname, devname);
2873 mgs_free_fsdb(obd, fsdb);
2877 /* Create a fake mti to hold everything */
2880 GOTO(out, rc = -ENOMEM);
2881 strncpy(mti->mti_fsname, fsname, MTI_NAME_MAXLEN);
2882 strncpy(mti->mti_svname, devname, MTI_NAME_MAXLEN);
2883 strncpy(mti->mti_params, param, sizeof(mti->mti_params));
2884 rc = server_name2index(mti->mti_svname, &mti->mti_stripe_index, &tmp);
2886 /* Not a valid server; may be only fsname */
2889 /* Strip -osc or -mdc suffix from svname */
2890 if (server_make_name(rc, mti->mti_stripe_index, mti->mti_fsname,
2892 GOTO(out, rc = -EINVAL);
2894 mti->mti_flags = rc | LDD_F_PARAM;
2896 down(&fsdb->fsdb_sem);
2897 /* this is lctl conf_param's single param path, there is not
2898 need to loop through parameters */
2899 rc = mgs_write_log_param(obd, fsdb, mti, mti->mti_params);
2900 up(&fsdb->fsdb_sem);
2907 static int mgs_write_log_pool(struct obd_device *obd, char *logname,
2908 struct fs_db *fsdb, char *lovname,
2909 enum lcfg_command_type cmd,
2910 char *poolname, char *fsname,
2911 char *ostname, char *comment)
2913 struct llog_handle *llh = NULL;
2916 rc = record_start_log(obd, &llh, logname);
2919 rc = record_marker(obd, llh, fsdb, CM_START, lovname, comment);
2920 record_base(obd, llh, lovname, 0, cmd, poolname, fsname, ostname, 0);
2921 rc = record_marker(obd, llh, fsdb, CM_END, lovname, comment);
2922 rc = record_end_log(obd, &llh);
2927 int mgs_pool_cmd(struct obd_device *obd, enum lcfg_command_type cmd,
2928 char *fsname, char *poolname, char *ostname)
2934 char *label = NULL, *canceled_label = NULL;
2936 struct mgs_target_info *mti = NULL;
2940 rc = mgs_find_or_make_fsdb(obd, fsname, &fsdb);
2942 CERROR("Can't get db for %s\n", fsname);
2945 if (fsdb->fsdb_flags & FSDB_LOG_EMPTY) {
2946 CERROR("%s is not defined\n", fsname);
2947 mgs_free_fsdb(obd, fsdb);
2951 label_sz = 10 + strlen(fsname) + strlen(poolname);
2953 /* check if ostname match fsname */
2954 if (ostname != NULL) {
2957 ptr = strrchr(ostname, '-');
2958 if ((ptr == NULL) ||
2959 (strncmp(fsname, ostname, ptr-ostname) != 0))
2961 label_sz += strlen(ostname);
2964 OBD_ALLOC(label, label_sz);
2966 GOTO(out, rc = -ENOMEM);
2969 case LCFG_POOL_NEW: {
2971 "new %s.%s", fsname, poolname);
2974 case LCFG_POOL_ADD: {
2976 "add %s.%s.%s", fsname, poolname, ostname);
2979 case LCFG_POOL_REM: {
2980 OBD_ALLOC(canceled_label, label_sz);
2981 if (canceled_label == NULL)
2982 GOTO(out, rc = -ENOMEM);
2984 "rem %s.%s.%s", fsname, poolname, ostname);
2985 sprintf(canceled_label,
2986 "add %s.%s.%s", fsname, poolname, ostname);
2989 case LCFG_POOL_DEL: {
2990 OBD_ALLOC(canceled_label, label_sz);
2991 if (canceled_label == NULL)
2992 GOTO(out, rc = -ENOMEM);
2994 "del %s.%s", fsname, poolname);
2995 sprintf(canceled_label,
2996 "new %s.%s", fsname, poolname);
3004 down(&fsdb->fsdb_sem);
3006 if (canceled_label != NULL) {
3009 GOTO(out, rc = -ENOMEM);
3012 /* loop on all potential MDT */
3013 for (i = 0; i < INDEX_MAP_SIZE * 8; i++) {
3014 if (test_bit(i, fsdb->fsdb_mdt_index_map)) {
3015 sprintf(mdt_index, "-MDT%04x", i);
3016 name_create(&logname, fsname, mdt_index);
3017 name_create(&lovname, logname, "-mdtlov");
3019 if (canceled_label != NULL) {
3020 strcpy(mti->mti_svname, "lov pool");
3021 mgs_modify(obd, fsdb, mti, logname, lovname,
3022 canceled_label, CM_SKIP);
3025 mgs_write_log_pool(obd, logname, fsdb, lovname,
3026 cmd, fsname, poolname, ostname,
3028 name_destroy(&logname);
3029 name_destroy(&lovname);
3033 name_create(&logname, fsname, "-client");
3034 if (canceled_label != NULL)
3035 mgs_modify(obd, fsdb, mti, logname, fsdb->fsdb_clilov,
3036 canceled_label, CM_SKIP);
3038 mgs_write_log_pool(obd, logname, fsdb, fsdb->fsdb_clilov,
3039 cmd, fsname, poolname, ostname, label);
3040 name_destroy(&logname);
3042 up(&fsdb->fsdb_sem);
3047 OBD_FREE(label, label_sz);
3049 if (canceled_label != NULL)
3050 OBD_FREE(canceled_label, label_sz);
3059 /******************** unused *********************/
3060 static int mgs_backup_llog(struct obd_device *obd, char* fsname)
3062 struct file *filp, *bak_filp;
3063 struct lvfs_run_ctxt saved;
3064 char *logname, *buf;
3065 loff_t soff = 0 , doff = 0;
3066 int count = 4096, len;
3069 OBD_ALLOC(logname, PATH_MAX);
3070 if (logname == NULL)
3073 OBD_ALLOC(buf, count);
3075 GOTO(out , rc = -ENOMEM);
3077 len = snprintf(logname, PATH_MAX, "%s/%s.bak",
3078 MOUNT_CONFIGS_DIR, fsname);
3080 if (len >= PATH_MAX - 1) {
3081 GOTO(out, -ENAMETOOLONG);
3084 push_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
3086 bak_filp = l_filp_open(logname, O_RDWR|O_CREAT|O_TRUNC, 0660);
3087 if (IS_ERR(bak_filp)) {
3088 rc = PTR_ERR(bak_filp);
3089 CERROR("backup logfile open %s: %d\n", logname, rc);
3092 sprintf(logname, "%s/%s", MOUNT_CONFIGS_DIR, fsname);
3093 filp = l_filp_open(logname, O_RDONLY, 0);
3096 CERROR("logfile open %s: %d\n", logname, rc);
3100 while ((rc = lustre_fread(filp, buf, count, &soff)) > 0) {
3101 rc = lustre_fwrite(bak_filp, buf, count, &doff);
3105 filp_close(filp, 0);
3107 filp_close(bak_filp, 0);
3109 pop_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
3112 OBD_FREE(buf, count);
3113 OBD_FREE(logname, PATH_MAX);