Fix some bugs when testing opensds ansible
[stor4nfv.git] / src / ceph / src / tools / cephfs / Resetter.cc
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);
173   
174   cout << "writing EResetJournal entry" << std::endl;
175   C_SaferCond cond;
176   journaler->append_entry(bl);
177   journaler->flush(&cond);
178
179   return cond.wait();
180 }
181