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){
73 /* see mds_cleanup_pending */
74 struct lvfs_run_ctxt saved;
76 struct dentry *dentry;
81 push_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
84 GOTO(out_pop, rc = PTR_ERR(dentry));
88 GOTO(out_pop, rc = PTR_ERR(mnt));
91 file = dentry_open(dentry, mnt, O_RDONLY);
93 /* dentry_open_it() drops the dentry, mnt refs */
94 GOTO(out_pop, rc = PTR_ERR(file));
96 INIT_LIST_HEAD(dentry_list);
97 rc = l_readdir(file, dentry_list);
99 /* filp_close->fput() drops the dentry, mnt refs */
102 pop_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
106 /******************** DB functions *********************/
108 static inline int name_create(char **newname, char *prefix, char *suffix)
111 OBD_ALLOC(*newname, strlen(prefix) + strlen(suffix) + 1);
114 sprintf(*newname, "%s%s", prefix, suffix);
118 static inline void name_destroy(char **name)
121 OBD_FREE(*name, strlen(*name) + 1);
125 /* from the (client) config log, figure out:
126 1. which ost's/mdt's are configured (by index)
127 2. what the last config step is
128 3. COMPAT_146 lov name
129 4. COMPAT_146 mdt lov name
130 5. COMPAT_146 mdc name
132 /* It might be better to have a separate db file, instead of parsing the info
133 out of the client log. This is slow and potentially error-prone. */
134 static int mgs_fsdb_handler(struct llog_handle *llh, struct llog_rec_hdr *rec,
137 struct fs_db *fsdb = (struct fs_db *)data;
138 int cfg_len = rec->lrh_len;
139 char *cfg_buf = (char*) (rec + 1);
140 struct lustre_cfg *lcfg;
145 if (rec->lrh_type != OBD_CFG_REC) {
146 CERROR("unhandled lrh_type: %#x\n", rec->lrh_type);
150 rc = lustre_cfg_sanity_check(cfg_buf, cfg_len);
152 CERROR("Insane cfg\n");
156 lcfg = (struct lustre_cfg *)cfg_buf;
158 CDEBUG(D_INFO, "cmd %x %s %s\n", lcfg->lcfg_command,
159 lustre_cfg_string(lcfg, 0), lustre_cfg_string(lcfg, 1));
161 /* Figure out ost indicies */
162 /* lov_modify_tgts add 0:lov1 1:ost1_UUID 2(index):0 3(gen):1 */
163 if (lcfg->lcfg_command == LCFG_LOV_ADD_OBD ||
164 lcfg->lcfg_command == LCFG_LOV_DEL_OBD) {
165 index = simple_strtoul(lustre_cfg_string(lcfg, 2),
167 CDEBUG(D_MGS, "OST index for %s is %u (%s)\n",
168 lustre_cfg_string(lcfg, 1), index,
169 lustre_cfg_string(lcfg, 2));
170 set_bit(index, fsdb->fsdb_ost_index_map);
173 /* Figure out mdt indicies */
174 /* attach 0:MDC_uml1_mdsA_MNT_client 1:mdc 2:1d834_MNT_client_03f */
175 if ((lcfg->lcfg_command == LCFG_ATTACH) &&
176 (strcmp(lustre_cfg_string(lcfg, 1), LUSTRE_MDC_NAME) == 0)) {
177 rc = server_name2index(lustre_cfg_string(lcfg, 0),
179 if (rc != LDD_F_SV_TYPE_MDT) {
180 CWARN("Unparsable MDC name %s, assuming index 0\n",
181 lustre_cfg_string(lcfg, 0));
185 CDEBUG(D_MGS, "MDT index is %u\n", index);
186 set_bit(index, fsdb->fsdb_mdt_index_map);
190 /* figure out the old LOV name. fsdb_gen = 0 means old log */
191 /* #01 L attach 0:lov_mdsA 1:lov 2:cdbe9_lov_mdsA_dc8cf7f3bb */
192 if ((fsdb->fsdb_gen == 0) && (lcfg->lcfg_command == LCFG_ATTACH) &&
193 (strcmp(lustre_cfg_string(lcfg, 1), LUSTRE_LOV_NAME) == 0)) {
194 fsdb->fsdb_flags |= FSDB_OLDLOG14;
195 name_destroy(&fsdb->fsdb_clilov);
196 rc = name_create(&fsdb->fsdb_clilov,
197 lustre_cfg_string(lcfg, 0), "");
200 CDEBUG(D_MGS, "client lov name is %s\n", fsdb->fsdb_clilov);
203 /* figure out the old MDT lov name from the MDT uuid */
204 if ((fsdb->fsdb_gen == 0) && (lcfg->lcfg_command == LCFG_SETUP) &&
205 (strncmp(lustre_cfg_string(lcfg, 0), "MDC_", 4) == 0)) {
207 fsdb->fsdb_flags |= FSDB_OLDLOG14;
208 ptr = strstr(lustre_cfg_string(lcfg, 1), "_UUID");
210 CERROR("Can't parse MDT uuid %s\n",
211 lustre_cfg_string(lcfg, 1));
215 name_destroy(&fsdb->fsdb_mdtlov);
216 rc = name_create(&fsdb->fsdb_mdtlov,
217 "lov_", lustre_cfg_string(lcfg, 1));
220 name_destroy(&fsdb->fsdb_mdc);
221 rc = name_create(&fsdb->fsdb_mdc,
222 lustre_cfg_string(lcfg, 0), "");
225 CDEBUG(D_MGS, "MDT lov name is %s\n", fsdb->fsdb_mdtlov);
229 /* Keep track of the latest marker step */
230 if (lcfg->lcfg_command == LCFG_MARKER) {
231 struct cfg_marker *marker;
232 marker = lustre_cfg_buf(lcfg, 1);
233 fsdb->fsdb_gen = max(fsdb->fsdb_gen, marker->cm_step);
239 static int mgs_get_fsdb_from_llog(struct obd_device *obd, struct fs_db *fsdb)
242 struct llog_handle *loghandle;
243 struct lvfs_run_ctxt saved;
244 struct llog_ctxt *ctxt;
248 ctxt = llog_get_context(obd, LLOG_CONFIG_ORIG_CTXT);
249 LASSERT(ctxt != NULL);
250 name_create(&logname, fsdb->fsdb_name, "-client");
251 down(&fsdb->fsdb_sem);
252 push_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
253 rc = llog_create(ctxt, &loghandle, NULL, logname);
257 rc = llog_init_handle(loghandle, LLOG_F_IS_PLAIN, NULL);
261 if (llog_get_size(loghandle) <= 1)
262 fsdb->fsdb_flags |= FSDB_LOG_EMPTY;
264 rc = llog_process(loghandle, mgs_fsdb_handler, (void *)fsdb, NULL);
265 CDEBUG(D_INFO, "get_db = %d\n", rc);
267 rc2 = llog_close(loghandle);
272 pop_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
274 name_destroy(&logname);
279 static struct fs_db *mgs_find_fsdb(struct obd_device *obd, char *fsname)
281 struct mgs_obd *mgs = &obd->u.mgs;
283 struct list_head *tmp;
285 list_for_each(tmp, &mgs->mgs_fs_db_list) {
286 fsdb = list_entry(tmp, struct fs_db, fsdb_list);
287 if (strcmp(fsdb->fsdb_name, fsname) == 0)
293 /* caller must hold the mgs->mgs_fs_db_lock */
294 static struct fs_db *mgs_new_fsdb(struct obd_device *obd, char *fsname)
296 struct mgs_obd *mgs = &obd->u.mgs;
305 OBD_ALLOC(fsdb->fsdb_ost_index_map, INDEX_MAP_SIZE);
306 OBD_ALLOC(fsdb->fsdb_mdt_index_map, INDEX_MAP_SIZE);
307 if (!fsdb->fsdb_ost_index_map || !fsdb->fsdb_mdt_index_map) {
308 CERROR("No memory for index maps\n");
312 strncpy(fsdb->fsdb_name, fsname, sizeof(fsdb->fsdb_name));
313 fsdb->fsdb_name[sizeof(fsdb->fsdb_name) - 1] = 0;
314 rc = name_create(&fsdb->fsdb_mdtlov, fsname, "-mdtlov");
317 rc = name_create(&fsdb->fsdb_clilov, fsname, "-clilov");
321 sema_init(&fsdb->fsdb_sem, 1);
322 list_add(&fsdb->fsdb_list, &mgs->mgs_fs_db_list);
323 lproc_mgs_add_live(obd, fsdb);
327 if (fsdb->fsdb_ost_index_map)
328 OBD_FREE(fsdb->fsdb_ost_index_map, INDEX_MAP_SIZE);
329 if (fsdb->fsdb_mdt_index_map)
330 OBD_FREE(fsdb->fsdb_mdt_index_map, INDEX_MAP_SIZE);
331 name_destroy(&fsdb->fsdb_clilov);
332 name_destroy(&fsdb->fsdb_mdtlov);
337 static void mgs_free_fsdb(struct obd_device *obd, struct fs_db *fsdb)
339 /* wait for anyone with the sem */
340 down(&fsdb->fsdb_sem);
341 lproc_mgs_del_live(obd, fsdb);
342 list_del(&fsdb->fsdb_list);
343 OBD_FREE(fsdb->fsdb_ost_index_map, INDEX_MAP_SIZE);
344 OBD_FREE(fsdb->fsdb_mdt_index_map, INDEX_MAP_SIZE);
345 name_destroy(&fsdb->fsdb_clilov);
346 name_destroy(&fsdb->fsdb_mdtlov);
347 name_destroy(&fsdb->fsdb_mdc);
351 int mgs_init_fsdb_list(struct obd_device *obd)
353 struct mgs_obd *mgs = &obd->u.mgs;
354 INIT_LIST_HEAD(&mgs->mgs_fs_db_list);
358 int mgs_cleanup_fsdb_list(struct obd_device *obd)
360 struct mgs_obd *mgs = &obd->u.mgs;
362 struct list_head *tmp, *tmp2;
364 list_for_each_safe(tmp, tmp2, &mgs->mgs_fs_db_list) {
365 fsdb = list_entry(tmp, struct fs_db, fsdb_list);
366 mgs_free_fsdb(obd, fsdb);
372 static int mgs_find_or_make_fsdb(struct obd_device *obd, char *name,
375 struct mgs_obd *mgs = &obd->u.mgs;
380 fsdb = mgs_find_fsdb(obd, name);
387 CDEBUG(D_MGS, "Creating new db\n");
388 fsdb = mgs_new_fsdb(obd, name);
393 /* populate the db from the client llog */
394 rc = mgs_get_fsdb_from_llog(obd, fsdb);
396 CERROR("Can't get db from client log %d\n", rc);
397 mgs_free_fsdb(obd, fsdb);
408 -1= empty client log */
409 int mgs_check_index(struct obd_device *obd, struct mgs_target_info *mti)
416 LASSERT(!(mti->mti_flags & LDD_F_NEED_INDEX));
418 rc = mgs_find_or_make_fsdb(obd, mti->mti_fsname, &fsdb);
420 CERROR("Can't get db for %s\n", mti->mti_fsname);
424 if (fsdb->fsdb_flags & FSDB_LOG_EMPTY)
427 if (mti->mti_flags & LDD_F_SV_TYPE_OST)
428 imap = fsdb->fsdb_ost_index_map;
429 else if (mti->mti_flags & LDD_F_SV_TYPE_MDT)
430 imap = fsdb->fsdb_mdt_index_map;
434 if (test_bit(mti->mti_stripe_index, imap))
439 static __inline__ int next_index(void *index_map, int map_len)
442 for (i = 0; i < map_len * 8; i++)
443 if (!test_bit(i, index_map)) {
446 CERROR("max index %d exceeded.\n", i);
451 0 newly marked as in use
453 +EALREADY for update of an old index */
454 int mgs_set_index(struct obd_device *obd, struct mgs_target_info *mti)
461 rc = mgs_find_or_make_fsdb(obd, mti->mti_fsname, &fsdb);
463 CERROR("Can't get db for %s\n", mti->mti_fsname);
467 if (mti->mti_flags & LDD_F_SV_TYPE_OST)
468 imap = fsdb->fsdb_ost_index_map;
469 else if (mti->mti_flags & LDD_F_SV_TYPE_MDT)
470 imap = fsdb->fsdb_mdt_index_map;
474 if (mti->mti_flags & LDD_F_NEED_INDEX) {
475 rc = next_index(imap, INDEX_MAP_SIZE);
478 mti->mti_stripe_index = rc;
481 /* Remove after CMD */
482 if ((mti->mti_flags & LDD_F_SV_TYPE_MDT) &&
483 (mti->mti_stripe_index > 0)) {
484 LCONSOLE_ERROR_MSG(0x13e, "MDT index must = 0 (until Clustered "
485 "MetaData feature is ready.)\n");
486 mti->mti_stripe_index = 0;
489 if (mti->mti_stripe_index >= INDEX_MAP_SIZE * 8) {
490 LCONSOLE_ERROR_MSG(0x13f, "Server %s requested index %d, but the"
491 "max index is %d.\n",
492 mti->mti_svname, mti->mti_stripe_index,
497 if (test_bit(mti->mti_stripe_index, imap)) {
498 if ((mti->mti_flags & LDD_F_VIRGIN) &&
499 !(mti->mti_flags & LDD_F_WRITECONF)) {
500 LCONSOLE_ERROR_MSG(0x140, "Server %s requested index "
501 "%d, but that index is already in "
502 "use. Use --writeconf to force\n",
504 mti->mti_stripe_index);
507 CDEBUG(D_MGS, "Server %s updating index %d\n",
508 mti->mti_svname, mti->mti_stripe_index);
513 set_bit(mti->mti_stripe_index, imap);
514 fsdb->fsdb_flags &= ~FSDB_LOG_EMPTY;
515 server_make_name(mti->mti_flags, mti->mti_stripe_index,
516 mti->mti_fsname, mti->mti_svname);
518 CDEBUG(D_MGS, "Set index for %s to %d\n", mti->mti_svname,
519 mti->mti_stripe_index);
524 struct mgs_modify_lookup {
525 struct cfg_marker mml_marker;
529 static int mgs_modify_handler(struct llog_handle *llh, struct llog_rec_hdr *rec,
532 struct mgs_modify_lookup *mml = (struct mgs_modify_lookup *)data;
533 struct cfg_marker *marker;
534 struct lustre_cfg *lcfg = (struct lustre_cfg *)(rec + 1);
535 int cfg_len = rec->lrh_len - sizeof(struct llog_rec_hdr) -
536 sizeof(struct llog_rec_tail);
540 if (rec->lrh_type != OBD_CFG_REC) {
541 CERROR("unhandled lrh_type: %#x\n", rec->lrh_type);
545 rc = lustre_cfg_sanity_check(lcfg, cfg_len);
547 CERROR("Insane cfg\n");
551 /* We only care about markers */
552 if (lcfg->lcfg_command != LCFG_MARKER)
555 marker = lustre_cfg_buf(lcfg, 1);
556 if ((strcmp(mml->mml_marker.cm_comment, marker->cm_comment) == 0) &&
557 (strcmp(mml->mml_marker.cm_tgtname, marker->cm_tgtname) == 0) &&
558 !(marker->cm_flags & CM_SKIP)) {
559 /* Found a non-skipped marker match */
560 CDEBUG(D_MGS, "Changing rec %u marker %d %x->%x: %s %s\n",
561 rec->lrh_index, marker->cm_step,
562 marker->cm_flags, mml->mml_marker.cm_flags,
563 marker->cm_tgtname, marker->cm_comment);
564 /* Overwrite the old marker llog entry */
565 marker->cm_flags &= ~CM_EXCLUDE; /* in case we're unexcluding */
566 marker->cm_flags |= mml->mml_marker.cm_flags;
567 marker->cm_canceltime = mml->mml_marker.cm_canceltime;
568 /* Header and tail are added back to lrh_len in
569 llog_lvfs_write_rec */
570 rec->lrh_len = cfg_len;
571 rc = llog_write_rec(llh, rec, NULL, 0, (void *)lcfg,
580 /* Modify an existing config log record (for CM_SKIP or CM_EXCLUDE) */
581 static int mgs_modify(struct obd_device *obd, struct fs_db *fsdb,
582 struct mgs_target_info *mti, char *logname,
583 char *devname, char *comment, int flags)
585 struct llog_handle *loghandle;
586 struct lvfs_run_ctxt saved;
587 struct llog_ctxt *ctxt;
588 struct mgs_modify_lookup *mml;
592 CDEBUG(D_MGS, "modify %s/%s/%s\n", logname, devname, comment);
594 push_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
596 ctxt = llog_get_context(obd, LLOG_CONFIG_ORIG_CTXT);
597 LASSERT(ctxt != NULL);
598 rc = llog_create(ctxt, &loghandle, NULL, logname);
602 rc = llog_init_handle(loghandle, LLOG_F_IS_PLAIN, NULL);
606 if (llog_get_size(loghandle) <= 1)
607 GOTO(out_close, rc = 0);
611 GOTO(out_close, rc = -ENOMEM);
612 strcpy(mml->mml_marker.cm_comment, comment);
613 strcpy(mml->mml_marker.cm_tgtname, devname);
614 /* Modify mostly means cancel */
615 mml->mml_marker.cm_flags = flags;
616 mml->mml_marker.cm_canceltime = flags ? cfs_time_current_sec() : 0;
617 mml->mml_modified = 0;
618 rc = llog_process(loghandle, mgs_modify_handler, (void *)mml, NULL);
619 if (!rc && !mml->mml_modified)
624 rc2 = llog_close(loghandle);
629 pop_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
630 if (rc && rc != -ENODEV)
631 CERROR("modify %s/%s failed %d\n",
632 mti->mti_svname, comment, rc);
638 /******************** config log recording functions *********************/
640 static int record_lcfg(struct obd_device *obd, struct llog_handle *llh,
641 struct lustre_cfg *lcfg)
643 struct lvfs_run_ctxt saved;
644 struct llog_rec_hdr rec;
650 LASSERT(llh->lgh_ctxt);
652 buflen = lustre_cfg_len(lcfg->lcfg_bufcount,
654 rec.lrh_len = llog_data_len(buflen);
655 rec.lrh_type = OBD_CFG_REC;
656 push_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
657 /* idx = -1 means append */
658 rc = llog_write_rec(llh, &rec, NULL, 0, (void *)lcfg, -1);
659 pop_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
661 CERROR("failed %d\n", rc);
665 static int record_base(struct obd_device *obd, struct llog_handle *llh,
666 char *cfgname, lnet_nid_t nid, int cmd,
667 char *s1, char *s2, char *s3, char *s4)
669 struct lustre_cfg_bufs bufs;
670 struct lustre_cfg *lcfg;
673 CDEBUG(D_MGS, "lcfg %s %#x %s %s %s %s\n", cfgname,
674 cmd, s1, s2, s3, s4);
676 lustre_cfg_bufs_reset(&bufs, cfgname);
678 lustre_cfg_bufs_set_string(&bufs, 1, s1);
680 lustre_cfg_bufs_set_string(&bufs, 2, s2);
682 lustre_cfg_bufs_set_string(&bufs, 3, s3);
684 lustre_cfg_bufs_set_string(&bufs, 4, s4);
686 lcfg = lustre_cfg_new(cmd, &bufs);
689 lcfg->lcfg_nid = nid;
691 rc = record_lcfg(obd, llh, lcfg);
693 lustre_cfg_free(lcfg);
696 CERROR("error %d: lcfg %s %#x %s %s %s %s\n", rc, cfgname,
697 cmd, s1, s2, s3, s4);
703 static inline int record_add_uuid(struct obd_device *obd,
704 struct llog_handle *llh,
705 __u64 nid, char *uuid)
707 return record_base(obd,llh,NULL,nid,LCFG_ADD_UUID,uuid,0,0,0);
711 static inline int record_add_conn(struct obd_device *obd,
712 struct llog_handle *llh,
716 return record_base(obd,llh,devname,0,LCFG_ADD_CONN,uuid,0,0,0);
719 static inline int record_attach(struct obd_device *obd, struct llog_handle *llh,
720 char *devname, char *type, char *uuid)
722 return record_base(obd,llh,devname,0,LCFG_ATTACH,type,uuid,0,0);
725 static inline int record_setup(struct obd_device *obd, struct llog_handle *llh,
727 char *s1, char *s2, char *s3, char *s4)
729 return record_base(obd,llh,devname,0,LCFG_SETUP,s1,s2,s3,s4);
732 static int record_lov_setup(struct obd_device *obd, struct llog_handle *llh,
733 char *devname, struct lov_desc *desc)
735 struct lustre_cfg_bufs bufs;
736 struct lustre_cfg *lcfg;
739 lustre_cfg_bufs_reset(&bufs, devname);
740 lustre_cfg_bufs_set(&bufs, 1, desc, sizeof(*desc));
741 lcfg = lustre_cfg_new(LCFG_SETUP, &bufs);
744 rc = record_lcfg(obd, llh, lcfg);
746 lustre_cfg_free(lcfg);
750 static inline int record_lov_add(struct obd_device *obd,
751 struct llog_handle *llh,
752 char *lov_name, char *ost_uuid,
753 char *index, char *gen)
755 return record_base(obd,llh,lov_name,0,LCFG_LOV_ADD_OBD,
756 ost_uuid,index,gen,0);
759 static inline int record_mount_opt(struct obd_device *obd,
760 struct llog_handle *llh,
761 char *profile, char *lov_name,
764 return record_base(obd,llh,NULL,0,LCFG_MOUNTOPT,
765 profile,lov_name,mdc_name,0);
768 static int record_marker(struct obd_device *obd, struct llog_handle *llh,
769 struct fs_db *fsdb, __u32 flags,
770 char *tgtname, char *comment)
772 struct cfg_marker marker;
773 struct lustre_cfg_bufs bufs;
774 struct lustre_cfg *lcfg;
777 if (flags & CM_START)
779 marker.cm_step = fsdb->fsdb_gen;
780 marker.cm_flags = flags;
781 marker.cm_vers = LUSTRE_VERSION_CODE;
782 strncpy(marker.cm_tgtname, tgtname, sizeof(marker.cm_tgtname));
783 strncpy(marker.cm_comment, comment, sizeof(marker.cm_comment));
784 marker.cm_createtime = cfs_time_current_sec();
785 marker.cm_canceltime = 0;
786 lustre_cfg_bufs_reset(&bufs, NULL);
787 lustre_cfg_bufs_set(&bufs, 1, &marker, sizeof(marker));
788 lcfg = lustre_cfg_new(LCFG_MARKER, &bufs);
791 rc = record_lcfg(obd, llh, lcfg);
793 lustre_cfg_free(lcfg);
797 static int record_start_log(struct obd_device *obd,
798 struct llog_handle **llh, char *name)
800 static struct obd_uuid cfg_uuid = { .uuid = "config_uuid" };
801 struct lvfs_run_ctxt saved;
802 struct llog_ctxt *ctxt;
806 GOTO(out, rc = -EBUSY);
808 ctxt = llog_get_context(obd, LLOG_CONFIG_ORIG_CTXT);
810 GOTO(out, rc = -ENODEV);
812 push_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
813 rc = llog_create(ctxt, llh, NULL, name);
815 llog_init_handle(*llh, LLOG_F_IS_PLAIN, &cfg_uuid);
819 pop_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
824 CERROR("Can't start log %s: %d\n", name, rc);
829 static int record_end_log(struct obd_device *obd, struct llog_handle **llh)
831 struct lvfs_run_ctxt saved;
834 push_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
836 rc = llog_close(*llh);
839 pop_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
843 static int mgs_log_is_empty(struct obd_device *obd, char *name)
845 struct lvfs_run_ctxt saved;
846 struct llog_handle *llh;
847 struct llog_ctxt *ctxt;
850 ctxt = llog_get_context(obd, LLOG_CONFIG_ORIG_CTXT);
851 LASSERT(ctxt != NULL);
852 push_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
853 rc = llog_create(ctxt, &llh, NULL, name);
855 llog_init_handle(llh, LLOG_F_IS_PLAIN, NULL);
856 rc = llog_get_size(llh);
859 pop_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
861 /* header is record 1 */
865 /******************** config "macros" *********************/
867 /* write an lcfg directly into a log (with markers) */
868 static int mgs_write_log_direct(struct obd_device *obd, struct fs_db *fsdb,
869 char *logname, struct lustre_cfg *lcfg,
870 char *devname, char *comment)
872 struct llog_handle *llh = NULL;
879 rc = record_start_log(obd, &llh, logname);
883 /* FIXME These should be a single journal transaction */
884 rc = record_marker(obd, llh, fsdb, CM_START, devname, comment);
886 rc = record_lcfg(obd, llh, lcfg);
888 rc = record_marker(obd, llh, fsdb, CM_END, devname, comment);
889 rc = record_end_log(obd, &llh);
894 /* write the lcfg in all logs for the given fs */
895 int mgs_write_log_direct_all(struct obd_device *obd, struct fs_db *fsdb,
896 struct mgs_target_info *mti,
897 struct lustre_cfg *lcfg,
898 char *devname, char *comment)
900 struct mgs_obd *mgs = &obd->u.mgs;
901 struct list_head dentry_list;
902 struct l_linux_dirent *dirent, *n;
903 char *fsname = mti->mti_fsname;
905 int rc = 0, len = strlen(fsname);
908 /* We need to set params for any future logs
909 as well. FIXME Append this file to every new log.
910 Actually, we should store as params (text), not llogs. Or
912 name_create(&logname, fsname, "-params");
913 if (mgs_log_is_empty(obd, logname)) {
914 struct llog_handle *llh = NULL;
915 rc = record_start_log(obd, &llh, logname);
916 record_end_log(obd, &llh);
918 name_destroy(&logname);
922 /* Find all the logs in the CONFIGS directory */
923 rc = class_dentry_readdir(obd, mgs->mgs_configs_dir,
924 mgs->mgs_vfsmnt, &dentry_list);
926 CERROR("Can't read %s dir\n", MOUNT_CONFIGS_DIR);
930 /* Could use fsdb index maps instead of directory listing */
931 list_for_each_entry_safe(dirent, n, &dentry_list, lld_list) {
932 list_del(&dirent->lld_list);
933 if (strncmp(fsname, dirent->lld_name, len) == 0) {
934 CDEBUG(D_MGS, "Changing log %s\n", dirent->lld_name);
935 /* Erase any old settings of this same parameter */
936 mgs_modify(obd, fsdb, mti, dirent->lld_name, devname,
938 /* Write the new one */
939 rc = mgs_write_log_direct(obd, fsdb, dirent->lld_name,
940 lcfg, devname, comment);
942 CERROR("err %d writing log %s\n", rc,
945 OBD_FREE(dirent, sizeof(*dirent));
951 /* lov is the first thing in the mdt and client logs */
952 static int mgs_write_log_lov(struct obd_device *obd, struct fs_db *fsdb,
953 struct mgs_target_info *mti,
954 char *logname, char *lovname)
956 struct llog_handle *llh = NULL;
957 struct lov_desc *lovdesc;
962 CDEBUG(D_MGS, "Writing log %s\n", logname);
965 #01 L attach 0:lov_mdsA 1:lov 2:71ccb_lov_mdsA_19f961a9e1
966 #02 L lov_setup 0:lov_mdsA 1:(struct lov_desc)
967 uuid=lov1_UUID, stripe count=1, size=1048576, offset=0, pattern=0
970 /* FIXME just make lov_setup accept empty desc (put uuid in buf 2) */
971 OBD_ALLOC(lovdesc, sizeof(*lovdesc));
974 lovdesc->ld_magic = LOV_DESC_MAGIC;
975 lovdesc->ld_tgt_count = 0;
976 /* Defaults. Can be changed later by lcfg config_param */
977 lovdesc->ld_default_stripe_count = 1;
978 lovdesc->ld_pattern = LOV_PATTERN_RAID0;
979 lovdesc->ld_default_stripe_size = 1024 * 1024;
980 lovdesc->ld_default_stripe_offset = 0;
981 lovdesc->ld_qos_maxage = QOS_DEFAULT_MAXAGE;
982 sprintf((char*)lovdesc->ld_uuid.uuid, "%s_UUID", lovname);
983 /* can these be the same? */
984 uuid = (char *)lovdesc->ld_uuid.uuid;
986 /* This should always be the first entry in a log.
987 rc = mgs_clear_log(obd, logname); */
988 rc = record_start_log(obd, &llh, logname);
991 /* FIXME these should be a single journal transaction */
992 rc = record_marker(obd, llh, fsdb, CM_START, lovname, "lov setup");
993 rc = record_attach(obd, llh, lovname, "lov", uuid);
994 rc = record_lov_setup(obd, llh, lovname, lovdesc);
995 rc = record_marker(obd, llh, fsdb, CM_END, lovname, "lov setup");
996 rc = record_end_log(obd, &llh);
998 OBD_FREE(lovdesc, sizeof(*lovdesc));
1002 /* add failnids to open log */
1003 static int mgs_write_log_failnids(struct obd_device *obd,
1004 struct mgs_target_info *mti,
1005 struct llog_handle *llh,
1008 char *failnodeuuid = NULL;
1009 char *ptr = mti->mti_params;
1014 #03 L add_uuid nid=uml1@tcp(0x20000c0a80201) nal=90 0: 1:uml1_UUID
1015 #04 L add_uuid nid=1@elan(0x1000000000001) nal=90 0: 1:uml1_UUID
1016 #05 L setup 0:OSC_uml1_ost1_mdsA 1:ost1_UUID 2:uml1_UUID
1017 #06 L add_uuid nid=uml2@tcp(0x20000c0a80202) nal=90 0: 1:uml2_UUID
1018 #0x L add_uuid nid=2@elan(0x1000000000002) nal=90 0: 1:uml2_UUID
1019 #07 L add_conn 0:OSC_uml1_ost1_mdsA 1:uml2_UUID
1022 /* Pull failnid info out of params string */
1023 while (class_find_param(ptr, PARAM_FAILNODE, &ptr) == 0) {
1024 while (class_parse_nid(ptr, &nid, &ptr) == 0) {
1025 if (failnodeuuid == NULL) {
1026 /* We don't know the failover node name,
1027 so just use the first nid as the uuid */
1028 rc = name_create(&failnodeuuid,
1029 libcfs_nid2str(nid), "");
1033 CDEBUG(D_MGS, "add nid %s for failover uuid %s, "
1034 "client %s\n", libcfs_nid2str(nid),
1035 failnodeuuid, cliname);
1036 rc = record_add_uuid(obd, llh, nid, failnodeuuid);
1039 rc = record_add_conn(obd, llh, cliname, failnodeuuid);
1040 name_destroy(&failnodeuuid);
1041 failnodeuuid = NULL;
1048 static int mgs_write_log_mdt(struct obd_device *obd, struct fs_db *fsdb,
1049 struct mgs_target_info *mti)
1051 struct llog_handle *llh = NULL;
1052 char *cliname, *mdcname, *nodeuuid, *mdcuuid;
1053 int rc, i, first_log = 0;
1056 CDEBUG(D_MGS, "writing new mdt %s\n", mti->mti_svname);
1058 if (mti->mti_uuid[0] == '\0') {
1059 /* Make up our own uuid */
1060 snprintf(mti->mti_uuid, sizeof(mti->mti_uuid),
1061 "%s_UUID", mti->mti_svname);
1064 /* Append mdt info to mdt log */
1065 if (mgs_log_is_empty(obd, mti->mti_svname)) {
1066 /* This is the first time for all logs for this fs,
1067 since any ost should have already started the mdt log. */
1069 rc = mgs_write_log_lov(obd, fsdb, mti, mti->mti_svname,
1072 /* else there's already some ost entries in the mdt log. */
1074 /* We added the lov, maybe some osc's, now for the mdt.
1075 We might add more ost's after this. Note that during the parsing
1076 of this log, this is when the mdt will start. (This was not
1077 formerly part of the old mds log, it was directly executed by
1080 mount_option 0: 1:mdsA 2:lov_mdsA
1081 attach mds mdsA mdsA_UUID
1082 setup /dev/loop2 ldiskfs mdsA errors=remount-ro,user_xattr
1084 rc = record_start_log(obd, &llh, mti->mti_svname);
1087 /* FIXME this whole fn should be a single journal transaction */
1088 rc = record_marker(obd, llh, fsdb, CM_START, mti->mti_svname,"add mdt");
1089 rc = record_mount_opt(obd, llh, mti->mti_svname, fsdb->fsdb_mdtlov, 0);
1090 rc = record_attach(obd, llh, mti->mti_svname, LUSTRE_MDS_NAME,
1092 rc = record_setup(obd, llh, mti->mti_svname,
1093 mti->mti_uuid /* Ignored. Compatible with future. */,
1094 "0" /* MDT Index, default to zero. */,
1097 rc = record_marker(obd, llh, fsdb, CM_END, mti->mti_svname, "add mdt");
1098 rc = record_end_log(obd, &llh);
1100 /* Append the mdt info to the client log */
1101 name_create(&cliname, mti->mti_fsname, "-client");
1103 /* Start client log */
1104 rc = mgs_write_log_lov(obd, fsdb, mti, cliname,
1108 name_create(&nodeuuid, libcfs_nid2str(mti->mti_nids[0]),/*"_UUID"*/"");
1109 name_create(&mdcname, mti->mti_svname, "-mdc");
1110 name_create(&mdcuuid, mdcname, "_UUID");
1112 #09 L add_uuid nid=uml1@tcp(0x20000c0a80201) 0: 1:uml1_UUID
1113 #10 L attach 0:MDC_uml1_mdsA_MNT_client 1:mdc 2:1d834_MNT_client_03f
1114 #11 L setup 0:MDC_uml1_mdsA_MNT_client 1:mdsA_UUID 2:uml1_UUID
1115 #12 L add_uuid nid=uml2@tcp(0x20000c0a80202) 0: 1:uml2_UUID
1116 #13 L add_conn 0:MDC_uml1_mdsA_MNT_client 1:uml2_UUID
1117 #14 L mount_option 0: 1:client 2:lov1 3:MDC_uml1_mdsA_MNT_client
1119 rc = record_start_log(obd, &llh, cliname);
1122 rc = record_marker(obd, llh, fsdb, CM_START, mti->mti_svname,"add mdc");
1124 if (fsdb->fsdb_flags & FSDB_OLDLOG14) {
1125 /* Old client log already has MDC entry, but needs mount opt
1126 for new client name (lustre-client) */
1127 /* FIXME Old MDT log already has an old mount opt
1128 which we should remove (currently handled by
1129 class_del_profiles()) */
1130 rc = record_mount_opt(obd, llh, cliname, fsdb->fsdb_clilov,
1132 /* Only add failnids with --writeconf
1133 rc = mgs_write_log_failnids(obd, mti, llh, fsdb->fsdb_mdc);
1135 /* end COMPAT_146 */
1137 for (i = 0; i < mti->mti_nid_count; i++) {
1138 CDEBUG(D_MGS, "add nid %s\n",
1139 libcfs_nid2str(mti->mti_nids[i]));
1140 rc = record_add_uuid(obd, llh, mti->mti_nids[i],
1143 rc = record_attach(obd, llh, mdcname, LUSTRE_MDC_NAME, mdcuuid);
1144 rc = record_setup(obd, llh, mdcname, mti->mti_uuid,nodeuuid,
1146 rc = mgs_write_log_failnids(obd, mti, llh, mdcname);
1147 rc = record_mount_opt(obd, llh, cliname, fsdb->fsdb_clilov,
1150 rc = record_marker(obd, llh, fsdb, CM_END, mti->mti_svname, "add mdc");
1151 rc = record_end_log(obd, &llh);
1153 name_destroy(&mdcuuid);
1154 name_destroy(&mdcname);
1155 name_destroy(&nodeuuid);
1156 name_destroy(&cliname);
1160 /* Add the ost info to the client/mdt lov */
1161 static int mgs_write_log_osc(struct obd_device *obd, struct fs_db *fsdb,
1162 struct mgs_target_info *mti,
1163 char *logname, char *lovname, int flags)
1165 struct llog_handle *llh = NULL;
1166 char *nodeuuid, *oscname, *oscuuid, *lovuuid;
1170 if (mgs_log_is_empty(obd, logname)) {
1171 /* The first item in the log must be the lov, so we have
1172 somewhere to add our osc. */
1173 rc = mgs_write_log_lov(obd, fsdb, mti, logname, lovname);
1176 CDEBUG(D_MGS, "adding osc for %s to log %s\n",
1177 mti->mti_svname, logname);
1179 name_create(&nodeuuid, libcfs_nid2str(mti->mti_nids[0]), "");
1180 name_create(&oscname, mti->mti_svname, "-osc");
1181 name_create(&oscuuid, oscname, "_UUID");
1182 name_create(&lovuuid, lovname, "_UUID");
1185 #03 L add_uuid nid=uml1@tcp(0x20000c0a80201) 0: 1:uml1_UUID
1187 #04 L add_uuid nid=1@elan(0x1000000000001) nal=90 0: 1:uml1_UUID
1188 #04 L attach 0:OSC_uml1_ost1_MNT_client 1:osc 2:89070_lov1_a41dff51a
1189 #05 L setup 0:OSC_uml1_ost1_MNT_client 1:ost1_UUID 2:uml1_UUID
1191 #06 L add_uuid nid=uml2@tcp(0x20000c0a80202) 0: 1:uml2_UUID
1192 #07 L add_conn 0:OSC_uml1_ost1_MNT_client 1:uml2_UUID
1193 #08 L lov_modify_tgts add 0:lov1 1:ost1_UUID 2(index):0 3(gen):1
1195 rc = record_start_log(obd, &llh, logname);
1198 /* FIXME these should be a single journal transaction */
1199 rc = record_marker(obd, llh, fsdb, CM_START | flags, mti->mti_svname,
1201 for (i = 0; i < mti->mti_nid_count; i++) {
1202 CDEBUG(D_MGS, "add nid %s\n", libcfs_nid2str(mti->mti_nids[i]));
1203 rc = record_add_uuid(obd, llh, mti->mti_nids[i], nodeuuid);
1205 rc = record_attach(obd, llh, oscname, LUSTRE_OSC_NAME, lovuuid);
1206 rc = record_setup(obd, llh, oscname, mti->mti_uuid, nodeuuid, 0, 0);
1207 rc = mgs_write_log_failnids(obd, mti, llh, oscname);
1208 snprintf(index, sizeof(index), "%d", mti->mti_stripe_index);
1209 rc = record_lov_add(obd, llh, lovname, mti->mti_uuid, index, "1");
1210 rc = record_marker(obd, llh, fsdb, CM_END | flags, mti->mti_svname,
1212 rc = record_end_log(obd, &llh);
1214 name_destroy(&lovuuid);
1215 name_destroy(&oscuuid);
1216 name_destroy(&oscname);
1217 name_destroy(&nodeuuid);
1221 static int mgs_write_log_ost(struct obd_device *obd, struct fs_db *fsdb,
1222 struct mgs_target_info *mti)
1224 struct llog_handle *llh = NULL;
1226 char *ptr = mti->mti_params;
1227 int rc, flags = 0, failout = 0;
1230 CDEBUG(D_MGS, "writing new ost %s\n", mti->mti_svname);
1232 /* The ost startup log */
1234 /* If the ost log already exists, that means that someone reformatted
1235 the ost and it called target_add again. */
1236 if (!mgs_log_is_empty(obd, mti->mti_svname)) {
1237 LCONSOLE_ERROR_MSG(0x141, "The config log for %s already "
1238 "exists, yet the server claims it never "
1239 "registered. It may have been reformatted, "
1240 "or the index changed. writeconf the MDT to "
1241 "regenerate all logs.\n", mti->mti_svname);
1245 attach obdfilter ost1 ost1_UUID
1246 setup /dev/loop2 ldiskfs f|n errors=remount-ro,user_xattr
1248 if (class_find_param(ptr, PARAM_FAILMODE, &ptr) == 0)
1249 failout = (strncmp(ptr, "failout", 7) == 0);
1250 rc = record_start_log(obd, &llh, mti->mti_svname);
1253 /* FIXME these should be a single journal transaction */
1254 rc = record_marker(obd, llh, fsdb, CM_START, mti->mti_svname,"add ost");
1255 if (*mti->mti_uuid == '\0')
1256 snprintf(mti->mti_uuid, sizeof(mti->mti_uuid),
1257 "%s_UUID", mti->mti_svname);
1258 rc = record_attach(obd, llh, mti->mti_svname,
1259 "obdfilter"/*LUSTRE_OST_NAME*/, mti->mti_uuid);
1260 rc = record_setup(obd, llh, mti->mti_svname,
1261 "dev"/*ignored*/, "type"/*ignored*/,
1262 failout ? "n" : "f", 0/*options*/);
1263 rc = record_marker(obd, llh, fsdb, CM_END, mti->mti_svname, "add ost");
1264 rc = record_end_log(obd, &llh);
1266 /* We also have to update the other logs where this osc is part of
1269 if (fsdb->fsdb_flags & FSDB_OLDLOG14) {
1270 /* If we're upgrading, the old mdt log already has our
1271 entry. Let's do a fake one for fun. */
1272 /* Note that we can't add any new failnids, since we don't
1273 know the old osc names. */
1274 flags = CM_SKIP | CM_UPGRADE146;
1275 } else if ((mti->mti_flags & LDD_F_UPDATE) != LDD_F_UPDATE) {
1276 /* If the update flag isn't set, don't really update
1279 LCONSOLE_WARN("Client log for %s was not updated; writeconf "
1280 "the MDT first to regenerate it.\n",
1284 /* Append ost info to mdt log */
1285 /* FIXME add to all MDT logs for CMD */
1286 /* FIXME need real MDT name, but MDT may not have registered yet! */
1287 name_create(&logname, mti->mti_fsname, "-MDT0000");
1288 rc = mgs_write_log_osc(obd, fsdb, mti, logname, fsdb->fsdb_mdtlov,
1290 name_destroy(&logname);
1292 /* Append ost info to the client log */
1293 name_create(&logname, mti->mti_fsname, "-client");
1294 rc = mgs_write_log_osc(obd, fsdb, mti, logname, fsdb->fsdb_clilov,
1296 name_destroy(&logname);
1301 /* Add additional failnids to an existing log.
1302 The mdc/osc must have been added to logs first */
1303 /* tcp nids must be in dotted-quad ascii -
1304 we can't resolve hostnames from the kernel. */
1305 static int mgs_write_log_add_failnid(struct obd_device *obd, struct fs_db *fsdb,
1306 struct mgs_target_info *mti)
1308 char *logname, *cliname;
1309 struct llog_handle *llh = NULL;
1313 /* FIXME how do we delete a failnid? Currently --writeconf is the
1314 only way. Maybe make --erase-params pass a flag to really
1315 erase all params from logs - except it can't erase the failnids
1316 given when a target first registers, since they aren't processed
1319 /* Verify that we know about this target */
1320 if (mgs_log_is_empty(obd, mti->mti_svname)) {
1321 LCONSOLE_ERROR_MSG(0x142, "The target %s has not registered "
1322 "yet. It must be started before failnids can"
1323 " be added.\n", mti->mti_svname);
1327 /* Create mdc/osc client name (e.g. lustre-OST0001-osc) */
1328 if (mti->mti_flags & LDD_F_SV_TYPE_MDT) {
1331 name_create(&cliname, fsdb->fsdb_mdc, "");
1333 name_create(&cliname, mti->mti_svname, "-mdc");
1334 } else if (mti->mti_flags & LDD_F_SV_TYPE_OST) {
1336 if (fsdb->fsdb_flags & FSDB_OLDLOG14) {
1337 LCONSOLE_ERROR_MSG(0x143, "Failover NIDs cannot be "
1338 "added to upgraded client logs for "
1339 "%s. Consider updating the "
1340 "configuration with --writeconf.\n",
1344 name_create(&cliname, mti->mti_svname, "-osc");
1349 /* Add failover nids to client log */
1350 name_create(&logname, mti->mti_fsname, "-client");
1351 rc = record_start_log(obd, &llh, logname);
1353 /* FIXME this fn should be a single journal transaction */
1354 rc = record_marker(obd, llh, fsdb, CM_START, mti->mti_svname,
1356 rc = mgs_write_log_failnids(obd, mti, llh, cliname);
1357 rc = record_marker(obd, llh, fsdb, CM_END, mti->mti_svname,
1359 rc = record_end_log(obd, &llh);
1361 name_destroy(&logname);
1363 if (mti->mti_flags & LDD_F_SV_TYPE_OST) {
1364 /* Add OST failover nids to the MDT log as well */
1365 name_create(&logname, mti->mti_fsname, "-MDT0000");
1366 rc = record_start_log(obd, &llh, logname);
1368 rc = record_marker(obd, llh, fsdb, CM_START,
1369 mti->mti_svname, "add failnid");
1370 rc = mgs_write_log_failnids(obd, mti, llh, cliname);
1371 rc = record_marker(obd, llh, fsdb, CM_END,
1372 mti->mti_svname, "add failnid");
1373 rc = record_end_log(obd, &llh);
1375 name_destroy(&logname);
1378 name_destroy(&cliname);
1382 static int mgs_wlp_lcfg(struct obd_device *obd, struct fs_db *fsdb,
1383 struct mgs_target_info *mti,
1384 char *logname, struct lustre_cfg_bufs *bufs,
1385 char *tgtname, char *ptr)
1387 char comment[MTI_NAME_MAXLEN];
1389 struct lustre_cfg *lcfg;
1392 /* Erase any old settings of this same parameter */
1393 memcpy(comment, ptr, MTI_NAME_MAXLEN);
1394 comment[MTI_NAME_MAXLEN - 1] = 0;
1395 /* But don't try to match the value. */
1396 if ((tmp = strchr(comment, '=')))
1398 /* FIXME we should skip settings that are the same as old values */
1399 rc = mgs_modify(obd, fsdb, mti, logname, tgtname, comment, CM_SKIP);
1400 LCONSOLE_INFO("%sing parameter %s.%s in log %s\n", rc ?
1401 "Sett" : "Modify", tgtname, comment, logname);
1403 lustre_cfg_bufs_reset(bufs, tgtname);
1404 lustre_cfg_bufs_set_string(bufs, 1, ptr);
1405 lcfg = lustre_cfg_new(LCFG_PARAM, bufs);
1408 rc = mgs_write_log_direct(obd, fsdb, logname, lcfg, tgtname, comment);
1409 lustre_cfg_free(lcfg);
1413 static int mgs_write_log_params(struct obd_device *obd, struct fs_db *fsdb,
1414 struct mgs_target_info *mti)
1416 struct lustre_cfg_bufs bufs;
1417 struct lustre_cfg *lcfg;
1419 char *ptr = mti->mti_params;
1424 if (!mti->mti_params)
1427 /* For various parameter settings, we have to figure out which logs
1428 care about them (e.g. both mdt and client for lov settings) */
1434 endptr = strchr(ptr, ' ');
1437 CDEBUG(D_MGS, "next param '%s'\n", ptr);
1439 /* The params are stored in MOUNT_DATA_FILE and modified
1440 via tunefs.lustre */
1442 /* Processed in lustre_start_mgc */
1443 if (class_match_param(ptr, PARAM_MGSNODE, NULL) == 0)
1446 /* Processed in mgs_write_log_ost */
1447 if (class_match_param(ptr, PARAM_FAILMODE, NULL) == 0) {
1448 if (mti->mti_flags & LDD_F_PARAM) {
1449 LCONSOLE_ERROR_MSG(0x169, "%s can only be "
1450 "changed with tunefs.lustre "
1451 "and --writeconf\n", ptr);
1457 if (class_match_param(ptr, PARAM_FAILNODE, NULL) == 0) {
1458 /* Add a failover nidlist */
1460 /* We already processed failovers params for new
1461 targets in mgs_write_log_target */
1462 if (mti->mti_flags & LDD_F_PARAM) {
1463 CDEBUG(D_MGS, "Adding failnode\n");
1464 rc = mgs_write_log_add_failnid(obd, fsdb, mti);
1469 if (class_match_param(ptr, PARAM_SYS_TIMEOUT, &tmp) == 0) {
1470 /* Change obd timeout */
1472 timeout = simple_strtoul(tmp, NULL, 0);
1474 CDEBUG(D_MGS, "obd timeout %d\n", timeout);
1476 lustre_cfg_bufs_reset(&bufs, NULL);
1477 lcfg = lustre_cfg_new(LCFG_SET_TIMEOUT, &bufs);
1478 lcfg->lcfg_num = timeout;
1479 /* modify all servers and clients */
1480 rc = mgs_write_log_direct_all(obd, fsdb, mti, lcfg,
1483 lustre_cfg_free(lcfg);
1487 if (class_match_param(ptr, PARAM_OSC""PARAM_ACTIVE, &tmp) == 0){
1488 /* active=0 means off, anything else means on */
1489 int flag = (*tmp == '0') ? CM_EXCLUDE : 0;
1490 if (!(mti->mti_flags & LDD_F_SV_TYPE_OST)) {
1491 LCONSOLE_ERROR_MSG(0x144, "%s: Only OSCs can be"
1492 " (de)activated.\n",
1497 LCONSOLE_WARN("Permanently %sactivating %s\n",
1498 flag ? "de": "re", mti->mti_svname);
1500 name_create(&logname, mti->mti_fsname, "-client");
1501 rc = mgs_modify(obd, fsdb, mti, logname,
1502 mti->mti_svname, "add osc", flag);
1503 name_destroy(&logname);
1507 /* FIXME add to all MDT logs for CMD */
1508 name_create(&logname, mti->mti_fsname, "-MDT0000");
1509 rc = mgs_modify(obd, fsdb, mti, logname,
1510 mti->mti_svname, "add osc", flag);
1511 name_destroy(&logname);
1514 LCONSOLE_ERROR_MSG(0x145, "Couldn't find %s in "
1515 "log (%d). No permanent "
1516 "changes were made to the "
1518 mti->mti_svname, rc);
1519 if (fsdb->fsdb_flags & FSDB_OLDLOG14)
1520 LCONSOLE_ERROR_MSG(0x146, "This may be "
1521 "because the log is in the old 1.4 "
1522 "style. Consider --writeconf to "
1523 "update the logs.\n");
1526 /* Fall through to osc proc for deactivating
1527 live OSC on running MDT / clients. */
1530 /* Below here, let obd's XXX_process_config methods handle it */
1532 /* All lov. in proc */
1533 if (class_match_param(ptr, PARAM_LOV, NULL) == 0) {
1534 CDEBUG(D_MGS, "lov param %s\n", ptr);
1535 if (!(mti->mti_flags & LDD_F_SV_TYPE_MDT)) {
1536 LCONSOLE_ERROR_MSG(0x147, "LOV params must be "
1537 "set on the MDT, not %s. "
1545 if (mgs_log_is_empty(obd, mti->mti_svname)) {
1549 rc = mgs_wlp_lcfg(obd, fsdb, mti, mti->mti_svname,
1550 &bufs, fsdb->fsdb_mdtlov, ptr);
1555 name_create(&logname, mti->mti_fsname, "-client");
1556 rc = mgs_wlp_lcfg(obd, fsdb, mti, logname, &bufs,
1557 fsdb->fsdb_clilov, ptr);
1558 name_destroy(&logname);
1562 /* All osc., mdc., llite. params in proc */
1563 if ((class_match_param(ptr, PARAM_OSC, NULL) == 0) ||
1564 (class_match_param(ptr, PARAM_MDC, NULL) == 0) ||
1565 (class_match_param(ptr, PARAM_LLITE, NULL) == 0)) {
1567 if (memcmp(ptr, PARAM_LLITE, strlen(PARAM_LLITE)) == 0) {
1568 name_create(&cname, mti->mti_fsname, "-client");
1569 /* Add the client type to match the obdname
1570 in class_config_llog_handler */
1571 } else if (mti->mti_flags & LDD_F_SV_TYPE_MDT) {
1574 name_create(&cname, fsdb->fsdb_mdc, "");
1576 name_create(&cname, mti->mti_svname,
1578 } else if (mti->mti_flags & LDD_F_SV_TYPE_OST) {
1580 if (fsdb->fsdb_flags & FSDB_OLDLOG14) {
1581 LCONSOLE_ERROR_MSG(0x148, "Upgraded client"
1582 " logs for %s cannot be modified. "
1583 "Consider updating the "
1584 "configuration with --writeconf\n",
1586 /* We don't know the names of all the
1591 name_create(&cname, mti->mti_svname, "-osc");
1597 CDEBUG(D_MGS, "%.3s param %s\n", ptr, ptr + 4);
1600 name_create(&logname, mti->mti_fsname, "-client");
1601 rc = mgs_wlp_lcfg(obd, fsdb, mti, logname, &bufs,
1603 name_destroy(&logname);
1605 /* osc params affect the MDT as well */
1606 if (mti->mti_flags & LDD_F_SV_TYPE_OST) {
1607 /* FIXME add to all MDT logs for CMD */
1608 name_create(&logname, mti->mti_fsname,
1610 if (!mgs_log_is_empty(obd, logname))
1611 rc = mgs_wlp_lcfg(obd, fsdb, mti,
1614 name_destroy(&logname);
1616 name_destroy(&cname);
1620 /* All mdt., ost. params in proc */
1621 if ((class_match_param(ptr, PARAM_MDT, NULL) == 0) ||
1622 (class_match_param(ptr, PARAM_OST, NULL) == 0)) {
1623 CDEBUG(D_MGS, "%.3s param %s\n", ptr, ptr + 4);
1624 if (mgs_log_is_empty(obd, mti->mti_svname)) {
1628 rc = mgs_wlp_lcfg(obd, fsdb, mti, mti->mti_svname,
1629 &bufs, mti->mti_svname, ptr);
1633 LCONSOLE_WARN("Ignoring unrecognized param '%s'\n", ptr);
1637 CERROR("err %d on param '%s\n", rc, ptr);
1652 int mgs_check_failnid(struct obd_device *obd, struct mgs_target_info *mti)
1654 /* Not implementing automatic failover nid addition at this time. */
1661 rc = mgs_find_or_make_fsdb(obd, fsname, &fsdb);
1665 if (mgs_log_is_empty(obd, mti->mti_svname))
1666 /* should never happen */
1669 CDEBUG(D_MGS, "Checking for new failnids for %s\n", mti->mti_svname);
1671 /* FIXME We can just check mti->params to see if we're already in
1672 the failover list. Modify mti->params for rewriting back at
1673 server_register_target(). */
1675 down(&fsdb->fsdb_sem);
1676 rc = mgs_write_log_add_failnid(obd, fsdb, mti);
1677 up(&fsdb->fsdb_sem);
1683 int mgs_write_log_target(struct obd_device *obd,
1684 struct mgs_target_info *mti)
1690 /* set/check the new target index */
1691 rc = mgs_set_index(obd, mti);
1693 CERROR("Can't get index (%d)\n", rc);
1697 if (mti->mti_flags & LDD_F_UPGRADE14) {
1698 if (rc == EALREADY) {
1699 LCONSOLE_INFO("Found index %d for %s 1.4 log, "
1700 "upgrading\n", mti->mti_stripe_index,
1703 LCONSOLE_ERROR_MSG(0x149, "Failed to find %s in the old"
1704 " client log. Apparently it is not "
1705 "part of this filesystem, or the old"
1706 " log is wrong.\nUse 'writeconf' on "
1707 "the MDT to force log regeneration."
1708 "\n", mti->mti_svname);
1709 /* Not in client log? Upgrade anyhow...*/
1710 /* Argument against upgrading: reformat MDT,
1711 upgrade OST, then OST will start but will be SKIPped
1712 in client logs. Maybe error now is better. */
1713 /* RETURN(-EINVAL); */
1715 /* end COMPAT_146 */
1717 if (rc == EALREADY) {
1718 /* This might be a params update, or a
1719 local writeconf. (For "full" writeconf, the client
1720 log won't have an entry for this target, so we
1722 LCONSOLE_WARN("Found index %d for %s, updating log\n",
1723 mti->mti_stripe_index, mti->mti_svname);
1724 /* We would like to mark old log sections as invalid
1725 and add new log sections in the client and mdt logs.
1726 But if we add new sections, then live clients will
1727 get repeat setup instructions for already running
1728 osc's. So don't update the client/mdt logs. */
1729 mti->mti_flags &= ~LDD_F_UPDATE;
1733 rc = mgs_find_or_make_fsdb(obd, mti->mti_fsname, &fsdb);
1735 CERROR("Can't get db for %s\n", mti->mti_fsname);
1739 down(&fsdb->fsdb_sem);
1741 if (mti->mti_flags &
1742 (LDD_F_VIRGIN | LDD_F_UPGRADE14 | LDD_F_WRITECONF)) {
1743 /* Generate a log from scratch */
1744 if (mti->mti_flags & LDD_F_SV_TYPE_MDT) {
1745 rc = mgs_write_log_mdt(obd, fsdb, mti);
1746 } else if (mti->mti_flags & LDD_F_SV_TYPE_OST) {
1747 rc = mgs_write_log_ost(obd, fsdb, mti);
1749 CERROR("Unknown target type %#x, can't create log for "
1750 "%s\n", mti->mti_flags, mti->mti_svname);
1753 CERROR("Can't write logs for %s (%d)\n",
1754 mti->mti_svname, rc);
1758 /* Just update the params from tunefs in mgs_write_log_params */
1759 CDEBUG(D_MGS, "Update params for %s\n", mti->mti_svname);
1760 mti->mti_flags |= LDD_F_PARAM;
1763 rc = mgs_write_log_params(obd, fsdb, mti);
1766 up(&fsdb->fsdb_sem);
1771 /* verify that we can handle the old config logs */
1772 int mgs_upgrade_sv_14(struct obd_device *obd, struct mgs_target_info *mti)
1778 /* Create ost log normally, as servers register. Servers
1779 register with their old uuids (from last_rcvd), so old
1780 (MDT and client) logs should work.
1781 - new MDT won't know about old OSTs, only the ones that have
1782 registered, so we need the old MDT log to get the LOV right
1783 in order for old clients to work.
1784 - Old clients connect to the MDT, not the MGS, for their logs, and
1785 will therefore receive the old client log from the MDT /LOGS dir.
1786 - Old clients can continue to use and connect to old or new OSTs
1787 - New clients will contact the MGS for their log
1790 LCONSOLE_INFO("upgrading server %s from pre-1.6\n", mti->mti_svname);
1791 server_mti_print("upgrade", mti);
1793 rc = mgs_find_or_make_fsdb(obd, mti->mti_fsname, &fsdb);
1797 if (fsdb->fsdb_flags & FSDB_LOG_EMPTY) {
1798 LCONSOLE_ERROR_MSG(0x14a, "The old client log %s-client is "
1799 "missing. Was tunefs.lustre successful?\n",
1804 if (fsdb->fsdb_gen == 0) {
1805 /* There were no markers in the client log, meaning we have
1806 not updated the logs for this fs */
1807 CDEBUG(D_MGS, "found old, unupdated client log\n");
1810 if (mti->mti_flags & LDD_F_SV_TYPE_MDT) {
1811 if (mgs_log_is_empty(obd, mti->mti_svname)) {
1812 LCONSOLE_ERROR_MSG(0x14b, "The old MDT log %s is "
1813 "missing. Was tunefs.lustre "
1819 /* We're starting with an old uuid. Assume old name for lov
1820 as well since the lov entry already exists in the log. */
1821 CDEBUG(D_MGS, "old mds uuid %s\n", mti->mti_uuid);
1822 if (strncmp(mti->mti_uuid, fsdb->fsdb_mdtlov + 4,
1823 strlen(fsdb->fsdb_mdtlov) - 4) != 0) {
1824 CERROR("old mds uuid %s doesn't match log %s (%s)\n",
1825 mti->mti_uuid, fsdb->fsdb_mdtlov,
1826 fsdb->fsdb_mdtlov + 4);
1831 if (!(fsdb->fsdb_flags & FSDB_OLDLOG14)) {
1832 LCONSOLE_ERROR_MSG(0x14c, "%s-client is supposedly an old log, "
1833 "but no old LOV or MDT was found. Consider "
1834 "updating the configuration with "
1835 "--writeconf.\n", mti->mti_fsname);
1840 /* end COMPAT_146 */
1842 int mgs_erase_log(struct obd_device *obd, char *name)
1844 struct lvfs_run_ctxt saved;
1845 struct llog_ctxt *ctxt;
1846 struct llog_handle *llh;
1849 ctxt = llog_get_context(obd, LLOG_CONFIG_ORIG_CTXT);
1850 LASSERT(ctxt != NULL);
1852 push_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
1853 rc = llog_create(ctxt, &llh, NULL, name);
1855 llog_init_handle(llh, LLOG_F_IS_PLAIN, NULL);
1856 rc = llog_destroy(llh);
1857 llog_free_handle(llh);
1859 pop_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
1860 llog_ctxt_put(ctxt);
1863 CERROR("failed to clear log %s: %d\n", name, rc);
1868 /* erase all logs for the given fs */
1869 int mgs_erase_logs(struct obd_device *obd, char *fsname)
1871 struct mgs_obd *mgs = &obd->u.mgs;
1872 static struct fs_db *fsdb;
1873 struct list_head dentry_list;
1874 struct l_linux_dirent *dirent, *n;
1875 int rc, len = strlen(fsname);
1878 /* Find all the logs in the CONFIGS directory */
1879 rc = class_dentry_readdir(obd, mgs->mgs_configs_dir,
1880 mgs->mgs_vfsmnt, &dentry_list);
1882 CERROR("Can't read %s dir\n", MOUNT_CONFIGS_DIR);
1886 down(&mgs->mgs_sem);
1888 /* Delete the fs db */
1889 fsdb = mgs_find_fsdb(obd, fsname);
1891 mgs_free_fsdb(obd, fsdb);
1893 list_for_each_entry_safe(dirent, n, &dentry_list, lld_list) {
1894 list_del(&dirent->lld_list);
1895 if (strncmp(fsname, dirent->lld_name, len) == 0) {
1896 CDEBUG(D_MGS, "Removing log %s\n", dirent->lld_name);
1897 mgs_erase_log(obd, dirent->lld_name);
1899 OBD_FREE(dirent, sizeof(*dirent));
1907 /* from llog_swab */
1908 static void print_lustre_cfg(struct lustre_cfg *lcfg)
1913 CDEBUG(D_MGS, "lustre_cfg: %p\n", lcfg);
1914 CDEBUG(D_MGS, "\tlcfg->lcfg_version: %#x\n", lcfg->lcfg_version);
1916 CDEBUG(D_MGS, "\tlcfg->lcfg_command: %#x\n", lcfg->lcfg_command);
1917 CDEBUG(D_MGS, "\tlcfg->lcfg_num: %#x\n", lcfg->lcfg_num);
1918 CDEBUG(D_MGS, "\tlcfg->lcfg_flags: %#x\n", lcfg->lcfg_flags);
1919 CDEBUG(D_MGS, "\tlcfg->lcfg_nid: %s\n", libcfs_nid2str(lcfg->lcfg_nid));
1921 CDEBUG(D_MGS, "\tlcfg->lcfg_bufcount: %d\n", lcfg->lcfg_bufcount);
1922 if (lcfg->lcfg_bufcount < LUSTRE_CFG_MAX_BUFCOUNT)
1923 for (i = 0; i < lcfg->lcfg_bufcount; i++) {
1924 CDEBUG(D_MGS, "\tlcfg->lcfg_buflens[%d]: %d %s\n",
1925 i, lcfg->lcfg_buflens[i],
1926 lustre_cfg_string(lcfg, i));
1931 /* Set a permanent (config log) param for a target or fs */
1932 int mgs_setparam(struct obd_device *obd, struct lustre_cfg *lcfg, char *fsname)
1935 struct mgs_target_info *mti;
1936 char *devname, *param;
1942 print_lustre_cfg(lcfg);
1944 /* lustre, lustre-mdtlov, lustre-client, lustre-MDT0000 */
1945 devname = lustre_cfg_string(lcfg, 0);
1946 param = lustre_cfg_string(lcfg, 1);
1948 /* Assume device name embedded in param:
1949 lustre-OST0000.osc.max_dirty_mb=32 */
1950 ptr = strchr(param, '.');
1958 LCONSOLE_ERROR_MSG(0x14d, "No target specified: %s\n", param);
1962 /* Extract fsname */
1963 ptr = strrchr(devname, '-');
1964 memset(fsname, 0, MTI_NAME_MAXLEN);
1965 if (ptr && (server_name2index(ptr, &index, NULL) >= 0)) {
1966 /* param related to llite isn't allowed to set by OST or MDT */
1967 if (strncmp(param, PARAM_LLITE, sizeof(PARAM_LLITE)) == 0)
1970 strncpy(fsname, devname, ptr - devname);
1972 /* assume devname is the fsname */
1973 strncpy(fsname, devname, MTI_NAME_MAXLEN);
1975 fsname[MTI_NAME_MAXLEN - 1] = 0;
1976 CDEBUG(D_MGS, "setparam on fs %s device %s\n", fsname, devname);
1978 rc = mgs_find_or_make_fsdb(obd, fsname, &fsdb);
1981 if (fsdb->fsdb_flags & FSDB_LOG_EMPTY) {
1982 CERROR("No filesystem targets for %s. cfg_device from lctl "
1983 "is '%s'\n", fsname, devname);
1984 mgs_free_fsdb(obd, fsdb);
1988 /* Create a fake mti to hold everything */
1991 GOTO(out, rc = -ENOMEM);
1992 strncpy(mti->mti_fsname, fsname, MTI_NAME_MAXLEN);
1993 strncpy(mti->mti_svname, devname, MTI_NAME_MAXLEN);
1994 strncpy(mti->mti_params, param, sizeof(mti->mti_params));
1995 rc = server_name2index(mti->mti_svname, &mti->mti_stripe_index, &tmp);
1997 /* Not a valid server; may be only fsname */
2000 /* Strip -osc or -mdc suffix from svname */
2001 if (server_make_name(rc, mti->mti_stripe_index, mti->mti_fsname,
2003 GOTO(out, rc = -EINVAL);
2005 mti->mti_flags = rc | LDD_F_PARAM;
2007 down(&fsdb->fsdb_sem);
2008 rc = mgs_write_log_params(obd, fsdb, mti);
2009 up(&fsdb->fsdb_sem);
2017 static int mgs_write_log_pool(struct obd_device *obd, char *logname, struct fs_db *fsdb,
2019 enum lcfg_command_type cmd,
2020 char *poolname, char *fsname,
2021 char *ostname, char *comment)
2023 struct llog_handle *llh = NULL;
2026 rc = record_start_log(obd, &llh, logname);
2029 rc = record_marker(obd, llh, fsdb, CM_START, lovname, comment);
2030 record_base(obd, llh, lovname, 0, cmd, poolname, fsname, ostname, 0);
2031 rc = record_marker(obd, llh, fsdb, CM_END, lovname, comment);
2032 rc = record_end_log(obd, &llh);
2037 int mgs_pool_cmd(struct obd_device *obd, enum lcfg_command_type cmd,
2038 char *fsname, char *poolname, char *ostname)
2044 char *label, *canceled_label = NULL;
2046 struct mgs_target_info *mti;
2050 rc = mgs_find_or_make_fsdb(obd, fsname, &fsdb);
2052 CERROR("Can't get db for %s\n", fsname);
2055 if (fsdb->fsdb_flags & FSDB_LOG_EMPTY) {
2056 CERROR("%s is not defined\n", fsname);
2057 mgs_free_fsdb(obd, fsdb);
2061 label_sz = 10 + strlen(fsname) + strlen(poolname);
2063 /* check if ostname match fsname */
2064 if (ostname != NULL) {
2067 ptr = strrchr(ostname, '-');
2068 if ((ptr == NULL) ||
2069 (strncmp(fsname, ostname, ptr-ostname) != 0))
2071 label_sz += strlen(ostname);
2074 OBD_ALLOC(label, label_sz);
2079 case LCFG_POOL_NEW: {
2081 "new %s.%s", fsname, poolname);
2084 case LCFG_POOL_ADD: {
2086 "add %s.%s.%s", fsname, poolname, ostname);
2089 case LCFG_POOL_REM: {
2090 OBD_ALLOC(canceled_label, label_sz);
2091 if (canceled_label == NULL)
2094 "rem %s.%s.%s", fsname, poolname, ostname);
2095 sprintf(canceled_label,
2096 "add %s.%s.%s", fsname, poolname, ostname);
2099 case LCFG_POOL_DEL: {
2100 OBD_ALLOC(canceled_label, label_sz);
2101 if (canceled_label == NULL)
2104 "del %s.%s", fsname, poolname);
2105 sprintf(canceled_label,
2106 "new %s.%s", fsname, poolname);
2114 down(&fsdb->fsdb_sem);
2116 sprintf(mdt_index, "-MDT%04x", 0);
2117 name_create(&logname, fsname, mdt_index);
2118 name_create(&lovname, fsdb->fsdb_mdtlov, "");
2121 if (canceled_label != NULL) {
2122 OBD_ALLOC(mti, sizeof(*mti));
2124 strcpy(mti->mti_svname, "lov pool");
2125 mgs_modify(obd, fsdb, mti, logname, lovname,
2126 canceled_label, CM_SKIP);
2130 mgs_write_log_pool(obd, logname, fsdb, lovname,
2131 cmd, fsname, poolname, ostname, label);
2132 name_destroy(&logname);
2134 name_create(&logname, fsname, "-client");
2135 if (canceled_label != NULL) {
2136 mgs_modify(obd, fsdb, mti, logname, lovname,
2137 canceled_label, CM_SKIP);
2139 mgs_write_log_pool(obd, logname, fsdb, fsdb->fsdb_clilov,
2140 cmd, fsname, poolname, ostname, label);
2141 name_destroy(&logname);
2142 name_destroy(&lovname);
2144 up(&fsdb->fsdb_sem);
2146 OBD_FREE(label, label_sz);
2147 if (canceled_label != NULL)
2148 OBD_FREE(canceled_label, label_sz);
2151 OBD_FREE(mti, sizeof(*mti));
2157 /******************** unused *********************/
2158 static int mgs_backup_llog(struct obd_device *obd, char* fsname)
2160 struct file *filp, *bak_filp;
2161 struct lvfs_run_ctxt saved;
2162 char *logname, *buf;
2163 loff_t soff = 0 , doff = 0;
2164 int count = 4096, len;
2167 OBD_ALLOC(logname, PATH_MAX);
2168 if (logname == NULL)
2171 OBD_ALLOC(buf, count);
2173 GOTO(out , rc = -ENOMEM);
2175 len = snprintf(logname, PATH_MAX, "%s/%s.bak",
2176 MOUNT_CONFIGS_DIR, fsname);
2178 if (len >= PATH_MAX - 1) {
2179 GOTO(out, -ENAMETOOLONG);
2182 push_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
2184 bak_filp = l_filp_open(logname, O_RDWR|O_CREAT|O_TRUNC, 0660);
2185 if (IS_ERR(bak_filp)) {
2186 rc = PTR_ERR(bak_filp);
2187 CERROR("backup logfile open %s: %d\n", logname, rc);
2190 sprintf(logname, "%s/%s", MOUNT_CONFIGS_DIR, fsname);
2191 filp = l_filp_open(logname, O_RDONLY, 0);
2194 CERROR("logfile open %s: %d\n", logname, rc);
2198 while ((rc = lustre_fread(filp, buf, count, &soff)) > 0) {
2199 rc = lustre_fwrite(bak_filp, buf, count, &doff);
2203 filp_close(filp, 0);
2205 filp_close(bak_filp, 0);
2207 pop_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
2210 OBD_FREE(buf, count);
2211 OBD_FREE(logname, PATH_MAX);