1 // -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
2 // vim: ts=8 sw=2 smarttab
4 * Ceph - scalable distributed file system
6 * Copyright (C) 2010 Greg Farnum <gregf@hq.newdream.net>
8 * This is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Lesser General Public
10 * License version 2.1, as published by the Free Software
11 * Foundation. See file COPYING.
15 #include "common/errno.h"
16 #include "osdc/Journaler.h"
17 #include "mds/JournalPointer.h"
19 #include "mds/mdstypes.h"
20 #include "mds/MDCache.h"
21 #include "mon/MonClient.h"
22 #include "mds/events/EResetJournal.h"
26 #define dout_context g_ceph_context
27 #define dout_subsys ceph_subsys_mds
29 int Resetter::reset(mds_role_t role
)
31 Mutex
mylock("Resetter::reset::lock");
36 auto fs
= fsmap
->get_filesystem(role
.fscid
);
37 assert(fs
!= nullptr);
38 int64_t const pool_id
= fs
->mds_map
.get_metadata_pool();
40 JournalPointer
jp(role
.rank
, pool_id
);
41 int jp_load_result
= jp
.load(objecter
);
42 if (jp_load_result
!= 0) {
43 std::cerr
<< "Error loading journal: " << cpp_strerror(jp_load_result
) <<
44 ", pass --force to forcibly reset this journal" << std::endl
;
45 return jp_load_result
;
48 Journaler
journaler("resetter", jp
.front
,
51 objecter
, 0, 0, &finisher
);
54 journaler
.recover(new C_SafeCond(&mylock
, &cond
, &done
, &r
));
64 cerr
<< "journal does not exist on-disk. Did you set a bad rank?"
66 std::cerr
<< "Error loading journal: " << cpp_strerror(r
) <<
67 ", pass --force to forcibly reset this journal" << std::endl
;
70 cerr
<< "got error " << r
<< "from Journaler, failing" << std::endl
;
76 uint64_t old_start
= journaler
.get_read_pos();
77 uint64_t old_end
= journaler
.get_write_pos();
78 uint64_t old_len
= old_end
- old_start
;
79 cout
<< "old journal was " << old_start
<< "~" << old_len
<< std::endl
;
81 uint64_t new_start
= ROUND_UP_TO(old_end
+1, journaler
.get_layout_period());
82 cout
<< "new journal start will be " << new_start
83 << " (" << (new_start
- old_end
) << " bytes past old end)" << std::endl
;
85 journaler
.set_read_pos(new_start
);
86 journaler
.set_write_pos(new_start
);
87 journaler
.set_expire_pos(new_start
);
88 journaler
.set_trimmed_pos(new_start
);
89 journaler
.set_writeable();
91 cout
<< "writing journal head" << std::endl
;
92 journaler
.write_head(new C_SafeCond(&mylock
, &cond
, &done
, &r
));
100 Mutex::Locker
l(lock
);
105 r
= _write_reset_event(&journaler
);
110 cout
<< "done" << std::endl
;
115 int Resetter::reset_hard(mds_role_t role
)
117 auto fs
= fsmap
->get_filesystem(role
.fscid
);
118 assert(fs
!= nullptr);
119 int64_t const pool_id
= fs
->mds_map
.get_metadata_pool();
121 JournalPointer
jp(role
.rank
, pool_id
);
122 jp
.front
= role
.rank
+ MDS_INO_LOG_OFFSET
;
124 int r
= jp
.save(objecter
);
126 derr
<< "Error writing journal pointer: " << cpp_strerror(r
) << dendl
;
130 Journaler
journaler("resetter", jp
.front
,
132 CEPH_FS_ONDISK_MAGIC
,
133 objecter
, 0, 0, &finisher
);
134 journaler
.set_writeable();
136 file_layout_t default_log_layout
= MDCache::gen_default_log_layout(
137 fsmap
->get_filesystem(role
.fscid
)->mds_map
);
138 journaler
.create(&default_log_layout
, g_conf
->mds_journal_format
);
142 Mutex::Locker
l(lock
);
143 journaler
.write_head(&cond
);
147 derr
<< "Error writing journal header: " << cpp_strerror(r
) << dendl
;
152 Mutex::Locker
l(lock
);
153 r
= _write_reset_event(&journaler
);
156 derr
<< "Error writing EResetJournal: " << cpp_strerror(r
) << dendl
;
160 dout(4) << "Successfully wrote new journal pointer and header for rank "
165 int Resetter::_write_reset_event(Journaler
*journaler
)
167 assert(journaler
!= NULL
);
169 LogEvent
*le
= new EResetJournal
;
172 le
->encode_with_header(bl
, CEPH_FEATURES_SUPPORTED_DEFAULT
);
174 cout
<< "writing EResetJournal entry" << std::endl
;
175 journaler
->append_entry(bl
);
180 journaler
->flush(&cond
);
186 // wait until all journal prezero ops are done
188 journaler
->wait_for_prezero(&cond
);