Skip to content

Commit 14000ba

Browse files
Merge pull request ceph#62148 from Jayaprakash-ibm/wip-create-bdev-label
os/bluestore: Implemented create-bdev-label Reviewed-by: Adam Kupczyk <[email protected]>
2 parents 3e2687d + f2faf3e commit 14000ba

File tree

5 files changed

+168
-0
lines changed

5 files changed

+168
-0
lines changed

doc/man/8/ceph-bluestore-tool.rst

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,8 @@ Synopsis
3535
| **ceph-bluestore-tool** trim --path *osd path*
3636
| **ceph-bluestore-tool** zap-device --dev *dev path*
3737
| **ceph-bluestore-tool** revert-wal-to-plain --path *osd path*
38+
| **ceph-bluestore-tool** create-bdev-labels --path *osd path* --dev *device*
39+
3840

3941

4042
Description
@@ -171,6 +173,14 @@ Commands
171173
Changes WAL files from envelope mode to the legacy plain mode.
172174
Useful for downgrades, or if you might want to disable this new feature (bluefs_wal_envelope_mode).
173175

176+
:command:`create-bdev-labels` --path *osd path* --dev *device*
177+
178+
Writes a bdev label to BlueStore devices that originally did not support labeling.
179+
Reads metadata (e.g., fsid, ceph version) from --path and writes it to the device at --dev.
180+
Only the main device (block) gets full metadata; block.db or block.wal do not.
181+
The --dev path must be inside the --path directory, as its name determines the device role.
182+
Use --yes-i-really-really-mean-it to recreate corrupted labels.
183+
174184
Options
175185
=======
176186

src/os/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ if(WITH_BLUESTORE)
2929
bluestore/Writer.cc
3030
bluestore/Compression.cc
3131
bluestore/BlueAdmin.cc
32+
bluestore/BlueEnv.cc
3233
)
3334
endif(WITH_BLUESTORE)
3435

src/os/bluestore/BlueEnv.cc

Lines changed: 113 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,113 @@
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 <filesystem>
7+
#include <iostream>
8+
#include <fstream>
9+
#include <time.h>
10+
#include <fcntl.h>
11+
#include <unistd.h>
12+
#include "global/global_init.h"
13+
#include "common/ceph_argparse.h"
14+
#include "include/stringify.h"
15+
#include "common/errno.h"
16+
#include "common/safe_io.h"
17+
18+
#include "os/bluestore/BlueStore.h"
19+
20+
using namespace std;
21+
22+
23+
int BlueStore::create_bdev_labels(CephContext *cct,
24+
const std::string& path,
25+
const std::vector<std::string>& devs,
26+
std::vector<uint64_t>* valid_positions,
27+
bool force)
28+
{
29+
std::vector<std::string> metadata_files = {
30+
"bfm_blocks",
31+
"bfm_blocks_per_key",
32+
"bfm_bytes_per_block",
33+
"bfm_size",
34+
"bluefs",
35+
"ceph_fsid",
36+
"ceph_version_when_created",
37+
"created_at",
38+
"elastic_shared_blobs",
39+
"fsid",
40+
"kv_backend",
41+
"magic",
42+
"osd_key",
43+
"ready",
44+
"require_osd_release",
45+
"type",
46+
"whoami"
47+
};
48+
49+
unique_ptr<BlockDevice> bdev(BlockDevice::create(cct, devs.front(), nullptr, nullptr, nullptr, nullptr));
50+
int r = bdev->open(devs.front());
51+
if (r < 0) {
52+
return r;
53+
}
54+
uint64_t size = bdev->get_size();
55+
56+
if (bdev->supported_bdev_label() && !force) {
57+
bdev->close();
58+
return -EPERM;
59+
}
60+
61+
bdev->close();
62+
63+
bluestore_bdev_label_t label;
64+
std::vector<uint64_t> out_positions;
65+
bool is_multi = false;
66+
int64_t epoch = -1;
67+
68+
r = BlueStore::read_bdev_label(cct, devs.front(), &label,
69+
&out_positions, &is_multi, &epoch);
70+
71+
if (r == 0 && !force)
72+
return -EEXIST;
73+
74+
label = bluestore_bdev_label_t();
75+
label.btime = ceph_clock_now();
76+
77+
if (devs.front().ends_with("block")) {
78+
label.description = "main";
79+
} else if (devs.front().ends_with("block.db")) {
80+
label.description = "bluefs db";
81+
} else if (devs.front().ends_with("block.wal")) {
82+
label.description = "bluefs wal";
83+
}
84+
85+
label.size = size;
86+
87+
for (const auto& file : metadata_files) {
88+
std::ifstream infile(path + "/" + file);
89+
if (infile) {
90+
std::string value((std::istreambuf_iterator<char>(infile)), std::istreambuf_iterator<char>());
91+
value.erase(std::remove(value.begin(), value.end(), '\n'), value.end());
92+
if (file == "fsid") {
93+
label.osd_uuid.parse(value.c_str());
94+
} else if (label.description == "main") {
95+
label.meta[file] = value;
96+
}
97+
} else {
98+
cerr << "Warning: unable to read metadata file: " << file << std::endl;
99+
}
100+
}
101+
102+
bool wrote_at_least_one = false;
103+
for (uint64_t position : *valid_positions) {
104+
r = BlueStore::write_bdev_label(cct, devs.front(), label, position);
105+
if (r < 0) {
106+
cerr << "unable to write label at 0x" << std::hex << position << std::dec
107+
<< ": " << cpp_strerror(r) << std::endl;
108+
} else {
109+
wrote_at_least_one = true;
110+
}
111+
}
112+
return wrote_at_least_one ? 0 : -EIO;
113+
}

src/os/bluestore/BlueStore.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4175,6 +4175,13 @@ class BlueStore : public ObjectStore,
41754175

41764176
void _fsck_check_objects(FSCKDepth depth,
41774177
FSCK_ObjectCtx& ctx);
4178+
4179+
public:
4180+
static int create_bdev_labels(CephContext *cct,
4181+
const std::string& path,
4182+
const std::vector<std::string>& devs,
4183+
std::vector<uint64_t>* valid_positions,
4184+
bool force);
41784185
};
41794186

41804187
inline std::ostream& operator<<(std::ostream& out, const BlueStore::volatile_statfs& s) {

src/os/bluestore/bluestore_tool.cc

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -357,6 +357,7 @@ int main(int argc, char **argv)
357357
"show-label, "
358358
"show-label-at, "
359359
"set-label-key, "
360+
"create-bdev-labels, "
360361
"rm-label-key, "
361362
"prime-osd-dir, "
362363
"bluefs-super-dump, "
@@ -520,6 +521,16 @@ int main(int argc, char **argv)
520521
exit(EXIT_FAILURE);
521522
}
522523
}
524+
if (action == "create-bdev-labels") {
525+
if (path.empty()) {
526+
cerr << "must specify bluestore path" << std::endl;
527+
exit(EXIT_FAILURE);
528+
}
529+
if (devs.size() != 1) {
530+
cerr << "must specify the main bluestore device" << std::endl;
531+
exit(EXIT_FAILURE);
532+
}
533+
}
523534
if (action == "show-label") {
524535
if (devs.empty() && path.empty()) {
525536
cerr << "must specify bluestore path *or* raw device(s)" << std::endl;
@@ -837,6 +848,32 @@ int main(int argc, char **argv)
837848
jf.close_section();
838849
jf.flush(cout);
839850
}
851+
else if (action == "create-bdev-labels") {
852+
853+
std::vector<uint64_t> valid_positions = {0};
854+
855+
bool force = vm.count("yes-i-really-really-mean-it");
856+
int r = BlueStore::create_bdev_labels(cct.get(), path, devs, &valid_positions, force);
857+
if (r == -EPERM && !force) {
858+
cerr << "device " << devs.front()
859+
<< " already supports bdev label refusing to create a new label without --yes-i-really-really-mean-it"
860+
<< std::endl;
861+
exit(EXIT_FAILURE);
862+
}
863+
864+
if (r == -EEXIST && !force) {
865+
cerr << "device " << devs.front() << " already has a label" << std::endl;
866+
cerr << "Creating a new label on top of an existing one is a dangerous operation "
867+
<< "which could cause data loss.\n"
868+
<< "Please confirm with --yes-i-really-really-mean-it option" << std::endl;
869+
exit(EXIT_FAILURE);
870+
}
871+
872+
if (r < 0) {
873+
cerr << "Failed to create bdev label: " << cpp_strerror(r) << std::endl;
874+
exit(EXIT_FAILURE);
875+
}
876+
}
840877
else if (action == "set-label-key") {
841878
bluestore_bdev_label_t label;
842879
std::vector<uint64_t> valid_positions;

0 commit comments

Comments
 (0)