]>
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 "
28 FileStoreDiff::FileStoreDiff(FileStore
*a
, FileStore
*b
)
29 : a_store(a
), b_store(b
)
32 err
= a_store
->mount();
33 ceph_assert(err
== 0);
35 err
= b_store
->mount();
36 ceph_assert(err
== 0);
39 FileStoreDiff::~FileStoreDiff()
46 bool FileStoreDiff::diff_attrs(std::map
<std::string
,bufferptr
>& b
,
47 std::map
<std::string
,bufferptr
>& a
)
50 std::map
<std::string
, bufferptr
>::iterator b_it
= b
.begin();
51 std::map
<std::string
, bufferptr
>::iterator a_it
= a
.begin();
52 for (; b_it
!= b
.end(); ++b_it
, ++a_it
) {
53 if (b_it
->first
!= a_it
->first
) {
54 cout
<< "diff_attrs name mismatch (verify: " << b_it
->first
55 << ", store: " << a_it
->first
<< ")" << std::endl
;
60 if (!b_it
->second
.cmp(a_it
->second
)) {
61 cout
<< "diff_attrs contents mismatch on attr " << b_it
->first
<< std::endl
;
69 static bool diff_omap(std::map
<std::string
,bufferlist
>& b
,
70 std::map
<std::string
,bufferlist
>& a
)
73 std::map
<std::string
, bufferlist
>::iterator b_it
= b
.begin();
74 std::map
<std::string
, bufferlist
>::iterator a_it
= a
.begin();
75 for (; b_it
!= b
.end(); ++b_it
, ++a_it
) {
76 if (a_it
== a
.end()) {
77 cout
<< __func__
<< " a reached end before b, a missing " << b_it
->first
82 if (b_it
->first
!= a_it
->first
) {
83 cout
<< "diff_attrs name mismatch (verify: " << b_it
->first
84 << ", store: " << a_it
->first
<< ")" << std::endl
;
89 if (!(b_it
->second
== a_it
->second
)) {
90 cout
<< "diff_attrs contents mismatch on attr " << b_it
->first
<< std::endl
;
98 bool FileStoreDiff::diff_objects_stat(struct stat
& a
, struct stat
& b
)
102 if (a
.st_uid
!= b
.st_uid
) {
103 cout
<< "diff_objects_stat uid mismatch (A: "
104 << a
.st_uid
<< " != B: " << b
.st_uid
<< ")" << std::endl
;
108 if (a
.st_gid
!= b
.st_gid
) {
109 cout
<< "diff_objects_stat gid mismatch (A: "
110 << a
.st_gid
<< " != B: " << b
.st_gid
<< ")" << std::endl
;
114 if (a
.st_mode
!= b
.st_mode
) {
115 cout
<< "diff_objects_stat mode mismatch (A: "
116 << a
.st_mode
<< " != B: " << b
.st_mode
<< ")" << std::endl
;
120 if (a
.st_nlink
!= b
.st_nlink
) {
121 cout
<< "diff_objects_stat nlink mismatch (A: "
122 << a
.st_nlink
<< " != B: " << b
.st_nlink
<< ")" << std::endl
;
126 if (a
.st_size
!= b
.st_size
) {
127 cout
<< "diff_objects_stat size mismatch (A: "
128 << a
.st_size
<< " != B: " << b
.st_size
<< ")" << std::endl
;
134 bool FileStoreDiff::diff_objects(FileStore
*a_store
, FileStore
*b_store
, coll_t coll
)
139 std::vector
<ghobject_t
> b_objects
, a_objects
;
140 err
= b_store
->collection_list(coll
, ghobject_t(), ghobject_t::get_max(),
141 INT_MAX
, &b_objects
, NULL
);
143 cout
<< "diff_objects list on verify coll " << coll
.to_str()
144 << " returns " << err
<< std::endl
;
147 err
= a_store
->collection_list(coll
, ghobject_t(), ghobject_t::get_max(),
148 INT_MAX
, &a_objects
, NULL
);
150 cout
<< "diff_objects list on store coll " << coll
.to_str()
151 << " returns " << err
<< std::endl
;
155 if (b_objects
.size() != a_objects
.size()) {
156 cout
<< "diff_objects num objs mismatch (A: " << a_objects
.size()
157 << ", B: " << b_objects
.size() << ")" << std::endl
;
161 std::vector
<ghobject_t
>::iterator b_it
= b_objects
.begin();
162 std::vector
<ghobject_t
>::iterator a_it
= b_objects
.begin();
163 for (; b_it
!= b_objects
.end(); ++b_it
, ++a_it
) {
164 ghobject_t b_obj
= *b_it
, a_obj
= *a_it
;
165 if (b_obj
.hobj
.oid
.name
!= a_obj
.hobj
.oid
.name
) {
166 cout
<< "diff_objects name mismatch on A object "
167 << coll
<< "/" << a_obj
<< " and B object "
168 << coll
<< "/" << b_obj
<< std::endl
;
173 struct stat b_stat
, a_stat
;
174 err
= b_store
->stat(coll
, b_obj
, &b_stat
);
176 cout
<< "diff_objects error stating B object "
177 << coll
.to_str() << "/" << b_obj
.hobj
.oid
.name
<< std::endl
;
180 err
= a_store
->stat(coll
, a_obj
, &a_stat
);
182 cout
<< "diff_objects error stating A object "
183 << coll
<< "/" << a_obj
<< std::endl
;
187 if (diff_objects_stat(a_stat
, b_stat
)) {
188 cout
<< "diff_objects stat mismatch on "
189 << coll
<< "/" << b_obj
<< std::endl
;
193 bufferlist a_obj_bl
, b_obj_bl
;
194 b_store
->read(coll
, b_obj
, 0, b_stat
.st_size
, b_obj_bl
);
195 a_store
->read(coll
, a_obj
, 0, a_stat
.st_size
, a_obj_bl
);
197 if (!a_obj_bl
.contents_equal(b_obj_bl
)) {
198 cout
<< "diff_objects content mismatch on "
199 << coll
<< "/" << b_obj
<< std::endl
;
203 std::map
<std::string
, bufferptr
> a_obj_attrs_map
, b_obj_attrs_map
;
204 err
= a_store
->getattrs(coll
, a_obj
, a_obj_attrs_map
);
206 cout
<< "diff_objects getattrs on A object " << coll
<< "/" << a_obj
207 << " returns " << err
<< std::endl
;
210 err
= b_store
->getattrs(coll
, b_obj
, b_obj_attrs_map
);
212 cout
<< "diff_objects getattrs on B object " << coll
<< "/" << b_obj
213 << "returns " << err
<< std::endl
;
217 if (diff_attrs(b_obj_attrs_map
, a_obj_attrs_map
)) {
218 cout
<< "diff_objects attrs mismatch on A object "
219 << coll
<< "/" << a_obj
<< " and B object "
220 << coll
<< "/" << b_obj
<< std::endl
;
224 std::map
<std::string
, bufferlist
> a_obj_omap
, b_obj_omap
;
225 std::set
<std::string
> a_omap_keys
, b_omap_keys
;
226 err
= a_store
->omap_get_keys(coll
, a_obj
, &a_omap_keys
);
228 cout
<< "diff_objects getomap on A object " << coll
<< "/" << a_obj
229 << " returns " << err
<< std::endl
;
232 err
= a_store
->omap_get_values(coll
, a_obj
, a_omap_keys
, &a_obj_omap
);
234 cout
<< "diff_objects getomap on A object " << coll
<< "/" << a_obj
235 << " returns " << err
<< std::endl
;
238 err
= b_store
->omap_get_keys(coll
, b_obj
, &b_omap_keys
);
240 cout
<< "diff_objects getomap on A object " << coll
<< "/" << b_obj
241 << " returns " << err
<< std::endl
;
244 err
= b_store
->omap_get_values(coll
, b_obj
, b_omap_keys
, &b_obj_omap
);
246 cout
<< "diff_objects getomap on A object " << coll
<< "/" << b_obj
247 << " returns " << err
<< std::endl
;
250 if (diff_omap(a_obj_omap
, b_obj_omap
)) {
251 cout
<< "diff_objects omap mismatch on A object "
252 << coll
<< "/" << a_obj
<< " and B object "
253 << coll
<< "/" << b_obj
<< std::endl
;
254 cout
<< "a: " << a_obj_omap
<< std::endl
;
255 cout
<< "b: " << b_obj_omap
<< std::endl
;
263 bool FileStoreDiff::diff()
267 std::vector
<coll_t
> a_coll_list
, b_coll_list
;
268 a_store
->list_collections(a_coll_list
);
269 b_store
->list_collections(b_coll_list
);
271 std::vector
<coll_t
>::iterator it
= b_coll_list
.begin();
272 for (; it
!= b_coll_list
.end(); ++it
) {
274 if (!a_store
->collection_exists(b_coll
)) {
275 cout
<< "diff B coll " << b_coll
.to_str() << " DNE on A" << std::endl
;
279 for (std::vector
<coll_t
>::iterator j
= a_coll_list
.begin();
280 j
!= a_coll_list
.end(); ++j
) {
282 a_coll_list
.erase(j
);
287 if (diff_objects(a_store
, b_store
, b_coll
))
290 for (std::vector
<coll_t
>::iterator it
= a_coll_list
.begin();
291 it
!= a_coll_list
.end(); ++it
) {
292 cout
<< "diff A coll " << *it
<< " DNE on B" << std::endl
;