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 static int mgs_srpc_set_param_disk(struct obd_device *obd,
1861 struct mgs_target_info *mti,
1864 struct llog_handle *llh = NULL;
1866 char *comment, *ptr;
1867 struct lustre_cfg_bufs bufs;
1868 struct lustre_cfg *lcfg;
1873 ptr = strchr(param, '=');
1877 OBD_ALLOC(comment, len + 1);
1878 if (comment == NULL)
1880 strncpy(comment, param, len);
1881 comment[len] = '\0';
1884 lustre_cfg_bufs_reset(&bufs, mti->mti_svname);
1885 lustre_cfg_bufs_set_string(&bufs, 1, param);
1886 lcfg = lustre_cfg_new(LCFG_SPTLRPC_CONF, &bufs);
1888 GOTO(out_comment, rc = -ENOMEM);
1890 /* construct log name */
1891 rc = name_create(&logname, mti->mti_fsname, "-sptlrpc");
1895 if (mgs_log_is_empty(obd, logname)) {
1896 rc = record_start_log(obd, &llh, logname);
1897 record_end_log(obd, &llh);
1902 /* obsolete old one */
1903 mgs_modify(obd, fsdb, mti, logname, mti->mti_svname, comment, CM_SKIP);
1905 /* write the new one */
1906 rc = mgs_write_log_direct(obd, fsdb, logname, lcfg,
1907 mti->mti_svname, comment);
1909 CERROR("err %d writing log %s\n", rc, logname);
1912 name_destroy(&logname);
1914 lustre_cfg_free(lcfg);
1916 OBD_FREE(comment, len + 1);
1920 static int mgs_srpc_set_param_udesc_mem(struct fs_db *fsdb,
1925 /* disable the adjustable udesc parameter for now, i.e. use default
1926 * setting that client always ship udesc to MDT if possible. to enable
1927 * it simply remove the following line */
1930 ptr = strchr(param, '=');
1935 if (strcmp(param, PARAM_SRPC_UDESC))
1938 if (strcmp(ptr, "yes") == 0) {
1939 fsdb->fsdb_fl_udesc = 1;
1940 CWARN("Enable user descriptor shipping from client to MDT\n");
1941 } else if (strcmp(ptr, "no") == 0) {
1942 fsdb->fsdb_fl_udesc = 0;
1943 CWARN("Disable user descriptor shipping from client to MDT\n");
1951 CERROR("Invalid param: %s\n", param);
1955 static int mgs_srpc_set_param_mem(struct fs_db *fsdb,
1959 struct sptlrpc_rule rule;
1960 struct sptlrpc_rule_set *rset;
1964 if (strncmp(param, PARAM_SRPC, sizeof(PARAM_SRPC) - 1) != 0) {
1965 CERROR("Invalid sptlrpc parameter: %s\n", param);
1969 if (strncmp(param, PARAM_SRPC_UDESC,
1970 sizeof(PARAM_SRPC_UDESC) - 1) == 0) {
1971 RETURN(mgs_srpc_set_param_udesc_mem(fsdb, param));
1974 if (strncmp(param, PARAM_SRPC_FLVR, sizeof(PARAM_SRPC_FLVR) - 1) != 0) {
1975 CERROR("Invalid sptlrpc flavor parameter: %s\n", param);
1979 param += sizeof(PARAM_SRPC_FLVR) - 1;
1981 rc = sptlrpc_parse_rule(param, &rule);
1985 /* mgs rules implies must be mgc->mgs */
1986 if (fsdb->fsdb_fl_mgsself) {
1987 if ((rule.sr_from != LUSTRE_SP_MGC &&
1988 rule.sr_from != LUSTRE_SP_ANY) ||
1989 (rule.sr_to != LUSTRE_SP_MGS &&
1990 rule.sr_to != LUSTRE_SP_ANY))
1994 /* preapre room for this coming rule. svcname format should be:
1995 * - fsname: general rule
1996 * - fsname-tgtname: target-specific rule
1998 if (strchr(svname, '-')) {
1999 struct mgs_tgt_srpc_conf *tgtconf;
2002 for (tgtconf = fsdb->fsdb_srpc_tgt; tgtconf != NULL;
2003 tgtconf = tgtconf->mtsc_next) {
2004 if (!strcmp(tgtconf->mtsc_tgt, svname)) {
2013 OBD_ALLOC_PTR(tgtconf);
2014 if (tgtconf == NULL)
2017 name_len = strlen(svname);
2019 OBD_ALLOC(tgtconf->mtsc_tgt, name_len + 1);
2020 if (tgtconf->mtsc_tgt == NULL) {
2021 OBD_FREE_PTR(tgtconf);
2024 memcpy(tgtconf->mtsc_tgt, svname, name_len);
2026 tgtconf->mtsc_next = fsdb->fsdb_srpc_tgt;
2027 fsdb->fsdb_srpc_tgt = tgtconf;
2030 rset = &tgtconf->mtsc_rset;
2032 rset = &fsdb->fsdb_srpc_gen;
2035 rc = sptlrpc_rule_set_merge(rset, &rule, 1);
2040 static int mgs_srpc_set_param(struct obd_device *obd,
2042 struct mgs_target_info *mti,
2049 /* keep a copy of original param, which could be destroied
2051 copy_size = strlen(param) + 1;
2052 OBD_ALLOC(copy, copy_size);
2055 memcpy(copy, param, copy_size);
2057 rc = mgs_srpc_set_param_mem(fsdb, mti->mti_svname, param);
2061 /* previous steps guaranteed the syntax is correct */
2062 rc = mgs_srpc_set_param_disk(obd, fsdb, mti, copy);
2066 if (fsdb->fsdb_fl_mgsself) {
2068 * for mgs rules, make them effective immediately.
2070 LASSERT(fsdb->fsdb_srpc_tgt == NULL);
2071 sptlrpc_target_update_exp_flavor(obd, &fsdb->fsdb_srpc_gen);
2075 OBD_FREE(copy, copy_size);
2079 struct mgs_srpc_read_data {
2080 struct fs_db *msrd_fsdb;
2084 static int mgs_srpc_read_handler(struct llog_handle *llh,
2085 struct llog_rec_hdr *rec,
2088 struct mgs_srpc_read_data *msrd = (struct mgs_srpc_read_data *) data;
2089 struct cfg_marker *marker;
2090 struct lustre_cfg *lcfg = (struct lustre_cfg *)(rec + 1);
2091 char *svname, *param;
2095 if (rec->lrh_type != OBD_CFG_REC) {
2096 CERROR("unhandled lrh_type: %#x\n", rec->lrh_type);
2100 cfg_len = rec->lrh_len - sizeof(struct llog_rec_hdr) -
2101 sizeof(struct llog_rec_tail);
2103 rc = lustre_cfg_sanity_check(lcfg, cfg_len);
2105 CERROR("Insane cfg\n");
2109 if (lcfg->lcfg_command == LCFG_MARKER) {
2110 marker = lustre_cfg_buf(lcfg, 1);
2112 if (marker->cm_flags & CM_START &&
2113 marker->cm_flags & CM_SKIP)
2114 msrd->msrd_skip = 1;
2115 if (marker->cm_flags & CM_END)
2116 msrd->msrd_skip = 0;
2121 if (msrd->msrd_skip)
2124 if (lcfg->lcfg_command != LCFG_SPTLRPC_CONF) {
2125 CERROR("invalid command (%x)\n", lcfg->lcfg_command);
2129 svname = lustre_cfg_string(lcfg, 0);
2130 if (svname == NULL) {
2131 CERROR("svname is empty\n");
2135 param = lustre_cfg_string(lcfg, 1);
2136 if (param == NULL) {
2137 CERROR("param is empty\n");
2141 rc = mgs_srpc_set_param_mem(msrd->msrd_fsdb, svname, param);
2143 CERROR("read sptlrpc record error (%d): %s\n", rc, param);
2148 int mgs_get_fsdb_srpc_from_llog(struct obd_device *obd,
2151 struct llog_handle *llh = NULL;
2152 struct lvfs_run_ctxt saved;
2153 struct llog_ctxt *ctxt;
2155 struct mgs_srpc_read_data msrd;
2159 /* construct log name */
2160 rc = name_create(&logname, fsdb->fsdb_name, "-sptlrpc");
2164 ctxt = llog_get_context(obd, LLOG_CONFIG_ORIG_CTXT);
2165 LASSERT(ctxt != NULL);
2167 if (mgs_log_is_empty(obd, logname))
2170 push_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
2172 rc = llog_create(ctxt, &llh, NULL, logname);
2176 rc = llog_init_handle(llh, LLOG_F_IS_PLAIN, NULL);
2178 GOTO(out_close, rc);
2180 if (llog_get_size(llh) <= 1)
2181 GOTO(out_close, rc = 0);
2183 msrd.msrd_fsdb = fsdb;
2186 rc = llog_process(llh, mgs_srpc_read_handler, (void *) &msrd, NULL);
2191 pop_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
2193 llog_ctxt_put(ctxt);
2194 name_destroy(&logname);
2197 CERROR("failed to read sptlrpc config database: %d\n", rc);
2201 static int mgs_write_log_params(struct obd_device *obd, struct fs_db *fsdb,
2202 struct mgs_target_info *mti)
2204 struct lustre_cfg_bufs bufs;
2205 struct lustre_cfg *lcfg;
2207 char *ptr = mti->mti_params;
2212 if (!mti->mti_params)
2215 /* For various parameter settings, we have to figure out which logs
2216 care about them (e.g. both mdt and client for lov settings) */
2222 endptr = strchr(ptr, ' ');
2225 CDEBUG(D_MGS, "next param '%s'\n", ptr);
2227 /* The params are stored in MOUNT_DATA_FILE and modified
2228 via tunefs.lustre, or set using lctl conf_param */
2230 /* Processed in lustre_start_mgc */
2231 if (class_match_param(ptr, PARAM_MGSNODE, NULL) == 0)
2232 GOTO(end_while, rc);
2234 /* Processed in mgs_write_log_ost */
2235 if (class_match_param(ptr, PARAM_FAILMODE, NULL) == 0) {
2236 if (mti->mti_flags & LDD_F_PARAM) {
2237 LCONSOLE_ERROR_MSG(0x169, "%s can only be "
2238 "changed with tunefs.lustre"
2239 "and --writeconf\n", ptr);
2242 GOTO(end_while, rc);
2245 if (class_match_param(ptr, PARAM_SRPC, NULL) == 0) {
2246 rc = mgs_srpc_set_param(obd, fsdb, mti, ptr);
2247 GOTO(end_while, rc);
2250 if (class_match_param(ptr, PARAM_FAILNODE, NULL) == 0) {
2251 /* Add a failover nidlist */
2253 /* We already processed failovers params for new
2254 targets in mgs_write_log_target */
2255 if (mti->mti_flags & LDD_F_PARAM) {
2256 CDEBUG(D_MGS, "Adding failnode\n");
2257 rc = mgs_write_log_add_failnid(obd, fsdb, mti);
2259 GOTO(end_while, rc);
2262 if (class_match_param(ptr, PARAM_SYS_TIMEOUT, &tmp) == 0) {
2263 /* Change obd timeout */
2265 timeout = simple_strtoul(tmp, NULL, 0);
2267 CDEBUG(D_MGS, "obd timeout %d\n", timeout);
2268 lustre_cfg_bufs_reset(&bufs, NULL);
2269 lcfg = lustre_cfg_new(LCFG_SET_TIMEOUT, &bufs);
2270 lcfg->lcfg_num = timeout;
2271 /* modify all servers and clients */
2272 rc = mgs_write_log_direct_all(obd, fsdb, mti, lcfg,
2275 lustre_cfg_free(lcfg);
2276 GOTO(end_while, rc);
2279 if (class_match_param(ptr, PARAM_OSC""PARAM_ACTIVE, &tmp) == 0) {
2280 /* active=0 means off, anything else means on */
2282 int flag = (*tmp == '0') ? CM_EXCLUDE : 0;
2285 if (!(mti->mti_flags & LDD_F_SV_TYPE_OST)) {
2286 LCONSOLE_ERROR_MSG(0x144, "%s: Only OSCs can "
2287 "be (de)activated.\n",
2292 LCONSOLE_WARN("Permanently %sactivating %s\n",
2293 flag ? "de": "re", mti->mti_svname);
2295 name_create(&logname, mti->mti_fsname, "-client");
2296 rc = mgs_modify(obd, fsdb, mti, logname,
2297 mti->mti_svname, "add osc", flag);
2298 name_destroy(&logname);
2302 /* FIXME add to all MDT logs for CMD */
2303 for (i = 0; i < INDEX_MAP_SIZE * 8; i++) {
2304 if (!test_bit(i, fsdb->fsdb_mdt_index_map))
2306 sprintf(mdt_index,"-MDT%04x", i);
2307 name_create(&logname, mti->mti_fsname, mdt_index);
2308 rc = mgs_modify(obd, fsdb, mti, logname,
2309 mti->mti_svname, "add osc", flag);
2310 name_destroy(&logname);
2316 LCONSOLE_ERROR_MSG(0x145, "Couldn't find %s in"
2317 "log (%d). No permanent "
2318 "changes were made to the "
2320 mti->mti_svname, rc);
2321 if (fsdb->fsdb_flags & FSDB_OLDLOG14)
2322 LCONSOLE_ERROR_MSG(0x146, "This may be"
2327 "update the logs.\n");
2330 /* Fall through to osc proc for deactivating
2331 live OSC on running MDT / clients. */
2333 /* Below here, let obd's XXX_process_config methods handle it */
2335 /* All lov. in proc */
2336 if (class_match_param(ptr, PARAM_LOV, NULL) == 0) {
2340 CDEBUG(D_MGS, "lov param %s\n", ptr);
2341 if (!(mti->mti_flags & LDD_F_SV_TYPE_MDT)) {
2342 LCONSOLE_ERROR_MSG(0x147, "LOV params must be "
2343 "set on the MDT, not %s. "
2351 if (mgs_log_is_empty(obd, mti->mti_svname))
2352 GOTO(end_while, rc = -ENODEV);
2354 sprintf(mdt_index,"-MDT%04x", mti->mti_stripe_index);
2355 name_create(&logname, mti->mti_fsname, mdt_index);
2356 name_create(&mdtlovname, logname, "-mdtlov");
2357 rc = mgs_wlp_lcfg(obd, fsdb, mti, mti->mti_svname,
2358 &bufs, mdtlovname, ptr);
2359 name_destroy(&logname);
2360 name_destroy(&mdtlovname);
2362 GOTO(end_while, rc);
2365 name_create(&logname, mti->mti_fsname, "-client");
2366 rc = mgs_wlp_lcfg(obd, fsdb, mti, logname, &bufs,
2367 fsdb->fsdb_clilov, ptr);
2368 name_destroy(&logname);
2369 GOTO(end_while, rc);
2372 /* All osc., mdc., llite. params in proc */
2373 if ((class_match_param(ptr, PARAM_OSC, NULL) == 0) ||
2374 (class_match_param(ptr, PARAM_MDC, NULL) == 0) ||
2375 (class_match_param(ptr, PARAM_LLITE, NULL) == 0)) {
2377 if (memcmp(ptr, PARAM_LLITE, strlen(PARAM_LLITE)) == 0) {
2378 name_create(&cname, mti->mti_fsname, "-client");
2379 /* Add the client type to match the obdname
2380 in class_config_llog_handler */
2381 } else if (mti->mti_flags & LDD_F_SV_TYPE_MDT) {
2384 name_create(&cname, fsdb->fsdb_mdc, "");
2386 name_create(&cname, mti->mti_svname,
2388 } else if (mti->mti_flags & LDD_F_SV_TYPE_OST) {
2390 if (fsdb->fsdb_flags & FSDB_OLDLOG14) {
2391 LCONSOLE_ERROR_MSG(0x148, "Upgraded "
2392 "client logs for %s"
2394 "modified. Consider"
2396 "configuration with"
2399 /* We don't know the names of all the
2404 name_create(&cname, mti->mti_svname, "-osc");
2410 CDEBUG(D_MGS, "%.3s param %s\n", ptr, ptr + 4);
2413 name_create(&logname, mti->mti_fsname, "-client");
2414 rc = mgs_wlp_lcfg(obd, fsdb, mti, logname, &bufs,
2417 /* osc params affect the MDT as well */
2418 if (!rc && (mti->mti_flags & LDD_F_SV_TYPE_OST)) {
2422 for (i = 0; i < INDEX_MAP_SIZE * 8; i++){
2423 if (!test_bit(i, fsdb->fsdb_mdt_index_map))
2425 name_destroy(&cname);
2426 sprintf(mdt_index, "-osc-MDT%04x", i);
2427 name_create(&cname, mti->mti_svname,
2429 name_destroy(&logname);
2430 sprintf(mdt_index, "-MDT%04x", i);
2431 name_create(&logname, mti->mti_fsname,
2433 if (!mgs_log_is_empty(obd, logname))
2434 rc = mgs_wlp_lcfg(obd, fsdb,
2442 name_destroy(&logname);
2443 name_destroy(&cname);
2444 GOTO(end_while, rc);
2447 /* All mdt., ost. params in proc */
2448 if ((class_match_param(ptr, PARAM_MDT, NULL) == 0) ||
2449 (class_match_param(ptr, PARAM_MDD, NULL) == 0) ||
2450 (class_match_param(ptr, PARAM_OST, NULL) == 0)) {
2451 CDEBUG(D_MGS, "%.3s param %s\n", ptr, ptr + 4);
2452 if (mgs_log_is_empty(obd, mti->mti_svname)) {
2456 rc = mgs_wlp_lcfg(obd, fsdb, mti, mti->mti_svname,
2457 &bufs, mti->mti_svname, ptr);
2458 GOTO(end_while, rc);
2461 LCONSOLE_WARN("Ignoring unrecognized param '%s'\n", ptr);
2465 CERROR("err %d on param '%s\n", rc, ptr);
2480 /* Not implementing automatic failover nid addition at this time. */
2481 int mgs_check_failnid(struct obd_device *obd, struct mgs_target_info *mti)
2488 rc = mgs_find_or_make_fsdb(obd, fsname, &fsdb);
2492 if (mgs_log_is_empty(obd, mti->mti_svname))
2493 /* should never happen */
2496 CDEBUG(D_MGS, "Checking for new failnids for %s\n", mti->mti_svname);
2498 /* FIXME We can just check mti->params to see if we're already in
2499 the failover list. Modify mti->params for rewriting back at
2500 server_register_target(). */
2502 down(&fsdb->fsdb_sem);
2503 rc = mgs_write_log_add_failnid(obd, fsdb, mti);
2504 up(&fsdb->fsdb_sem);
2511 int mgs_write_log_target(struct obd_device *obd,
2512 struct mgs_target_info *mti)
2518 /* set/check the new target index */
2519 rc = mgs_set_index(obd, mti);
2521 CERROR("Can't get index (%d)\n", rc);
2526 if (mti->mti_flags & LDD_F_UPGRADE14) {
2527 if (rc == EALREADY) {
2528 LCONSOLE_INFO("Found index %d for %s 1.4 log, "
2529 "upgrading\n", mti->mti_stripe_index,
2532 LCONSOLE_ERROR_MSG(0x149, "Failed to find %s in the old"
2533 " client log. Apparently it is not "
2534 "part of this filesystem, or the old"
2535 " log is wrong.\nUse 'writeconf' on "
2536 "the MDT to force log regeneration."
2537 "\n", mti->mti_svname);
2538 /* Not in client log? Upgrade anyhow...*/
2539 /* Argument against upgrading: reformat MDT,
2540 upgrade OST, then OST will start but will be SKIPped
2541 in client logs. Maybe error now is better. */
2542 /* RETURN(-EINVAL); */
2544 /* end COMPAT_146 */
2546 if (rc == EALREADY) {
2547 LCONSOLE_WARN("Found index %d for %s, updating log\n",
2548 mti->mti_stripe_index, mti->mti_svname);
2549 /* We would like to mark old log sections as invalid
2550 and add new log sections in the client and mdt logs.
2551 But if we add new sections, then live clients will
2552 get repeat setup instructions for already running
2553 osc's. So don't update the client/mdt logs. */
2554 mti->mti_flags &= ~LDD_F_UPDATE;
2558 rc = mgs_find_or_make_fsdb(obd, mti->mti_fsname, &fsdb);
2560 CERROR("Can't get db for %s\n", mti->mti_fsname);
2564 down(&fsdb->fsdb_sem);
2566 if (mti->mti_flags &
2567 (LDD_F_VIRGIN | LDD_F_UPGRADE14 | LDD_F_WRITECONF)) {
2568 /* Generate a log from scratch */
2569 if (mti->mti_flags & LDD_F_SV_TYPE_MDT) {
2570 rc = mgs_write_log_mdt(obd, fsdb, mti);
2571 } else if (mti->mti_flags & LDD_F_SV_TYPE_OST) {
2572 rc = mgs_write_log_ost(obd, fsdb, mti);
2574 CERROR("Unknown target type %#x, can't create log for "
2575 "%s\n", mti->mti_flags, mti->mti_svname);
2578 CERROR("Can't write logs for %s (%d)\n",
2579 mti->mti_svname, rc);
2583 /* Just update the params from tunefs in mgs_write_log_params */
2584 CDEBUG(D_MGS, "Update params for %s\n", mti->mti_svname);
2585 mti->mti_flags |= LDD_F_PARAM;
2588 rc = mgs_write_log_params(obd, fsdb, mti);
2591 up(&fsdb->fsdb_sem);
2596 /* verify that we can handle the old config logs */
2597 int mgs_upgrade_sv_14(struct obd_device *obd, struct mgs_target_info *mti)
2603 /* Create ost log normally, as servers register. Servers
2604 register with their old uuids (from last_rcvd), so old
2605 (MDT and client) logs should work.
2606 - new MDT won't know about old OSTs, only the ones that have
2607 registered, so we need the old MDT log to get the LOV right
2608 in order for old clients to work.
2609 - Old clients connect to the MDT, not the MGS, for their logs, and
2610 will therefore receive the old client log from the MDT /LOGS dir.
2611 - Old clients can continue to use and connect to old or new OSTs
2612 - New clients will contact the MGS for their log
2615 LCONSOLE_INFO("upgrading server %s from pre-1.6\n", mti->mti_svname);
2616 server_mti_print("upgrade", mti);
2618 rc = mgs_find_or_make_fsdb(obd, mti->mti_fsname, &fsdb);
2622 if (fsdb->fsdb_flags & FSDB_LOG_EMPTY) {
2623 LCONSOLE_ERROR_MSG(0x14a, "The old client log %s-client is "
2624 "missing. Was tunefs.lustre successful?\n",
2629 if (fsdb->fsdb_gen == 0) {
2630 /* There were no markers in the client log, meaning we have
2631 not updated the logs for this fs */
2632 CDEBUG(D_MGS, "found old, unupdated client log\n");
2635 if (mti->mti_flags & LDD_F_SV_TYPE_MDT) {
2636 if (mgs_log_is_empty(obd, mti->mti_svname)) {
2637 LCONSOLE_ERROR_MSG(0x14b, "The old MDT log %s is "
2638 "missing. Was tunefs.lustre "
2643 /* We're starting with an old uuid. Assume old name for lov
2644 as well since the lov entry already exists in the log. */
2645 CDEBUG(D_MGS, "old mds uuid %s\n", mti->mti_uuid);
2646 if (strncmp(mti->mti_uuid, fsdb->fsdb_mdtlov + 4,
2647 strlen(fsdb->fsdb_mdtlov) - 4) != 0) {
2648 CERROR("old mds uuid %s doesn't match log %s (%s)\n",
2649 mti->mti_uuid, fsdb->fsdb_mdtlov,
2650 fsdb->fsdb_mdtlov + 4);
2655 if (!(fsdb->fsdb_flags & FSDB_OLDLOG14)) {
2656 LCONSOLE_ERROR_MSG(0x14c, "%s-client is supposedly an old "
2657 "log, but no old LOV or MDT was found. "
2658 "Consider updating the configuration with"
2659 " --writeconf.\n", mti->mti_fsname);
2664 /* end COMPAT_146 */
2666 int mgs_erase_log(struct obd_device *obd, char *name)
2668 struct lvfs_run_ctxt saved;
2669 struct llog_ctxt *ctxt;
2670 struct llog_handle *llh;
2673 ctxt = llog_get_context(obd, LLOG_CONFIG_ORIG_CTXT);
2674 LASSERT(ctxt != NULL);
2676 push_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
2677 rc = llog_create(ctxt, &llh, NULL, name);
2679 llog_init_handle(llh, LLOG_F_IS_PLAIN, NULL);
2680 rc = llog_destroy(llh);
2681 llog_free_handle(llh);
2683 pop_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
2684 llog_ctxt_put(ctxt);
2687 CERROR("failed to clear log %s: %d\n", name, rc);
2692 /* erase all logs for the given fs */
2693 int mgs_erase_logs(struct obd_device *obd, char *fsname)
2695 struct mgs_obd *mgs = &obd->u.mgs;
2696 static struct fs_db *fsdb;
2697 struct list_head dentry_list;
2698 struct l_linux_dirent *dirent, *n;
2699 int rc, len = strlen(fsname);
2702 /* Find all the logs in the CONFIGS directory */
2703 rc = class_dentry_readdir(obd, mgs->mgs_configs_dir,
2704 mgs->mgs_vfsmnt, &dentry_list);
2706 CERROR("Can't read %s dir\n", MOUNT_CONFIGS_DIR);
2710 down(&mgs->mgs_sem);
2712 /* Delete the fs db */
2713 fsdb = mgs_find_fsdb(obd, fsname);
2715 mgs_free_fsdb(obd, fsdb);
2717 list_for_each_entry_safe(dirent, n, &dentry_list, lld_list) {
2718 list_del(&dirent->lld_list);
2719 if (strncmp(fsname, dirent->lld_name, len) == 0) {
2720 CDEBUG(D_MGS, "Removing log %s\n", dirent->lld_name);
2721 mgs_erase_log(obd, dirent->lld_name);
2723 OBD_FREE(dirent, sizeof(*dirent));
2731 /* from llog_swab */
2732 static void print_lustre_cfg(struct lustre_cfg *lcfg)
2737 CDEBUG(D_MGS, "lustre_cfg: %p\n", lcfg);
2738 CDEBUG(D_MGS, "\tlcfg->lcfg_version: %#x\n", lcfg->lcfg_version);
2740 CDEBUG(D_MGS, "\tlcfg->lcfg_command: %#x\n", lcfg->lcfg_command);
2741 CDEBUG(D_MGS, "\tlcfg->lcfg_num: %#x\n", lcfg->lcfg_num);
2742 CDEBUG(D_MGS, "\tlcfg->lcfg_flags: %#x\n", lcfg->lcfg_flags);
2743 CDEBUG(D_MGS, "\tlcfg->lcfg_nid: %s\n", libcfs_nid2str(lcfg->lcfg_nid));
2745 CDEBUG(D_MGS, "\tlcfg->lcfg_bufcount: %d\n", lcfg->lcfg_bufcount);
2746 if (lcfg->lcfg_bufcount < LUSTRE_CFG_MAX_BUFCOUNT)
2747 for (i = 0; i < lcfg->lcfg_bufcount; i++) {
2748 CDEBUG(D_MGS, "\tlcfg->lcfg_buflens[%d]: %d %s\n",
2749 i, lcfg->lcfg_buflens[i],
2750 lustre_cfg_string(lcfg, i));
2755 /* Set a permanent (config log) param for a target or fs */
2756 int mgs_setparam(struct obd_device *obd, struct lustre_cfg *lcfg, char *fsname)
2759 struct mgs_target_info *mti;
2760 char *devname, *param;
2766 print_lustre_cfg(lcfg);
2768 /* lustre, lustre-mdtlov, lustre-client, lustre-MDT0000 */
2769 devname = lustre_cfg_string(lcfg, 0);
2770 param = lustre_cfg_string(lcfg, 1);
2772 /* Assume device name embedded in param:
2773 lustre-OST0000.osc.max_dirty_mb=32 */
2774 ptr = strchr(param, '.');
2782 LCONSOLE_ERROR_MSG(0x14d, "No target specified: %s\n", param);
2786 /* Extract fsname */
2787 ptr = strrchr(devname, '-');
2788 memset(fsname, 0, MTI_NAME_MAXLEN);
2789 if (ptr && (server_name2index(ptr, &index, NULL) >= 0)) {
2790 strncpy(fsname, devname, ptr - devname);
2792 /* assume devname is the fsname */
2793 strncpy(fsname, devname, MTI_NAME_MAXLEN);
2795 fsname[MTI_NAME_MAXLEN - 1] = 0;
2796 CDEBUG(D_MGS, "setparam on fs %s device %s\n", fsname, devname);
2798 rc = mgs_find_or_make_fsdb(obd, fsname, &fsdb);
2801 if (!fsdb->fsdb_fl_mgsself && fsdb->fsdb_flags & FSDB_LOG_EMPTY) {
2802 CERROR("No filesystem targets for %s. cfg_device from lctl "
2803 "is '%s'\n", fsname, devname);
2804 mgs_free_fsdb(obd, fsdb);
2808 /* Create a fake mti to hold everything */
2811 GOTO(out, rc = -ENOMEM);
2812 strncpy(mti->mti_fsname, fsname, MTI_NAME_MAXLEN);
2813 strncpy(mti->mti_svname, devname, MTI_NAME_MAXLEN);
2814 strncpy(mti->mti_params, param, sizeof(mti->mti_params));
2815 rc = server_name2index(mti->mti_svname, &mti->mti_stripe_index, &tmp);
2817 /* Not a valid server; may be only fsname */
2820 /* Strip -osc or -mdc suffix from svname */
2821 if (server_make_name(rc, mti->mti_stripe_index, mti->mti_fsname,
2823 GOTO(out, rc = -EINVAL);
2825 mti->mti_flags = rc | LDD_F_PARAM;
2827 down(&fsdb->fsdb_sem);
2828 rc = mgs_write_log_params(obd, fsdb, mti);
2829 up(&fsdb->fsdb_sem);
2836 static int mgs_write_log_pool(struct obd_device *obd, char *logname,
2837 struct fs_db *fsdb, char *lovname,
2838 enum lcfg_command_type cmd,
2839 char *poolname, char *fsname,
2840 char *ostname, char *comment)
2842 struct llog_handle *llh = NULL;
2845 rc = record_start_log(obd, &llh, logname);
2848 rc = record_marker(obd, llh, fsdb, CM_START, lovname, comment);
2849 record_base(obd, llh, lovname, 0, cmd, poolname, fsname, ostname, 0);
2850 rc = record_marker(obd, llh, fsdb, CM_END, lovname, comment);
2851 rc = record_end_log(obd, &llh);
2856 int mgs_pool_cmd(struct obd_device *obd, enum lcfg_command_type cmd,
2857 char *fsname, char *poolname, char *ostname)
2863 char *label = NULL, *canceled_label = NULL;
2865 struct mgs_target_info *mti = NULL;
2869 rc = mgs_find_or_make_fsdb(obd, fsname, &fsdb);
2871 CERROR("Can't get db for %s\n", fsname);
2874 if (fsdb->fsdb_flags & FSDB_LOG_EMPTY) {
2875 CERROR("%s is not defined\n", fsname);
2876 mgs_free_fsdb(obd, fsdb);
2880 label_sz = 10 + strlen(fsname) + strlen(poolname);
2882 /* check if ostname match fsname */
2883 if (ostname != NULL) {
2886 ptr = strrchr(ostname, '-');
2887 if ((ptr == NULL) ||
2888 (strncmp(fsname, ostname, ptr-ostname) != 0))
2890 label_sz += strlen(ostname);
2893 OBD_ALLOC(label, label_sz);
2895 GOTO(out, rc = -ENOMEM);
2898 case LCFG_POOL_NEW: {
2900 "new %s.%s", fsname, poolname);
2903 case LCFG_POOL_ADD: {
2905 "add %s.%s.%s", fsname, poolname, ostname);
2908 case LCFG_POOL_REM: {
2909 OBD_ALLOC(canceled_label, label_sz);
2910 if (canceled_label == NULL)
2911 GOTO(out, rc = -ENOMEM);
2913 "rem %s.%s.%s", fsname, poolname, ostname);
2914 sprintf(canceled_label,
2915 "add %s.%s.%s", fsname, poolname, ostname);
2918 case LCFG_POOL_DEL: {
2919 OBD_ALLOC(canceled_label, label_sz);
2920 if (canceled_label == NULL)
2921 GOTO(out, rc = -ENOMEM);
2923 "del %s.%s", fsname, poolname);
2924 sprintf(canceled_label,
2925 "new %s.%s", fsname, poolname);
2933 down(&fsdb->fsdb_sem);
2935 if (canceled_label != NULL) {
2938 GOTO(out, rc = -ENOMEM);
2941 /* loop on all potential MDT */
2942 for (i = 0; i < INDEX_MAP_SIZE * 8; i++) {
2943 if (test_bit(i, fsdb->fsdb_mdt_index_map)) {
2944 sprintf(mdt_index, "-MDT%04x", i);
2945 name_create(&logname, fsname, mdt_index);
2946 name_create(&lovname, logname, "-mdtlov");
2948 if (canceled_label != NULL) {
2949 strcpy(mti->mti_svname, "lov pool");
2950 mgs_modify(obd, fsdb, mti, logname, lovname,
2951 canceled_label, CM_SKIP);
2954 mgs_write_log_pool(obd, logname, fsdb, lovname,
2955 cmd, fsname, poolname, ostname,
2957 name_destroy(&logname);
2958 name_destroy(&lovname);
2962 name_create(&logname, fsname, "-client");
2963 if (canceled_label != NULL)
2964 mgs_modify(obd, fsdb, mti, logname, fsdb->fsdb_clilov,
2965 canceled_label, CM_SKIP);
2967 mgs_write_log_pool(obd, logname, fsdb, fsdb->fsdb_clilov,
2968 cmd, fsname, poolname, ostname, label);
2969 name_destroy(&logname);
2971 up(&fsdb->fsdb_sem);
2976 OBD_FREE(label, label_sz);
2978 if (canceled_label != NULL)
2979 OBD_FREE(canceled_label, label_sz);
2988 /******************** unused *********************/
2989 static int mgs_backup_llog(struct obd_device *obd, char* fsname)
2991 struct file *filp, *bak_filp;
2992 struct lvfs_run_ctxt saved;
2993 char *logname, *buf;
2994 loff_t soff = 0 , doff = 0;
2995 int count = 4096, len;
2998 OBD_ALLOC(logname, PATH_MAX);
2999 if (logname == NULL)
3002 OBD_ALLOC(buf, count);
3004 GOTO(out , rc = -ENOMEM);
3006 len = snprintf(logname, PATH_MAX, "%s/%s.bak",
3007 MOUNT_CONFIGS_DIR, fsname);
3009 if (len >= PATH_MAX - 1) {
3010 GOTO(out, -ENAMETOOLONG);
3013 push_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
3015 bak_filp = l_filp_open(logname, O_RDWR|O_CREAT|O_TRUNC, 0660);
3016 if (IS_ERR(bak_filp)) {
3017 rc = PTR_ERR(bak_filp);
3018 CERROR("backup logfile open %s: %d\n", logname, rc);
3021 sprintf(logname, "%s/%s", MOUNT_CONFIGS_DIR, fsname);
3022 filp = l_filp_open(logname, O_RDONLY, 0);
3025 CERROR("logfile open %s: %d\n", logname, rc);
3029 while ((rc = lustre_fread(filp, buf, count, &soff)) > 0) {
3030 rc = lustre_fwrite(bak_filp, buf, count, &doff);
3034 filp_close(filp, 0);
3036 filp_close(bak_filp, 0);
3038 pop_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
3041 OBD_FREE(buf, count);
3042 OBD_FREE(logname, PATH_MAX);