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_LDLM_TIMEOUT, &tmp) == 0) {
1488 /* Change ldlm timeout */
1490 timeout = simple_strtoul(tmp, NULL, 0);
1492 CDEBUG(D_MGS, "ldlm timeout %d\n", timeout);
1494 lustre_cfg_bufs_reset(&bufs, NULL);
1495 lcfg = lustre_cfg_new(LCFG_SET_LDLM_TIMEOUT, &bufs);
1496 lcfg->lcfg_num = timeout;
1497 /* modify all servers and clients */
1498 rc = mgs_write_log_direct_all(obd, fsdb, mti, lcfg,
1501 lustre_cfg_free(lcfg);
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 /* set/check the new target index */
1709 rc = mgs_set_index(obd, mti);
1711 CERROR("Can't get index (%d)\n", rc);
1715 if (mti->mti_flags & LDD_F_UPGRADE14) {
1716 if (rc == EALREADY) {
1717 LCONSOLE_INFO("Found index %d for %s 1.4 log, "
1718 "upgrading\n", mti->mti_stripe_index,
1721 LCONSOLE_ERROR_MSG(0x149, "Failed to find %s in the old"
1722 " client log. Apparently it is not "
1723 "part of this filesystem, or the old"
1724 " log is wrong.\nUse 'writeconf' on "
1725 "the MDT to force log regeneration."
1726 "\n", mti->mti_svname);
1727 /* Not in client log? Upgrade anyhow...*/
1728 /* Argument against upgrading: reformat MDT,
1729 upgrade OST, then OST will start but will be SKIPped
1730 in client logs. Maybe error now is better. */
1731 /* RETURN(-EINVAL); */
1733 /* end COMPAT_146 */
1735 if (rc == EALREADY) {
1736 /* This might be a params update, or a
1737 local writeconf. (For "full" writeconf, the client
1738 log won't have an entry for this target, so we
1740 LCONSOLE_WARN("Found index %d for %s, updating log\n",
1741 mti->mti_stripe_index, mti->mti_svname);
1742 /* We would like to mark old log sections as invalid
1743 and add new log sections in the client and mdt logs.
1744 But if we add new sections, then live clients will
1745 get repeat setup instructions for already running
1746 osc's. So don't update the client/mdt logs. */
1747 mti->mti_flags &= ~LDD_F_UPDATE;
1751 rc = mgs_find_or_make_fsdb(obd, mti->mti_fsname, &fsdb);
1753 CERROR("Can't get db for %s\n", mti->mti_fsname);
1757 down(&fsdb->fsdb_sem);
1759 if (mti->mti_flags &
1760 (LDD_F_VIRGIN | LDD_F_UPGRADE14 | LDD_F_WRITECONF)) {
1761 /* Generate a log from scratch */
1762 if (mti->mti_flags & LDD_F_SV_TYPE_MDT) {
1763 rc = mgs_write_log_mdt(obd, fsdb, mti);
1764 } else if (mti->mti_flags & LDD_F_SV_TYPE_OST) {
1765 rc = mgs_write_log_ost(obd, fsdb, mti);
1767 CERROR("Unknown target type %#x, can't create log for "
1768 "%s\n", mti->mti_flags, mti->mti_svname);
1771 CERROR("Can't write logs for %s (%d)\n",
1772 mti->mti_svname, rc);
1776 /* Just update the params from tunefs in mgs_write_log_params */
1777 CDEBUG(D_MGS, "Update params for %s\n", mti->mti_svname);
1778 mti->mti_flags |= LDD_F_PARAM;
1781 rc = mgs_write_log_params(obd, fsdb, mti);
1784 up(&fsdb->fsdb_sem);
1789 /* verify that we can handle the old config logs */
1790 int mgs_upgrade_sv_14(struct obd_device *obd, struct mgs_target_info *mti)
1796 /* Create ost log normally, as servers register. Servers
1797 register with their old uuids (from last_rcvd), so old
1798 (MDT and client) logs should work.
1799 - new MDT won't know about old OSTs, only the ones that have
1800 registered, so we need the old MDT log to get the LOV right
1801 in order for old clients to work.
1802 - Old clients connect to the MDT, not the MGS, for their logs, and
1803 will therefore receive the old client log from the MDT /LOGS dir.
1804 - Old clients can continue to use and connect to old or new OSTs
1805 - New clients will contact the MGS for their log
1808 LCONSOLE_INFO("upgrading server %s from pre-1.6\n", mti->mti_svname);
1809 server_mti_print("upgrade", mti);
1811 rc = mgs_find_or_make_fsdb(obd, mti->mti_fsname, &fsdb);
1815 if (fsdb->fsdb_flags & FSDB_LOG_EMPTY) {
1816 LCONSOLE_ERROR_MSG(0x14a, "The old client log %s-client is "
1817 "missing. Was tunefs.lustre successful?\n",
1822 if (fsdb->fsdb_gen == 0) {
1823 /* There were no markers in the client log, meaning we have
1824 not updated the logs for this fs */
1825 CDEBUG(D_MGS, "found old, unupdated client log\n");
1828 if (mti->mti_flags & LDD_F_SV_TYPE_MDT) {
1829 if (mgs_log_is_empty(obd, mti->mti_svname)) {
1830 LCONSOLE_ERROR_MSG(0x14b, "The old MDT log %s is "
1831 "missing. Was tunefs.lustre "
1837 /* We're starting with an old uuid. Assume old name for lov
1838 as well since the lov entry already exists in the log. */
1839 CDEBUG(D_MGS, "old mds uuid %s\n", mti->mti_uuid);
1840 if (strncmp(mti->mti_uuid, fsdb->fsdb_mdtlov + 4,
1841 strlen(fsdb->fsdb_mdtlov) - 4) != 0) {
1842 CERROR("old mds uuid %s doesn't match log %s (%s)\n",
1843 mti->mti_uuid, fsdb->fsdb_mdtlov,
1844 fsdb->fsdb_mdtlov + 4);
1849 if (!(fsdb->fsdb_flags & FSDB_OLDLOG14)) {
1850 LCONSOLE_ERROR_MSG(0x14c, "%s-client is supposedly an old log, "
1851 "but no old LOV or MDT was found. Consider "
1852 "updating the configuration with "
1853 "--writeconf.\n", mti->mti_fsname);
1858 /* end COMPAT_146 */
1860 int mgs_erase_log(struct obd_device *obd, char *name)
1862 struct lvfs_run_ctxt saved;
1863 struct llog_ctxt *ctxt;
1864 struct llog_handle *llh;
1867 ctxt = llog_get_context(obd, LLOG_CONFIG_ORIG_CTXT);
1868 LASSERT(ctxt != NULL);
1870 push_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
1871 rc = llog_create(ctxt, &llh, NULL, name);
1873 llog_init_handle(llh, LLOG_F_IS_PLAIN, NULL);
1874 rc = llog_destroy(llh);
1875 llog_free_handle(llh);
1877 pop_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
1878 llog_ctxt_put(ctxt);
1881 CERROR("failed to clear log %s: %d\n", name, rc);
1886 /* erase all logs for the given fs */
1887 int mgs_erase_logs(struct obd_device *obd, char *fsname)
1889 struct mgs_obd *mgs = &obd->u.mgs;
1890 static struct fs_db *fsdb;
1891 struct list_head dentry_list;
1892 struct l_linux_dirent *dirent, *n;
1893 int rc, len = strlen(fsname);
1896 /* Find all the logs in the CONFIGS directory */
1897 rc = class_dentry_readdir(obd, mgs->mgs_configs_dir,
1898 mgs->mgs_vfsmnt, &dentry_list);
1900 CERROR("Can't read %s dir\n", MOUNT_CONFIGS_DIR);
1904 down(&mgs->mgs_sem);
1906 /* Delete the fs db */
1907 fsdb = mgs_find_fsdb(obd, fsname);
1909 mgs_free_fsdb(obd, fsdb);
1911 list_for_each_entry_safe(dirent, n, &dentry_list, lld_list) {
1912 list_del(&dirent->lld_list);
1913 if (strncmp(fsname, dirent->lld_name, len) == 0) {
1914 CDEBUG(D_MGS, "Removing log %s\n", dirent->lld_name);
1915 mgs_erase_log(obd, dirent->lld_name);
1917 OBD_FREE(dirent, sizeof(*dirent));
1925 /* from llog_swab */
1926 static void print_lustre_cfg(struct lustre_cfg *lcfg)
1931 CDEBUG(D_MGS, "lustre_cfg: %p\n", lcfg);
1932 CDEBUG(D_MGS, "\tlcfg->lcfg_version: %#x\n", lcfg->lcfg_version);
1934 CDEBUG(D_MGS, "\tlcfg->lcfg_command: %#x\n", lcfg->lcfg_command);
1935 CDEBUG(D_MGS, "\tlcfg->lcfg_num: %#x\n", lcfg->lcfg_num);
1936 CDEBUG(D_MGS, "\tlcfg->lcfg_flags: %#x\n", lcfg->lcfg_flags);
1937 CDEBUG(D_MGS, "\tlcfg->lcfg_nid: %s\n", libcfs_nid2str(lcfg->lcfg_nid));
1939 CDEBUG(D_MGS, "\tlcfg->lcfg_bufcount: %d\n", lcfg->lcfg_bufcount);
1940 if (lcfg->lcfg_bufcount < LUSTRE_CFG_MAX_BUFCOUNT)
1941 for (i = 0; i < lcfg->lcfg_bufcount; i++) {
1942 CDEBUG(D_MGS, "\tlcfg->lcfg_buflens[%d]: %d %s\n",
1943 i, lcfg->lcfg_buflens[i],
1944 lustre_cfg_string(lcfg, i));
1949 /* Set a permanent (config log) param for a target or fs */
1950 int mgs_setparam(struct obd_device *obd, struct lustre_cfg *lcfg, char *fsname)
1953 struct mgs_target_info *mti;
1954 char *devname, *param;
1960 print_lustre_cfg(lcfg);
1962 /* lustre, lustre-mdtlov, lustre-client, lustre-MDT0000 */
1963 devname = lustre_cfg_string(lcfg, 0);
1964 param = lustre_cfg_string(lcfg, 1);
1966 /* Assume device name embedded in param:
1967 lustre-OST0000.osc.max_dirty_mb=32 */
1968 ptr = strchr(param, '.');
1976 LCONSOLE_ERROR_MSG(0x14d, "No target specified: %s\n", param);
1980 /* Extract fsname */
1981 ptr = strrchr(devname, '-');
1982 memset(fsname, 0, MTI_NAME_MAXLEN);
1983 if (ptr && (server_name2index(ptr, &index, NULL) >= 0)) {
1984 /* param related to llite isn't allowed to set by OST or MDT */
1985 if (strncmp(param, PARAM_LLITE, sizeof(PARAM_LLITE)) == 0)
1988 strncpy(fsname, devname, ptr - devname);
1990 /* assume devname is the fsname */
1991 strncpy(fsname, devname, MTI_NAME_MAXLEN);
1993 fsname[MTI_NAME_MAXLEN - 1] = 0;
1994 CDEBUG(D_MGS, "setparam on fs %s device %s\n", fsname, devname);
1996 rc = mgs_find_or_make_fsdb(obd, fsname, &fsdb);
1999 if (fsdb->fsdb_flags & FSDB_LOG_EMPTY) {
2000 CERROR("No filesystem targets for %s. cfg_device from lctl "
2001 "is '%s'\n", fsname, devname);
2002 mgs_free_fsdb(obd, fsdb);
2006 /* Create a fake mti to hold everything */
2009 GOTO(out, rc = -ENOMEM);
2010 strncpy(mti->mti_fsname, fsname, MTI_NAME_MAXLEN);
2011 strncpy(mti->mti_svname, devname, MTI_NAME_MAXLEN);
2012 strncpy(mti->mti_params, param, sizeof(mti->mti_params));
2013 rc = server_name2index(mti->mti_svname, &mti->mti_stripe_index, &tmp);
2015 /* Not a valid server; may be only fsname */
2018 /* Strip -osc or -mdc suffix from svname */
2019 if (server_make_name(rc, mti->mti_stripe_index, mti->mti_fsname,
2021 GOTO(out, rc = -EINVAL);
2023 mti->mti_flags = rc | LDD_F_PARAM;
2025 down(&fsdb->fsdb_sem);
2026 rc = mgs_write_log_params(obd, fsdb, mti);
2027 up(&fsdb->fsdb_sem);
2035 static int mgs_write_log_pool(struct obd_device *obd, char *logname, struct fs_db *fsdb,
2037 enum lcfg_command_type cmd,
2038 char *poolname, char *fsname,
2039 char *ostname, char *comment)
2041 struct llog_handle *llh = NULL;
2044 rc = record_start_log(obd, &llh, logname);
2047 rc = record_marker(obd, llh, fsdb, CM_START, lovname, comment);
2048 record_base(obd, llh, lovname, 0, cmd, poolname, fsname, ostname, 0);
2049 rc = record_marker(obd, llh, fsdb, CM_END, lovname, comment);
2050 rc = record_end_log(obd, &llh);
2055 int mgs_pool_cmd(struct obd_device *obd, enum lcfg_command_type cmd,
2056 char *fsname, char *poolname, char *ostname)
2062 char *label, *canceled_label = NULL;
2064 struct mgs_target_info *mti;
2068 rc = mgs_find_or_make_fsdb(obd, fsname, &fsdb);
2070 CERROR("Can't get db for %s\n", fsname);
2073 if (fsdb->fsdb_flags & FSDB_LOG_EMPTY) {
2074 CERROR("%s is not defined\n", fsname);
2075 mgs_free_fsdb(obd, fsdb);
2079 label_sz = 10 + strlen(fsname) + strlen(poolname);
2081 /* check if ostname match fsname */
2082 if (ostname != NULL) {
2085 ptr = strrchr(ostname, '-');
2086 if ((ptr == NULL) ||
2087 (strncmp(fsname, ostname, ptr-ostname) != 0))
2089 label_sz += strlen(ostname);
2092 OBD_ALLOC(label, label_sz);
2097 case LCFG_POOL_NEW: {
2099 "new %s.%s", fsname, poolname);
2102 case LCFG_POOL_ADD: {
2104 "add %s.%s.%s", fsname, poolname, ostname);
2107 case LCFG_POOL_REM: {
2108 OBD_ALLOC(canceled_label, label_sz);
2109 if (canceled_label == NULL)
2112 "rem %s.%s.%s", fsname, poolname, ostname);
2113 sprintf(canceled_label,
2114 "add %s.%s.%s", fsname, poolname, ostname);
2117 case LCFG_POOL_DEL: {
2118 OBD_ALLOC(canceled_label, label_sz);
2119 if (canceled_label == NULL)
2122 "del %s.%s", fsname, poolname);
2123 sprintf(canceled_label,
2124 "new %s.%s", fsname, poolname);
2132 down(&fsdb->fsdb_sem);
2134 sprintf(mdt_index, "-MDT%04x", 0);
2135 name_create(&logname, fsname, mdt_index);
2136 name_create(&lovname, fsdb->fsdb_mdtlov, "");
2139 if (canceled_label != NULL) {
2140 OBD_ALLOC(mti, sizeof(*mti));
2142 strcpy(mti->mti_svname, "lov pool");
2143 mgs_modify(obd, fsdb, mti, logname, lovname,
2144 canceled_label, CM_SKIP);
2148 mgs_write_log_pool(obd, logname, fsdb, lovname,
2149 cmd, fsname, poolname, ostname, label);
2150 name_destroy(&logname);
2152 name_create(&logname, fsname, "-client");
2153 if (canceled_label != NULL) {
2154 mgs_modify(obd, fsdb, mti, logname, lovname,
2155 canceled_label, CM_SKIP);
2157 mgs_write_log_pool(obd, logname, fsdb, fsdb->fsdb_clilov,
2158 cmd, fsname, poolname, ostname, label);
2159 name_destroy(&logname);
2160 name_destroy(&lovname);
2162 up(&fsdb->fsdb_sem);
2164 OBD_FREE(label, label_sz);
2165 if (canceled_label != NULL)
2166 OBD_FREE(canceled_label, label_sz);
2169 OBD_FREE(mti, sizeof(*mti));
2175 /******************** unused *********************/
2176 static int mgs_backup_llog(struct obd_device *obd, char* fsname)
2178 struct file *filp, *bak_filp;
2179 struct lvfs_run_ctxt saved;
2180 char *logname, *buf;
2181 loff_t soff = 0 , doff = 0;
2182 int count = 4096, len;
2185 OBD_ALLOC(logname, PATH_MAX);
2186 if (logname == NULL)
2189 OBD_ALLOC(buf, count);
2191 GOTO(out , rc = -ENOMEM);
2193 len = snprintf(logname, PATH_MAX, "%s/%s.bak",
2194 MOUNT_CONFIGS_DIR, fsname);
2196 if (len >= PATH_MAX - 1) {
2197 GOTO(out, -ENAMETOOLONG);
2200 push_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
2202 bak_filp = l_filp_open(logname, O_RDWR|O_CREAT|O_TRUNC, 0660);
2203 if (IS_ERR(bak_filp)) {
2204 rc = PTR_ERR(bak_filp);
2205 CERROR("backup logfile open %s: %d\n", logname, rc);
2208 sprintf(logname, "%s/%s", MOUNT_CONFIGS_DIR, fsname);
2209 filp = l_filp_open(logname, O_RDONLY, 0);
2212 CERROR("logfile open %s: %d\n", logname, rc);
2216 while ((rc = lustre_fread(filp, buf, count, &soff)) > 0) {
2217 rc = lustre_fwrite(bak_filp, buf, count, &doff);
2221 filp_close(filp, 0);
2223 filp_close(bak_filp, 0);
2225 pop_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
2228 OBD_FREE(buf, count);
2229 OBD_FREE(logname, PATH_MAX);