| **ceph-bluestore-tool** trim --path *osd path*
| **ceph-bluestore-tool** zap-device --dev *dev path*
| **ceph-bluestore-tool** revert-wal-to-plain --path *osd path*
+| **ceph-bluestore-tool** create-bdev-labels --path *osd path* --dev *device*
+
Description
Changes WAL files from envelope mode to the legacy plain mode.
Useful for downgrades, or if you might want to disable this new feature (bluefs_wal_envelope_mode).
+:command:`create-bdev-labels` --path *osd path* --dev *device*
+
+ Writes a bdev label to BlueStore devices that originally did not support labeling.
+ Reads metadata (e.g., fsid, ceph version) from --path and writes it to the device at --dev.
+ Only the main device (block) gets full metadata; block.db or block.wal do not.
+ The --dev path must be inside the --path directory, as its name determines the device role.
+ Use --yes-i-really-really-mean-it to recreate corrupted labels.
+
Options
=======
--- /dev/null
+// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
+// vim: ts=8 sw=2 smarttab
+
+#include <stdio.h>
+#include <string.h>
+#include <filesystem>
+#include <iostream>
+#include <fstream>
+#include <time.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include "global/global_init.h"
+#include "common/ceph_argparse.h"
+#include "include/stringify.h"
+#include "common/errno.h"
+#include "common/safe_io.h"
+
+#include "os/bluestore/BlueStore.h"
+
+using namespace std;
+
+
+int BlueStore::create_bdev_labels(CephContext *cct,
+ const std::string& path,
+ const std::vector<std::string>& devs,
+ std::vector<uint64_t>* valid_positions,
+ bool force)
+{
+ std::vector<std::string> metadata_files = {
+ "bfm_blocks",
+ "bfm_blocks_per_key",
+ "bfm_bytes_per_block",
+ "bfm_size",
+ "bluefs",
+ "ceph_fsid",
+ "ceph_version_when_created",
+ "created_at",
+ "elastic_shared_blobs",
+ "fsid",
+ "kv_backend",
+ "magic",
+ "osd_key",
+ "ready",
+ "require_osd_release",
+ "type",
+ "whoami"
+ };
+
+ unique_ptr<BlockDevice> bdev(BlockDevice::create(cct, devs.front(), nullptr, nullptr, nullptr, nullptr));
+ int r = bdev->open(devs.front());
+ if (r < 0) {
+ return r;
+ }
+ uint64_t size = bdev->get_size();
+
+ if (bdev->supported_bdev_label() && !force) {
+ bdev->close();
+ return -EPERM;
+ }
+
+ bdev->close();
+
+ bluestore_bdev_label_t label;
+ std::vector<uint64_t> out_positions;
+ bool is_multi = false;
+ int64_t epoch = -1;
+
+ r = BlueStore::read_bdev_label(cct, devs.front(), &label,
+ &out_positions, &is_multi, &epoch);
+
+ if (r == 0 && !force)
+ return -EEXIST;
+
+ label = bluestore_bdev_label_t();
+ label.btime = ceph_clock_now();
+
+ if (devs.front().ends_with("block")) {
+ label.description = "main";
+ } else if (devs.front().ends_with("block.db")) {
+ label.description = "bluefs db";
+ } else if (devs.front().ends_with("block.wal")) {
+ label.description = "bluefs wal";
+ }
+
+ label.size = size;
+
+ for (const auto& file : metadata_files) {
+ std::ifstream infile(path + "/" + file);
+ if (infile) {
+ std::string value((std::istreambuf_iterator<char>(infile)), std::istreambuf_iterator<char>());
+ value.erase(std::remove(value.begin(), value.end(), '\n'), value.end());
+ if (file == "fsid") {
+ label.osd_uuid.parse(value.c_str());
+ } else if (label.description == "main") {
+ label.meta[file] = value;
+ }
+ } else {
+ cerr << "Warning: unable to read metadata file: " << file << std::endl;
+ }
+ }
+
+ bool wrote_at_least_one = false;
+ for (uint64_t position : *valid_positions) {
+ r = BlueStore::write_bdev_label(cct, devs.front(), label, position);
+ if (r < 0) {
+ cerr << "unable to write label at 0x" << std::hex << position << std::dec
+ << ": " << cpp_strerror(r) << std::endl;
+ } else {
+ wrote_at_least_one = true;
+ }
+ }
+ return wrote_at_least_one ? 0 : -EIO;
+}
"show-label, "
"show-label-at, "
"set-label-key, "
+ "create-bdev-labels, "
"rm-label-key, "
"prime-osd-dir, "
"bluefs-super-dump, "
exit(EXIT_FAILURE);
}
}
+ if (action == "create-bdev-labels") {
+ if (path.empty()) {
+ cerr << "must specify bluestore path" << std::endl;
+ exit(EXIT_FAILURE);
+ }
+ if (devs.size() != 1) {
+ cerr << "must specify the main bluestore device" << std::endl;
+ exit(EXIT_FAILURE);
+ }
+ }
if (action == "show-label") {
if (devs.empty() && path.empty()) {
cerr << "must specify bluestore path *or* raw device(s)" << std::endl;
jf.close_section();
jf.flush(cout);
}
+ else if (action == "create-bdev-labels") {
+
+ std::vector<uint64_t> valid_positions = {0};
+
+ bool force = vm.count("yes-i-really-really-mean-it");
+ int r = BlueStore::create_bdev_labels(cct.get(), path, devs, &valid_positions, force);
+ if (r == -EPERM && !force) {
+ cerr << "device " << devs.front()
+ << " already supports bdev label refusing to create a new label without --yes-i-really-really-mean-it"
+ << std::endl;
+ exit(EXIT_FAILURE);
+ }
+
+ if (r == -EEXIST && !force) {
+ cerr << "device " << devs.front() << " already has a label" << std::endl;
+ cerr << "Creating a new label on top of an existing one is a dangerous operation "
+ << "which could cause data loss.\n"
+ << "Please confirm with --yes-i-really-really-mean-it option" << std::endl;
+ exit(EXIT_FAILURE);
+ }
+
+ if (r < 0) {
+ cerr << "Failed to create bdev label: " << cpp_strerror(r) << std::endl;
+ exit(EXIT_FAILURE);
+ }
+ }
else if (action == "set-label-key") {
bluestore_bdev_label_t label;
std::vector<uint64_t> valid_positions;