]>
Commit | Line | Data |
---|---|---|
7c673cae FG |
1 | // -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*- |
2 | // vim: ts=8 sw=2 smarttab | |
3 | /* | |
4 | * Ceph - scalable distributed file system | |
5 | * | |
6 | * Copyright (C) 2010 Greg Farnum <gregf@hq.newdream.net> | |
7 | * | |
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. | |
12 | * | |
13 | */ | |
eafe8130 | 14 | #include <memory> |
7c673cae FG |
15 | #include "common/errno.h" |
16 | #include "osdc/Journaler.h" | |
17 | #include "mds/JournalPointer.h" | |
18 | ||
19 | #include "mds/mdstypes.h" | |
20 | #include "mds/MDCache.h" | |
21 | #include "mon/MonClient.h" | |
22 | #include "mds/events/EResetJournal.h" | |
23 | ||
24 | #include "Resetter.h" | |
25 | ||
26 | #define dout_context g_ceph_context | |
27 | #define dout_subsys ceph_subsys_mds | |
28 | ||
20effc67 TL |
29 | using namespace std; |
30 | ||
11fdf7f2 TL |
31 | int Resetter::init(mds_role_t role_, const std::string &type, bool hard) |
32 | { | |
33 | role = role_; | |
34 | int r = MDSUtility::init(); | |
35 | if (r < 0) { | |
36 | return r; | |
37 | } | |
38 | ||
39 | auto fs = fsmap->get_filesystem(role.fscid); | |
40 | ceph_assert(nullptr != fs); | |
41 | ||
42 | is_mdlog = false; | |
43 | if (type == "mdlog") { | |
44 | JournalPointer jp(role.rank, fs->mds_map.get_metadata_pool()); | |
45 | int rt = 0; | |
46 | if (hard) { | |
47 | jp.front = role.rank + MDS_INO_LOG_OFFSET; | |
48 | jp.back = 0; | |
49 | rt = jp.save(objecter); | |
50 | if (rt != 0) { | |
51 | derr << "Error writing journal pointer: " << cpp_strerror(rt) << dendl; | |
52 | return rt; | |
53 | } | |
54 | ino = jp.front; // only need to reset ino for mdlog | |
55 | } else { | |
56 | rt = jp.load(objecter); | |
57 | if (rt != 0) { | |
58 | std::cerr << "Error loading journal: " << cpp_strerror(rt) << | |
59 | ", pass --force to forcibly reset this journal" << std::endl; | |
60 | return rt; | |
61 | } else { | |
62 | ino = jp.front; | |
63 | } | |
64 | } | |
65 | is_mdlog = true; | |
66 | } else if (type == "purge_queue") { | |
67 | ino = MDS_INO_PURGE_QUEUE + role.rank; | |
68 | } else { | |
69 | ceph_abort(); // should not get here | |
70 | } | |
71 | return 0; | |
72 | } | |
73 | ||
74 | int Resetter::reset() | |
7c673cae | 75 | { |
9f95a23c TL |
76 | ceph::mutex mylock = ceph::make_mutex("Resetter::reset::lock"); |
77 | ceph::condition_variable cond; | |
7c673cae FG |
78 | bool done; |
79 | int r; | |
80 | ||
81 | auto fs = fsmap->get_filesystem(role.fscid); | |
11fdf7f2 | 82 | ceph_assert(fs != nullptr); |
7c673cae | 83 | |
11fdf7f2 TL |
84 | Journaler journaler("resetter", ino, |
85 | fs->mds_map.get_metadata_pool(), | |
7c673cae FG |
86 | CEPH_FS_ONDISK_MAGIC, |
87 | objecter, 0, 0, &finisher); | |
9f95a23c TL |
88 | { |
89 | std::lock_guard locker{lock}; | |
90 | journaler.recover(new C_SafeCond(mylock, cond, &done, &r)); | |
91 | } | |
92 | { | |
93 | std::unique_lock locker{mylock}; | |
94 | cond.wait(locker, [&done] { return done; }); | |
95 | } | |
7c673cae FG |
96 | if (r != 0) { |
97 | if (r == -ENOENT) { | |
98 | cerr << "journal does not exist on-disk. Did you set a bad rank?" | |
99 | << std::endl; | |
100 | std::cerr << "Error loading journal: " << cpp_strerror(r) << | |
101 | ", pass --force to forcibly reset this journal" << std::endl; | |
102 | return r; | |
103 | } else { | |
104 | cerr << "got error " << r << "from Journaler, failing" << std::endl; | |
105 | return r; | |
106 | } | |
107 | } | |
108 | ||
9f95a23c | 109 | lock.lock(); |
7c673cae FG |
110 | uint64_t old_start = journaler.get_read_pos(); |
111 | uint64_t old_end = journaler.get_write_pos(); | |
112 | uint64_t old_len = old_end - old_start; | |
113 | cout << "old journal was " << old_start << "~" << old_len << std::endl; | |
114 | ||
11fdf7f2 | 115 | uint64_t new_start = round_up_to(old_end+1, journaler.get_layout_period()); |
7c673cae FG |
116 | cout << "new journal start will be " << new_start |
117 | << " (" << (new_start - old_end) << " bytes past old end)" << std::endl; | |
118 | ||
119 | journaler.set_read_pos(new_start); | |
120 | journaler.set_write_pos(new_start); | |
121 | journaler.set_expire_pos(new_start); | |
122 | journaler.set_trimmed_pos(new_start); | |
123 | journaler.set_writeable(); | |
124 | ||
125 | cout << "writing journal head" << std::endl; | |
9f95a23c TL |
126 | journaler.write_head(new C_SafeCond(mylock, cond, &done, &r)); |
127 | lock.unlock(); | |
128 | { | |
129 | std::unique_lock locker{mylock}; | |
130 | cond.wait(locker, [&done] { return done; }); | |
131 | } | |
132 | std::lock_guard l{lock}; | |
7c673cae FG |
133 | if (r != 0) { |
134 | return r; | |
135 | } | |
11fdf7f2 TL |
136 | |
137 | if (is_mdlog) { | |
138 | r = _write_reset_event(&journaler); // reset envent is specific for mdlog journal | |
139 | if (r != 0) { | |
140 | return r; | |
141 | } | |
7c673cae | 142 | } |
7c673cae FG |
143 | cout << "done" << std::endl; |
144 | ||
145 | return 0; | |
146 | } | |
147 | ||
11fdf7f2 | 148 | int Resetter::reset_hard() |
7c673cae FG |
149 | { |
150 | auto fs = fsmap->get_filesystem(role.fscid); | |
11fdf7f2 TL |
151 | |
152 | Journaler journaler("resetter", ino, | |
153 | fs->mds_map.get_metadata_pool(), | |
7c673cae FG |
154 | CEPH_FS_ONDISK_MAGIC, |
155 | objecter, 0, 0, &finisher); | |
156 | journaler.set_writeable(); | |
157 | ||
158 | file_layout_t default_log_layout = MDCache::gen_default_log_layout( | |
159 | fsmap->get_filesystem(role.fscid)->mds_map); | |
11fdf7f2 | 160 | journaler.create(&default_log_layout, g_conf()->mds_journal_format); |
7c673cae FG |
161 | |
162 | C_SaferCond cond; | |
163 | { | |
9f95a23c | 164 | std::lock_guard l{lock}; |
7c673cae FG |
165 | journaler.write_head(&cond); |
166 | } | |
11fdf7f2 TL |
167 | |
168 | int r = cond.wait(); | |
7c673cae FG |
169 | if (r != 0) { |
170 | derr << "Error writing journal header: " << cpp_strerror(r) << dendl; | |
171 | return r; | |
172 | } | |
11fdf7f2 TL |
173 | |
174 | if (is_mdlog) // reset event is specific for mdlog journal | |
7c673cae | 175 | { |
9f95a23c | 176 | std::lock_guard l{lock}; |
7c673cae | 177 | r = _write_reset_event(&journaler); |
11fdf7f2 TL |
178 | if (r != 0) { |
179 | derr << "Error writing EResetJournal: " << cpp_strerror(r) << dendl; | |
180 | return r; | |
181 | } | |
7c673cae | 182 | } |
11fdf7f2 TL |
183 | |
184 | if (is_mdlog) { | |
185 | dout(4) << "Successfully wrote new journal pointer and header for rank " | |
186 | << role << dendl; | |
187 | } else { | |
188 | dout(4) << "Successfully wrote header for rank " << role << dendl; | |
7c673cae | 189 | } |
7c673cae FG |
190 | return 0; |
191 | } | |
192 | ||
193 | int Resetter::_write_reset_event(Journaler *journaler) | |
194 | { | |
11fdf7f2 | 195 | ceph_assert(journaler != NULL); |
7c673cae | 196 | |
eafe8130 | 197 | auto le = std::make_unique<EResetJournal>(); |
7c673cae FG |
198 | |
199 | bufferlist bl; | |
200 | le->encode_with_header(bl, CEPH_FEATURES_SUPPORTED_DEFAULT); | |
28e407b8 | 201 | |
7c673cae | 202 | cout << "writing EResetJournal entry" << std::endl; |
7c673cae | 203 | journaler->append_entry(bl); |
7c673cae | 204 | |
28e407b8 AA |
205 | int ret; |
206 | { | |
207 | C_SaferCond cond; | |
208 | journaler->flush(&cond); | |
209 | ret = cond.wait(); | |
210 | if (ret < 0) | |
211 | return ret; | |
212 | } | |
213 | { | |
214 | // wait until all journal prezero ops are done | |
215 | C_SaferCond cond; | |
216 | journaler->wait_for_prezero(&cond); | |
217 | cond.wait(); | |
218 | } | |
219 | ||
220 | return ret; | |
7c673cae FG |
221 | } |
222 |