From: Hannes Laimer <h.laimer@proxmox.com>
To: pbs-devel@lists.proxmox.com
Subject: [pbs-devel] [PATCH proxmox-backup v15 25/26] bin: debug: add inspect device command
Date: Mon, 25 Nov 2024 17:22:12 +0100 [thread overview]
Message-ID: <20241125162213.157011-26-h.laimer@proxmox.com> (raw)
In-Reply-To: <20241125162213.157011-1-h.laimer@proxmox.com>
... to get information about (removable) datastores a device contains
Signed-off-by: Hannes Laimer <h.laimer@proxmox.com>
---
src/bin/proxmox_backup_debug/inspect.rs | 149 ++++++++++++++++++++++++
1 file changed, 149 insertions(+)
diff --git a/src/bin/proxmox_backup_debug/inspect.rs b/src/bin/proxmox_backup_debug/inspect.rs
index 28a472b0f..17df09be2 100644
--- a/src/bin/proxmox_backup_debug/inspect.rs
+++ b/src/bin/proxmox_backup_debug/inspect.rs
@@ -331,6 +331,151 @@ fn inspect_file(
Ok(())
}
+/// Return the count of VM, CT and host backup groups and the count of namespaces
+/// as this tuple (vm, ct, host, ns)
+fn get_basic_ds_info(path: String) -> Result<(i64, i64, i64, i64), Error> {
+ let mut vms = 0;
+ let mut cts = 0;
+ let mut hosts = 0;
+ let mut ns = 0;
+ let mut walker = WalkDir::new(path).into_iter();
+
+ while let Some(entry_result) = walker.next() {
+ let entry = entry_result?;
+ if !entry.file_type().is_dir() {
+ continue;
+ }
+
+ let Some(name) = entry.path().file_name().and_then(|a| a.to_str()) else {
+ continue;
+ };
+
+ if name == ".chunks" {
+ walker.skip_current_dir();
+ continue;
+ }
+
+ let dir_count = std::fs::read_dir(entry.path())?
+ .filter_map(Result::ok)
+ .filter(|entry| entry.path().is_dir())
+ .count() as i64;
+
+ match name {
+ "ns" => ns += dir_count,
+ "vm" => {
+ vms += dir_count;
+ walker.skip_current_dir();
+ }
+ "ct" => {
+ cts += dir_count;
+ walker.skip_current_dir();
+ }
+ "host" => {
+ hosts += dir_count;
+ walker.skip_current_dir();
+ }
+ _ => {
+ // root or ns dir
+ }
+ }
+ }
+
+ Ok((vms, cts, hosts, ns))
+}
+
+#[api(
+ input: {
+ properties: {
+ device: {
+ description: "Device path, usually /dev/...",
+ type: String,
+ },
+ "output-format": {
+ schema: OUTPUT_FORMAT,
+ optional: true,
+ },
+ }
+ }
+)]
+/// Inspect a device for possible datastores on it
+fn inspect_device(device: String, param: Value) -> Result<(), Error> {
+ let output_format = get_output_format(¶m);
+ let tmp_mount_path = format!(
+ "{}/{:x}",
+ pbs_buildcfg::rundir!("/mount"),
+ proxmox_uuid::Uuid::generate()
+ );
+
+ let default_options = proxmox_sys::fs::CreateOptions::new();
+ proxmox_sys::fs::create_path(
+ &tmp_mount_path,
+ Some(default_options.clone()),
+ Some(default_options.clone()),
+ )?;
+ let mut mount_cmd = std::process::Command::new("mount");
+ mount_cmd.arg(device.clone());
+ mount_cmd.arg(tmp_mount_path.clone());
+ proxmox_sys::command::run_command(mount_cmd, None)?;
+
+ let mut walker = WalkDir::new(tmp_mount_path.clone()).into_iter();
+
+ let mut stores = Vec::new();
+
+ let mut ds_count = 0;
+ while let Some(entry_result) = walker.next() {
+ let entry = entry_result?;
+
+ if entry.file_type().is_dir()
+ && entry
+ .file_name()
+ .to_str()
+ .map_or(false, |name| name == ".chunks")
+ {
+ let store_path = entry
+ .path()
+ .to_str()
+ .and_then(|n| n.strip_suffix("/.chunks"));
+
+ if let Some(store_path) = store_path {
+ ds_count += 1;
+ let (vm, ct, host, ns) = get_basic_ds_info(store_path.to_string())?;
+ stores.push(json!({
+ "path": store_path.strip_prefix(&tmp_mount_path).unwrap_or("???"),
+ "vm-count": vm,
+ "ct-count": ct,
+ "host-count": host,
+ "ns-count": ns,
+ }));
+ };
+
+ walker.skip_current_dir();
+ }
+ }
+
+ let mut umount_cmd = std::process::Command::new("umount");
+ umount_cmd.arg(tmp_mount_path.clone());
+ proxmox_sys::command::run_command(umount_cmd, None)?;
+ std::fs::remove_dir(std::path::Path::new(&tmp_mount_path))?;
+
+ if output_format == "text" {
+ println!("Device containes {} stores", ds_count);
+ println!("---------------");
+ for s in stores {
+ println!(
+ "Datastore at {} | VM: {}, CT: {}, HOST: {}, NS: {}",
+ s["path"], s["vm-count"], s["ct-count"], s["host-count"], s["ns-count"]
+ );
+ }
+ } else {
+ format_and_print_result(
+ &json!({"store_count": stores.len(), "stores": stores}),
+ &output_format,
+ );
+ }
+
+ Ok(())
+}
+
pub fn inspect_commands() -> CommandLineInterface {
let cmd_def = CliCommandMap::new()
.insert(
@@ -340,6 +485,10 @@ pub fn inspect_commands() -> CommandLineInterface {
.insert(
"file",
CliCommand::new(&API_METHOD_INSPECT_FILE).arg_param(&["file"]),
+ )
+ .insert(
+ "device",
+ CliCommand::new(&API_METHOD_INSPECT_DEVICE).arg_param(&["device"]),
);
cmd_def.into()
--
2.39.5
_______________________________________________
pbs-devel mailing list
pbs-devel@lists.proxmox.com
https://lists.proxmox.com/cgi-bin/mailman/listinfo/pbs-devel
next prev parent reply other threads:[~2024-11-25 16:23 UTC|newest]
Thread overview: 28+ messages / expand[flat|nested] mbox.gz Atom feed top
2024-11-25 16:21 [pbs-devel] [PATCH proxmox-backup v15 00/26] add removable datastores Hannes Laimer
2024-11-25 16:21 ` [pbs-devel] [PATCH proxmox-backup v15 01/26] pbs-api-types: add backing-device to DataStoreConfig Hannes Laimer
2024-11-25 16:21 ` [pbs-devel] [PATCH proxmox-backup v15 02/26] maintenance: make is_offline more generic Hannes Laimer
2024-11-25 16:21 ` [pbs-devel] [PATCH proxmox-backup v15 03/26] maintenance: add 'Unmount' maintenance type Hannes Laimer
2024-11-25 16:21 ` [pbs-devel] [PATCH proxmox-backup v15 04/26] datastore: add helper for checking if a datastore is mounted Hannes Laimer
2024-11-25 16:21 ` [pbs-devel] [PATCH proxmox-backup v15 05/26] api: admin: add (un)mount endpoint for removable datastores Hannes Laimer
2024-11-25 16:21 ` [pbs-devel] [PATCH proxmox-backup v15 06/26] api: removable datastore creation Hannes Laimer
2024-11-25 16:21 ` [pbs-devel] [PATCH proxmox-backup v15 07/26] api: add check for nested datastores on creation Hannes Laimer
2024-11-25 16:21 ` [pbs-devel] [PATCH proxmox-backup v15 08/26] pbs-api-types: add mount_status field to DataStoreListItem Hannes Laimer
2024-11-25 16:21 ` [pbs-devel] [PATCH proxmox-backup v15 09/26] bin: manager: add (un)mount command Hannes Laimer
2024-11-25 16:21 ` [pbs-devel] [PATCH proxmox-backup v15 10/26] add auto-mounting for removable datastores Hannes Laimer
2024-11-25 16:21 ` [pbs-devel] [PATCH proxmox-backup v15 11/26] datastore: handle deletion of removable datastore properly Hannes Laimer
2024-11-25 16:21 ` [pbs-devel] [PATCH proxmox-backup v15 12/26] docs: add removable datastores section Hannes Laimer
2024-11-25 16:22 ` [pbs-devel] [PATCH proxmox-backup v15 13/26] ui: add partition selector form Hannes Laimer
2024-11-25 16:22 ` [pbs-devel] [PATCH proxmox-backup v15 14/26] ui: add removable datastore creation support Hannes Laimer
2024-11-25 16:22 ` [pbs-devel] [PATCH proxmox-backup v15 15/26] ui: add (un)mount button to summary Hannes Laimer
2024-11-25 16:22 ` [pbs-devel] [PATCH proxmox-backup v15 16/26] ui: tree: render unmounted datastores correctly Hannes Laimer
2024-11-25 16:22 ` [pbs-devel] [PATCH proxmox-backup v15 17/26] ui: utils: make parseMaintenanceMode more robust Hannes Laimer
2024-11-25 16:22 ` [pbs-devel] [PATCH proxmox-backup v15 18/26] ui: add datastore status mask for unmounted removable datastores Hannes Laimer
2024-11-25 16:22 ` [pbs-devel] [PATCH proxmox-backup v15 19/26] ui: maintenance: fix disable msg field if no type is selected Hannes Laimer
2024-11-25 16:22 ` [pbs-devel] [PATCH proxmox-backup v15 20/26] ui: render 'unmount' maintenance mode correctly Hannes Laimer
2024-11-25 16:22 ` [pbs-devel] [PATCH proxmox-backup v15 21/26] api: node: allow creation of removable datastore through directory endpoint Hannes Laimer
2024-11-25 16:22 ` [pbs-devel] [PATCH proxmox-backup v15 22/26] api: node: include removable datastores in directory list Hannes Laimer
2024-11-25 16:22 ` [pbs-devel] [PATCH proxmox-backup v15 23/26] node: disks: replace BASE_MOUNT_DIR with DATASTORE_MOUNT_DIR Hannes Laimer
2024-11-25 16:22 ` [pbs-devel] [PATCH proxmox-backup v15 24/26] ui: support create removable datastore through directory creation Hannes Laimer
2024-11-25 16:22 ` Hannes Laimer [this message]
2024-11-25 16:22 ` [pbs-devel] [PATCH proxmox-backup v15 26/26] api: disks: only return UUID of partitions if it actually is one Hannes Laimer
2024-11-25 20:48 ` [pbs-devel] applied-series: [PATCH proxmox-backup v15 00/26] add removable datastores Thomas Lamprecht
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20241125162213.157011-26-h.laimer@proxmox.com \
--to=h.laimer@proxmox.com \
--cc=pbs-devel@lists.proxmox.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox