public inbox for pve-devel@lists.proxmox.com
 help / color / mirror / Atom feed
From: Kefu Chai <k.chai@proxmox.com>
To: pve-devel@lists.proxmox.com
Subject: [PATCH pve-cluster 02/14 v2] pmxcfs-rs: add pmxcfs-api-types crate
Date: Fri, 13 Feb 2026 17:33:39 +0800	[thread overview]
Message-ID: <20260213094119.2379288-3-k.chai@proxmox.com> (raw)
In-Reply-To: <20260213094119.2379288-1-k.chai@proxmox.com>

Add pmxcfs-api-types crate which provides foundational types:
- PmxcfsError: Error type with errno mapping for FUSE operations
- FuseMessage: Filesystem operation messages
- KvStoreMessage: Status synchronization messages
- ApplicationMessage: Wrapper enum for both message types
- VmType: VM type enum (Qemu, Lxc)

All other crates will depend on these shared type definitions.

Signed-off-by: Kefu Chai <k.chai@proxmox.com>
---
 src/pmxcfs-rs/Cargo.toml                    |  10 +-
 src/pmxcfs-rs/pmxcfs-api-types/Cargo.toml   |  19 +++
 src/pmxcfs-rs/pmxcfs-api-types/README.md    |  88 ++++++++++++++
 src/pmxcfs-rs/pmxcfs-api-types/src/error.rs | 122 ++++++++++++++++++++
 src/pmxcfs-rs/pmxcfs-api-types/src/lib.rs   |  67 +++++++++++
 5 files changed, 305 insertions(+), 1 deletion(-)
 create mode 100644 src/pmxcfs-rs/pmxcfs-api-types/Cargo.toml
 create mode 100644 src/pmxcfs-rs/pmxcfs-api-types/README.md
 create mode 100644 src/pmxcfs-rs/pmxcfs-api-types/src/error.rs
 create mode 100644 src/pmxcfs-rs/pmxcfs-api-types/src/lib.rs

diff --git a/src/pmxcfs-rs/Cargo.toml b/src/pmxcfs-rs/Cargo.toml
index d109221fb..13407f402 100644
--- a/src/pmxcfs-rs/Cargo.toml
+++ b/src/pmxcfs-rs/Cargo.toml
@@ -1,6 +1,7 @@
 # Workspace root for pmxcfs Rust implementation
 [workspace]
 members = [
+    "pmxcfs-api-types",  # Shared types and error definitions
 ]
 resolver = "2"
 
@@ -13,7 +14,14 @@ repository = "https://git.proxmox.com/?p=pve-cluster.git"
 rust-version = "1.85"
 
 [workspace.dependencies]
-# Dependencies will be added incrementally as crates are introduced
+# Internal workspace dependencies
+pmxcfs-api-types = { path = "pmxcfs-api-types" }
+
+# Error handling
+thiserror = "1.0"
+
+# System integration
+libc = "0.2"
 
 [workspace.lints.clippy]
 uninlined_format_args = "warn"
