]> git.proxmox.com Git - ceph.git/blame - ceph/src/test/objectstore/test_bluefs.cc
import 14.2.4 nautilus point release
[ceph.git] / ceph / src / test / objectstore / test_bluefs.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#include <stdio.h>
5#include <string.h>
6#include <iostream>
7#include <time.h>
8#include <fcntl.h>
9#include <unistd.h>
91327a77 10#include <random>
7c673cae
FG
11#include <thread>
12#include "global/global_init.h"
13#include "common/ceph_argparse.h"
14#include "include/stringify.h"
11fdf7f2 15#include "include/scope_guard.h"
7c673cae
FG
16#include "common/errno.h"
17#include <gtest/gtest.h>
18
19#include "os/bluestore/BlueFS.h"
20
21string get_temp_bdev(uint64_t size)
22{
23 static int n = 0;
24 string fn = "ceph_test_bluefs.tmp.block." + stringify(getpid())
25 + "." + stringify(++n);
26 int fd = ::open(fn.c_str(), O_CREAT|O_RDWR|O_TRUNC, 0644);
11fdf7f2 27 ceph_assert(fd >= 0);
7c673cae 28 int r = ::ftruncate(fd, size);
11fdf7f2 29 ceph_assert(r >= 0);
7c673cae
FG
30 ::close(fd);
31 return fn;
32}
33
11fdf7f2 34std::unique_ptr<char[]> gen_buffer(uint64_t size)
7c673cae 35{
11fdf7f2
TL
36 std::unique_ptr<char[]> buffer = std::make_unique<char[]>(size);
37 std::independent_bits_engine<std::default_random_engine, CHAR_BIT, unsigned char> e;
38 std::generate(buffer.get(), buffer.get()+size, std::ref(e));
7c673cae
FG
39 return buffer;
40}
41
42
43void rm_temp_bdev(string f)
44{
45 ::unlink(f.c_str());
46}
47
48TEST(BlueFS, mkfs) {
49 uint64_t size = 1048576 * 128;
50 string fn = get_temp_bdev(size);
51 uuid_d fsid;
52 BlueFS fs(g_ceph_context);
11fdf7f2 53 ASSERT_EQ(0, fs.add_block_device(BlueFS::BDEV_DB, fn, false));
7c673cae
FG
54 fs.add_block_extent(BlueFS::BDEV_DB, 1048576, size - 1048576);
55 ASSERT_EQ(0, fs.mkfs(fsid));
56 rm_temp_bdev(fn);
57}
58
59TEST(BlueFS, mkfs_mount) {
60 uint64_t size = 1048576 * 128;
61 string fn = get_temp_bdev(size);
62 BlueFS fs(g_ceph_context);
11fdf7f2 63 ASSERT_EQ(0, fs.add_block_device(BlueFS::BDEV_DB, fn, false));
7c673cae
FG
64 fs.add_block_extent(BlueFS::BDEV_DB, 1048576, size - 1048576);
65 uuid_d fsid;
66 ASSERT_EQ(0, fs.mkfs(fsid));
67 ASSERT_EQ(0, fs.mount());
68 ASSERT_EQ(fs.get_total(BlueFS::BDEV_DB), size - 1048576);
69 ASSERT_LT(fs.get_free(BlueFS::BDEV_DB), size - 1048576);
70 fs.umount();
71 rm_temp_bdev(fn);
72}
73
74TEST(BlueFS, write_read) {
75 uint64_t size = 1048576 * 128;
76 string fn = get_temp_bdev(size);
77 BlueFS fs(g_ceph_context);
11fdf7f2 78 ASSERT_EQ(0, fs.add_block_device(BlueFS::BDEV_DB, fn, false));
7c673cae
FG
79 fs.add_block_extent(BlueFS::BDEV_DB, 1048576, size - 1048576);
80 uuid_d fsid;
81 ASSERT_EQ(0, fs.mkfs(fsid));
82 ASSERT_EQ(0, fs.mount());
83 {
84 BlueFS::FileWriter *h;
85 ASSERT_EQ(0, fs.mkdir("dir"));
86 ASSERT_EQ(0, fs.open_for_write("dir", "file", &h, false));
87 h->append("foo", 3);
88 h->append("bar", 3);
89 h->append("baz", 3);
90 fs.fsync(h);
91 fs.close_writer(h);
92 }
93 {
94 BlueFS::FileReader *h;
95 ASSERT_EQ(0, fs.open_for_read("dir", "file", &h));
96 bufferlist bl;
97 BlueFS::FileReaderBuffer buf(4096);
98 ASSERT_EQ(9, fs.read(h, &buf, 0, 1024, &bl, NULL));
99 ASSERT_EQ(0, strncmp("foobarbaz", bl.c_str(), 9));
100 delete h;
101 }
102 fs.umount();
103 rm_temp_bdev(fn);
104}
105
106TEST(BlueFS, small_appends) {
107 uint64_t size = 1048576 * 128;
108 string fn = get_temp_bdev(size);
109 BlueFS fs(g_ceph_context);
11fdf7f2 110 ASSERT_EQ(0, fs.add_block_device(BlueFS::BDEV_DB, fn, false));
7c673cae
FG
111 fs.add_block_extent(BlueFS::BDEV_DB, 1048576, size - 1048576);
112 uuid_d fsid;
113 ASSERT_EQ(0, fs.mkfs(fsid));
114 ASSERT_EQ(0, fs.mount());
115 {
116 BlueFS::FileWriter *h;
117 ASSERT_EQ(0, fs.mkdir("dir"));
118 ASSERT_EQ(0, fs.open_for_write("dir", "file", &h, false));
119 for (unsigned i = 0; i < 10000; ++i) {
120 h->append("abcdeabcdeabcdeabcdeabcdeabc", 23);
121 }
122 fs.fsync(h);
123 fs.close_writer(h);
124 }
125 {
126 BlueFS::FileWriter *h;
127 ASSERT_EQ(0, fs.open_for_write("dir", "file_sync", &h, false));
128 for (unsigned i = 0; i < 1000; ++i) {
129 h->append("abcdeabcdeabcdeabcdeabcdeabc", 23);
31f18b77 130 ASSERT_EQ(0, fs.fsync(h));
7c673cae
FG
131 }
132 fs.close_writer(h);
133 }
134 fs.umount();
135 rm_temp_bdev(fn);
136}
137
494da23a
TL
138TEST(BlueFS, very_large_write) {
139 // we'll write a ~3G file, so allocate more than that for the whole fs
140 uint64_t size = 1048576 * 1024 * 8ull;
141 string fn = get_temp_bdev(size);
142 BlueFS fs(g_ceph_context);
143
144 bool old = g_ceph_context->_conf.get_val<bool>("bluefs_buffered_io");
145 g_ceph_context->_conf.set_val("bluefs_buffered_io", "false");
146
147 ASSERT_EQ(0, fs.add_block_device(BlueFS::BDEV_DB, fn, false));
148 fs.add_block_extent(BlueFS::BDEV_DB, 1048576, size - 1048576);
149 uuid_d fsid;
150 ASSERT_EQ(0, fs.mkfs(fsid));
151 ASSERT_EQ(0, fs.mount());
152 char buf[1048571]; // this is biggish, but intentionally not evenly aligned
153 for (unsigned i = 0; i < sizeof(buf); ++i) {
154 buf[i] = i;
155 }
156 {
157 BlueFS::FileWriter *h;
158 ASSERT_EQ(0, fs.mkdir("dir"));
159 ASSERT_EQ(0, fs.open_for_write("dir", "bigfile", &h, false));
160 for (unsigned i = 0; i < 3*1024*1048576ull / sizeof(buf); ++i) {
161 h->append(buf, sizeof(buf));
162 }
163 fs.fsync(h);
164 fs.close_writer(h);
165 }
166 {
167 BlueFS::FileReader *h;
168 ASSERT_EQ(0, fs.open_for_read("dir", "bigfile", &h));
169 bufferlist bl;
170 BlueFS::FileReaderBuffer readbuf(10485760);
171 for (unsigned i = 0; i < 3*1024*1048576ull / sizeof(buf); ++i) {
172 bl.clear();
173 fs.read(h, &readbuf, i * sizeof(buf), sizeof(buf), &bl, NULL);
174 int r = memcmp(buf, bl.c_str(), sizeof(buf));
175 if (r) {
176 cerr << "read got mismatch at offset " << i*sizeof(buf) << " r " << r
177 << std::endl;
178 }
179 ASSERT_EQ(0, r);
180 }
181 delete h;
182 }
183 fs.umount();
184
185 g_ceph_context->_conf.set_val("bluefs_buffered_io", stringify((int)old));
186
187 rm_temp_bdev(fn);
188}
189
7c673cae
FG
190#define ALLOC_SIZE 4096
191
192void write_data(BlueFS &fs, uint64_t rationed_bytes)
193{
7c673cae
FG
194 int j=0, r=0;
195 uint64_t written_bytes = 0;
196 rationed_bytes -= ALLOC_SIZE;
197 stringstream ss;
198 string dir = "dir.";
199 ss << std::this_thread::get_id();
200 dir.append(ss.str());
201 dir.append(".");
202 dir.append(to_string(j));
203 ASSERT_EQ(0, fs.mkdir(dir));
204 while (1) {
205 string file = "file.";
206 file.append(to_string(j));
11fdf7f2 207 BlueFS::FileWriter *h;
7c673cae 208 ASSERT_EQ(0, fs.open_for_write(dir, file, &h, false));
11fdf7f2
TL
209 ASSERT_NE(nullptr, h);
210 auto sg = make_scope_guard([&fs, h] { fs.close_writer(h); });
7c673cae 211 bufferlist bl;
11fdf7f2
TL
212 std::unique_ptr<char[]> buf = gen_buffer(ALLOC_SIZE);
213 bufferptr bp = buffer::claim_char(ALLOC_SIZE, buf.get());
7c673cae
FG
214 bl.push_back(bp);
215 h->append(bl.c_str(), bl.length());
216 r = fs.fsync(h);
217 if (r < 0) {
7c673cae
FG
218 break;
219 }
11fdf7f2 220 written_bytes += g_conf()->bluefs_alloc_size;
7c673cae 221 j++;
11fdf7f2 222 if ((rationed_bytes - written_bytes) <= g_conf()->bluefs_alloc_size) {
7c673cae
FG
223 break;
224 }
225 }
226}
227
228void create_single_file(BlueFS &fs)
229{
230 BlueFS::FileWriter *h;
231 stringstream ss;
232 string dir = "dir.test";
233 ASSERT_EQ(0, fs.mkdir(dir));
234 string file = "testfile";
235 ASSERT_EQ(0, fs.open_for_write(dir, file, &h, false));
236 bufferlist bl;
11fdf7f2
TL
237 std::unique_ptr<char[]> buf = gen_buffer(ALLOC_SIZE);
238 bufferptr bp = buffer::claim_char(ALLOC_SIZE, buf.get());
7c673cae
FG
239 bl.push_back(bp);
240 h->append(bl.c_str(), bl.length());
241 fs.fsync(h);
242 fs.close_writer(h);
243}
244
245void write_single_file(BlueFS &fs, uint64_t rationed_bytes)
246{
7c673cae 247 stringstream ss;
11fdf7f2
TL
248 const string dir = "dir.test";
249 const string file = "testfile";
7c673cae
FG
250 uint64_t written_bytes = 0;
251 rationed_bytes -= ALLOC_SIZE;
252 while (1) {
11fdf7f2 253 BlueFS::FileWriter *h;
7c673cae 254 ASSERT_EQ(0, fs.open_for_write(dir, file, &h, false));
11fdf7f2
TL
255 ASSERT_NE(nullptr, h);
256 auto sg = make_scope_guard([&fs, h] { fs.close_writer(h); });
7c673cae 257 bufferlist bl;
11fdf7f2
TL
258 std::unique_ptr<char[]> buf = gen_buffer(ALLOC_SIZE);
259 bufferptr bp = buffer::claim_char(ALLOC_SIZE, buf.get());
7c673cae
FG
260 bl.push_back(bp);
261 h->append(bl.c_str(), bl.length());
11fdf7f2 262 int r = fs.fsync(h);
7c673cae 263 if (r < 0) {
7c673cae
FG
264 break;
265 }
11fdf7f2
TL
266 written_bytes += g_conf()->bluefs_alloc_size;
267 if ((rationed_bytes - written_bytes) <= g_conf()->bluefs_alloc_size) {
7c673cae
FG
268 break;
269 }
270 }
271}
272
273bool writes_done = false;
274
275void sync_fs(BlueFS &fs)
276{
277 while (1) {
278 if (writes_done == true)
279 break;
280 fs.sync_metadata();
281 sleep(1);
282 }
283}
284
285
286void do_join(std::thread& t)
287{
288 t.join();
289}
290
291void join_all(std::vector<std::thread>& v)
292{
293 std::for_each(v.begin(),v.end(),do_join);
294}
295
296#define NUM_WRITERS 3
297#define NUM_SYNC_THREADS 1
298
299#define NUM_SINGLE_FILE_WRITERS 1
300#define NUM_MULTIPLE_FILE_WRITERS 2
301
302TEST(BlueFS, test_flush_1) {
303 uint64_t size = 1048576 * 128;
304 string fn = get_temp_bdev(size);
11fdf7f2 305 g_ceph_context->_conf.set_val(
7c673cae
FG
306 "bluefs_alloc_size",
307 "65536");
11fdf7f2 308 g_ceph_context->_conf.apply_changes(nullptr);
7c673cae
FG
309
310 BlueFS fs(g_ceph_context);
11fdf7f2 311 ASSERT_EQ(0, fs.add_block_device(BlueFS::BDEV_DB, fn, false));
7c673cae
FG
312 fs.add_block_extent(BlueFS::BDEV_DB, 1048576, size - 1048576);
313 uuid_d fsid;
314 ASSERT_EQ(0, fs.mkfs(fsid));
315 ASSERT_EQ(0, fs.mount());
316 {
317 std::vector<std::thread> write_thread_multiple;
318 uint64_t effective_size = size - (32 * 1048576); // leaving the last 32 MB for log compaction
319 uint64_t per_thread_bytes = (effective_size/(NUM_MULTIPLE_FILE_WRITERS + NUM_SINGLE_FILE_WRITERS));
320 for (int i=0; i<NUM_MULTIPLE_FILE_WRITERS ; i++) {
321 write_thread_multiple.push_back(std::thread(write_data, std::ref(fs), per_thread_bytes));
322 }
323
324 create_single_file(fs);
325 std::vector<std::thread> write_thread_single;
326 for (int i=0; i<NUM_SINGLE_FILE_WRITERS; i++) {
327 write_thread_single.push_back(std::thread(write_single_file, std::ref(fs), per_thread_bytes));
328 }
329
330 join_all(write_thread_single);
331 join_all(write_thread_multiple);
332 }
333 fs.umount();
334 rm_temp_bdev(fn);
335}
336
337TEST(BlueFS, test_flush_2) {
338 uint64_t size = 1048576 * 256;
339 string fn = get_temp_bdev(size);
11fdf7f2 340 g_ceph_context->_conf.set_val(
7c673cae
FG
341 "bluefs_alloc_size",
342 "65536");
11fdf7f2 343 g_ceph_context->_conf.apply_changes(nullptr);
7c673cae
FG
344
345 BlueFS fs(g_ceph_context);
11fdf7f2 346 ASSERT_EQ(0, fs.add_block_device(BlueFS::BDEV_DB, fn, false));
7c673cae
FG
347 fs.add_block_extent(BlueFS::BDEV_DB, 1048576, size - 1048576);
348 uuid_d fsid;
349 ASSERT_EQ(0, fs.mkfs(fsid));
350 ASSERT_EQ(0, fs.mount());
351 {
352 uint64_t effective_size = size - (128 * 1048576); // leaving the last 32 MB for log compaction
353 uint64_t per_thread_bytes = (effective_size/(NUM_WRITERS));
354 std::vector<std::thread> write_thread_multiple;
355 for (int i=0; i<NUM_WRITERS; i++) {
356 write_thread_multiple.push_back(std::thread(write_data, std::ref(fs), per_thread_bytes));
357 }
358
359 join_all(write_thread_multiple);
360 }
361 fs.umount();
362 rm_temp_bdev(fn);
363}
364
365TEST(BlueFS, test_flush_3) {
366 uint64_t size = 1048576 * 256;
367 string fn = get_temp_bdev(size);
11fdf7f2 368 g_ceph_context->_conf.set_val(
7c673cae
FG
369 "bluefs_alloc_size",
370 "65536");
11fdf7f2 371 g_ceph_context->_conf.apply_changes(nullptr);
7c673cae
FG
372
373 BlueFS fs(g_ceph_context);
11fdf7f2 374 ASSERT_EQ(0, fs.add_block_device(BlueFS::BDEV_DB, fn, false));
7c673cae
FG
375 fs.add_block_extent(BlueFS::BDEV_DB, 1048576, size - 1048576);
376 uuid_d fsid;
377 ASSERT_EQ(0, fs.mkfs(fsid));
378 ASSERT_EQ(0, fs.mount());
379 {
380 std::vector<std::thread> write_threads;
381 uint64_t effective_size = size - (64 * 1048576); // leaving the last 11 MB for log compaction
382 uint64_t per_thread_bytes = (effective_size/(NUM_WRITERS));
383 for (int i=0; i<NUM_WRITERS; i++) {
384 write_threads.push_back(std::thread(write_data, std::ref(fs), per_thread_bytes));
385 }
386
387 std::vector<std::thread> sync_threads;
388 for (int i=0; i<NUM_SYNC_THREADS; i++) {
389 sync_threads.push_back(std::thread(sync_fs, std::ref(fs)));
390 }
391
392 join_all(write_threads);
393 writes_done = true;
394 join_all(sync_threads);
395 }
396 fs.umount();
397 rm_temp_bdev(fn);
398}
399
400TEST(BlueFS, test_simple_compaction_sync) {
11fdf7f2 401 g_ceph_context->_conf.set_val(
7c673cae
FG
402 "bluefs_compact_log_sync",
403 "true");
404 uint64_t size = 1048576 * 128;
405 string fn = get_temp_bdev(size);
406
407 BlueFS fs(g_ceph_context);
11fdf7f2 408 ASSERT_EQ(0, fs.add_block_device(BlueFS::BDEV_DB, fn, false));
7c673cae
FG
409 fs.add_block_extent(BlueFS::BDEV_DB, 1048576, size - 1048576);
410 uuid_d fsid;
411 ASSERT_EQ(0, fs.mkfs(fsid));
412 ASSERT_EQ(0, fs.mount());
413 {
7c673cae
FG
414 for (int i=0; i<10; i++) {
415 string dir = "dir.";
416 dir.append(to_string(i));
417 ASSERT_EQ(0, fs.mkdir(dir));
418 for (int j=0; j<10; j++) {
419 string file = "file.";
420 file.append(to_string(j));
11fdf7f2 421 BlueFS::FileWriter *h;
7c673cae 422 ASSERT_EQ(0, fs.open_for_write(dir, file, &h, false));
11fdf7f2
TL
423 ASSERT_NE(nullptr, h);
424 auto sg = make_scope_guard([&fs, h] { fs.close_writer(h); });
7c673cae 425 bufferlist bl;
11fdf7f2
TL
426 std::unique_ptr<char[]> buf = gen_buffer(4096);
427 bufferptr bp = buffer::claim_char(4096, buf.get());
7c673cae
FG
428 bl.push_back(bp);
429 h->append(bl.c_str(), bl.length());
430 fs.fsync(h);
7c673cae
FG
431 }
432 }
433 }
7c673cae
FG
434 {
435 for (int i=0; i<10; i+=2) {
436 string dir = "dir.";
437 dir.append(to_string(i));
11fdf7f2 438 for (int j=0; j<10; j++) {
7c673cae
FG
439 string file = "file.";
440 file.append(to_string(j));
441 fs.unlink(dir, file);
442 fs.flush_log();
443 }
11fdf7f2 444 ASSERT_EQ(0, fs.rmdir(dir));
7c673cae
FG
445 fs.flush_log();
446 }
447 }
448 fs.compact_log();
449 fs.umount();
450 rm_temp_bdev(fn);
451}
452
453TEST(BlueFS, test_simple_compaction_async) {
11fdf7f2 454 g_ceph_context->_conf.set_val(
7c673cae
FG
455 "bluefs_compact_log_sync",
456 "false");
457 uint64_t size = 1048576 * 128;
458 string fn = get_temp_bdev(size);
459
460 BlueFS fs(g_ceph_context);
11fdf7f2 461 ASSERT_EQ(0, fs.add_block_device(BlueFS::BDEV_DB, fn, false));
7c673cae
FG
462 fs.add_block_extent(BlueFS::BDEV_DB, 1048576, size - 1048576);
463 uuid_d fsid;
464 ASSERT_EQ(0, fs.mkfs(fsid));
465 ASSERT_EQ(0, fs.mount());
466 {
7c673cae
FG
467 for (int i=0; i<10; i++) {
468 string dir = "dir.";
469 dir.append(to_string(i));
470 ASSERT_EQ(0, fs.mkdir(dir));
471 for (int j=0; j<10; j++) {
472 string file = "file.";
473 file.append(to_string(j));
11fdf7f2 474 BlueFS::FileWriter *h;
7c673cae 475 ASSERT_EQ(0, fs.open_for_write(dir, file, &h, false));
11fdf7f2
TL
476 ASSERT_NE(nullptr, h);
477 auto sg = make_scope_guard([&fs, h] { fs.close_writer(h); });
7c673cae 478 bufferlist bl;
11fdf7f2
TL
479 std::unique_ptr<char[]> buf = gen_buffer(4096);
480 bufferptr bp = buffer::claim_char(4096, buf.get());
7c673cae
FG
481 bl.push_back(bp);
482 h->append(bl.c_str(), bl.length());
483 fs.fsync(h);
7c673cae
FG
484 }
485 }
486 }
7c673cae
FG
487 {
488 for (int i=0; i<10; i+=2) {
489 string dir = "dir.";
490 dir.append(to_string(i));
11fdf7f2 491 for (int j=0; j<10; j++) {
7c673cae
FG
492 string file = "file.";
493 file.append(to_string(j));
494 fs.unlink(dir, file);
495 fs.flush_log();
496 }
11fdf7f2 497 ASSERT_EQ(0, fs.rmdir(dir));
7c673cae
FG
498 fs.flush_log();
499 }
500 }
501 fs.compact_log();
502 fs.umount();
503 rm_temp_bdev(fn);
504}
505
506TEST(BlueFS, test_compaction_sync) {
507 uint64_t size = 1048576 * 128;
508 string fn = get_temp_bdev(size);
11fdf7f2 509 g_ceph_context->_conf.set_val(
7c673cae
FG
510 "bluefs_alloc_size",
511 "65536");
11fdf7f2 512 g_ceph_context->_conf.set_val(
7c673cae
FG
513 "bluefs_compact_log_sync",
514 "true");
515
516 BlueFS fs(g_ceph_context);
11fdf7f2 517 ASSERT_EQ(0, fs.add_block_device(BlueFS::BDEV_DB, fn, false));
7c673cae
FG
518 fs.add_block_extent(BlueFS::BDEV_DB, 1048576, size - 1048576);
519 uuid_d fsid;
520 ASSERT_EQ(0, fs.mkfs(fsid));
521 ASSERT_EQ(0, fs.mount());
522 {
523 std::vector<std::thread> write_threads;
524 uint64_t effective_size = size - (32 * 1048576); // leaving the last 32 MB for log compaction
525 uint64_t per_thread_bytes = (effective_size/(NUM_WRITERS));
526 for (int i=0; i<NUM_WRITERS; i++) {
527 write_threads.push_back(std::thread(write_data, std::ref(fs), per_thread_bytes));
528 }
529
530 std::vector<std::thread> sync_threads;
531 for (int i=0; i<NUM_SYNC_THREADS; i++) {
532 sync_threads.push_back(std::thread(sync_fs, std::ref(fs)));
533 }
534
535 join_all(write_threads);
536 writes_done = true;
537 join_all(sync_threads);
538 fs.compact_log();
539 }
540 fs.umount();
541 rm_temp_bdev(fn);
542}
543
544TEST(BlueFS, test_compaction_async) {
545 uint64_t size = 1048576 * 128;
546 string fn = get_temp_bdev(size);
11fdf7f2 547 g_ceph_context->_conf.set_val(
7c673cae
FG
548 "bluefs_alloc_size",
549 "65536");
11fdf7f2 550 g_ceph_context->_conf.set_val(
7c673cae
FG
551 "bluefs_compact_log_sync",
552 "false");
553
554 BlueFS fs(g_ceph_context);
11fdf7f2 555 ASSERT_EQ(0, fs.add_block_device(BlueFS::BDEV_DB, fn, false));
7c673cae
FG
556 fs.add_block_extent(BlueFS::BDEV_DB, 1048576, size - 1048576);
557 uuid_d fsid;
558 ASSERT_EQ(0, fs.mkfs(fsid));
559 ASSERT_EQ(0, fs.mount());
560 {
561 std::vector<std::thread> write_threads;
562 uint64_t effective_size = size - (32 * 1048576); // leaving the last 32 MB for log compaction
563 uint64_t per_thread_bytes = (effective_size/(NUM_WRITERS));
564 for (int i=0; i<NUM_WRITERS; i++) {
565 write_threads.push_back(std::thread(write_data, std::ref(fs), per_thread_bytes));
566 }
567
568 std::vector<std::thread> sync_threads;
569 for (int i=0; i<NUM_SYNC_THREADS; i++) {
570 sync_threads.push_back(std::thread(sync_fs, std::ref(fs)));
571 }
572
573 join_all(write_threads);
574 writes_done = true;
575 join_all(sync_threads);
576 fs.compact_log();
577 }
578 fs.umount();
579 rm_temp_bdev(fn);
580}
581
582TEST(BlueFS, test_replay) {
583 uint64_t size = 1048576 * 128;
584 string fn = get_temp_bdev(size);
11fdf7f2 585 g_ceph_context->_conf.set_val(
7c673cae
FG
586 "bluefs_alloc_size",
587 "65536");
11fdf7f2 588 g_ceph_context->_conf.set_val(
7c673cae
FG
589 "bluefs_compact_log_sync",
590 "false");
591
592 BlueFS fs(g_ceph_context);
11fdf7f2 593 ASSERT_EQ(0, fs.add_block_device(BlueFS::BDEV_DB, fn, false));
7c673cae
FG
594 fs.add_block_extent(BlueFS::BDEV_DB, 1048576, size - 1048576);
595 uuid_d fsid;
596 ASSERT_EQ(0, fs.mkfs(fsid));
597 ASSERT_EQ(0, fs.mount());
598 {
599 std::vector<std::thread> write_threads;
600 uint64_t effective_size = size - (32 * 1048576); // leaving the last 32 MB for log compaction
601 uint64_t per_thread_bytes = (effective_size/(NUM_WRITERS));
602 for (int i=0; i<NUM_WRITERS; i++) {
603 write_threads.push_back(std::thread(write_data, std::ref(fs), per_thread_bytes));
604 }
605
606 std::vector<std::thread> sync_threads;
607 for (int i=0; i<NUM_SYNC_THREADS; i++) {
608 sync_threads.push_back(std::thread(sync_fs, std::ref(fs)));
609 }
610
611 join_all(write_threads);
612 writes_done = true;
613 join_all(sync_threads);
614 fs.compact_log();
615 }
616 fs.umount();
617 // remount and check log can replay safe?
31f18b77 618 ASSERT_EQ(0, fs.mount());
7c673cae
FG
619 fs.umount();
620 rm_temp_bdev(fn);
621}
622
623int main(int argc, char **argv) {
624 vector<const char*> args;
625 argv_to_vec(argc, (const char **)argv, args);
7c673cae 626
11fdf7f2
TL
627 map<string,string> defaults = {
628 { "debug_bluefs", "1/20" },
629 { "debug_bdev", "1/20" }
630 };
7c673cae 631
11fdf7f2 632 auto cct = global_init(&defaults, args, CEPH_ENTITY_TYPE_CLIENT,
7c673cae 633 CODE_ENVIRONMENT_UTILITY,
11fdf7f2 634 CINIT_FLAG_NO_DEFAULT_CONFIG_FILE);
7c673cae 635 common_init_finish(g_ceph_context);
11fdf7f2 636 g_ceph_context->_conf.set_val(
7c673cae
FG
637 "enable_experimental_unrecoverable_data_corrupting_features",
638 "*");
11fdf7f2 639 g_ceph_context->_conf.apply_changes(nullptr);
7c673cae
FG
640
641 ::testing::InitGoogleTest(&argc, argv);
642 return RUN_ALL_TESTS();
643}