]>
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 | */ | |
14 | ||
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 | ||
29 | int Resetter::reset(mds_role_t role) | |
30 | { | |
31 | Mutex mylock("Resetter::reset::lock"); | |
32 | Cond cond; | |
33 | bool done; | |
34 | int r; | |
35 | ||
36 | auto fs = fsmap->get_filesystem(role.fscid); | |
37 | assert(fs != nullptr); | |
38 | int64_t const pool_id = fs->mds_map.get_metadata_pool(); | |
39 | ||
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; | |
46 | } | |
47 | ||
48 | Journaler journaler("resetter", jp.front, | |
49 | pool_id, | |
50 | CEPH_FS_ONDISK_MAGIC, | |
51 | objecter, 0, 0, &finisher); | |
52 | ||
53 | lock.Lock(); | |
54 | journaler.recover(new C_SafeCond(&mylock, &cond, &done, &r)); | |
55 | lock.Unlock(); | |
56 | ||
57 | mylock.Lock(); | |
58 | while (!done) | |
59 | cond.Wait(mylock); | |
60 | mylock.Unlock(); | |
61 | ||
62 | if (r != 0) { | |
63 | if (r == -ENOENT) { | |
64 | cerr << "journal does not exist on-disk. Did you set a bad rank?" | |
65 | << std::endl; | |
66 | std::cerr << "Error loading journal: " << cpp_strerror(r) << | |
67 | ", pass --force to forcibly reset this journal" << std::endl; | |
68 | return r; | |
69 | } else { | |
70 | cerr << "got error " << r << "from Journaler, failing" << std::endl; | |
71 | return r; | |
72 | } | |
73 | } | |
74 | ||
75 | lock.Lock(); | |
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; | |
80 | ||
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; | |
84 | ||
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(); | |
90 | ||
91 | cout << "writing journal head" << std::endl; | |
92 | journaler.write_head(new C_SafeCond(&mylock, &cond, &done, &r)); | |
93 | lock.Unlock(); | |
94 | ||
95 | mylock.Lock(); | |
96 | while (!done) | |
97 | cond.Wait(mylock); | |
98 | mylock.Unlock(); | |
99 | ||
100 | Mutex::Locker l(lock); | |
101 | if (r != 0) { | |
102 | return r; | |
103 | } | |
104 | ||
105 | r = _write_reset_event(&journaler); | |
106 | if (r != 0) { | |
107 | return r; | |
108 | } | |
109 | ||
110 | cout << "done" << std::endl; | |
111 | ||
112 | return 0; | |
113 | } | |
114 | ||
115 | int Resetter::reset_hard(mds_role_t role) | |
116 | { | |
117 | auto fs = fsmap->get_filesystem(role.fscid); | |
118 | assert(fs != nullptr); | |
119 | int64_t const pool_id = fs->mds_map.get_metadata_pool(); | |
120 | ||
121 | JournalPointer jp(role.rank, pool_id); | |
122 | jp.front = role.rank + MDS_INO_LOG_OFFSET; | |
123 | jp.back = 0; | |
124 | int r = jp.save(objecter); | |
125 | if (r != 0) { | |
126 | derr << "Error writing journal pointer: " << cpp_strerror(r) << dendl; | |
127 | return r; | |
128 | } | |
129 | ||
130 | Journaler journaler("resetter", jp.front, | |
131 | pool_id, | |
132 | CEPH_FS_ONDISK_MAGIC, | |
133 | objecter, 0, 0, &finisher); | |
134 | journaler.set_writeable(); | |
135 | ||
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); | |
139 | ||
140 | C_SaferCond cond; | |
141 | { | |
142 | Mutex::Locker l(lock); | |
143 | journaler.write_head(&cond); | |
144 | } | |
145 | r = cond.wait(); | |
146 | if (r != 0) { | |
147 | derr << "Error writing journal header: " << cpp_strerror(r) << dendl; | |
148 | return r; | |
149 | } | |
150 | ||
151 | { | |
152 | Mutex::Locker l(lock); | |
153 | r = _write_reset_event(&journaler); | |
154 | } | |
155 | if (r != 0) { | |
156 | derr << "Error writing EResetJournal: " << cpp_strerror(r) << dendl; | |
157 | return r; | |
158 | } | |
159 | ||
160 | dout(4) << "Successfully wrote new journal pointer and header for rank " | |
161 | << role << dendl; | |
162 | return 0; | |
163 | } | |
164 | ||
165 | int Resetter::_write_reset_event(Journaler *journaler) | |
166 | { | |
167 | assert(journaler != NULL); | |
168 | ||
169 | LogEvent *le = new EResetJournal; | |
170 | ||
171 | bufferlist bl; | |
172 | le->encode_with_header(bl, CEPH_FEATURES_SUPPORTED_DEFAULT); | |
28e407b8 | 173 | |
7c673cae | 174 | cout << "writing EResetJournal entry" << std::endl; |
7c673cae | 175 | journaler->append_entry(bl); |
7c673cae | 176 | |
28e407b8 AA |
177 | int ret; |
178 | { | |
179 | C_SaferCond cond; | |
180 | journaler->flush(&cond); | |
181 | ret = cond.wait(); | |
182 | if (ret < 0) | |
183 | return ret; | |
184 | } | |
185 | { | |
186 | // wait until all journal prezero ops are done | |
187 | C_SaferCond cond; | |
188 | journaler->wait_for_prezero(&cond); | |
189 | cond.wait(); | |
190 | } | |
191 | ||
192 | return ret; | |
7c673cae FG |
193 | } |
194 |