]> git.proxmox.com Git - ceph.git/blame - ceph/src/tools/cephfs/Resetter.cc
bump version to 18.2.2-pve1
[ceph.git] / ceph / src / tools / cephfs / Resetter.cc
CommitLineData
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
29using namespace std;
30
11fdf7f2
TL
31int 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
74int 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 148int 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
193int 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