mirror of
https://github.com/koverstreet/bcachefs-tools.git
synced 2025-12-08 00:00:12 +03:00
cmd_show_super: Look up and print names of member devices
bch2_sb_to_text_with_names(): print device paths and models of each member. Fixes: https://github.com/koverstreet/bcachefs/issues/801 Signed-off-by: Kent Overstreet <kent.overstreet@linux.dev>
This commit is contained in:
parent
4174fe0bae
commit
6704e252ef
@ -85,6 +85,7 @@ fn main() {
|
||||
.opaque_type("gc_stripe")
|
||||
.opaque_type("open_bucket.*")
|
||||
.opaque_type("replicas_delta_list")
|
||||
.allowlist_type("sb_names")
|
||||
.no_copy("btree_trans")
|
||||
.no_copy("printbuf")
|
||||
.no_partialeq("bkey")
|
||||
|
||||
@ -13,6 +13,7 @@
|
||||
#include "include/linux/blkdev.h"
|
||||
#include "cmds.h"
|
||||
#include "raid/raid.h"
|
||||
#include "src/rust_to_c.h"
|
||||
|
||||
/* Fix753 is a workaround for https://github.com/rust-lang/rust-bindgen/issues/753
|
||||
* Functional macro are not expanded with bindgen, e.g. ioctl are automatically ignored
|
||||
|
||||
@ -21,6 +21,7 @@
|
||||
#include <uuid/uuid.h>
|
||||
|
||||
#include "cmds.h"
|
||||
#include "cmd_super.h"
|
||||
#include "tools-util.h"
|
||||
#include "posix_to_bcachefs.h"
|
||||
#include "libbcachefs.h"
|
||||
@ -293,7 +294,7 @@ int cmd_format(int argc, char *argv[])
|
||||
struct printbuf buf = PRINTBUF;
|
||||
buf.human_readable_units = true;
|
||||
|
||||
bch2_sb_to_text(&buf, sb, false, 1 << BCH_SB_FIELD_members_v2);
|
||||
bch2_sb_to_text_with_names(&buf, sb, false, 1 << BCH_SB_FIELD_members_v2, -1);
|
||||
printf("%s", buf.buf);
|
||||
printbuf_exit(&buf);
|
||||
}
|
||||
|
||||
@ -21,6 +21,7 @@
|
||||
#include <uuid/uuid.h>
|
||||
|
||||
#include "cmds.h"
|
||||
#include "cmd_super.h"
|
||||
#include "libbcachefs.h"
|
||||
#include "libbcachefs/opts.h"
|
||||
#include "libbcachefs/super-io.h"
|
||||
@ -28,6 +29,8 @@
|
||||
|
||||
#include "libbcachefs/darray.h"
|
||||
|
||||
#include "src/rust_to_c.h"
|
||||
|
||||
static void show_super_usage(void)
|
||||
{
|
||||
puts("bcachefs show-super \n"
|
||||
@ -42,6 +45,72 @@ static void show_super_usage(void)
|
||||
exit(EXIT_SUCCESS);
|
||||
}
|
||||
|
||||
static struct sb_name *sb_dev_to_name(sb_names sb_names, unsigned idx)
|
||||
{
|
||||
darray_for_each(sb_names, i)
|
||||
if (i->sb.sb->dev_idx == idx)
|
||||
return i;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static void print_one_member(struct printbuf *out, sb_names sb_names,
|
||||
struct bch_sb *sb,
|
||||
struct bch_sb_field_disk_groups *gi,
|
||||
struct bch_member m, unsigned idx)
|
||||
{
|
||||
struct sb_name *name = sb_dev_to_name(sb_names, idx);
|
||||
prt_printf(out, "Device %u:\t%s\t", idx, name ? name->name : "(not found)");
|
||||
|
||||
if (name) {
|
||||
char *model = fd_to_dev_model(name->sb.bdev->bd_fd);
|
||||
prt_str(out, model);
|
||||
free(model);
|
||||
}
|
||||
prt_newline(out);
|
||||
|
||||
printbuf_indent_add(out, 2);
|
||||
bch2_member_to_text(out, &m, gi, sb, idx);
|
||||
printbuf_indent_sub(out, 2);
|
||||
}
|
||||
|
||||
void bch2_sb_to_text_with_names(struct printbuf *out, struct bch_sb *sb,
|
||||
bool print_layout, unsigned fields, int field_only)
|
||||
{
|
||||
CLASS(printbuf, uuid_buf)();
|
||||
prt_str(&uuid_buf, "UUID=");
|
||||
pr_uuid(&uuid_buf, sb->user_uuid.b);
|
||||
|
||||
sb_names sb_names = {};
|
||||
bch2_scan_device_sbs(uuid_buf.buf, &sb_names);
|
||||
|
||||
if (field_only >= 0) {
|
||||
struct bch_sb_field *f = bch2_sb_field_get_id(sb, field_only);
|
||||
|
||||
if (f)
|
||||
__bch2_sb_field_to_text(out, sb, f);
|
||||
} else {
|
||||
printbuf_tabstop_push(out, 44);
|
||||
|
||||
bch2_sb_to_text(out, sb, print_layout,
|
||||
fields & ~(BIT(BCH_SB_FIELD_members_v1)|
|
||||
BIT(BCH_SB_FIELD_members_v2)));
|
||||
|
||||
struct bch_sb_field_disk_groups *gi = bch2_sb_field_get(sb, disk_groups);
|
||||
|
||||
struct bch_sb_field_members_v1 *mi1;
|
||||
if ((fields & BIT(BCH_SB_FIELD_members_v1)) &&
|
||||
(mi1 = bch2_sb_field_get(sb, members_v1)))
|
||||
for (unsigned i = 0; i < sb->nr_devices; i++)
|
||||
print_one_member(out, sb_names, sb, gi, bch2_members_v1_get(mi1, i), i);
|
||||
|
||||
struct bch_sb_field_members_v2 *mi2;
|
||||
if ((fields & BIT(BCH_SB_FIELD_members_v2)) &&
|
||||
(mi2 = bch2_sb_field_get(sb, members_v2)))
|
||||
for (unsigned i = 0; i < sb->nr_devices; i++)
|
||||
print_one_member(out, sb_names, sb, gi, bch2_members_v2_get(mi2, i), i);
|
||||
}
|
||||
}
|
||||
|
||||
int cmd_show_super(int argc, char *argv[])
|
||||
{
|
||||
static const struct option longopts[] = {
|
||||
@ -98,32 +167,16 @@ int cmd_show_super(int argc, char *argv[])
|
||||
|
||||
if (print_default_fields) {
|
||||
fields |= bch2_sb_field_get(sb.sb, members_v2)
|
||||
? 1 << BCH_SB_FIELD_members_v2
|
||||
: 1 << BCH_SB_FIELD_members_v1;
|
||||
fields |= 1 << BCH_SB_FIELD_errors;
|
||||
? BIT(BCH_SB_FIELD_members_v2)
|
||||
: BIT(BCH_SB_FIELD_members_v1);
|
||||
fields |= BIT(BCH_SB_FIELD_errors);
|
||||
}
|
||||
|
||||
struct printbuf buf = PRINTBUF;
|
||||
|
||||
buf.human_readable_units = true;
|
||||
|
||||
if (field_only >= 0) {
|
||||
struct bch_sb_field *f = bch2_sb_field_get_id(sb.sb, field_only);
|
||||
|
||||
if (f)
|
||||
__bch2_sb_field_to_text(&buf, sb.sb, f);
|
||||
} else {
|
||||
printbuf_tabstop_push(&buf, 44);
|
||||
|
||||
char *model = fd_to_dev_model(sb.bdev->bd_fd);
|
||||
prt_str(&buf, "Device:");
|
||||
prt_tab(&buf);
|
||||
prt_str(&buf, model);
|
||||
prt_newline(&buf);
|
||||
free(model);
|
||||
|
||||
bch2_sb_to_text(&buf, sb.sb, print_layout, fields);
|
||||
}
|
||||
bch2_sb_to_text_with_names(&buf, sb.sb, print_layout, fields, field_only);
|
||||
printf("%s", buf.buf);
|
||||
|
||||
bch2_free_super(&sb);
|
||||
|
||||
8
c_src/cmd_super.h
Normal file
8
c_src/cmd_super.h
Normal file
@ -0,0 +1,8 @@
|
||||
#ifndef _TOOLS_CMD_SHOW_SUPER_H
|
||||
#define _TOOLS_CMD_SHOW_SUPER_H
|
||||
|
||||
#include "libbcachefs/super-io.h"
|
||||
|
||||
void bch2_sb_to_text_with_names(struct printbuf *, struct bch_sb *, bool, unsigned, int);
|
||||
|
||||
#endif /* _TOOLS_CMD_SHOW_SUPER_H */
|
||||
@ -1,5 +1,5 @@
|
||||
use std::{
|
||||
ffi::{CStr, CString, c_char},
|
||||
ffi::{CStr, CString, c_char, c_int},
|
||||
collections::HashMap,
|
||||
env,
|
||||
path::{Path, PathBuf},
|
||||
@ -7,7 +7,12 @@ use std::{
|
||||
};
|
||||
|
||||
use anyhow::Result;
|
||||
use bch_bindgen::{bcachefs, bcachefs::bch_sb_handle, opt_set};
|
||||
use bch_bindgen::{bcachefs, opt_set};
|
||||
use bcachefs::{
|
||||
bch_sb_handle,
|
||||
sb_name,
|
||||
sb_names,
|
||||
};
|
||||
use bcachefs::bch_opts;
|
||||
use uuid::Uuid;
|
||||
use log::debug;
|
||||
@ -185,13 +190,39 @@ pub fn scan_devices(device: &String, opts: &bch_opts) -> Result<String> {
|
||||
Ok(joined_device_str(&sbs))
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
pub extern "C" fn bch2_scan_device_sbs(device: *const c_char, ret: *mut sb_names) -> c_int {
|
||||
let device = unsafe { CStr::from_ptr(device) };
|
||||
let device = device.to_str().unwrap().to_string();
|
||||
|
||||
// how to initialize to default/empty?
|
||||
let opts = bch_bindgen::opts::parse_mount_opts(None, None, true).unwrap_or_default();
|
||||
|
||||
let sbs = scan_sbs(&device, &opts).unwrap();
|
||||
|
||||
let mut sbs = sbs.iter()
|
||||
.map(|(name, sb)| sb_name {
|
||||
name: CString::new(name.clone().into_os_string().into_string().unwrap()).unwrap().into_raw(),
|
||||
sb: *sb } )
|
||||
.collect::<Vec<sb_name>>();
|
||||
|
||||
unsafe {
|
||||
(*ret).data = sbs.as_mut_ptr();
|
||||
(*ret).nr = sbs.len();
|
||||
(*ret).size = sbs.capacity();
|
||||
|
||||
std::mem::forget(sbs);
|
||||
}
|
||||
0
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
pub extern "C" fn bch2_scan_devices(device: *const c_char) -> *mut c_char {
|
||||
let device = unsafe { CStr::from_ptr(device) };
|
||||
let device = device.to_str().unwrap().to_string();
|
||||
|
||||
let opts = bch_bindgen::opts::parse_mount_opts(None, None, true)
|
||||
.unwrap_or_default();
|
||||
// how to initialize to default/empty?
|
||||
let opts = bch_bindgen::opts::parse_mount_opts(None, None, true).unwrap_or_default();
|
||||
|
||||
CString::new(scan_devices(&device, &opts).unwrap()).unwrap().into_raw()
|
||||
}
|
||||
|
||||
@ -1,6 +1,17 @@
|
||||
#ifndef _BCACHEFS_TOOLS_RUST_TO_C_H
|
||||
#define _BCACHEFS_TOOLS_RUST_TO_C_H
|
||||
|
||||
#include "libbcachefs/super_types.h"
|
||||
#include "libbcachefs/darray.h"
|
||||
|
||||
struct sb_name {
|
||||
const char *name;
|
||||
struct bch_sb_handle sb;
|
||||
};
|
||||
typedef DARRAY(struct sb_name) sb_names;
|
||||
|
||||
int bch2_scan_device_sbs(char *, sb_names *ret);
|
||||
|
||||
char *bch2_scan_devices(char *);
|
||||
|
||||
#endif /* _BCACHEFS_TOOLS_RUST_TO_C_H */
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user