]>
git.proxmox.com Git - ceph.git/blob - ceph/src/test/objectstore/FileStoreDiff.cc
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) 2012 New Dream Network
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.
16 #include <boost/scoped_ptr.hpp>
17 #include "common/debug.h"
18 #include "os/filestore/FileStore.h"
19 #include "common/config.h"
21 #include "FileStoreDiff.h"
23 #define dout_context g_ceph_context
24 #define dout_subsys ceph_subsys_filestore
26 #define dout_prefix *_dout << "filestore_diff "
30 FileStoreDiff::FileStoreDiff(FileStore
*a
, FileStore
*b
)
31 : a_store(a
), b_store(b
)
34 err
= a_store
->mount();
35 ceph_assert(err
== 0);
37 err
= b_store
->mount();
38 ceph_assert(err
== 0);
41 FileStoreDiff::~FileStoreDiff()
48 bool FileStoreDiff::diff_attrs(std::map
<std::string
,bufferptr
,std::less
<>>& b
,
49 std::map
<std::string
,bufferptr
,std::less
<>>& a
)
52 auto b_it
= b
.begin();
53 auto a_it
= a
.begin();
54 for (; b_it
!= b
.end(); ++b_it
, ++a_it
) {
55 if (b_it
->first
!= a_it
->first
) {
56 cout
<< "diff_attrs name mismatch (verify: " << b_it
->first
57 << ", store: " << a_it
->first
<< ")" << std::endl
;
62 if (!b_it
->second
.cmp(a_it
->second
)) {
63 cout
<< "diff_attrs contents mismatch on attr " << b_it
->first
<< std::endl
;
71 static bool diff_omap(std::map
<std::string
,bufferlist
>& b
,
72 std::map
<std::string
,bufferlist
>& a
)
75 std::map
<std::string
, bufferlist
>::iterator b_it
= b
.begin();
76 std::map
<std::string
, bufferlist
>::iterator a_it
= a
.begin();
77 for (; b_it
!= b
.end(); ++b_it
, ++a_it
) {
78 if (a_it
== a
.end()) {
79 cout
<< __func__
<< " a reached end before b, a missing " << b_it
->first
84 if (b_it
->first
!= a_it
->first
) {
85 cout
<< "diff_attrs name mismatch (verify: " << b_it
->first
86 << ", store: " << a_it
->first
<< ")" << std::endl
;
91 if (!(b_it
->second
== a_it
->second
)) {
92 cout
<< "diff_attrs contents mismatch on attr " << b_it
->first
<< std::endl
;
100 bool FileStoreDiff::diff_objects_stat(struct stat
& a
, struct stat
& b
)
104 if (a
.st_uid
!= b
.st_uid
) {
105 cout
<< "diff_objects_stat uid mismatch (A: "
106 << a
.st_uid
<< " != B: " << b
.st_uid
<< ")" << std::endl
;
110 if (a
.st_gid
!= b
.st_gid
) {
111 cout
<< "diff_objects_stat gid mismatch (A: "
112 << a
.st_gid
<< " != B: " << b
.st_gid
<< ")" << std::endl
;
116 if (a
.st_mode
!= b
.st_mode
) {
117 cout
<< "diff_objects_stat mode mismatch (A: "
118 << a
.st_mode
<< " != B: " << b
.st_mode
<< ")" << std::endl
;
122 if (a
.st_nlink
!= b
.st_nlink
) {
123 cout
<< "diff_objects_stat nlink mismatch (A: "
124 << a
.st_nlink
<< " != B: " << b
.st_nlink
<< ")" << std::endl
;
128 if (a
.st_size
!= b
.st_size
) {
129 cout
<< "diff_objects_stat size mismatch (A: "
130 << a
.st_size
<< " != B: " << b
.st_size
<< ")" << std::endl
;
136 bool FileStoreDiff::diff_objects(FileStore
*a_store
, FileStore
*b_store
, coll_t coll
)
141 std::vector
<ghobject_t
> b_objects
, a_objects
;
142 err
= b_store
->collection_list(coll
, ghobject_t(), ghobject_t::get_max(),
143 INT_MAX
, &b_objects
, NULL
);
145 cout
<< "diff_objects list on verify coll " << coll
.to_str()
146 << " returns " << err
<< std::endl
;
149 err
= a_store
->collection_list(coll
, ghobject_t(), ghobject_t::get_max(),
150 INT_MAX
, &a_objects
, NULL
);
152 cout
<< "diff_objects list on store coll " << coll
.to_str()
153 << " returns " << err
<< std::endl
;
157 if (b_objects
.size() != a_objects
.size()) {
158 cout
<< "diff_objects " << coll
<< " num objs mismatch (A: " << a_objects
.size()
159 << ", B: " << b_objects
.size() << ")" << std::endl
;
161 cout
<< "a: " << a_objects
<< std::endl
;
162 cout
<< "b: " << b_objects
<< std::endl
;
165 auto a_ch
= a_store
->open_collection(coll
);
166 auto b_ch
= b_store
->open_collection(coll
);
167 std::vector
<ghobject_t
>::iterator b_it
= b_objects
.begin();
168 std::vector
<ghobject_t
>::iterator a_it
= b_objects
.begin();
169 for (; b_it
!= b_objects
.end(); ++b_it
, ++a_it
) {
170 ghobject_t b_obj
= *b_it
, a_obj
= *a_it
;
171 if (b_obj
.hobj
.oid
.name
!= a_obj
.hobj
.oid
.name
) {
172 cout
<< "diff_objects name mismatch on A object "
173 << coll
<< "/" << a_obj
<< " and B object "
174 << coll
<< "/" << b_obj
<< std::endl
;
179 struct stat b_stat
, a_stat
;
180 err
= b_store
->stat(b_ch
, b_obj
, &b_stat
);
182 cout
<< "diff_objects error stating B object "
183 << coll
.to_str() << "/" << b_obj
.hobj
.oid
.name
<< std::endl
;
186 err
= a_store
->stat(a_ch
, a_obj
, &a_stat
);
188 cout
<< "diff_objects error stating A object "
189 << coll
<< "/" << a_obj
<< std::endl
;
193 if (diff_objects_stat(a_stat
, b_stat
)) {
194 cout
<< "diff_objects stat mismatch on "
195 << coll
<< "/" << b_obj
<< std::endl
;
199 bufferlist a_obj_bl
, b_obj_bl
;
200 b_store
->read(b_ch
, b_obj
, 0, b_stat
.st_size
, b_obj_bl
);
201 a_store
->read(a_ch
, a_obj
, 0, a_stat
.st_size
, a_obj_bl
);
203 if (!a_obj_bl
.contents_equal(b_obj_bl
)) {
204 cout
<< "diff_objects content mismatch on "
205 << coll
<< "/" << b_obj
<< std::endl
;
209 std::map
<std::string
, bufferptr
, std::less
<>> a_obj_attrs_map
, b_obj_attrs_map
;
210 err
= a_store
->getattrs(a_ch
, a_obj
, a_obj_attrs_map
);
212 cout
<< "diff_objects getattrs on A object " << coll
<< "/" << a_obj
213 << " returns " << err
<< std::endl
;
216 err
= b_store
->getattrs(b_ch
, b_obj
, b_obj_attrs_map
);
218 cout
<< "diff_objects getattrs on B object " << coll
<< "/" << b_obj
219 << "returns " << err
<< std::endl
;
223 if (diff_attrs(b_obj_attrs_map
, a_obj_attrs_map
)) {
224 cout
<< "diff_objects attrs mismatch on A object "
225 << coll
<< "/" << a_obj
<< " and B object "
226 << coll
<< "/" << b_obj
<< std::endl
;
230 std::map
<std::string
, bufferlist
> a_obj_omap
, b_obj_omap
;
231 std::set
<std::string
> a_omap_keys
, b_omap_keys
;
232 err
= a_store
->omap_get_keys(a_ch
, a_obj
, &a_omap_keys
);
234 cout
<< "diff_objects getomap on A object " << coll
<< "/" << a_obj
235 << " returns " << err
<< std::endl
;
238 err
= a_store
->omap_get_values(a_ch
, a_obj
, a_omap_keys
, &a_obj_omap
);
240 cout
<< "diff_objects getomap on A object " << coll
<< "/" << a_obj
241 << " returns " << err
<< std::endl
;
244 err
= b_store
->omap_get_keys(b_ch
, b_obj
, &b_omap_keys
);
246 cout
<< "diff_objects getomap on A object " << coll
<< "/" << b_obj
247 << " returns " << err
<< std::endl
;
250 err
= b_store
->omap_get_values(b_ch
, b_obj
, b_omap_keys
, &b_obj_omap
);
252 cout
<< "diff_objects getomap on A object " << coll
<< "/" << b_obj
253 << " returns " << err
<< std::endl
;
256 if (diff_omap(a_obj_omap
, b_obj_omap
)) {
257 cout
<< "diff_objects omap mismatch on A object "
258 << coll
<< "/" << a_obj
<< " and B object "
259 << coll
<< "/" << b_obj
<< std::endl
;
260 cout
<< "a: " << a_obj_omap
<< std::endl
;
261 cout
<< "b: " << b_obj_omap
<< std::endl
;
269 bool FileStoreDiff::diff()
273 std::vector
<coll_t
> a_coll_list
, b_coll_list
;
274 a_store
->list_collections(a_coll_list
);
275 b_store
->list_collections(b_coll_list
);
277 std::vector
<coll_t
>::iterator it
= b_coll_list
.begin();
278 for (; it
!= b_coll_list
.end(); ++it
) {
280 if (!a_store
->collection_exists(b_coll
)) {
281 cout
<< "diff B coll " << b_coll
.to_str() << " DNE on A" << std::endl
;
285 for (std::vector
<coll_t
>::iterator j
= a_coll_list
.begin();
286 j
!= a_coll_list
.end(); ++j
) {
288 a_coll_list
.erase(j
);
293 if (diff_objects(a_store
, b_store
, b_coll
))
296 for (std::vector
<coll_t
>::iterator it
= a_coll_list
.begin();
297 it
!= a_coll_list
.end(); ++it
) {
298 cout
<< "diff A coll " << *it
<< " DNE on B" << std::endl
;