diff --git a/src/pmxcfs-rs/pmxcfs-api-types/Cargo.toml b/src/pmxcfs-rs/pmxcfs-api-types/Cargo.toml
new file mode 100644
index 000000000..cdce7951a
--- /dev/null
+++ b/src/pmxcfs-rs/pmxcfs-api-types/Cargo.toml
@@ -0,0 +1,19 @@
+[package]
+name = "pmxcfs-api-types"
+description = "Shared types and error definitions for pmxcfs"
+
+version.workspace = true
+edition.workspace = true
+authors.workspace = true
+license.workspace = true
+repository.workspace = true
+
+[lints]
+workspace = true
+
+[dependencies]
+# Error handling
+thiserror.workspace = true
+
+# System integration
+libc.workspace = true
diff --git a/src/pmxcfs-rs/pmxcfs-api-types/README.md b/src/pmxcfs-rs/pmxcfs-api-types/README.md
new file mode 100644
index 000000000..ddcd4e478
--- /dev/null
+++ b/src/pmxcfs-rs/pmxcfs-api-types/README.md
@@ -0,0 +1,88 @@
+# pmxcfs-api-types
+
+**Shared Types and Error Definitions** for pmxcfs.
+
+This crate provides common types and error definitions used across all pmxcfs crates.
+
+## Overview
+
+The crate contains:
+- **Error types**: `PmxcfsError` with errno mapping for FUSE
+- **Shared types**: `MemberInfo`, `NodeSyncInfo`, `VmType`, `VmEntry`
+
+## Error Types
+
+### PmxcfsError
+
+Type-safe error enum with automatic errno conversion.
+
+### errno Mapping
+
+Errors automatically convert to POSIX errno values for FUSE.
+
+| Error | errno | Value | Note |
+|-------|-------|-------|------|
+| `NotFound(_)` | `ENOENT` | 2 | File or directory not found |
+| `PermissionDenied` | `EACCES` | 13 | File permission denied |
+| `AlreadyExists(_)` | `EEXIST` | 17 | File already exists |
+| `NotADirectory(_)` | `ENOTDIR` | 20 | Not a directory |
+| `IsADirectory(_)` | `EISDIR` | 21 | Is a directory |
+| `DirectoryNotEmpty(_)` | `ENOTEMPTY` | 39 | Directory not empty |
+| `InvalidArgument(_)` | `EINVAL` | 22 | Invalid argument |
+| `InvalidPath(_)` | `EINVAL` | 22 | Invalid path |
+| `FileTooLarge` | `EFBIG` | 27 | File too large |
+| `ReadOnlyFilesystem` | `EROFS` | 30 | Read-only filesystem |
+| `NoQuorum` | `EACCES` | 13 | No cluster quorum |
+| `Lock(_)` | `EAGAIN` | 11 | Lock unavailable, try again |
+| `Timeout` | `ETIMEDOUT` | 110 | Operation timed out |
+| `Io(e)` | varies | varies | OS error code or `EIO` |
+| Others* | `EIO` | 5 | Internal error |
+
+*Others include: `Database`, `Fuse`, `Cluster`, `Corosync`, `Configuration`, `System`, `Ipc`
+
+## Shared Types
+
+### MemberInfo
+
+Cluster member information.
+
+### NodeSyncInfo
+
+DFSM synchronization state.
+
+### VmType
+
+VM/CT type enum (Qemu or Lxc).
+
+### VmEntry
+
+VM/CT entry for vmlist.
+
+## C to Rust Mapping
+
+### Error Handling
+
+**C Version (cfs-utils.h):**
+- Return codes: `0` = success, negative = error
+- errno-based error reporting
+- Manual error checking everywhere
+
+**Rust Version:**
+- `Result<T, PmxcfsError>` type
+
+## Known Issues / TODOs
+
+### Missing Features
+- None identified
+
+### Compatibility
+- **errno values**: Match POSIX standards
+
+## References
+
+### C Implementation
+- `src/pmxcfs/cfs-utils.h` - Utility types and error codes
+
+### Related Crates
+- **pmxcfs-dfsm**: Uses shared types for cluster sync
+- **pmxcfs-memdb**: Uses PmxcfsError for database operations
diff --git a/src/pmxcfs-rs/pmxcfs-api-types/src/error.rs b/src/pmxcfs-rs/pmxcfs-api-types/src/error.rs
new file mode 100644
index 000000000..dcb5d1e9e
--- /dev/null
+++ b/src/pmxcfs-rs/pmxcfs-api-types/src/error.rs
@@ -0,0 +1,122 @@
+use thiserror::Error;
+
+/// Error types for pmxcfs operations
+#[derive(Error, Debug)]
+pub enum PmxcfsError {
+    #[error("I/O error: {0}")]
+    Io(#[from] std::io::Error),
+
+    #[error("Database error: {0}")]
+    Database(String),
+
+    #[error("FUSE error: {0}")]
+    Fuse(String),
+
+    #[error("Cluster error: {0}")]
+    Cluster(String),
+
+    #[error("Corosync error: {0}")]
+    Corosync(String),
+
+    #[error("Configuration error: {0}")]
+    Configuration(String),
+
+    #[error("System error: {0}")]
+    System(String),
+
+    #[error("IPC error: {0}")]
+    Ipc(String),
+
+    #[error("Permission denied")]
+    PermissionDenied,
+
+    #[error("Not found: {0}")]
+    NotFound(String),
+
+    #[error("Already exists: {0}")]
+    AlreadyExists(String),
+
+    #[error("Invalid argument: {0}")]
+    InvalidArgument(String),
+
+    #[error("Not a directory: {0}")]
+    NotADirectory(String),
+
+    #[error("Is a directory: {0}")]
+    IsADirectory(String),
+
+    #[error("Directory not empty: {0}")]
+    DirectoryNotEmpty(String),
+
+    #[error("No quorum")]
+    NoQuorum,
+
+    #[error("Read-only filesystem")]
+    ReadOnlyFilesystem,
+
+    #[error("File too large")]
+    FileTooLarge,
+
+    #[error("Filesystem full")]
+    FilesystemFull,
+
+    #[error("Lock error: {0}")]
+    Lock(String),
+
+    #[error("Timeout")]
+    Timeout,
+
+    #[error("Invalid path: {0}")]
+    InvalidPath(String),
+}
+
+impl PmxcfsError {
+    /// Convert error to errno value for FUSE operations
+    pub fn to_errno(&self) -> i32 {
+        match self {
+            // File/directory errors
+            PmxcfsError::NotFound(_) => libc::ENOENT,
+            PmxcfsError::AlreadyExists(_) => libc::EEXIST,
+            PmxcfsError::NotADirectory(_) => libc::ENOTDIR,
+            PmxcfsError::IsADirectory(_) => libc::EISDIR,
+            PmxcfsError::DirectoryNotEmpty(_) => libc::ENOTEMPTY,
+            PmxcfsError::FileTooLarge => libc::EFBIG,
+            PmxcfsError::FilesystemFull => libc::ENOSPC,
+            PmxcfsError::ReadOnlyFilesystem => libc::EROFS,
+
+            // Permission and access errors
+            // EACCES: Permission denied for file operations (standard POSIX)
+            // C implementation uses EACCES as default for access/quorum issues
+            PmxcfsError::PermissionDenied => libc::EACCES,
+            PmxcfsError::NoQuorum => libc::EACCES,
+
+            // Validation errors
+            PmxcfsError::InvalidArgument(_) => libc::EINVAL,
+            PmxcfsError::InvalidPath(_) => libc::EINVAL,
+
+            // Lock errors - use EAGAIN for temporary failures
+            PmxcfsError::Lock(_) => libc::EAGAIN,
+
+            // Timeout
+            PmxcfsError::Timeout => libc::ETIMEDOUT,
+
+            // I/O errors with automatic errno extraction
+            PmxcfsError::Io(e) => match e.raw_os_error() {
+                Some(errno) => errno,
+                None => libc::EIO,
+            },
+
+            // Fallback to EIO for internal/system errors
+            PmxcfsError::Database(_) |
+            PmxcfsError::Fuse(_) |
+            PmxcfsError::Cluster(_) |
+            PmxcfsError::Corosync(_) |
+            PmxcfsError::Configuration(_) |
+            PmxcfsError::System(_) |
+            PmxcfsError::Ipc(_) => libc::EIO,
+        }
+    }
+}
+
+/// Result type for pmxcfs operations
+pub type Result<T> = std::result::Result<T, PmxcfsError>;
diff --git a/src/pmxcfs-rs/pmxcfs-api-types/src/lib.rs b/src/pmxcfs-rs/pmxcfs-api-types/src/lib.rs
new file mode 100644
index 000000000..99cafbaa3
--- /dev/null
+++ b/src/pmxcfs-rs/pmxcfs-api-types/src/lib.rs
@@ -0,0 +1,67 @@
+mod error;
+
+pub use error::{PmxcfsError, Result};
+
+/// Maximum size for status data (matches C implementation)
+/// From status.h: #define CFS_MAX_STATUS_SIZE (32 * 1024)
+pub const CFS_MAX_STATUS_SIZE: usize = 32 * 1024;
+
+/// VM/CT types
+///
+/// Note: OpenVZ was historically supported (VMTYPE_OPENVZ = 2 in C implementation)
+/// but was removed in PVE 4.0 in favor of LXC. Only QEMU and LXC are currently supported.
+#[derive(Debug, Clone, Copy, PartialEq, Eq)]
+pub enum VmType {
+    Qemu,
+    Lxc,
+}
+
+impl VmType {
+    /// Returns the directory name where config files are stored
+    pub fn config_dir(&self) -> &'static str {
+        match self {
+            VmType::Qemu => "qemu-server",
+            VmType::Lxc => "lxc",
+        }
+    }
+}
+
+impl std::fmt::Display for VmType {
+    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
+        match self {
+            VmType::Qemu => write!(f, "qemu"),
+            VmType::Lxc => write!(f, "lxc"),
+        }
+    }
+}
+
+/// VM/CT entry for vmlist
+#[derive(Debug, Clone)]
+pub struct VmEntry {
+    pub vmid: u32,
+    pub vmtype: VmType,
+    pub node: String,
+    /// Per-VM version counter (increments when this VM's config changes)
+    pub version: u32,
+}
+
+/// Information about a cluster member
+///
+/// This is a shared type used by both cluster and DFSM modules
+#[derive(Debug, Clone)]
+pub struct MemberInfo {
+    pub node_id: u32,
+    pub pid: u32,
+    pub joined_at: u64,
+}
+
+/// Node synchronization info for DFSM state sync
+///
+/// Used during DFSM synchronization to track which nodes have provided state
+#[derive(Debug, Clone)]
+pub struct NodeSyncInfo {
+    pub node_id: u32,
+    pub pid: u32,
+    pub state: Option<Vec<u8>>,
+    pub synced: bool,
+}
-- 
2.47.3





  parent reply	other threads:[~2026-02-13  9:41 UTC|newest]

