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 "mgs_internal.h"
67 /******************** Class functions *********************/
69 /* Caller must list_del and OBD_FREE each dentry from the list */
70 int class_dentry_readdir(struct obd_device *obd, struct dentry *dir,
71 struct vfsmount *inmnt,
72 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 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 static int mgs_get_fsdb_from_llog(struct obd_device *obd, struct fs_db *fsdb)
243 struct llog_handle *loghandle;
244 struct lvfs_run_ctxt saved;
245 struct llog_ctxt *ctxt;
249 ctxt = llog_get_context(obd, LLOG_CONFIG_ORIG_CTXT);
250 LASSERT(ctxt != NULL);
251 name_create(&logname, fsdb->fsdb_name, "-client");
252 down(&fsdb->fsdb_sem);
253 push_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
254 rc = llog_create(ctxt, &loghandle, NULL, logname);
258 rc = llog_init_handle(loghandle, LLOG_F_IS_PLAIN, NULL);
262 if (llog_get_size(loghandle) <= 1)
263 fsdb->fsdb_flags |= FSDB_LOG_EMPTY;
265 rc = llog_process(loghandle, mgs_fsdb_handler, (void *)fsdb, NULL);
266 CDEBUG(D_INFO, "get_db = %d\n", rc);
268 rc2 = llog_close(loghandle);
273 pop_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
275 name_destroy(&logname);
280 static struct fs_db *mgs_find_fsdb(struct obd_device *obd, char *fsname)
282 struct mgs_obd *mgs = &obd->u.mgs;
284 struct list_head *tmp;
286 list_for_each(tmp, &mgs->mgs_fs_db_list) {
287 fsdb = list_entry(tmp, struct fs_db, fsdb_list);
288 if (strcmp(fsdb->fsdb_name, fsname) == 0)
294 /* caller must hold the mgs->mgs_fs_db_lock */
295 static struct fs_db *mgs_new_fsdb(struct obd_device *obd, char *fsname)
297 struct mgs_obd *mgs = &obd->u.mgs;
306 OBD_ALLOC(fsdb->fsdb_ost_index_map, INDEX_MAP_SIZE);
307 OBD_ALLOC(fsdb->fsdb_mdt_index_map, INDEX_MAP_SIZE);
308 if (!fsdb->fsdb_ost_index_map || !fsdb->fsdb_mdt_index_map) {
309 CERROR("No memory for index maps\n");
313 strncpy(fsdb->fsdb_name, fsname, sizeof(fsdb->fsdb_name));
314 fsdb->fsdb_name[sizeof(fsdb->fsdb_name) - 1] = 0;
315 rc = name_create(&fsdb->fsdb_mdtlov, fsname, "-mdtlov");
318 rc = name_create(&fsdb->fsdb_clilov, fsname, "-clilov");
322 sema_init(&fsdb->fsdb_sem, 1);
323 list_add(&fsdb->fsdb_list, &mgs->mgs_fs_db_list);
324 lproc_mgs_add_live(obd, fsdb);
328 if (fsdb->fsdb_ost_index_map)
329 OBD_FREE(fsdb->fsdb_ost_index_map, INDEX_MAP_SIZE);
330 if (fsdb->fsdb_mdt_index_map)
331 OBD_FREE(fsdb->fsdb_mdt_index_map, INDEX_MAP_SIZE);
332 name_destroy(&fsdb->fsdb_clilov);
333 name_destroy(&fsdb->fsdb_mdtlov);
338 static void mgs_free_fsdb(struct obd_device *obd, struct fs_db *fsdb)
340 /* wait for anyone with the sem */
341 down(&fsdb->fsdb_sem);
342 lproc_mgs_del_live(obd, fsdb);
343 list_del(&fsdb->fsdb_list);
344 OBD_FREE(fsdb->fsdb_ost_index_map, INDEX_MAP_SIZE);
345 OBD_FREE(fsdb->fsdb_mdt_index_map, INDEX_MAP_SIZE);
346 name_destroy(&fsdb->fsdb_clilov);
347 name_destroy(&fsdb->fsdb_mdtlov);
348 name_destroy(&fsdb->fsdb_mdc);
352 int mgs_init_fsdb_list(struct obd_device *obd)
354 struct mgs_obd *mgs = &obd->u.mgs;
355 INIT_LIST_HEAD(&mgs->mgs_fs_db_list);
359 int mgs_cleanup_fsdb_list(struct obd_device *obd)
361 struct mgs_obd *mgs = &obd->u.mgs;
363 struct list_head *tmp, *tmp2;
365 list_for_each_safe(tmp, tmp2, &mgs->mgs_fs_db_list) {
366 fsdb = list_entry(tmp, struct fs_db, fsdb_list);
367 mgs_free_fsdb(obd, fsdb);
373 static int mgs_find_or_make_fsdb(struct obd_device *obd, char *name,
376 struct mgs_obd *mgs = &obd->u.mgs;
381 fsdb = mgs_find_fsdb(obd, name);
388 CDEBUG(D_MGS, "Creating new db\n");
389 fsdb = mgs_new_fsdb(obd, name);
394 /* populate the db from the client llog */
395 rc = mgs_get_fsdb_from_llog(obd, fsdb);
397 CERROR("Can't get db from client log %d\n", rc);
398 mgs_free_fsdb(obd, fsdb);
409 -1= empty client log */
410 int mgs_check_index(struct obd_device *obd, struct mgs_target_info *mti)
417 LASSERT(!(mti->mti_flags & LDD_F_NEED_INDEX));
419 rc = mgs_find_or_make_fsdb(obd, mti->mti_fsname, &fsdb);
421 CERROR("Can't get db for %s\n", mti->mti_fsname);
425 if (fsdb->fsdb_flags & FSDB_LOG_EMPTY)
428 if (mti->mti_flags & LDD_F_SV_TYPE_OST)
429 imap = fsdb->fsdb_ost_index_map;
430 else if (mti->mti_flags & LDD_F_SV_TYPE_MDT)
431 imap = fsdb->fsdb_mdt_index_map;
435 if (test_bit(mti->mti_stripe_index, imap))
440 static __inline__ int next_index(void *index_map, int map_len)
443 for (i = 0; i < map_len * 8; i++)
444 if (!test_bit(i, index_map)) {
447 CERROR("max index %d exceeded.\n", i);
452 0 newly marked as in use
454 +EALREADY for update of an old index */
455 static int mgs_set_index(struct fs_db *fsdb, struct mgs_target_info *mti)
461 if (mti->mti_flags & LDD_F_SV_TYPE_OST)
462 imap = fsdb->fsdb_ost_index_map;
463 else if (mti->mti_flags & LDD_F_SV_TYPE_MDT)
464 imap = fsdb->fsdb_mdt_index_map;
468 if (mti->mti_flags & LDD_F_NEED_INDEX) {
469 rc = next_index(imap, INDEX_MAP_SIZE);
472 mti->mti_stripe_index = rc;
475 /* Remove after CMD */
476 if ((mti->mti_flags & LDD_F_SV_TYPE_MDT) &&
477 (mti->mti_stripe_index > 0)) {
478 LCONSOLE_ERROR_MSG(0x13e, "MDT index must = 0 (until Clustered "
479 "MetaData feature is ready.)\n");
480 mti->mti_stripe_index = 0;
483 if (mti->mti_stripe_index >= INDEX_MAP_SIZE * 8) {
484 LCONSOLE_ERROR_MSG(0x13f, "Server %s requested index %d, but the"
485 "max index is %d.\n",
486 mti->mti_svname, mti->mti_stripe_index,
491 if (test_bit(mti->mti_stripe_index, imap)) {
492 if ((mti->mti_flags & LDD_F_VIRGIN) &&
493 !(mti->mti_flags & LDD_F_WRITECONF)) {
494 LCONSOLE_ERROR_MSG(0x140, "Server %s requested index "
495 "%d, but that index is already in "
496 "use. Use --writeconf to force\n",
498 mti->mti_stripe_index);
501 CDEBUG(D_MGS, "Server %s updating index %d\n",
502 mti->mti_svname, mti->mti_stripe_index);
507 set_bit(mti->mti_stripe_index, imap);
508 fsdb->fsdb_flags &= ~FSDB_LOG_EMPTY;
509 server_make_name(mti->mti_flags, mti->mti_stripe_index,
510 mti->mti_fsname, mti->mti_svname);
512 CDEBUG(D_MGS, "Set index for %s to %d\n", mti->mti_svname,
513 mti->mti_stripe_index);
518 struct mgs_modify_lookup {
519 struct cfg_marker mml_marker;
523 static int mgs_modify_handler(struct llog_handle *llh, struct llog_rec_hdr *rec,
526 struct mgs_modify_lookup *mml = (struct mgs_modify_lookup *)data;
527 struct cfg_marker *marker;
528 struct lustre_cfg *lcfg = (struct lustre_cfg *)(rec + 1);
529 int cfg_len = rec->lrh_len - sizeof(struct llog_rec_hdr) -
530 sizeof(struct llog_rec_tail);
534 if (rec->lrh_type != OBD_CFG_REC) {
535 CERROR("unhandled lrh_type: %#x\n", rec->lrh_type);
539 rc = lustre_cfg_sanity_check(lcfg, cfg_len);
541 CERROR("Insane cfg\n");
545 /* We only care about markers */
546 if (lcfg->lcfg_command != LCFG_MARKER)
549 marker = lustre_cfg_buf(lcfg, 1);
550 if ((strcmp(mml->mml_marker.cm_comment, marker->cm_comment) == 0) &&
551 (strcmp(mml->mml_marker.cm_tgtname, marker->cm_tgtname) == 0) &&
552 !(marker->cm_flags & CM_SKIP)) {
553 /* Found a non-skipped marker match */
554 CDEBUG(D_MGS, "Changing rec %u marker %d %x->%x: %s %s\n",
555 rec->lrh_index, marker->cm_step,
556 marker->cm_flags, mml->mml_marker.cm_flags,
557 marker->cm_tgtname, marker->cm_comment);
558 /* Overwrite the old marker llog entry */
559 marker->cm_flags &= ~CM_EXCLUDE; /* in case we're unexcluding */
560 marker->cm_flags |= mml->mml_marker.cm_flags;
561 marker->cm_canceltime = mml->mml_marker.cm_canceltime;
562 /* Header and tail are added back to lrh_len in
563 llog_lvfs_write_rec */
564 rec->lrh_len = cfg_len;
565 rc = llog_write_rec(llh, rec, NULL, 0, (void *)lcfg,
574 /* Modify an existing config log record (for CM_SKIP or CM_EXCLUDE) */
575 static int mgs_modify(struct obd_device *obd, struct fs_db *fsdb,
576 struct mgs_target_info *mti, char *logname,
577 char *devname, char *comment, int flags)
579 struct llog_handle *loghandle;
580 struct lvfs_run_ctxt saved;
581 struct llog_ctxt *ctxt;
582 struct mgs_modify_lookup *mml;
586 CDEBUG(D_MGS, "modify %s/%s/%s\n", logname, devname, comment);
588 push_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
590 ctxt = llog_get_context(obd, LLOG_CONFIG_ORIG_CTXT);
591 LASSERT(ctxt != NULL);
592 rc = llog_create(ctxt, &loghandle, NULL, logname);
596 rc = llog_init_handle(loghandle, LLOG_F_IS_PLAIN, NULL);
600 if (llog_get_size(loghandle) <= 1)
601 GOTO(out_close, rc = 0);
605 GOTO(out_close, rc = -ENOMEM);
606 strcpy(mml->mml_marker.cm_comment, comment);
607 strcpy(mml->mml_marker.cm_tgtname, devname);
608 /* Modify mostly means cancel */
609 mml->mml_marker.cm_flags = flags;
610 mml->mml_marker.cm_canceltime = flags ? cfs_time_current_sec() : 0;
611 mml->mml_modified = 0;
612 rc = llog_process(loghandle, mgs_modify_handler, (void *)mml, NULL);
613 if (!rc && !mml->mml_modified)
618 rc2 = llog_close(loghandle);
623 pop_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
624 if (rc && rc != -ENODEV)
625 CERROR("modify %s/%s failed %d\n",
626 mti->mti_svname, comment, rc);
632 /******************** config log recording functions *********************/
634 static int record_lcfg(struct obd_device *obd, struct llog_handle *llh,
635 struct lustre_cfg *lcfg)
637 struct lvfs_run_ctxt saved;
638 struct llog_rec_hdr rec;
644 LASSERT(llh->lgh_ctxt);
646 buflen = lustre_cfg_len(lcfg->lcfg_bufcount,
648 rec.lrh_len = llog_data_len(buflen);
649 rec.lrh_type = OBD_CFG_REC;
650 push_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
651 /* idx = -1 means append */
652 rc = llog_write_rec(llh, &rec, NULL, 0, (void *)lcfg, -1);
653 pop_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
655 CERROR("failed %d\n", rc);
659 static int record_base(struct obd_device *obd, struct llog_handle *llh,
660 char *cfgname, lnet_nid_t nid, int cmd,
661 char *s1, char *s2, char *s3, char *s4)
663 struct lustre_cfg_bufs bufs;
664 struct lustre_cfg *lcfg;
667 CDEBUG(D_MGS, "lcfg %s %#x %s %s %s %s\n", cfgname,
668 cmd, s1, s2, s3, s4);
670 lustre_cfg_bufs_reset(&bufs, cfgname);
672 lustre_cfg_bufs_set_string(&bufs, 1, s1);
674 lustre_cfg_bufs_set_string(&bufs, 2, s2);
676 lustre_cfg_bufs_set_string(&bufs, 3, s3);
678 lustre_cfg_bufs_set_string(&bufs, 4, s4);
680 lcfg = lustre_cfg_new(cmd, &bufs);
683 lcfg->lcfg_nid = nid;
685 rc = record_lcfg(obd, llh, lcfg);
687 lustre_cfg_free(lcfg);
690 CERROR("error %d: lcfg %s %#x %s %s %s %s\n", rc, cfgname,
691 cmd, s1, s2, s3, s4);
697 static inline int record_add_uuid(struct obd_device *obd,
698 struct llog_handle *llh,
699 __u64 nid, char *uuid)
701 return record_base(obd,llh,NULL,nid,LCFG_ADD_UUID,uuid,0,0,0);
705 static inline int record_add_conn(struct obd_device *obd,
706 struct llog_handle *llh,
710 return record_base(obd,llh,devname,0,LCFG_ADD_CONN,uuid,0,0,0);
713 static inline int record_attach(struct obd_device *obd, struct llog_handle *llh,
714 char *devname, char *type, char *uuid)
716 return record_base(obd,llh,devname,0,LCFG_ATTACH,type,uuid,0,0);
719 static inline int record_setup(struct obd_device *obd, struct llog_handle *llh,
721 char *s1, char *s2, char *s3, char *s4)
723 return record_base(obd,llh,devname,0,LCFG_SETUP,s1,s2,s3,s4);
726 static int record_lov_setup(struct obd_device *obd, struct llog_handle *llh,
727 char *devname, struct lov_desc *desc)
729 struct lustre_cfg_bufs bufs;
730 struct lustre_cfg *lcfg;
733 lustre_cfg_bufs_reset(&bufs, devname);
734 lustre_cfg_bufs_set(&bufs, 1, desc, sizeof(*desc));
735 lcfg = lustre_cfg_new(LCFG_SETUP, &bufs);
738 rc = record_lcfg(obd, llh, lcfg);
740 lustre_cfg_free(lcfg);
744 static inline int record_lov_add(struct obd_device *obd,
745 struct llog_handle *llh,
746 char *lov_name, char *ost_uuid,
747 char *index, char *gen)
749 return record_base(obd,llh,lov_name,0,LCFG_LOV_ADD_OBD,
750 ost_uuid,index,gen,0);
753 static inline int record_mount_opt(struct obd_device *obd,
754 struct llog_handle *llh,
755 char *profile, char *lov_name,
758 return record_base(obd,llh,NULL,0,LCFG_MOUNTOPT,
759 profile,lov_name,mdc_name,0);
762 static int record_marker(struct obd_device *obd, struct llog_handle *llh,
763 struct fs_db *fsdb, __u32 flags,
764 char *tgtname, char *comment)
766 struct cfg_marker marker;
767 struct lustre_cfg_bufs bufs;
768 struct lustre_cfg *lcfg;
771 if (flags & CM_START)
773 marker.cm_step = fsdb->fsdb_gen;
774 marker.cm_flags = flags;
775 marker.cm_vers = LUSTRE_VERSION_CODE;
776 strncpy(marker.cm_tgtname, tgtname, sizeof(marker.cm_tgtname));
777 strncpy(marker.cm_comment, comment, sizeof(marker.cm_comment));
778 marker.cm_createtime = cfs_time_current_sec();
779 marker.cm_canceltime = 0;
780 lustre_cfg_bufs_reset(&bufs, NULL);
781 lustre_cfg_bufs_set(&bufs, 1, &marker, sizeof(marker));
782 lcfg = lustre_cfg_new(LCFG_MARKER, &bufs);
785 rc = record_lcfg(obd, llh, lcfg);
787 lustre_cfg_free(lcfg);
791 static int record_start_log(struct obd_device *obd,
792 struct llog_handle **llh, char *name)
794 static struct obd_uuid cfg_uuid = { .uuid = "config_uuid" };
795 struct lvfs_run_ctxt saved;
796 struct llog_ctxt *ctxt;
800 GOTO(out, rc = -EBUSY);
802 ctxt = llog_get_context(obd, LLOG_CONFIG_ORIG_CTXT);
804 GOTO(out, rc = -ENODEV);
806 push_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
807 rc = llog_create(ctxt, llh, NULL, name);
809 llog_init_handle(*llh, LLOG_F_IS_PLAIN, &cfg_uuid);
813 pop_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
818 CERROR("Can't start log %s: %d\n", name, rc);
823 static int record_end_log(struct obd_device *obd, struct llog_handle **llh)
825 struct lvfs_run_ctxt saved;
828 push_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
830 rc = llog_close(*llh);
833 pop_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
837 static int mgs_log_is_empty(struct obd_device *obd, char *name)
839 struct lvfs_run_ctxt saved;
840 struct llog_handle *llh;
841 struct llog_ctxt *ctxt;
844 ctxt = llog_get_context(obd, LLOG_CONFIG_ORIG_CTXT);
845 LASSERT(ctxt != NULL);
846 push_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
847 rc = llog_create(ctxt, &llh, NULL, name);
849 llog_init_handle(llh, LLOG_F_IS_PLAIN, NULL);
850 rc = llog_get_size(llh);
853 pop_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
855 /* header is record 1 */
859 /******************** config "macros" *********************/
861 /* write an lcfg directly into a log (with markers) */
862 static int mgs_write_log_direct(struct obd_device *obd, struct fs_db *fsdb,
863 char *logname, struct lustre_cfg *lcfg,
864 char *devname, char *comment)
866 struct llog_handle *llh = NULL;
873 rc = record_start_log(obd, &llh, logname);
877 /* FIXME These should be a single journal transaction */
878 rc = record_marker(obd, llh, fsdb, CM_START, devname, comment);
880 rc = record_lcfg(obd, llh, lcfg);
882 rc = record_marker(obd, llh, fsdb, CM_END, devname, comment);
883 rc = record_end_log(obd, &llh);
888 /* write the lcfg in all logs for the given fs */
889 int mgs_write_log_direct_all(struct obd_device *obd, struct fs_db *fsdb,
890 struct mgs_target_info *mti,
891 struct lustre_cfg *lcfg,
892 char *devname, char *comment)
894 struct mgs_obd *mgs = &obd->u.mgs;
895 struct list_head dentry_list;
896 struct l_linux_dirent *dirent, *n;
897 char *fsname = mti->mti_fsname;
899 int rc = 0, len = strlen(fsname);
902 /* We need to set params for any future logs
903 as well. FIXME Append this file to every new log.
904 Actually, we should store as params (text), not llogs. Or
906 name_create(&logname, fsname, "-params");
907 if (mgs_log_is_empty(obd, logname)) {
908 struct llog_handle *llh = NULL;
909 rc = record_start_log(obd, &llh, logname);
910 record_end_log(obd, &llh);
912 name_destroy(&logname);
916 /* Find all the logs in the CONFIGS directory */
917 rc = class_dentry_readdir(obd, mgs->mgs_configs_dir,
918 mgs->mgs_vfsmnt, &dentry_list);
920 CERROR("Can't read %s dir\n", MOUNT_CONFIGS_DIR);
924 /* Could use fsdb index maps instead of directory listing */
925 list_for_each_entry_safe(dirent, n, &dentry_list, lld_list) {
926 list_del(&dirent->lld_list);
927 if (strncmp(fsname, dirent->lld_name, len) == 0) {
928 CDEBUG(D_MGS, "Changing log %s\n", dirent->lld_name);
929 /* Erase any old settings of this same parameter */
930 mgs_modify(obd, fsdb, mti, dirent->lld_name, devname,
932 /* Write the new one */
933 rc = mgs_write_log_direct(obd, fsdb, dirent->lld_name,
934 lcfg, devname, comment);
936 CERROR("err %d writing log %s\n", rc,
939 OBD_FREE(dirent, sizeof(*dirent));
945 /* lov is the first thing in the mdt and client logs */
946 static int mgs_write_log_lov(struct obd_device *obd, struct fs_db *fsdb,
947 struct mgs_target_info *mti,
948 char *logname, char *lovname)
950 struct llog_handle *llh = NULL;
951 struct lov_desc *lovdesc;
956 CDEBUG(D_MGS, "Writing log %s\n", logname);
959 #01 L attach 0:lov_mdsA 1:lov 2:71ccb_lov_mdsA_19f961a9e1
960 #02 L lov_setup 0:lov_mdsA 1:(struct lov_desc)
961 uuid=lov1_UUID, stripe count=1, size=1048576, offset=0, pattern=0
964 /* FIXME just make lov_setup accept empty desc (put uuid in buf 2) */
965 OBD_ALLOC(lovdesc, sizeof(*lovdesc));
968 lovdesc->ld_magic = LOV_DESC_MAGIC;
969 lovdesc->ld_tgt_count = 0;
970 /* Defaults. Can be changed later by lcfg config_param */
971 lovdesc->ld_default_stripe_count = 1;
972 lovdesc->ld_pattern = LOV_PATTERN_RAID0;
973 lovdesc->ld_default_stripe_size = 1024 * 1024;
974 lovdesc->ld_default_stripe_offset = 0;
975 lovdesc->ld_qos_maxage = QOS_DEFAULT_MAXAGE;
976 sprintf((char*)lovdesc->ld_uuid.uuid, "%s_UUID", lovname);
977 /* can these be the same? */
978 uuid = (char *)lovdesc->ld_uuid.uuid;
980 /* This should always be the first entry in a log.
981 rc = mgs_clear_log(obd, logname); */
982 rc = record_start_log(obd, &llh, logname);
985 /* FIXME these should be a single journal transaction */
986 rc = record_marker(obd, llh, fsdb, CM_START, lovname, "lov setup");
987 rc = record_attach(obd, llh, lovname, "lov", uuid);
988 rc = record_lov_setup(obd, llh, lovname, lovdesc);
989 rc = record_marker(obd, llh, fsdb, CM_END, lovname, "lov setup");
990 rc = record_end_log(obd, &llh);
992 OBD_FREE(lovdesc, sizeof(*lovdesc));
996 /* add failnids to open log */
997 static int mgs_write_log_failnids(struct obd_device *obd,
998 struct mgs_target_info *mti,
999 struct llog_handle *llh,
1002 char *failnodeuuid = NULL;
1003 char *ptr = mti->mti_params;
1008 #03 L add_uuid nid=uml1@tcp(0x20000c0a80201) nal=90 0: 1:uml1_UUID
1009 #04 L add_uuid nid=1@elan(0x1000000000001) nal=90 0: 1:uml1_UUID
1010 #05 L setup 0:OSC_uml1_ost1_mdsA 1:ost1_UUID 2:uml1_UUID
1011 #06 L add_uuid nid=uml2@tcp(0x20000c0a80202) nal=90 0: 1:uml2_UUID
1012 #0x L add_uuid nid=2@elan(0x1000000000002) nal=90 0: 1:uml2_UUID
1013 #07 L add_conn 0:OSC_uml1_ost1_mdsA 1:uml2_UUID
1016 /* Pull failnid info out of params string */
1017 while (class_find_param(ptr, PARAM_FAILNODE, &ptr) == 0) {
1018 while (class_parse_nid(ptr, &nid, &ptr) == 0) {
1019 if (failnodeuuid == NULL) {
1020 /* We don't know the failover node name,
1021 so just use the first nid as the uuid */
1022 rc = name_create(&failnodeuuid,
1023 libcfs_nid2str(nid), "");
1027 CDEBUG(D_MGS, "add nid %s for failover uuid %s, "
1028 "client %s\n", libcfs_nid2str(nid),
1029 failnodeuuid, cliname);
1030 rc = record_add_uuid(obd, llh, nid, failnodeuuid);
1033 rc = record_add_conn(obd, llh, cliname, failnodeuuid);
1034 name_destroy(&failnodeuuid);
1035 failnodeuuid = NULL;
1042 static int mgs_write_log_mdt(struct obd_device *obd, struct fs_db *fsdb,
1043 struct mgs_target_info *mti)
1045 struct llog_handle *llh = NULL;
1046 char *cliname, *mdcname, *nodeuuid, *mdcuuid;
1047 int rc, i, first_log = 0;
1050 CDEBUG(D_MGS, "writing new mdt %s\n", mti->mti_svname);
1052 if (mti->mti_uuid[0] == '\0') {
1053 /* Make up our own uuid */
1054 snprintf(mti->mti_uuid, sizeof(mti->mti_uuid),
1055 "%s_UUID", mti->mti_svname);
1058 /* Append mdt info to mdt log */
1059 if (mgs_log_is_empty(obd, mti->mti_svname)) {
1060 /* This is the first time for all logs for this fs,
1061 since any ost should have already started the mdt log. */
1063 rc = mgs_write_log_lov(obd, fsdb, mti, mti->mti_svname,
1066 /* else there's already some ost entries in the mdt log. */
1068 /* We added the lov, maybe some osc's, now for the mdt.
1069 We might add more ost's after this. Note that during the parsing
1070 of this log, this is when the mdt will start. (This was not
1071 formerly part of the old mds log, it was directly executed by
1074 mount_option 0: 1:mdsA 2:lov_mdsA
1075 attach mds mdsA mdsA_UUID
1076 setup /dev/loop2 ldiskfs mdsA errors=remount-ro,user_xattr
1078 rc = record_start_log(obd, &llh, mti->mti_svname);
1081 /* FIXME this whole fn should be a single journal transaction */
1082 rc = record_marker(obd, llh, fsdb, CM_START, mti->mti_svname,"add mdt");
1083 rc = record_mount_opt(obd, llh, mti->mti_svname, fsdb->fsdb_mdtlov, 0);
1084 rc = record_attach(obd, llh, mti->mti_svname, LUSTRE_MDS_NAME,
1086 rc = record_setup(obd, llh, mti->mti_svname,
1087 mti->mti_uuid /* Ignored. Compatible with future. */,
1088 "0" /* MDT Index, default to zero. */,
1091 rc = record_marker(obd, llh, fsdb, CM_END, mti->mti_svname, "add mdt");
1092 rc = record_end_log(obd, &llh);
1094 /* Append the mdt info to the client log */
1095 name_create(&cliname, mti->mti_fsname, "-client");
1097 /* Start client log */
1098 rc = mgs_write_log_lov(obd, fsdb, mti, cliname,
1102 name_create(&nodeuuid, libcfs_nid2str(mti->mti_nids[0]),/*"_UUID"*/"");
1103 name_create(&mdcname, mti->mti_svname, "-mdc");
1104 name_create(&mdcuuid, mdcname, "_UUID");
1106 #09 L add_uuid nid=uml1@tcp(0x20000c0a80201) 0: 1:uml1_UUID
1107 #10 L attach 0:MDC_uml1_mdsA_MNT_client 1:mdc 2:1d834_MNT_client_03f
1108 #11 L setup 0:MDC_uml1_mdsA_MNT_client 1:mdsA_UUID 2:uml1_UUID
1109 #12 L add_uuid nid=uml2@tcp(0x20000c0a80202) 0: 1:uml2_UUID
1110 #13 L add_conn 0:MDC_uml1_mdsA_MNT_client 1:uml2_UUID
1111 #14 L mount_option 0: 1:client 2:lov1 3:MDC_uml1_mdsA_MNT_client
1113 rc = record_start_log(obd, &llh, cliname);
1116 rc = record_marker(obd, llh, fsdb, CM_START, mti->mti_svname,"add mdc");
1118 if (fsdb->fsdb_flags & FSDB_OLDLOG14) {
1119 /* Old client log already has MDC entry, but needs mount opt
1120 for new client name (lustre-client) */
1121 /* FIXME Old MDT log already has an old mount opt
1122 which we should remove (currently handled by
1123 class_del_profiles()) */
1124 rc = record_mount_opt(obd, llh, cliname, fsdb->fsdb_clilov,
1126 /* Only add failnids with --writeconf
1127 rc = mgs_write_log_failnids(obd, mti, llh, fsdb->fsdb_mdc);
1129 /* end COMPAT_146 */
1131 for (i = 0; i < mti->mti_nid_count; i++) {
1132 CDEBUG(D_MGS, "add nid %s\n",
1133 libcfs_nid2str(mti->mti_nids[i]));
1134 rc = record_add_uuid(obd, llh, mti->mti_nids[i],
1137 rc = record_attach(obd, llh, mdcname, LUSTRE_MDC_NAME, mdcuuid);
1138 rc = record_setup(obd, llh, mdcname, mti->mti_uuid,nodeuuid,
1140 rc = mgs_write_log_failnids(obd, mti, llh, mdcname);
1141 rc = record_mount_opt(obd, llh, cliname, fsdb->fsdb_clilov,
1144 rc = record_marker(obd, llh, fsdb, CM_END, mti->mti_svname, "add mdc");
1145 rc = record_end_log(obd, &llh);
1147 name_destroy(&mdcuuid);
1148 name_destroy(&mdcname);
1149 name_destroy(&nodeuuid);
1150 name_destroy(&cliname);
1154 /* Add the ost info to the client/mdt lov */
1155 static int mgs_write_log_osc(struct obd_device *obd, struct fs_db *fsdb,
1156 struct mgs_target_info *mti,
1157 char *logname, char *lovname, int flags)
1159 struct llog_handle *llh = NULL;
1160 char *nodeuuid, *oscname, *oscuuid, *lovuuid;
1164 if (mgs_log_is_empty(obd, logname)) {
1165 /* The first item in the log must be the lov, so we have
1166 somewhere to add our osc. */
1167 rc = mgs_write_log_lov(obd, fsdb, mti, logname, lovname);
1170 CDEBUG(D_MGS, "adding osc for %s to log %s\n",
1171 mti->mti_svname, logname);
1173 name_create(&nodeuuid, libcfs_nid2str(mti->mti_nids[0]), "");
1174 name_create(&oscname, mti->mti_svname, "-osc");
1175 name_create(&oscuuid, oscname, "_UUID");
1176 name_create(&lovuuid, lovname, "_UUID");
1179 #03 L add_uuid nid=uml1@tcp(0x20000c0a80201) 0: 1:uml1_UUID
1181 #04 L add_uuid nid=1@elan(0x1000000000001) nal=90 0: 1:uml1_UUID
1182 #04 L attach 0:OSC_uml1_ost1_MNT_client 1:osc 2:89070_lov1_a41dff51a
1183 #05 L setup 0:OSC_uml1_ost1_MNT_client 1:ost1_UUID 2:uml1_UUID
1185 #06 L add_uuid nid=uml2@tcp(0x20000c0a80202) 0: 1:uml2_UUID
1186 #07 L add_conn 0:OSC_uml1_ost1_MNT_client 1:uml2_UUID
1187 #08 L lov_modify_tgts add 0:lov1 1:ost1_UUID 2(index):0 3(gen):1
1189 rc = record_start_log(obd, &llh, logname);
1192 /* FIXME these should be a single journal transaction */
1193 rc = record_marker(obd, llh, fsdb, CM_START | flags, mti->mti_svname,
1195 for (i = 0; i < mti->mti_nid_count; i++) {
1196 CDEBUG(D_MGS, "add nid %s\n", libcfs_nid2str(mti->mti_nids[i]));
1197 rc = record_add_uuid(obd, llh, mti->mti_nids[i], nodeuuid);
1199 rc = record_attach(obd, llh, oscname, LUSTRE_OSC_NAME, lovuuid);
1200 rc = record_setup(obd, llh, oscname, mti->mti_uuid, nodeuuid, 0, 0);
1201 rc = mgs_write_log_failnids(obd, mti, llh, oscname);
1202 snprintf(index, sizeof(index), "%d", mti->mti_stripe_index);
1203 rc = record_lov_add(obd, llh, lovname, mti->mti_uuid, index, "1");
1204 rc = record_marker(obd, llh, fsdb, CM_END | flags, mti->mti_svname,
1206 rc = record_end_log(obd, &llh);
1208 name_destroy(&lovuuid);
1209 name_destroy(&oscuuid);
1210 name_destroy(&oscname);
1211 name_destroy(&nodeuuid);
1215 static int mgs_write_log_ost(struct obd_device *obd, struct fs_db *fsdb,
1216 struct mgs_target_info *mti)
1218 struct llog_handle *llh = NULL;
1220 char *ptr = mti->mti_params;
1221 int rc, flags = 0, failout = 0;
1224 CDEBUG(D_MGS, "writing new ost %s\n", mti->mti_svname);
1226 /* The ost startup log */
1228 /* If the ost log already exists, that means that someone reformatted
1229 the ost and it called target_add again. */
1230 if (!mgs_log_is_empty(obd, mti->mti_svname)) {
1231 LCONSOLE_ERROR_MSG(0x141, "The config log for %s already "
1232 "exists, yet the server claims it never "
1233 "registered. It may have been reformatted, "
1234 "or the index changed. writeconf the MDT to "
1235 "regenerate all logs.\n", mti->mti_svname);
1239 attach obdfilter ost1 ost1_UUID
1240 setup /dev/loop2 ldiskfs f|n errors=remount-ro,user_xattr
1242 if (class_find_param(ptr, PARAM_FAILMODE, &ptr) == 0)
1243 failout = (strncmp(ptr, "failout", 7) == 0);
1244 rc = record_start_log(obd, &llh, mti->mti_svname);
1247 /* FIXME these should be a single journal transaction */
1248 rc = record_marker(obd, llh, fsdb, CM_START, mti->mti_svname,"add ost");
1249 if (*mti->mti_uuid == '\0')
1250 snprintf(mti->mti_uuid, sizeof(mti->mti_uuid),
1251 "%s_UUID", mti->mti_svname);
1252 rc = record_attach(obd, llh, mti->mti_svname,
1253 "obdfilter"/*LUSTRE_OST_NAME*/, mti->mti_uuid);
1254 rc = record_setup(obd, llh, mti->mti_svname,
1255 "dev"/*ignored*/, "type"/*ignored*/,
1256 failout ? "n" : "f", 0/*options*/);
1257 rc = record_marker(obd, llh, fsdb, CM_END, mti->mti_svname, "add ost");
1258 rc = record_end_log(obd, &llh);
1260 /* We also have to update the other logs where this osc is part of
1263 if (fsdb->fsdb_flags & FSDB_OLDLOG14) {
1264 /* If we're upgrading, the old mdt log already has our
1265 entry. Let's do a fake one for fun. */
1266 /* Note that we can't add any new failnids, since we don't
1267 know the old osc names. */
1268 flags = CM_SKIP | CM_UPGRADE146;
1269 } else if ((mti->mti_flags & LDD_F_UPDATE) != LDD_F_UPDATE) {
1270 /* If the update flag isn't set, don't really update
1273 LCONSOLE_WARN("Client log for %s was not updated; writeconf "
1274 "the MDT first to regenerate it.\n",
1278 /* Append ost info to mdt log */
1279 /* FIXME add to all MDT logs for CMD */
1280 /* FIXME need real MDT name, but MDT may not have registered yet! */
1281 name_create(&logname, mti->mti_fsname, "-MDT0000");
1282 rc = mgs_write_log_osc(obd, fsdb, mti, logname, fsdb->fsdb_mdtlov,
1284 name_destroy(&logname);
1286 /* Append ost info to the client log */
1287 name_create(&logname, mti->mti_fsname, "-client");
1288 rc = mgs_write_log_osc(obd, fsdb, mti, logname, fsdb->fsdb_clilov,
1290 name_destroy(&logname);
1295 /* Add additional failnids to an existing log.
1296 The mdc/osc must have been added to logs first */
1297 /* tcp nids must be in dotted-quad ascii -
1298 we can't resolve hostnames from the kernel. */
1299 static int mgs_write_log_add_failnid(struct obd_device *obd, struct fs_db *fsdb,
1300 struct mgs_target_info *mti)
1302 char *logname, *cliname;
1303 struct llog_handle *llh = NULL;
1307 /* FIXME how do we delete a failnid? Currently --writeconf is the
1308 only way. Maybe make --erase-params pass a flag to really
1309 erase all params from logs - except it can't erase the failnids
1310 given when a target first registers, since they aren't processed
1313 /* Verify that we know about this target */
1314 if (mgs_log_is_empty(obd, mti->mti_svname)) {
1315 LCONSOLE_ERROR_MSG(0x142, "The target %s has not registered "
1316 "yet. It must be started before failnids can"
1317 " be added.\n", mti->mti_svname);
1321 /* Create mdc/osc client name (e.g. lustre-OST0001-osc) */
1322 if (mti->mti_flags & LDD_F_SV_TYPE_MDT) {
1325 name_create(&cliname, fsdb->fsdb_mdc, "");
1327 name_create(&cliname, mti->mti_svname, "-mdc");
1328 } else if (mti->mti_flags & LDD_F_SV_TYPE_OST) {
1330 if (fsdb->fsdb_flags & FSDB_OLDLOG14) {
1331 LCONSOLE_ERROR_MSG(0x143, "Failover NIDs cannot be "
1332 "added to upgraded client logs for "
1333 "%s. Consider updating the "
1334 "configuration with --writeconf.\n",
1338 name_create(&cliname, mti->mti_svname, "-osc");
1343 /* Add failover nids to client log */
1344 name_create(&logname, mti->mti_fsname, "-client");
1345 rc = record_start_log(obd, &llh, logname);
1347 /* FIXME this fn should be a single journal transaction */
1348 rc = record_marker(obd, llh, fsdb, CM_START, mti->mti_svname,
1350 rc = mgs_write_log_failnids(obd, mti, llh, cliname);
1351 rc = record_marker(obd, llh, fsdb, CM_END, mti->mti_svname,
1353 rc = record_end_log(obd, &llh);
1355 name_destroy(&logname);
1357 if (mti->mti_flags & LDD_F_SV_TYPE_OST) {
1358 /* Add OST failover nids to the MDT log as well */
1359 name_create(&logname, mti->mti_fsname, "-MDT0000");
1360 rc = record_start_log(obd, &llh, logname);
1362 rc = record_marker(obd, llh, fsdb, CM_START,
1363 mti->mti_svname, "add failnid");
1364 rc = mgs_write_log_failnids(obd, mti, llh, cliname);
1365 rc = record_marker(obd, llh, fsdb, CM_END,
1366 mti->mti_svname, "add failnid");
1367 rc = record_end_log(obd, &llh);
1369 name_destroy(&logname);
1372 name_destroy(&cliname);
1376 static int mgs_wlp_lcfg(struct obd_device *obd, struct fs_db *fsdb,
1377 struct mgs_target_info *mti,
1378 char *logname, struct lustre_cfg_bufs *bufs,
1379 char *tgtname, char *ptr)
1381 char comment[MTI_NAME_MAXLEN];
1383 struct lustre_cfg *lcfg;
1386 /* Erase any old settings of this same parameter */
1387 memcpy(comment, ptr, MTI_NAME_MAXLEN);
1388 comment[MTI_NAME_MAXLEN - 1] = 0;
1389 /* But don't try to match the value. */
1390 if ((tmp = strchr(comment, '=')))
1392 /* FIXME we should skip settings that are the same as old values */
1393 rc = mgs_modify(obd, fsdb, mti, logname, tgtname, comment, CM_SKIP);
1394 LCONSOLE_INFO("%sing parameter %s.%s in log %s\n", rc ?
1395 "Sett" : "Modify", tgtname, comment, logname);
1397 lustre_cfg_bufs_reset(bufs, tgtname);
1398 lustre_cfg_bufs_set_string(bufs, 1, ptr);
1399 lcfg = lustre_cfg_new(LCFG_PARAM, bufs);
1402 rc = mgs_write_log_direct(obd, fsdb, logname, lcfg, tgtname, comment);
1403 lustre_cfg_free(lcfg);
1407 /* write global variable settings into log */
1408 static int mgs_write_log_sys(struct obd_device *obd, struct fs_db *fsdb,
1409 struct mgs_target_info *mti, char *sys, char *ptr)
1411 struct lustre_cfg_bufs bufs;
1412 struct lustre_cfg *lcfg;
1417 if (class_match_param(ptr, PARAM_TIMEOUT, &tmp) == 0)
1418 cmd = LCFG_SET_TIMEOUT;
1419 else if (class_match_param(ptr, PARAM_LDLM_TIMEOUT, &tmp) == 0)
1420 cmd = LCFG_SET_LDLM_TIMEOUT;
1421 /* Check for known params here so we can return error to lctl */
1422 else if ((class_match_param(ptr, PARAM_AT_MIN, &tmp) == 0)
1423 || (class_match_param(ptr, PARAM_AT_MAX, &tmp) == 0)
1424 || (class_match_param(ptr, PARAM_AT_EXTRA, &tmp) == 0)
1425 || (class_match_param(ptr, PARAM_AT_EARLY_MARGIN, &tmp) == 0)
1426 || (class_match_param(ptr, PARAM_AT_HISTORY, &tmp) == 0))
1431 val = simple_strtoul(tmp, NULL, 0);
1432 CDEBUG(D_MGS, "global %s = %d\n", ptr, val);
1434 lustre_cfg_bufs_reset(&bufs, NULL);
1435 lustre_cfg_bufs_set_string(&bufs, 1, sys);
1436 lcfg = lustre_cfg_new(cmd, &bufs);
1437 lcfg->lcfg_num = val;
1438 /* modify all servers and clients */
1439 rc = mgs_write_log_direct_all(obd, fsdb, mti, lcfg, mti->mti_fsname,
1441 lustre_cfg_free(lcfg);
1445 static int mgs_write_log_params(struct obd_device *obd, struct fs_db *fsdb,
1446 struct mgs_target_info *mti)
1448 struct lustre_cfg_bufs bufs;
1450 char *ptr = mti->mti_params;
1455 if (!mti->mti_params)
1458 /* For various parameter settings, we have to figure out which logs
1459 care about them (e.g. both mdt and client for lov settings) */
1465 endptr = strchr(ptr, ' ');
1468 CDEBUG(D_MGS, "next param '%s'\n", ptr);
1470 /* The params are stored in MOUNT_DATA_FILE and modified
1471 via tunefs.lustre */
1473 /* Processed in lustre_start_mgc */
1474 if (class_match_param(ptr, PARAM_MGSNODE, NULL) == 0)
1477 /* Processed in mgs_write_log_ost */
1478 if (class_match_param(ptr, PARAM_FAILMODE, NULL) == 0) {
1479 if (mti->mti_flags & LDD_F_PARAM) {
1480 LCONSOLE_ERROR_MSG(0x169, "%s can only be "
1481 "changed with tunefs.lustre "
1482 "and --writeconf\n", ptr);
1488 if (class_match_param(ptr, PARAM_FAILNODE, NULL) == 0) {
1489 /* Add a failover nidlist */
1491 /* We already processed failovers params for new
1492 targets in mgs_write_log_target */
1493 if (mti->mti_flags & LDD_F_PARAM) {
1494 CDEBUG(D_MGS, "Adding failnode\n");
1495 rc = mgs_write_log_add_failnid(obd, fsdb, mti);
1500 if (class_match_param(ptr, PARAM_SYS, &tmp) == 0) {
1501 rc = mgs_write_log_sys(obd, fsdb, mti, ptr, tmp);
1505 if (class_match_param(ptr, PARAM_OSC""PARAM_ACTIVE, &tmp) == 0){
1506 /* active=0 means off, anything else means on */
1507 int flag = (*tmp == '0') ? CM_EXCLUDE : 0;
1508 if (!(mti->mti_flags & LDD_F_SV_TYPE_OST)) {
1509 LCONSOLE_ERROR_MSG(0x144, "%s: Only OSCs can be"
1510 " (de)activated.\n",
1515 LCONSOLE_WARN("Permanently %sactivating %s\n",
1516 flag ? "de": "re", mti->mti_svname);
1518 name_create(&logname, mti->mti_fsname, "-client");
1519 rc = mgs_modify(obd, fsdb, mti, logname,
1520 mti->mti_svname, "add osc", flag);
1521 name_destroy(&logname);
1525 /* FIXME add to all MDT logs for CMD */
1526 name_create(&logname, mti->mti_fsname, "-MDT0000");
1527 rc = mgs_modify(obd, fsdb, mti, logname,
1528 mti->mti_svname, "add osc", flag);
1529 name_destroy(&logname);
1532 LCONSOLE_ERROR_MSG(0x145, "Couldn't find %s in "
1533 "log (%d). No permanent "
1534 "changes were made to the "
1536 mti->mti_svname, rc);
1537 if (fsdb->fsdb_flags & FSDB_OLDLOG14)
1538 LCONSOLE_ERROR_MSG(0x146, "This may be "
1539 "because the log is in the old 1.4 "
1540 "style. Consider --writeconf to "
1541 "update the logs.\n");
1544 /* Fall through to osc proc for deactivating
1545 live OSC on running MDT / clients. */
1548 /* Below here, let obd's XXX_process_config methods handle it */
1550 /* All lov. in proc */
1551 if (class_match_param(ptr, PARAM_LOV, NULL) == 0) {
1552 CDEBUG(D_MGS, "lov param %s\n", ptr);
1553 if (!(mti->mti_flags & LDD_F_SV_TYPE_MDT)) {
1554 LCONSOLE_ERROR_MSG(0x147, "LOV params must be "
1555 "set on the MDT, not %s. "
1563 if (mgs_log_is_empty(obd, mti->mti_svname)) {
1567 rc = mgs_wlp_lcfg(obd, fsdb, mti, mti->mti_svname,
1568 &bufs, fsdb->fsdb_mdtlov, ptr);
1573 name_create(&logname, mti->mti_fsname, "-client");
1574 rc = mgs_wlp_lcfg(obd, fsdb, mti, logname, &bufs,
1575 fsdb->fsdb_clilov, ptr);
1576 name_destroy(&logname);
1580 /* All osc., mdc., llite. params in proc */
1581 if ((class_match_param(ptr, PARAM_OSC, NULL) == 0) ||
1582 (class_match_param(ptr, PARAM_MDC, NULL) == 0) ||
1583 (class_match_param(ptr, PARAM_LLITE, NULL) == 0)) {
1585 if (memcmp(ptr, PARAM_LLITE, strlen(PARAM_LLITE)) == 0){
1586 name_create(&cname, mti->mti_fsname, "-client");
1587 /* Add the client type to match the obdname
1588 in class_config_llog_handler */
1589 } else if (mti->mti_flags & LDD_F_SV_TYPE_MDT) {
1592 name_create(&cname, fsdb->fsdb_mdc, "");
1594 name_create(&cname, mti->mti_svname,
1596 } else if (mti->mti_flags & LDD_F_SV_TYPE_OST) {
1598 if (fsdb->fsdb_flags & FSDB_OLDLOG14) {
1599 LCONSOLE_ERROR_MSG(0x148, "Upgraded client"
1600 " logs for %s cannot be modified. "
1601 "Consider updating the "
1602 "configuration with --writeconf\n",
1604 /* We don't know the names of all the
1609 name_create(&cname, mti->mti_svname, "-osc");
1615 CDEBUG(D_MGS, "%.3s param %s\n", ptr, ptr + 4);
1618 name_create(&logname, mti->mti_fsname, "-client");
1619 rc = mgs_wlp_lcfg(obd, fsdb, mti, logname, &bufs,
1621 name_destroy(&logname);
1623 /* osc params affect the MDT as well */
1624 if (mti->mti_flags & LDD_F_SV_TYPE_OST) {
1625 /* FIXME add to all MDT logs for CMD */
1626 name_create(&logname, mti->mti_fsname,
1628 if (!mgs_log_is_empty(obd, logname))
1629 rc = mgs_wlp_lcfg(obd, fsdb, mti,
1632 name_destroy(&logname);
1634 name_destroy(&cname);
1638 /* All mdt., ost. params in proc */
1639 if ((class_match_param(ptr, PARAM_MDT, NULL) == 0) ||
1640 (class_match_param(ptr, PARAM_OST, NULL) == 0)) {
1641 CDEBUG(D_MGS, "%.3s param %s\n", ptr, ptr + 4);
1642 if (mgs_log_is_empty(obd, mti->mti_svname)) {
1646 rc = mgs_wlp_lcfg(obd, fsdb, mti, mti->mti_svname,
1647 &bufs, mti->mti_svname, ptr);
1651 LCONSOLE_WARN("Ignoring unrecognized param '%s'\n", ptr);
1655 CERROR("err %d on param '%s\n", rc, ptr);
1670 int mgs_check_failnid(struct obd_device *obd, struct mgs_target_info *mti)
1672 /* Not implementing automatic failover nid addition at this time. */
1679 rc = mgs_find_or_make_fsdb(obd, fsname, &fsdb);
1683 if (mgs_log_is_empty(obd, mti->mti_svname))
1684 /* should never happen */
1687 CDEBUG(D_MGS, "Checking for new failnids for %s\n", mti->mti_svname);
1689 /* FIXME We can just check mti->params to see if we're already in
1690 the failover list. Modify mti->params for rewriting back at
1691 server_register_target(). */
1693 down(&fsdb->fsdb_sem);
1694 rc = mgs_write_log_add_failnid(obd, fsdb, mti);
1695 up(&fsdb->fsdb_sem);
1701 int mgs_write_log_target(struct obd_device *obd,
1702 struct mgs_target_info *mti)
1708 rc = mgs_find_or_make_fsdb(obd, mti->mti_fsname, &fsdb);
1710 CERROR("Can't get db for %s\n", mti->mti_fsname);
1714 down(&fsdb->fsdb_sem);
1716 /* set/check the new target index */
1717 rc = mgs_set_index(fsdb, mti);
1719 CERROR("Can't get index (%d)\n", rc);
1724 if (mti->mti_flags & LDD_F_UPGRADE14) {
1725 if (rc == EALREADY) {
1726 LCONSOLE_INFO("Found index %d for %s 1.4 log, "
1727 "upgrading\n", mti->mti_stripe_index,
1730 LCONSOLE_ERROR_MSG(0x149, "Failed to find %s in the old"
1731 " client log. Apparently it is not "
1732 "part of this filesystem, or the old"
1733 " log is wrong.\nUse 'writeconf' on "
1734 "the MDT to force log regeneration."
1735 "\n", mti->mti_svname);
1736 /* Not in client log? Upgrade anyhow...*/
1737 /* Argument against upgrading: reformat MDT,
1738 upgrade OST, then OST will start but will be SKIPped
1739 in client logs. Maybe error now is better. */
1740 /* RETURN(-EINVAL); */
1742 /* end COMPAT_146 */
1744 if (rc == EALREADY) {
1745 /* This might be a params update, or a
1746 local writeconf. (For "full" writeconf, the client
1747 log won't have an entry for this target, so we
1749 LCONSOLE_WARN("Found index %d for %s, updating log\n",
1750 mti->mti_stripe_index, mti->mti_svname);
1751 /* We would like to mark old log sections as invalid
1752 and add new log sections in the client and mdt logs.
1753 But if we add new sections, then live clients will
1754 get repeat setup instructions for already running
1755 osc's. So don't update the client/mdt logs. */
1756 mti->mti_flags &= ~LDD_F_UPDATE;
1760 if (mti->mti_flags &
1761 (LDD_F_VIRGIN | LDD_F_UPGRADE14 | LDD_F_WRITECONF)) {
1762 /* Generate a log from scratch */
1763 if (mti->mti_flags & LDD_F_SV_TYPE_MDT) {
1764 rc = mgs_write_log_mdt(obd, fsdb, mti);
1765 } else if (mti->mti_flags & LDD_F_SV_TYPE_OST) {
1766 rc = mgs_write_log_ost(obd, fsdb, mti);
1768 CERROR("Unknown target type %#x, can't create log for "
1769 "%s\n", mti->mti_flags, mti->mti_svname);
1772 CERROR("Can't write logs for %s (%d)\n",
1773 mti->mti_svname, rc);
1777 /* Just update the params from tunefs in mgs_write_log_params */
1778 CDEBUG(D_MGS, "Update params for %s\n", mti->mti_svname);
1779 mti->mti_flags |= LDD_F_PARAM;
1782 rc = mgs_write_log_params(obd, fsdb, mti);
1785 up(&fsdb->fsdb_sem);
1790 /* verify that we can handle the old config logs */
1791 int mgs_upgrade_sv_14(struct obd_device *obd, struct mgs_target_info *mti)
1797 /* Create ost log normally, as servers register. Servers
1798 register with their old uuids (from last_rcvd), so old
1799 (MDT and client) logs should work.
1800 - new MDT won't know about old OSTs, only the ones that have
1801 registered, so we need the old MDT log to get the LOV right
1802 in order for old clients to work.
1803 - Old clients connect to the MDT, not the MGS, for their logs, and
1804 will therefore receive the old client log from the MDT /LOGS dir.
1805 - Old clients can continue to use and connect to old or new OSTs
1806 - New clients will contact the MGS for their log
1809 LCONSOLE_INFO("upgrading server %s from pre-1.6\n", mti->mti_svname);
1810 server_mti_print("upgrade", mti);
1812 rc = mgs_find_or_make_fsdb(obd, mti->mti_fsname, &fsdb);
1816 if (fsdb->fsdb_flags & FSDB_LOG_EMPTY) {
1817 LCONSOLE_ERROR_MSG(0x14a, "The old client log %s-client is "
1818 "missing. Was tunefs.lustre successful?\n",
1823 if (fsdb->fsdb_gen == 0) {
1824 /* There were no markers in the client log, meaning we have
1825 not updated the logs for this fs */
1826 CDEBUG(D_MGS, "found old, unupdated client log\n");
1829 if (mti->mti_flags & LDD_F_SV_TYPE_MDT) {
1830 if (mgs_log_is_empty(obd, mti->mti_svname)) {
1831 LCONSOLE_ERROR_MSG(0x14b, "The old MDT log %s is "
1832 "missing. Was tunefs.lustre "
1838 /* We're starting with an old uuid. Assume old name for lov
1839 as well since the lov entry already exists in the log. */
1840 CDEBUG(D_MGS, "old mds uuid %s\n", mti->mti_uuid);
1841 if (strncmp(mti->mti_uuid, fsdb->fsdb_mdtlov + 4,
1842 strlen(fsdb->fsdb_mdtlov) - 4) != 0) {
1843 CERROR("old mds uuid %s doesn't match log %s (%s)\n",
1844 mti->mti_uuid, fsdb->fsdb_mdtlov,
1845 fsdb->fsdb_mdtlov + 4);
1850 if (!(fsdb->fsdb_flags & FSDB_OLDLOG14)) {
1851 LCONSOLE_ERROR_MSG(0x14c, "%s-client is supposedly an old log, "
1852 "but no old LOV or MDT was found. Consider "
1853 "updating the configuration with "
1854 "--writeconf.\n", mti->mti_fsname);
1859 /* end COMPAT_146 */
1861 int mgs_erase_log(struct obd_device *obd, char *name)
1863 struct lvfs_run_ctxt saved;
1864 struct llog_ctxt *ctxt;
1865 struct llog_handle *llh;
1868 ctxt = llog_get_context(obd, LLOG_CONFIG_ORIG_CTXT);
1869 LASSERT(ctxt != NULL);
1871 push_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
1872 rc = llog_create(ctxt, &llh, NULL, name);
1874 llog_init_handle(llh, LLOG_F_IS_PLAIN, NULL);
1875 rc = llog_destroy(llh);
1876 llog_free_handle(llh);
1878 pop_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
1879 llog_ctxt_put(ctxt);
1882 CERROR("failed to clear log %s: %d\n", name, rc);
1887 /* erase all logs for the given fs */
1888 int mgs_erase_logs(struct obd_device *obd, char *fsname)
1890 struct mgs_obd *mgs = &obd->u.mgs;
1891 static struct fs_db *fsdb;
1892 struct list_head dentry_list;
1893 struct l_linux_dirent *dirent, *n;
1894 int rc, len = strlen(fsname);
1897 /* Find all the logs in the CONFIGS directory */
1898 rc = class_dentry_readdir(obd, mgs->mgs_configs_dir,
1899 mgs->mgs_vfsmnt, &dentry_list);
1901 CERROR("Can't read %s dir\n", MOUNT_CONFIGS_DIR);
1905 down(&mgs->mgs_sem);
1907 /* Delete the fs db */
1908 fsdb = mgs_find_fsdb(obd, fsname);
1910 mgs_free_fsdb(obd, fsdb);
1912 list_for_each_entry_safe(dirent, n, &dentry_list, lld_list) {
1913 list_del(&dirent->lld_list);
1914 if (strncmp(fsname, dirent->lld_name, len) == 0) {
1915 CDEBUG(D_MGS, "Removing log %s\n", dirent->lld_name);
1916 mgs_erase_log(obd, dirent->lld_name);
1918 OBD_FREE(dirent, sizeof(*dirent));
1926 /* from llog_swab */
1927 static void print_lustre_cfg(struct lustre_cfg *lcfg)
1932 CDEBUG(D_MGS, "lustre_cfg: %p\n", lcfg);
1933 CDEBUG(D_MGS, "\tlcfg->lcfg_version: %#x\n", lcfg->lcfg_version);
1935 CDEBUG(D_MGS, "\tlcfg->lcfg_command: %#x\n", lcfg->lcfg_command);
1936 CDEBUG(D_MGS, "\tlcfg->lcfg_num: %#x\n", lcfg->lcfg_num);
1937 CDEBUG(D_MGS, "\tlcfg->lcfg_flags: %#x\n", lcfg->lcfg_flags);
1938 CDEBUG(D_MGS, "\tlcfg->lcfg_nid: %s\n", libcfs_nid2str(lcfg->lcfg_nid));
1940 CDEBUG(D_MGS, "\tlcfg->lcfg_bufcount: %d\n", lcfg->lcfg_bufcount);
1941 if (lcfg->lcfg_bufcount < LUSTRE_CFG_MAX_BUFCOUNT)
1942 for (i = 0; i < lcfg->lcfg_bufcount; i++) {
1943 CDEBUG(D_MGS, "\tlcfg->lcfg_buflens[%d]: %d %s\n",
1944 i, lcfg->lcfg_buflens[i],
1945 lustre_cfg_string(lcfg, i));
1950 /* Set a permanent (config log) param for a target or fs */
1951 int mgs_setparam(struct obd_device *obd, struct lustre_cfg *lcfg, char *fsname)
1954 struct mgs_target_info *mti;
1955 char *devname, *param;
1961 print_lustre_cfg(lcfg);
1963 /* lustre, lustre-mdtlov, lustre-client, lustre-MDT0000 */
1964 devname = lustre_cfg_string(lcfg, 0);
1965 param = lustre_cfg_string(lcfg, 1);
1967 /* Assume device name embedded in param:
1968 lustre-OST0000.osc.max_dirty_mb=32 */
1969 ptr = strchr(param, '.');
1977 LCONSOLE_ERROR_MSG(0x14d, "No target specified: %s\n", param);
1981 /* Extract fsname */
1982 ptr = strrchr(devname, '-');
1983 memset(fsname, 0, MTI_NAME_MAXLEN);
1984 if (ptr && (server_name2index(ptr, &index, NULL) >= 0)) {
1985 /* param related to llite isn't allowed to set by OST or MDT */
1986 if (strncmp(param, PARAM_LLITE, sizeof(PARAM_LLITE)) == 0)
1989 strncpy(fsname, devname, ptr - devname);
1991 /* assume devname is the fsname */
1992 strncpy(fsname, devname, MTI_NAME_MAXLEN);
1994 fsname[MTI_NAME_MAXLEN - 1] = 0;
1995 CDEBUG(D_MGS, "setparam on fs %s device %s\n", fsname, devname);
1997 rc = mgs_find_or_make_fsdb(obd, fsname, &fsdb);
2000 if (fsdb->fsdb_flags & FSDB_LOG_EMPTY) {
2001 CERROR("No filesystem targets for %s. cfg_device from lctl "
2002 "is '%s'\n", fsname, devname);
2003 mgs_free_fsdb(obd, fsdb);
2007 /* Create a fake mti to hold everything */
2010 GOTO(out, rc = -ENOMEM);
2011 strncpy(mti->mti_fsname, fsname, MTI_NAME_MAXLEN);
2012 strncpy(mti->mti_svname, devname, MTI_NAME_MAXLEN);
2013 strncpy(mti->mti_params, param, sizeof(mti->mti_params));
2014 rc = server_name2index(mti->mti_svname, &mti->mti_stripe_index, &tmp);
2016 /* Not a valid server; may be only fsname */
2019 /* Strip -osc or -mdc suffix from svname */
2020 if (server_make_name(rc, mti->mti_stripe_index, mti->mti_fsname,
2022 GOTO(out, rc = -EINVAL);
2024 mti->mti_flags = rc | LDD_F_PARAM;
2026 down(&fsdb->fsdb_sem);
2027 rc = mgs_write_log_params(obd, fsdb, mti);
2028 up(&fsdb->fsdb_sem);
2036 static int mgs_write_log_pool(struct obd_device *obd, char *logname, struct fs_db *fsdb,
2038 enum lcfg_command_type cmd,
2039 char *poolname, char *fsname,
2040 char *ostname, char *comment)
2042 struct llog_handle *llh = NULL;
2045 rc = record_start_log(obd, &llh, logname);
2048 rc = record_marker(obd, llh, fsdb, CM_START, lovname, comment);
2049 record_base(obd, llh, lovname, 0, cmd, poolname, fsname, ostname, 0);
2050 rc = record_marker(obd, llh, fsdb, CM_END, lovname, comment);
2051 rc = record_end_log(obd, &llh);
2056 int mgs_pool_cmd(struct obd_device *obd, enum lcfg_command_type cmd,
2057 char *fsname, char *poolname, char *ostname)
2063 char *label, *canceled_label = NULL;
2065 struct mgs_target_info *mti;
2069 rc = mgs_find_or_make_fsdb(obd, fsname, &fsdb);
2071 CERROR("Can't get db for %s\n", fsname);
2074 if (fsdb->fsdb_flags & FSDB_LOG_EMPTY) {
2075 CERROR("%s is not defined\n", fsname);
2076 mgs_free_fsdb(obd, fsdb);
2080 label_sz = 10 + strlen(fsname) + strlen(poolname);
2082 /* check if ostname match fsname */
2083 if (ostname != NULL) {
2086 ptr = strrchr(ostname, '-');
2087 if ((ptr == NULL) ||
2088 (strncmp(fsname, ostname, ptr-ostname) != 0))
2090 label_sz += strlen(ostname);
2093 OBD_ALLOC(label, label_sz);
2098 case LCFG_POOL_NEW: {
2100 "new %s.%s", fsname, poolname);
2103 case LCFG_POOL_ADD: {
2105 "add %s.%s.%s", fsname, poolname, ostname);
2108 case LCFG_POOL_REM: {
2109 OBD_ALLOC(canceled_label, label_sz);
2110 if (canceled_label == NULL)
2113 "rem %s.%s.%s", fsname, poolname, ostname);
2114 sprintf(canceled_label,
2115 "add %s.%s.%s", fsname, poolname, ostname);
2118 case LCFG_POOL_DEL: {
2119 OBD_ALLOC(canceled_label, label_sz);
2120 if (canceled_label == NULL)
2123 "del %s.%s", fsname, poolname);
2124 sprintf(canceled_label,
2125 "new %s.%s", fsname, poolname);
2133 down(&fsdb->fsdb_sem);
2135 sprintf(mdt_index, "-MDT%04x", 0);
2136 name_create(&logname, fsname, mdt_index);
2137 name_create(&lovname, fsdb->fsdb_mdtlov, "");
2140 if (canceled_label != NULL) {
2141 OBD_ALLOC(mti, sizeof(*mti));
2143 strcpy(mti->mti_svname, "lov pool");
2144 mgs_modify(obd, fsdb, mti, logname, lovname,
2145 canceled_label, CM_SKIP);
2149 mgs_write_log_pool(obd, logname, fsdb, lovname,
2150 cmd, fsname, poolname, ostname, label);
2151 name_destroy(&logname);
2153 name_create(&logname, fsname, "-client");
2154 if (canceled_label != NULL) {
2155 mgs_modify(obd, fsdb, mti, logname, lovname,
2156 canceled_label, CM_SKIP);
2158 mgs_write_log_pool(obd, logname, fsdb, fsdb->fsdb_clilov,
2159 cmd, fsname, poolname, ostname, label);
2160 name_destroy(&logname);
2161 name_destroy(&lovname);
2163 up(&fsdb->fsdb_sem);
2165 OBD_FREE(label, label_sz);
2166 if (canceled_label != NULL)
2167 OBD_FREE(canceled_label, label_sz);
2170 OBD_FREE(mti, sizeof(*mti));
2176 /******************** unused *********************/
2177 static int mgs_backup_llog(struct obd_device *obd, char* fsname)
2179 struct file *filp, *bak_filp;
2180 struct lvfs_run_ctxt saved;
2181 char *logname, *buf;
2182 loff_t soff = 0 , doff = 0;
2183 int count = 4096, len;
2186 OBD_ALLOC(logname, PATH_MAX);
2187 if (logname == NULL)
2190 OBD_ALLOC(buf, count);
2192 GOTO(out , rc = -ENOMEM);
2194 len = snprintf(logname, PATH_MAX, "%s/%s.bak",
2195 MOUNT_CONFIGS_DIR, fsname);
2197 if (len >= PATH_MAX - 1) {
2198 GOTO(out, -ENAMETOOLONG);
2201 push_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
2203 bak_filp = l_filp_open(logname, O_RDWR|O_CREAT|O_TRUNC, 0660);
2204 if (IS_ERR(bak_filp)) {
2205 rc = PTR_ERR(bak_filp);
2206 CERROR("backup logfile open %s: %d\n", logname, rc);
2209 sprintf(logname, "%s/%s", MOUNT_CONFIGS_DIR, fsname);
2210 filp = l_filp_open(logname, O_RDONLY, 0);
2213 CERROR("logfile open %s: %d\n", logname, rc);
2217 while ((rc = lustre_fread(filp, buf, count, &soff)) > 0) {
2218 rc = lustre_fwrite(bak_filp, buf, count, &doff);
2222 filp_close(filp, 0);
2224 filp_close(bak_filp, 0);
2226 pop_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
2229 OBD_FREE(buf, count);
2230 OBD_FREE(logname, PATH_MAX);