]> git.proxmox.com Git - ceph.git/blob - ceph/src/test/objectstore/test_bdev.cc
update source to Ceph Pacific 16.2.2
[ceph.git] / ceph / src / test / objectstore / test_bdev.cc
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 <gtest/gtest.h>
8 #include "global/global_init.h"
9 #include "global/global_context.h"
10 #include "common/ceph_context.h"
11 #include "common/ceph_argparse.h"
12 #include "include/stringify.h"
13 #include "common/errno.h"
14
15 #include "blk/BlockDevice.h"
16
17 class TempBdev {
18 public:
19 TempBdev(uint64_t size)
20 : path{get_temp_bdev(size)}
21 {}
22 ~TempBdev() {
23 rm_temp_bdev(path);
24 }
25 const std::string path;
26 private:
27 static string get_temp_bdev(uint64_t size)
28 {
29 static int n = 0;
30 string fn = "ceph_test_bluefs.tmp.block." + stringify(getpid())
31 + "." + stringify(++n);
32 int fd = ::open(fn.c_str(), O_CREAT|O_RDWR|O_TRUNC, 0644);
33 ceph_assert(fd >= 0);
34 int r = ::ftruncate(fd, size);
35 ceph_assert(r >= 0);
36 ::close(fd);
37 return fn;
38 }
39 static void rm_temp_bdev(string f)
40 {
41 ::unlink(f.c_str());
42 }
43 };
44
45 TEST(KernelDevice, Ticket45337) {
46 // Large (>=2 GB) writes are incomplete when bluefs_buffered_io = true
47
48 uint64_t size = 1048576ull * 8192;
49 TempBdev bdev{ size };
50
51 const bool buffered = true;
52
53 std::unique_ptr<BlockDevice> b(
54 BlockDevice::create(g_ceph_context, bdev.path, NULL, NULL,
55 [](void* handle, void* aio) {}, NULL));
56 bufferlist bl;
57 // writing a bit less than 4GB
58 for (auto i = 0; i < 4000; i++) {
59 string s(1048576, 'a' + (i % 28));
60 bl.append(s);
61 }
62 uint64_t magic_offs = bl.length();
63 string s(4086, 'z');
64 s += "0123456789";
65 bl.append(s);
66
67 {
68 int r = b->open(bdev.path);
69 if (r < 0) {
70 std::cerr << "open " << bdev.path << " failed" << std::endl;
71 return;
72 }
73 }
74 std::unique_ptr<IOContext> ioc(new IOContext(g_ceph_context, NULL));
75
76 auto r = b->aio_write(0, bl, ioc.get(), buffered);
77 ASSERT_EQ(r, 0);
78
79 if (ioc->has_pending_aios()) {
80 b->aio_submit(ioc.get());
81 ioc->aio_wait();
82 }
83
84 char outbuf[0x1000];
85 r = b->read_random(magic_offs, sizeof(outbuf), outbuf, buffered);
86 ASSERT_EQ(r, 0);
87 ASSERT_EQ(memcmp(s.c_str(), outbuf, sizeof(outbuf)), 0);
88
89 b->close();
90 }
91
92 int main(int argc, char **argv) {
93 vector<const char*> args;
94 argv_to_vec(argc, (const char **)argv, args);
95
96 map<string,string> defaults = {
97 { "debug_bdev", "1/20" }
98 };
99
100 auto cct = global_init(&defaults, args, CEPH_ENTITY_TYPE_CLIENT,
101 CODE_ENVIRONMENT_UTILITY,
102 CINIT_FLAG_NO_DEFAULT_CONFIG_FILE);
103 common_init_finish(g_ceph_context);
104 g_ceph_context->_conf.set_val(
105 "enable_experimental_unrecoverable_data_corrupting_features",
106 "*");
107 g_ceph_context->_conf.apply_changes(nullptr);
108
109 ::testing::InitGoogleTest(&argc, argv);
110 return RUN_ALL_TESTS();
111 }