Thread overview: 17+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-02-13  9:33 [PATCH pve-cluster 00/14 v2] Rewrite pmxcfs with Rust Kefu Chai
2026-02-13  9:33 ` [PATCH pve-cluster 01/14 v2] pmxcfs-rs: add Rust workspace configuration Kefu Chai
2026-02-18 10:41   ` Samuel Rufinatscha
2026-02-13  9:33 ` Kefu Chai [this message]
2026-02-18 15:06   ` [PATCH pve-cluster 02/14 v2] pmxcfs-rs: add pmxcfs-api-types crate Samuel Rufinatscha
2026-02-13  9:33 ` [PATCH pve-cluster 03/14 v2] pmxcfs-rs: add pmxcfs-config crate Kefu Chai
2026-02-18 16:41   ` Samuel Rufinatscha
2026-02-13  9:33 ` [PATCH pve-cluster 04/14 v2] pmxcfs-rs: add pmxcfs-logger crate Kefu Chai
2026-02-13  9:33 ` [PATCH pve-cluster 05/14 v2] pmxcfs-rs: add pmxcfs-rrd crate Kefu Chai
2026-02-13  9:33 ` [PATCH pve-cluster 06/14 v2] pmxcfs-rs: add pmxcfs-memdb crate Kefu Chai
2026-02-13  9:33 ` [PATCH pve-cluster 07/14 v2] pmxcfs-rs: add pmxcfs-status and pmxcfs-test-utils crates Kefu Chai
2026-02-13  9:33 ` [PATCH pve-cluster 08/14 v2] pmxcfs-rs: add pmxcfs-services crate Kefu Chai
2026-02-13  9:33 ` [PATCH pve-cluster 09/14 v2] pmxcfs-rs: add pmxcfs-ipc crate Kefu Chai
2026-02-13  9:33 ` [PATCH pve-cluster 10/14 v2] pmxcfs-rs: add pmxcfs-dfsm crate Kefu Chai
2026-02-13  9:33 ` [PATCH pve-cluster 11/14 v2] pmxcfs-rs: vendor patched rust-corosync for CPG compatibility Kefu Chai
2026-02-13  9:33 ` [PATCH pve-cluster 12/14 v2] pmxcfs-rs: add pmxcfs main daemon binary Kefu Chai
2026-02-13  9:33 ` [PATCH pve-cluster 14/14 v2] pmxcfs-rs: add project documentation Kefu Chai

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=20260213094119.2379288-3-k.chai@proxmox.com \
    --to=k.chai@proxmox.com \
    --cc=pve-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
Service provided by Proxmox Server Solutions GmbH | Privacy | Legal