Skip to content

Commit f2faf3e

Browse files
os/bluestore: Implemented create-bdev-label
Introduces a helper function create_bdev_label() and a new command create-bdev-label to write essential OSD metadata (e.g., fsid, whoami) directly into the device label at offset 0, for use on devices where support_bdev_label == false. Usage: ./bin/ceph-bluestore-tool --path dev/osd0 --dev dev/osd0/block create-bdev-label If a label already exists, the function throws an error to avoid overwriting. This lays the groundwork for eventually removing duplicated metadata from the OSD directory for devices that don’t support native bdev labels Signed-off-by: Jaya Prakash <[email protected]>
1 parent e7cb253 commit f2faf3e

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)