From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from firstgate.proxmox.com (firstgate.proxmox.com [IPv6:2a01:7e0:0:424::9]) by lore.proxmox.com (Postfix) with ESMTPS id 5AD661FF141 for ; Fri, 13 Feb 2026 10:41:52 +0100 (CET) Received: from firstgate.proxmox.com (localhost [127.0.0.1]) by firstgate.proxmox.com (Proxmox) with ESMTP id 6E14632547; Fri, 13 Feb 2026 10:42:39 +0100 (CET) From: Kefu Chai To: pve-devel@lists.proxmox.com Subject: [PATCH pve-cluster 00/14 v2] Rewrite pmxcfs with Rust Date: Fri, 13 Feb 2026 17:33:37 +0800 Message-ID: <20260213094119.2379288-1-k.chai@proxmox.com> X-Mailer: git-send-email 2.47.3 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-Bm-Milter-Handled: 55990f41-d878-4baa-be0a-ee34c49e34d2 X-Bm-Transport-Timestamp: 1770975690094 X-SPAM-LEVEL: Spam detection results: 0 AWL -1.777 Adjusted score from AWL reputation of From: address BAYES_00 -1.9 Bayes spam probability is 0 to 1% DMARC_MISSING 0.1 Missing DMARC policy KAM_ASCII_DIVIDERS 0.8 Email that uses ascii formatting dividers and possible spam tricks KAM_DMARC_STATUS 0.01 Test Rule for DKIM or SPF Failure with Strict Alignment SPF_HELO_NONE 0.001 SPF: HELO does not publish an SPF Record SPF_PASS -0.001 SPF: sender matches SPF record URIBL_BLACK 3 Contains an URL listed in the URIBL blacklist [types.rs] Message-ID-Hash: QCQIOLJOJ6YJF5XV6CV7YIJJROSRM6KT X-Message-ID-Hash: QCQIOLJOJ6YJF5XV6CV7YIJJROSRM6KT X-MailFrom: k.chai@proxmox.com X-Mailman-Rule-Misses: dmarc-mitigation; no-senders; approved; loop; banned-address; emergency; member-moderation; nonmember-moderation; administrivia; implicit-dest; max-recipients; max-size; news-moderation; no-subject; digests; suspicious-header X-Mailman-Version: 3.3.10 Precedence: list List-Id: Proxmox VE development discussion List-Help: List-Owner: List-Post: List-Subscribe: List-Unsubscribe: Hello, Thank you for the detailed code reviews. V2 incorporates your feedback with focus on safety improvements, C compatibility verification, and code quality. Changes are organized by crate below. 1. pmxcfs-dfsm Addressing Review Comments --------------------------- Buffer Overflow Protection in KvStore LOG Parsing Review: "No overflow check when computing expected_len - could wrap around on malicious input [...] If node_len is 0, this is offset..offset-1 which wraps!" Changes: - Added overflow checking using checked_add() for total size calculation - Validate individual field lengths are non-zero (must have null terminator) - Created safe extract_string() helper with bounds checking - All string extraction operations now validate offsets don't exceed buffer Before: Could read beyond buffer if malicious field lengths cause wraparound After: Overflow returns error, bounds checked before every string extraction Wire Format Buffer Size Validation Review: "No validation that total_size matches actual data.len() - attacker could send a small message with large header values" Changes: - Added validation that expected total size equals actual buffer length - Check performed after overflow validation, before parsing fields FFI Panic Safety in CPG Callbacks Review: Discussion about panic safety in FFI boundaries (from pmxcfs-services.review) Changes: - Added std::panic::catch_unwind to CPG deliver and confchg callbacks - Panics are now caught and logged instead of unwinding through C code - Prevents undefined behavior when Rust code panics in C-called callback Race Condition in Drop Implementation Review feedback on lifecycle management prompted examination of cleanup order. Changes: - Reordered Drop to finalize CPG handle BEFORE recovering Arc - Prevents callbacks from firing during Arc deallocation - Old: recover Arc → finalize → potential callback during deallocation - New: finalize → no more callbacks → safe to recover Arc Self-Review Improvements ------------------------- Message Trait Constraints Review: Self-identified need for stronger type constraints on generic messages. Changes: - Extended Message trait bounds from just `Sized` to include: - Clone: Required for message queueing and retransmission - Debug: Essential for logging and debugging cluster issues - Send + Sync: Required for safe cross-thread message passing - 'static: Ensures messages don't contain borrowed references - Prevents runtime issues with message handling across async boundaries Impact: Compile-time guarantees that message types are safe for concurrent cluster communication. Bounded Sync Queue Review: Self-identified memory exhaustion risk from unbounded queues. Changes: - Added MAX_QUEUE_LEN constant (500 messages) for both sync_queue and msg_queue - C implementation uses unbounded GSequence/GList structures - When queue is full, oldest messages are dropped with warning log - Prevents memory exhaustion from slow or stuck nodes Impact: Protection against memory exhaustion in production clusters with network congestion or slow nodes. Broadcast-First Message Ordering Review: Self-identified EEXIST race condition in v1 implementation. Changes: - V1 approach: Create file locally first, then broadcast message to cluster - Problem: When originator receives its own broadcast, file already exists - Result: deliver_message() would fail with EEXIST on originator node - Workaround: Had to ignore errors from self-originated messages - V2 approach: Send message first via send_message_sync(), then create via callback - Originator sends message and waits for delivery callback - ALL nodes (including originator) create file via deliver_message() - No special case needed - originator creates file same way as other nodes - FUSE operation returns the result from deliver_message() Impact: Eliminates EEXIST race condition and simplifies message handling logic. All nodes follow identical code path for file operations. Replace Magic Numbers with Structured Definitions - Defined ClogEntryHeader struct with #[repr(C)] matching wire format - Use std::mem::size_of::() directly instead of magic constant - Eliminates 4+1+3+16 calculation, makes structure explicit Efficient Serialization - Use std::mem::transmute for #[repr(C)] struct serialization/deserialization - Replaces 48 lines of field-by-field byte manipulation with single operation - Safety documented: platform is x86_64 little-endian, layout is well-defined Minor Fixes - Removed redundant cast: mtime is already u32, no need for "as u32" - Added debug_assert! for group name validation (names hardcoded in app) - Enhanced thread safety documentation with explicit dispatch limitations - Documented Y2038 limitation for u32 mtime field 2. pmxcfs-logger Addressing Review Comments --------------------------- Merge Deduplication Semantics Review: "BTreeMap::insert overwrites on duplicate. Please re-check whether we want that; if we want to keep-first, use entry(key).or_insert(...)" Changes: - Changed from insert() to entry().or_insert() pattern - Now correctly implements keep-first semantics for duplicate entries - Only updates merge_dedup when entry is newly inserted Impact: Merge behavior now matches C implementation's duplicate handling. Merge Iteration Order Review: "C iterates oldest -> newest and clog_copy() makes each entry the new head, so result is newest first. With .rev() and push_front we likely invert it. Maybe drop .rev()?" Changes: - Removed .rev() from merge iteration - Entries now processed in correct order matching C behavior Impact: Merged log entries maintain correct chronological order. Atomic Merge Operation Review: "clusterlog_merge() in C updates both cl->dedup and cl->base under the same mutex. Here we update only dedup but return a RingBuffer which then requires a separate update_buffer() call. Shouldn't this be an atomic operation?" Changes: - Unified ClusterLogInner struct with single mutex protecting both buffer and dedup - Merge now atomically updates both buffer and dedup in single operation - Eliminated separate update_buffer() call and associated race window Impact: Merge is now atomic, preventing race conditions between buffer and dedup updates. Constant Duplication Review: "This constant is also defined in ring_buffer.rs." Changes: - Removed duplicate CLOG_MAX_ENTRY_SIZE definition from entry.rs - Now imports constant from ring_buffer module Impact: Single source of truth for buffer size constants. Buffer Size Constants Mismatch Review: "These constants don't match the C constants: #define CLOG_DEFAULT_SIZE (8192 * 16), #define CLOG_MAX_ENTRY_SIZE 4096" Changes: - Corrected CLOG_DEFAULT_SIZE from 5MB to 131,072 bytes (128 KB) - Corrected CLOG_MAX_ENTRY_SIZE from 12,288 to 4,096 bytes (4 KB) Impact: Buffer capacity and entry size limits now match C implementation exactly. String Length Field Overflow Review: "These three fields are u8 incl. NUL. Payload must cap at 254 bytes, otherwise len + 1 wraps to 0. C does MIN(strlen + 1,255)" Changes: - Truncate node/ident/tag strings to 254 bytes before adding null terminator - Cap serialized length at 255 in wire format - Prevents u8 wraparound that could cause buffer overflow Impact: Eliminates buffer overflow vulnerability from string length wraparound. JSON Output Order Review: "C prints entries newest to oldest (walk prev from cpos). Shouldn't this line be removed?" Changes: - Removed .reverse() call from JSON dump generation - Now outputs newest-first matching C's prev-walk behavior Impact: JSON output order matches C implementation. Binary Serialization Format Review: "Please re-check, but in C, clusterlog_get_state() returns a full memdump (allocated ring buffer capacity), with cpos pointing at the newest entry offset (not always 8). Also in C, entry.next is not a pointer to the next/newer entry, it's the end offset of this entry" Changes: - Binary dump now returns full capacity buffer (not just used portion) - cpos correctly points to newest entry offset - entry.next is end offset of current entry (not pointer to next) - Matches C's memdump format exactly Impact: Binary state format is now wire-compatible with C implementation. Wrap-Around Guards in Deserialization Review: "C has wrap/overwrite guards when walking prev. We should probably mirror those checks here too" Changes: - Added visited set to prevent infinite loops - Check for already-visited positions during prev-walk - Validate entry bounds before access - Added C-style wrap-around guard logic Impact: Prevents infinite loops and crashes when deserializing corrupted state. Additional Improvements - UTF-8 truncation safety: Truncate at character boundaries to prevent panics - Integer overflow protection: Use checked arithmetic in size calculations - Enhanced documentation: UID wraparound behavior and hash collision risks 3. pmxcfs-memdb Addressing Review Comments --------------------------- Integer Overflow in write() Operation Review: "Cast before check: offset as usize can truncate on 32-bit systems [...] Addition overflow: offset as usize + data.len() can overflow" Changes: - Changed "offset as usize" to usize::try_from(offset) - Returns error if offset doesn't fit in platform's usize - Prevents silent truncation that could bypass size limits on 32-bit systems Extract Magic Numbers to Constants Review pointed out hardcoded permission modes (0o755, 0o644) scattered in code. Changes: - Added MODE_DIR_DEFAULT constant (S_IFDIR | 0o755) - Added MODE_FILE_DEFAULT constant (S_IFREG | 0o644) - Replaced hardcoded values in locks.rs for consistency Verification of Existing C Compatibility ----------------------------------------- During review response, verified these features already correctly implement C behavior (no changes needed): - Error flag checking: All write operations properly check errors flag via with_mutation() helper, matching C's memdb->errors check pattern - Directory deletion: Already validates directory is empty before deletion, matching C implementation in memdb.c - Write guard usage: Consistently used across all mutation operations via with_mutation(), serializing writes correctly - Lock protection: Proper mtime/writer validation for lock directories, preventing replay attacks and lock hijacking 4. pmxcfs-status Addressing Review Comments --------------------------- Cluster Version Counter Separation Review: "cluster_version field used as change counter gets overwritten in update_cluster_info(). In C we have clinfo_version vs cman_version. These need to be separate fields." Changes: - Separated cluster_version (change counter) from config_version (config version) - cluster_version matches C's clinfo_version (increments on membership changes) - config_version in ClusterInfo matches C's cman_version (from corosync) - update_cluster_info() increments cluster_version separately, never overwrites it Impact: Change detection now works correctly, matching C implementation semantics. KV Store Version Tracking Review: "C removes kvstore entry when len==0 and maintains per-key version counter. Our kvstore currently stores only Vec and doesn't reflect this." Changes: - Changed kvstore structure to HashMap, u32)>> - Each key now has tuple of (value, version_counter) - Empty values are removed from kvstore (matching C behavior) - Version counter increments on each key update Impact: Per-key version tracking enables proper state synchronization across cluster. Node IP Handling Review: "set_node_status() missing dedicated branch for nodeip. C has separate handling for nodeip with backing iphash structure." Changes: - Added dedicated node_ips HashMap (matches C's iphash structure) - Implemented dedicated nodeip branch in set_node_status() - Added 3-way check: rrd vs nodeip vs other - Strips NUL termination from IP strings - Atomic check-and-update with version bump Impact: Node IP tracking now works correctly, matching C's nodeip_hash_set behavior. VM Version Counter Semantics Review: "Per-VM version counters instead of global vminfo_version_counter. C uses global counter to determine update order." Changes: - Implemented global vminfo_version_counter (not per-VM counters) - All VM operations (register, delete, scan) use global counter - Counter increments on any VM change across entire cluster - Enables determining VM update order cluster-wide Impact: VM update ordering now matches C implementation, enabling proper synchronization. Online Status Preservation Review: "Doesn't preserve online status from old nodes. C's cfs_status_set_clinfo copies from oldnode." Changes: - update_cluster_info() now preserves online status from existing nodes - Saves old_nodes before clearing node list - Restores online status for nodes that still exist after update - Defaults to false for new nodes Impact: Online status no longer lost during cluster configuration updates. Kvstore Cleanup on Node Removal Review: "No cleanup of kvstore entries when nodes removed" Changes: - Added kvstore.retain() in update_cluster_info() - Removes entries for nodes no longer in cluster - Prevents memory leak from accumulating stale node data Impact: Memory usage stays bounded as nodes join/leave cluster. 5. pmxcfs-services Addressing Review Comments --------------------------- Note: pmxcfs-services was completely rewritten in v2 with simplified design. Many review comments from v1 no longer apply due to architectural changes. Graceful Shutdown with CancellationToken Review: "handle.abort() doesn't invoke finalization. Should use shutdown_token.cancel() + handle.await" Changes: - Replaced abort() with CancellationToken-based graceful shutdown - Service tasks monitor cancellation token in main loop - On cancellation, tasks call finalize() before exiting - Manager awaits task completion with 30-second timeout - Ensures proper resource cleanup on shutdown Impact: Services now shut down gracefully with proper finalization, preventing resource leaks and ensuring clean state transitions. Resource Cleanup on AsyncFd Registration Failure Review: "If AsyncFd::new() fails after initialize(), service marked Failed but finalize() never called" Changes: - Added explicit finalize() call in AsyncFd registration error path - If initialize() succeeds but AsyncFd::new() fails, finalize() is called - Ensures resources allocated during initialization are properly cleaned up Impact: Prevents resource leaks when AsyncFd registration fails after successful service initialization. Service Restart Logic Simplification Review: "reinitialize_service() sets Uninitialized, but retry_failed_services() refuses if !is_restartable after first attempt" Changes: - Eliminated "non-restartable" concept entirely - All services are now restartable by default - Dispatch failures trigger automatic reinitialize with 5-second retry loop - Simpler state machine without stuck states Impact: Services cannot get stuck in failed state. Automatic retry ensures services recover from transient failures. Simplify Service Framework Review: "The lifecycle overview [...] is great [...] I think the rest should move to rustdoc to avoid duplication and drift" Changes: - Removed unnecessary abstraction layers in service management - Services now directly implement Service trait without intermediate wrappers - Clearer ownership model and lifecycle management - Documentation consolidated per review feedback IPCC.xs Empty Response Handling Context: IPCC.xs (Perl XS binding, src/PVE/IPCC.xs line 165) returns undef when IPC operations succeed but return no data (dsize=0), even though error=0 indicates success. This affects SET_STATUS and LOG_CLUSTER_MSG. Note: A bug report about this issue was sent to the mailing list (Subject: "Confirmation needed: IPCC.xs behavior with empty response data") proposing to fix IPCC.xs to return empty string instead of undef for successful operations with no data. Changes: - Rust service returns Vec::new() matching C implementation exactly - Bug handling isolated to integration test layer (IPCTestLib.pm) - Test library treats "undef with errno=0" as successful empty response - Documented workaround with reference to production code's handling (PVE::Cluster.pm wrapper accepts this pattern) Rationale: - Rust service maintains C compatibility exactly - Bug properly isolated in test layer where it belongs - Production semantics correct: success returns empty, failure returns error - When IPCC.xs is fixed, only test library needs update 6. pmxcfs-ipc Addressing Review Comments --------------------------- Task Leak - Explicit Task Abortion Review: "The comment says 'auto-aborted on drop' which is not correct. Tokio detaches the task, it keeps running in the background." Changes: - Store all task handles (connection tasks, worker tasks, sender tasks) - Explicitly call abort() on all tasks in Connection::drop() - Remove misleading "auto-aborted" documentation - Verify cleanup in shutdown tests Impact: Tasks now properly terminate on connection close instead of leaking. Connection Memory Leak Review: "Connections are never removed which could result into memory leak." Changes: - Remove connections from server HashMap when they close - Track connection closure via task completion - Log connection removal for debugging Impact: Server no longer accumulates closed connection state in memory. Unbounded Response Queue - OOM Risk Review: "if the response ring buffer fills up (slow/stuck client), responses queue in memory without limit and can OOM the daemon." Changes: - Changed response channel from unbounded to bounded (1024 capacity) - Apply backpressure when queue fills: try_send() returns error - Match work queue's bounded behavior for consistency Impact: Slow clients can no longer exhaust server memory. Cross-Process Ring Buffer Hang Review: "Tokio notify only works inside one process. But another process frees up the space. So this would hang likely forever?" Changes: - Removed tokio::Notify (intra-process only) - Use POSIX process-shared semaphore (sem_post/sem_wait) - Match libqb's notification mechanism exactly - Verify with cross-process tests Impact: Ring buffer send/receive now works correctly across processes. Shutdown-Aware sem_wait - Use-After-Free Fix Review: "On shutdown the async task can be dropped while the blocking sem_wait keeps running, but RingBuffer may then sem_destroy/unmap." Changes: - Replaced blocking sem_wait with sem_timedwait loop (500ms timeout) - Check Arc shutdown flag after each timeout - Track active waiters with Arc sem_access_count - RingBuffer::drop() signals shutdown, posts to semaphore, waits for exit - Follow libqb's BSD replacement pattern (rpl_sem.c:120-136) Impact: Prevents undefined behavior when recv() futures are cancelled during shutdown. The blocking thread cleanly exits before shared memory is unmapped. Memory Ordering - write_pt Race Condition Review: "write_pt could eventually be peeked before the chunk is committed? We should publish the chunk by advancing write_pt with Release." Changes: - Write chunk data and header first - Set chunk magic with Ordering::Release - Update write_pt with Ordering::Release after magic - Reader loads write_pt with Ordering::Acquire Impact: Readers can no longer observe new write_pt before chunk is fully committed. Establishes proper happens-before relationship. EINTR Handling in sem_wait Review: "this says 'will retry' but actually crashes?" Changes: - Fixed retry loop to actually retry on EINTR - Changed from bail!() to continue on EINTR - Only bail on non-EINTR errors Impact: Signal interruptions no longer crash the server. Security Hardening - Clamp client max_msg_size to server maximum (8MB) - Validate chunk sizes don't exceed buffer bounds - Set file permissions mode(0o600) explicitly on ring buffer files - Track ring buffer header files for cleanup (request/response/event) Input Validation Review comments on validation addressed: - Handshake protocol validation already implemented - Chunk size validation with max bounds checking - Magic number verification prevents corruption Documentation and Code Quality Review: "for consistency with other repos I suggest to remove the emojies" Review: "nit: not all READMEs have a table of contents" Changes: - Removed table of contents from README.md for consistency - Updated documentation to reflect SHM implementation (not socket streaming) - Created PATCH_NOTES.md with commit message guidelines for upstream submission - Removed emojis from all test output and bash scripts - Consolidated duplicate wait_for_server_ready test utility - Fixed test helper to check abstract Unix socket instead of ring buffer files Test Coverage Expansion Review: "Can we please also test additionally for: the expected behaviour when the ring buffer is full, connection disconnect cleanup, adversarial inputs, graceful shutdown, concurrent connections" Changes: Added comprehensive edge_cases_test.rs with 7 scenarios: - Ring buffer full behavior - Connection disconnect cleanup - Adversarial inputs - Graceful shutdown - Concurrent connections - Flow control under load - Resource limits 7. pmxcfs-api-types Addressing Review Comments --------------------------- errno Mapping Precision Review: "Wrong errno mappings: PermissionDenied should map to EACCES not EPERM, InvalidPath should map to EINVAL not EIO, Lock should explicitly map to EBUSY/EDEADLK/EAGAIN" Changes: - PermissionDenied now maps to EACCES (was EPERM) - InvalidPath now maps to EINVAL (was EIO) - Lock explicitly maps to EAGAIN (was generic EIO) - Added comments explaining EACCES choice matches C implementation - NoQuorum also maps to EACCES (matching C's access/quorum error handling) Impact: Error codes returned to FUSE clients now match C implementation, ensuring consistent behavior and proper error handling in client applications. 7. pmxcfs-rrd Addressing Review Comments --------------------------- transform_data() Skip Logic Review: "Skip logic only applies to Pve2 format, but C implementation skips unconditionally based on metric type. This causes column misalignment for Pve9_0 data." Changes: - Removed format-conditional skip logic - Skip now applies unconditionally based on metric type: * Node metrics: skip 2 columns * VM metrics: skip 4 columns * Storage metrics: skip 0 columns - Matches C implementation behavior exactly - Added tests for both Pve2 and Pve9_0 formats Impact: Data transformation now works correctly for all format combinations, preventing column misalignment and data corruption. Path Sanitization Review: "Path components like nodename or storage could contain '..' or '/' allowing directory traversal attacks." Changes: - Added validate_path_component() function in key_type.rs - Rejects dangerous path components: * ".." (parent directory traversal) * Absolute paths (starting with "/") * Null bytes * Backslashes, newlines, carriage returns - All path components validated during key parsing Impact: Prevents directory traversal attacks through malicious node names or storage identifiers. Real Payload Test Fixtures Review: "Tests use synthetic data instead of real payloads from running systems to verify transform_data() correctness." Changes: - Added 6 new test cases using real RRD data captured from production PVE systems - test_real_payload_node_pve2: Real pve2-node data from PVE 6.x - test_real_payload_vm_pve2: Real pve2.3-vm data from PVE 6.x - test_real_payload_storage_pve2: Real pve2-storage data from PVE 6.x - test_real_payload_node_pve9_0: Real pve-node-9.0 data from PVE 8.x - test_real_payload_with_missing_values: Real data with "U" (unavailable) values - Validates transform_data() against actual production payloads Impact: Increased confidence in data transformation correctness using real-world data instead of only synthetic test data. File Path Naming Consistency Review: "Inconsistency between file_path() returning paths without .rrd extension, but tests using .rrd extension." Changes: - Clarified that file_path() returns paths WITHOUT .rrd extension (matching C) - Updated comments to explain C implementation behavior - C's rrd_create_r() and rrdc_update() add .rrd internally - Test helpers correctly add .rrd for filesystem operations - Consistent with C implementation in status.c:1287 Impact: Code now clearly documents the .rrd extension convention, matching C implementation behavior exactly. 8. Integration Tests & Documentation Cleanup Expanded IPC Operation Coverage -------------------------------- Added comprehensive IPC operation tests: - LOG_CLUSTER_MSG: Cluster log message sending with various string lengths - GET_CLUSTER_LOG: Log retrieval with user filtering and limits - GET_RRD_DUMP: RRD data dump with NUL terminator verification - Read-only operations: GET_FS_VERSION, GET_CLUSTER_INFO, GET_GUEST_LIST - Write operations: SET_STATUS roundtrip, VERIFY_TOKEN validation - Guest config operations: Single/multiple property retrieval - Complete IPC suite: All 12 operations with error case testing Perl Test Library (IPCTestLib.pm) - Provides ipc_call() wrapper handling IPCC.xs behavior - Treats "undef with errno=0" as successful empty response - Documented with explanation of IPCC.xs bug and workaround strategy - Works with both current IPCC.xs and future fixes Coverage: 12/12 IPC operations (complete) Documentation & Style Consistency ---------------------------------- Emoji Removal (applies across all crates) Review: "for consistency with other repos I suggest to remove the emojies" Changes applied to: - pmxcfs-ipc: Test output (qb_wire_compat.rs, auth_test.rs, edge_cases_test.rs) - pmxcfs-logger: Performance test output - pmxcfs: Integration tests (6 files) - pmxcfs workspace: Integration tests (8 files) - Integration test scripts: 46 bash scripts Replacements: - Checkmarks (✓/✅) → [OK] - Cross marks (✗/❌) → [FAIL] - Warning signs (⚠️/⚠) → [WARN] - Skip indicators (⏭️) → [SKIP] - Decorative emojis removed README Consistency - Removed table of contents from pmxcfs-ipc README.md - Matches style of other crate READMEs Test Utility Consolidation - Moved wait_for_server_ready() to pmxcfs-test-utils for reuse - Fixed implementation to check abstract Unix socket (/proc/net/unix) - Works for all server configurations including reject-all cases Best regards, Kefu Chai (14): pmxcfs-rs: add Rust workspace configuration pmxcfs-rs: add pmxcfs-api-types crate pmxcfs-rs: add pmxcfs-config crate pmxcfs-rs: add pmxcfs-logger crate pmxcfs-rs: add pmxcfs-rrd crate pmxcfs-rs: add pmxcfs-memdb crate pmxcfs-rs: add pmxcfs-status and pmxcfs-test-utils crates pmxcfs-rs: add pmxcfs-services crate pmxcfs-rs: add pmxcfs-ipc crate pmxcfs-rs: add pmxcfs-dfsm crate pmxcfs-rs: vendor patched rust-corosync for CPG compatibility pmxcfs-rs: add pmxcfs main daemon binary pmxcfs-rs: add integration and workspace tests pmxcfs-rs: add project documentation src/pmxcfs-rs/.gitignore | 3 + src/pmxcfs-rs/ARCHITECTURE.txt | 350 ++ src/pmxcfs-rs/Cargo.toml | 102 + src/pmxcfs-rs/Makefile | 39 + src/pmxcfs-rs/README.md | 304 ++ src/pmxcfs-rs/integration-tests/.gitignore | 1 + src/pmxcfs-rs/integration-tests/README.md | 367 ++ .../integration-tests/docker/.dockerignore | 17 + .../integration-tests/docker/Dockerfile | 96 + .../integration-tests/docker/debian.sources | 5 + .../docker/docker-compose.cluster.yml | 115 + .../docker/docker-compose.mixed.yml | 125 + .../docker/docker-compose.yml | 55 + .../integration-tests/docker/healthcheck.sh | 19 + .../docker/lib/corosync.conf.mixed.template | 46 + .../docker/lib/corosync.conf.template | 45 + .../docker/lib/setup-cluster.sh | 67 + .../docker/proxmox-archive-keyring.gpg | Bin 0 -> 2372 bytes .../docker/pve-no-subscription.sources | 5 + .../docker/start-cluster-node.sh | 106 + src/pmxcfs-rs/integration-tests/run-tests.sh | 470 +++ src/pmxcfs-rs/integration-tests/test | 238 ++ src/pmxcfs-rs/integration-tests/test-local | 333 ++ .../tests/cluster/01-connectivity.sh | 56 + .../tests/cluster/02-file-sync.sh | 216 ++ .../tests/cluster/03-clusterlog-sync.sh | 292 ++ .../tests/cluster/04-binary-format-sync.sh | 350 ++ .../tests/core/01-test-paths.sh | 74 + .../tests/core/02-plugin-version.sh | 87 + .../integration-tests/tests/dfsm/01-sync.sh | 218 ++ .../tests/dfsm/02-multi-node.sh | 159 + .../tests/fuse/01-operations.sh | 100 + .../tests/fuse/02-quorum-permissions.sh | 317 ++ .../tests/fuse/03-write-operations.sh | 285 ++ .../tests/fuse/04-chmod-chown.sh | 142 + .../tests/ipc/01-socket-api.sh | 104 + .../tests/ipc/02-flow-control.sh | 89 + .../tests/ipc/03-log-cluster-msg.sh | 231 ++ .../tests/ipc/04-get-cluster-log.sh | 344 ++ .../tests/ipc/05-get-rrd-dump.sh | 251 ++ .../tests/ipc/06-readonly-ops.sh | 231 ++ .../tests/ipc/07-write-ops.sh | 185 + .../tests/ipc/08-guest-config-ops.sh | 273 ++ .../tests/ipc/09-all-ipc-ops.sh | 136 + .../integration-tests/tests/ipc/COVERAGE.md | 111 + .../integration-tests/tests/ipc/QUICKSTART.md | 143 + .../integration-tests/tests/ipc/README.md | 388 ++ .../integration-tests/tests/ipc/SUMMARY.md | 151 + .../tests/ipc/TESTING-IMPROVEMENTS.md | 314 ++ .../tests/ipc/perl/IPCTestLib.pm | 102 + .../tests/ipc/perl/README.md | 45 + .../tests/ipc/perl/get-cluster-info.pl | 38 + .../tests/ipc/perl/get-cluster-log.pl | 52 + .../tests/ipc/perl/get-config.pl | 37 + .../tests/ipc/perl/get-fs-version.pl | 31 + .../ipc/perl/get-guest-config-properties.pl | 51 + .../ipc/perl/get-guest-config-property.pl | 42 + .../tests/ipc/perl/get-guest-list.pl | 38 + .../tests/ipc/perl/get-rrd-dump.pl | 28 + .../tests/ipc/perl/get-status.pl | 33 + .../tests/ipc/perl/log-cluster-msg.pl | 43 + .../tests/ipc/perl/set-status.pl | 30 + .../tests/ipc/perl/verify-token.pl | 29 + .../integration-tests/tests/ipc/test-lib.sh | 101 + .../tests/locks/01-lock-management.sh | 134 + .../tests/logger/01-clusterlog-basic.sh | 119 + .../integration-tests/tests/logger/README.md | 111 + .../tests/memdb/01-access.sh | 103 + .../tests/mixed-cluster/01-node-types.sh | 135 + .../tests/mixed-cluster/02-file-sync.sh | 180 + .../tests/mixed-cluster/03-quorum.sh | 149 + .../04-c-rust-binary-validation.sh | 360 ++ .../mixed-cluster/05-merge-correctness.sh | 328 ++ .../tests/mixed-cluster/06-stress-test.sh | 339 ++ .../tests/mixed-cluster/07-mtime-sync.sh | 369 ++ .../08-mixed-cluster-rrd-interop.sh | 374 ++ .../tests/plugins/01-plugin-files.sh | 146 + .../tests/plugins/02-clusterlog-plugin.sh | 355 ++ .../tests/plugins/03-plugin-write.sh | 197 + .../integration-tests/tests/plugins/README.md | 52 + .../tests/rrd/01-rrd-basic.sh | 93 + .../tests/rrd/02-schema-validation.sh | 411 ++ .../tests/rrd/03-rrdcached-integration.sh | 367 ++ .../tests/rrd/05-column-skip-transform.sh | 391 ++ .../tests/rrd/README-MIXED-CLUSTER-RRD.md | 373 ++ .../integration-tests/tests/rrd/README.md | 164 + .../integration-tests/tests/run-c-tests.sh | 321 ++ .../tests/status/01-status-tracking.sh | 113 + .../tests/status/02-status-operations.sh | 193 + .../tests/status/03-multinode-sync.sh | 481 +++ .../integration-tests/tests/test-config.sh | 195 + 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 + src/pmxcfs-rs/pmxcfs-config/Cargo.toml | 19 + src/pmxcfs-rs/pmxcfs-config/README.md | 15 + src/pmxcfs-rs/pmxcfs-config/src/lib.rs | 521 +++ src/pmxcfs-rs/pmxcfs-dfsm/Cargo.toml | 46 + src/pmxcfs-rs/pmxcfs-dfsm/README.md | 340 ++ src/pmxcfs-rs/pmxcfs-dfsm/src/callbacks.rs | 80 + .../src/cluster_database_service.rs | 116 + src/pmxcfs-rs/pmxcfs-dfsm/src/cpg_service.rs | 235 ++ src/pmxcfs-rs/pmxcfs-dfsm/src/dfsm_message.rs | 722 ++++ src/pmxcfs-rs/pmxcfs-dfsm/src/fuse_message.rs | 194 + .../pmxcfs-dfsm/src/kv_store_message.rs | 387 ++ src/pmxcfs-rs/pmxcfs-dfsm/src/lib.rs | 32 + src/pmxcfs-rs/pmxcfs-dfsm/src/message.rs | 21 + .../pmxcfs-dfsm/src/state_machine.rs | 1251 +++++++ .../pmxcfs-dfsm/src/status_sync_service.rs | 118 + src/pmxcfs-rs/pmxcfs-dfsm/src/types.rs | 107 + src/pmxcfs-rs/pmxcfs-dfsm/src/wire_format.rs | 279 ++ .../tests/multi_node_sync_tests.rs | 563 +++ src/pmxcfs-rs/pmxcfs-ipc/Cargo.toml | 44 + src/pmxcfs-rs/pmxcfs-ipc/README.md | 171 + .../pmxcfs-ipc/examples/test_server.rs | 92 + src/pmxcfs-rs/pmxcfs-ipc/src/connection.rs | 772 ++++ src/pmxcfs-rs/pmxcfs-ipc/src/handler.rs | 93 + src/pmxcfs-rs/pmxcfs-ipc/src/lib.rs | 41 + src/pmxcfs-rs/pmxcfs-ipc/src/protocol.rs | 332 ++ src/pmxcfs-rs/pmxcfs-ipc/src/ringbuffer.rs | 1410 +++++++ src/pmxcfs-rs/pmxcfs-ipc/src/server.rs | 298 ++ src/pmxcfs-rs/pmxcfs-ipc/src/socket.rs | 84 + src/pmxcfs-rs/pmxcfs-ipc/tests/auth_test.rs | 421 +++ .../pmxcfs-ipc/tests/edge_cases_test.rs | 304 ++ .../pmxcfs-ipc/tests/qb_wire_compat.rs | 389 ++ src/pmxcfs-rs/pmxcfs-logger/Cargo.toml | 15 + src/pmxcfs-rs/pmxcfs-logger/README.md | 58 + .../pmxcfs-logger/src/cluster_log.rs | 615 +++ src/pmxcfs-rs/pmxcfs-logger/src/entry.rs | 694 ++++ src/pmxcfs-rs/pmxcfs-logger/src/hash.rs | 176 + src/pmxcfs-rs/pmxcfs-logger/src/lib.rs | 27 + .../pmxcfs-logger/src/ring_buffer.rs | 628 ++++ .../tests/binary_compatibility_tests.rs | 315 ++ .../pmxcfs-logger/tests/performance_tests.rs | 294 ++ src/pmxcfs-rs/pmxcfs-memdb/Cargo.toml | 42 + src/pmxcfs-rs/pmxcfs-memdb/README.md | 263 ++ src/pmxcfs-rs/pmxcfs-memdb/src/database.rs | 2551 +++++++++++++ src/pmxcfs-rs/pmxcfs-memdb/src/index.rs | 823 ++++ src/pmxcfs-rs/pmxcfs-memdb/src/lib.rs | 26 + src/pmxcfs-rs/pmxcfs-memdb/src/locks.rs | 316 ++ src/pmxcfs-rs/pmxcfs-memdb/src/sync.rs | 257 ++ src/pmxcfs-rs/pmxcfs-memdb/src/traits.rs | 102 + src/pmxcfs-rs/pmxcfs-memdb/src/types.rs | 343 ++ src/pmxcfs-rs/pmxcfs-memdb/src/vmlist.rs | 257 ++ .../pmxcfs-memdb/tests/checksum_test.rs | 175 + .../tests/sync_integration_tests.rs | 394 ++ src/pmxcfs-rs/pmxcfs-rrd/Cargo.toml | 23 + src/pmxcfs-rs/pmxcfs-rrd/README.md | 119 + src/pmxcfs-rs/pmxcfs-rrd/src/backend.rs | 62 + .../pmxcfs-rrd/src/backend/backend_daemon.rs | 184 + .../pmxcfs-rrd/src/backend/backend_direct.rs | 586 +++ .../src/backend/backend_fallback.rs | 212 ++ src/pmxcfs-rs/pmxcfs-rrd/src/daemon.rs | 140 + src/pmxcfs-rs/pmxcfs-rrd/src/key_type.rs | 408 ++ src/pmxcfs-rs/pmxcfs-rrd/src/lib.rs | 23 + src/pmxcfs-rs/pmxcfs-rrd/src/parse.rs | 124 + .../pmxcfs-rrd/src/rrdcached/LICENSE | 21 + .../pmxcfs-rrd/src/rrdcached/client.rs | 208 ++ .../src/rrdcached/consolidation_function.rs | 30 + .../pmxcfs-rrd/src/rrdcached/create.rs | 410 ++ .../pmxcfs-rrd/src/rrdcached/errors.rs | 29 + src/pmxcfs-rs/pmxcfs-rrd/src/rrdcached/mod.rs | 45 + src/pmxcfs-rs/pmxcfs-rrd/src/rrdcached/now.rs | 18 + .../pmxcfs-rrd/src/rrdcached/parsers.rs | 65 + .../pmxcfs-rrd/src/rrdcached/sanitisation.rs | 100 + src/pmxcfs-rs/pmxcfs-rrd/src/schema.rs | 577 +++ src/pmxcfs-rs/pmxcfs-rrd/src/writer.rs | 582 +++ src/pmxcfs-rs/pmxcfs-services/Cargo.toml | 17 + src/pmxcfs-rs/pmxcfs-services/README.md | 162 + src/pmxcfs-rs/pmxcfs-services/src/error.rs | 21 + src/pmxcfs-rs/pmxcfs-services/src/lib.rs | 15 + src/pmxcfs-rs/pmxcfs-services/src/manager.rs | 341 ++ src/pmxcfs-rs/pmxcfs-services/src/service.rs | 149 + .../pmxcfs-services/tests/service_tests.rs | 1271 +++++++ src/pmxcfs-rs/pmxcfs-status/Cargo.toml | 39 + src/pmxcfs-rs/pmxcfs-status/README.md | 142 + src/pmxcfs-rs/pmxcfs-status/src/lib.rs | 94 + src/pmxcfs-rs/pmxcfs-status/src/status.rs | 1852 +++++++++ src/pmxcfs-rs/pmxcfs-status/src/traits.rs | 492 +++ src/pmxcfs-rs/pmxcfs-status/src/types.rs | 77 + src/pmxcfs-rs/pmxcfs-test-utils/Cargo.toml | 34 + src/pmxcfs-rs/pmxcfs-test-utils/src/lib.rs | 570 +++ .../pmxcfs-test-utils/src/mock_memdb.rs | 771 ++++ src/pmxcfs-rs/pmxcfs/Cargo.toml | 84 + src/pmxcfs-rs/pmxcfs/README.md | 174 + .../pmxcfs/src/cluster_config_service.rs | 317 ++ src/pmxcfs-rs/pmxcfs/src/daemon.rs | 314 ++ src/pmxcfs-rs/pmxcfs/src/file_lock.rs | 105 + src/pmxcfs-rs/pmxcfs/src/fuse/README.md | 199 + src/pmxcfs-rs/pmxcfs/src/fuse/filesystem.rs | 1644 ++++++++ src/pmxcfs-rs/pmxcfs/src/fuse/mod.rs | 4 + src/pmxcfs-rs/pmxcfs/src/ipc/mod.rs | 16 + src/pmxcfs-rs/pmxcfs/src/ipc/request.rs | 314 ++ src/pmxcfs-rs/pmxcfs/src/ipc/service.rs | 684 ++++ src/pmxcfs-rs/pmxcfs/src/lib.rs | 13 + src/pmxcfs-rs/pmxcfs/src/logging.rs | 44 + src/pmxcfs-rs/pmxcfs/src/main.rs | 711 ++++ src/pmxcfs-rs/pmxcfs/src/memdb_callbacks.rs | 663 ++++ src/pmxcfs-rs/pmxcfs/src/plugins/README.md | 203 + .../pmxcfs/src/plugins/clusterlog.rs | 293 ++ src/pmxcfs-rs/pmxcfs/src/plugins/debug.rs | 145 + src/pmxcfs-rs/pmxcfs/src/plugins/members.rs | 198 + src/pmxcfs-rs/pmxcfs/src/plugins/mod.rs | 30 + src/pmxcfs-rs/pmxcfs/src/plugins/registry.rs | 305 ++ src/pmxcfs-rs/pmxcfs/src/plugins/rrd.rs | 97 + src/pmxcfs-rs/pmxcfs/src/plugins/types.rs | 112 + src/pmxcfs-rs/pmxcfs/src/plugins/version.rs | 178 + src/pmxcfs-rs/pmxcfs/src/plugins/vmlist.rs | 120 + src/pmxcfs-rs/pmxcfs/src/quorum_service.rs | 207 + src/pmxcfs-rs/pmxcfs/src/restart_flag.rs | 60 + src/pmxcfs-rs/pmxcfs/src/status_callbacks.rs | 352 ++ src/pmxcfs-rs/pmxcfs/tests/common/mod.rs | 221 ++ src/pmxcfs-rs/pmxcfs/tests/fuse_basic_test.rs | 216 ++ .../pmxcfs/tests/fuse_cluster_test.rs | 220 ++ .../pmxcfs/tests/fuse_integration_test.rs | 414 ++ src/pmxcfs-rs/pmxcfs/tests/fuse_locks_test.rs | 377 ++ .../pmxcfs/tests/local_integration.rs | 277 ++ src/pmxcfs-rs/pmxcfs/tests/quorum_behavior.rs | 274 ++ .../pmxcfs/tests/single_node_functional.rs | 361 ++ .../pmxcfs/tests/symlink_quorum_test.rs | 145 + src/pmxcfs-rs/tests/fuse_basic_test.rs | 229 ++ src/pmxcfs-rs/tests/fuse_cluster_test.rs | 445 +++ src/pmxcfs-rs/tests/fuse_integration_test.rs | 436 +++ src/pmxcfs-rs/tests/fuse_locks_test.rs | 370 ++ src/pmxcfs-rs/tests/local_integration.rs | 151 + src/pmxcfs-rs/tests/quorum_behavior_test.rs | 255 ++ src/pmxcfs-rs/tests/single_node_test.rs | 342 ++ src/pmxcfs-rs/tests/symlink_quorum_test.rs | 157 + src/pmxcfs-rs/tests/two_node_test.rs | 288 ++ src/pmxcfs-rs/vendor/rust-corosync/Cargo.toml | 33 + .../vendor/rust-corosync/Cargo.toml.orig | 19 + src/pmxcfs-rs/vendor/rust-corosync/LICENSE | 21 + .../vendor/rust-corosync/README.PATCH.md | 36 + src/pmxcfs-rs/vendor/rust-corosync/README.md | 13 + src/pmxcfs-rs/vendor/rust-corosync/build.rs | 64 + .../vendor/rust-corosync/regenerate-sys.sh | 15 + src/pmxcfs-rs/vendor/rust-corosync/src/cfg.rs | 392 ++ .../vendor/rust-corosync/src/cmap.rs | 812 ++++ src/pmxcfs-rs/vendor/rust-corosync/src/cpg.rs | 657 ++++ src/pmxcfs-rs/vendor/rust-corosync/src/lib.rs | 297 ++ .../vendor/rust-corosync/src/quorum.rs | 337 ++ .../vendor/rust-corosync/src/sys/cfg.rs | 1239 ++++++ .../vendor/rust-corosync/src/sys/cmap.rs | 3323 +++++++++++++++++ .../vendor/rust-corosync/src/sys/cpg.rs | 1310 +++++++ .../vendor/rust-corosync/src/sys/mod.rs | 8 + .../vendor/rust-corosync/src/sys/quorum.rs | 537 +++ .../rust-corosync/src/sys/votequorum.rs | 574 +++ .../vendor/rust-corosync/src/votequorum.rs | 556 +++ 249 files changed, 66592 insertions(+) create mode 100644 src/pmxcfs-rs/.gitignore create mode 100644 src/pmxcfs-rs/ARCHITECTURE.txt create mode 100644 src/pmxcfs-rs/Cargo.toml create mode 100644 src/pmxcfs-rs/Makefile create mode 100644 src/pmxcfs-rs/README.md create mode 100644 src/pmxcfs-rs/integration-tests/.gitignore create mode 100644 src/pmxcfs-rs/integration-tests/README.md create mode 100644 src/pmxcfs-rs/integration-tests/docker/.dockerignore create mode 100644 src/pmxcfs-rs/integration-tests/docker/Dockerfile create mode 100644 src/pmxcfs-rs/integration-tests/docker/debian.sources create mode 100644 src/pmxcfs-rs/integration-tests/docker/docker-compose.cluster.yml create mode 100644 src/pmxcfs-rs/integration-tests/docker/docker-compose.mixed.yml create mode 100644 src/pmxcfs-rs/integration-tests/docker/docker-compose.yml create mode 100644 src/pmxcfs-rs/integration-tests/docker/healthcheck.sh create mode 100644 src/pmxcfs-rs/integration-tests/docker/lib/corosync.conf.mixed.template create mode 100644 src/pmxcfs-rs/integration-tests/docker/lib/corosync.conf.template create mode 100755 src/pmxcfs-rs/integration-tests/docker/lib/setup-cluster.sh create mode 100644 src/pmxcfs-rs/integration-tests/docker/proxmox-archive-keyring.gpg create mode 100644 src/pmxcfs-rs/integration-tests/docker/pve-no-subscription.sources create mode 100755 src/pmxcfs-rs/integration-tests/docker/start-cluster-node.sh create mode 100755 src/pmxcfs-rs/integration-tests/run-tests.sh create mode 100755 src/pmxcfs-rs/integration-tests/test create mode 100755 src/pmxcfs-rs/integration-tests/test-local create mode 100755 src/pmxcfs-rs/integration-tests/tests/cluster/01-connectivity.sh create mode 100755 src/pmxcfs-rs/integration-tests/tests/cluster/02-file-sync.sh create mode 100755 src/pmxcfs-rs/integration-tests/tests/cluster/03-clusterlog-sync.sh create mode 100755 src/pmxcfs-rs/integration-tests/tests/cluster/04-binary-format-sync.sh create mode 100755 src/pmxcfs-rs/integration-tests/tests/core/01-test-paths.sh create mode 100755 src/pmxcfs-rs/integration-tests/tests/core/02-plugin-version.sh create mode 100755 src/pmxcfs-rs/integration-tests/tests/dfsm/01-sync.sh create mode 100755 src/pmxcfs-rs/integration-tests/tests/dfsm/02-multi-node.sh create mode 100755 src/pmxcfs-rs/integration-tests/tests/fuse/01-operations.sh create mode 100755 src/pmxcfs-rs/integration-tests/tests/fuse/02-quorum-permissions.sh create mode 100755 src/pmxcfs-rs/integration-tests/tests/fuse/03-write-operations.sh create mode 100755 src/pmxcfs-rs/integration-tests/tests/fuse/04-chmod-chown.sh create mode 100755 src/pmxcfs-rs/integration-tests/tests/ipc/01-socket-api.sh create mode 100755 src/pmxcfs-rs/integration-tests/tests/ipc/02-flow-control.sh create mode 100755 src/pmxcfs-rs/integration-tests/tests/ipc/03-log-cluster-msg.sh create mode 100755 src/pmxcfs-rs/integration-tests/tests/ipc/04-get-cluster-log.sh create mode 100755 src/pmxcfs-rs/integration-tests/tests/ipc/05-get-rrd-dump.sh create mode 100755 src/pmxcfs-rs/integration-tests/tests/ipc/06-readonly-ops.sh create mode 100755 src/pmxcfs-rs/integration-tests/tests/ipc/07-write-ops.sh create mode 100755 src/pmxcfs-rs/integration-tests/tests/ipc/08-guest-config-ops.sh create mode 100755 src/pmxcfs-rs/integration-tests/tests/ipc/09-all-ipc-ops.sh create mode 100644 src/pmxcfs-rs/integration-tests/tests/ipc/COVERAGE.md create mode 100644 src/pmxcfs-rs/integration-tests/tests/ipc/QUICKSTART.md create mode 100644 src/pmxcfs-rs/integration-tests/tests/ipc/README.md create mode 100644 src/pmxcfs-rs/integration-tests/tests/ipc/SUMMARY.md create mode 100644 src/pmxcfs-rs/integration-tests/tests/ipc/TESTING-IMPROVEMENTS.md create mode 100644 src/pmxcfs-rs/integration-tests/tests/ipc/perl/IPCTestLib.pm create mode 100644 src/pmxcfs-rs/integration-tests/tests/ipc/perl/README.md create mode 100755 src/pmxcfs-rs/integration-tests/tests/ipc/perl/get-cluster-info.pl create mode 100755 src/pmxcfs-rs/integration-tests/tests/ipc/perl/get-cluster-log.pl create mode 100755 src/pmxcfs-rs/integration-tests/tests/ipc/perl/get-config.pl create mode 100755 src/pmxcfs-rs/integration-tests/tests/ipc/perl/get-fs-version.pl create mode 100755 src/pmxcfs-rs/integration-tests/tests/ipc/perl/get-guest-config-properties.pl create mode 100755 src/pmxcfs-rs/integration-tests/tests/ipc/perl/get-guest-config-property.pl create mode 100755 src/pmxcfs-rs/integration-tests/tests/ipc/perl/get-guest-list.pl create mode 100755 src/pmxcfs-rs/integration-tests/tests/ipc/perl/get-rrd-dump.pl create mode 100755 src/pmxcfs-rs/integration-tests/tests/ipc/perl/get-status.pl create mode 100755 src/pmxcfs-rs/integration-tests/tests/ipc/perl/log-cluster-msg.pl create mode 100755 src/pmxcfs-rs/integration-tests/tests/ipc/perl/set-status.pl create mode 100755 src/pmxcfs-rs/integration-tests/tests/ipc/perl/verify-token.pl create mode 100644 src/pmxcfs-rs/integration-tests/tests/ipc/test-lib.sh create mode 100755 src/pmxcfs-rs/integration-tests/tests/locks/01-lock-management.sh create mode 100755 src/pmxcfs-rs/integration-tests/tests/logger/01-clusterlog-basic.sh create mode 100644 src/pmxcfs-rs/integration-tests/tests/logger/README.md create mode 100755 src/pmxcfs-rs/integration-tests/tests/memdb/01-access.sh create mode 100755 src/pmxcfs-rs/integration-tests/tests/mixed-cluster/01-node-types.sh create mode 100755 src/pmxcfs-rs/integration-tests/tests/mixed-cluster/02-file-sync.sh create mode 100755 src/pmxcfs-rs/integration-tests/tests/mixed-cluster/03-quorum.sh create mode 100755 src/pmxcfs-rs/integration-tests/tests/mixed-cluster/04-c-rust-binary-validation.sh create mode 100755 src/pmxcfs-rs/integration-tests/tests/mixed-cluster/05-merge-correctness.sh create mode 100755 src/pmxcfs-rs/integration-tests/tests/mixed-cluster/06-stress-test.sh create mode 100755 src/pmxcfs-rs/integration-tests/tests/mixed-cluster/07-mtime-sync.sh create mode 100755 src/pmxcfs-rs/integration-tests/tests/mixed-cluster/08-mixed-cluster-rrd-interop.sh create mode 100755 src/pmxcfs-rs/integration-tests/tests/plugins/01-plugin-files.sh create mode 100755 src/pmxcfs-rs/integration-tests/tests/plugins/02-clusterlog-plugin.sh create mode 100755 src/pmxcfs-rs/integration-tests/tests/plugins/03-plugin-write.sh create mode 100644 src/pmxcfs-rs/integration-tests/tests/plugins/README.md create mode 100755 src/pmxcfs-rs/integration-tests/tests/rrd/01-rrd-basic.sh create mode 100755 src/pmxcfs-rs/integration-tests/tests/rrd/02-schema-validation.sh create mode 100755 src/pmxcfs-rs/integration-tests/tests/rrd/03-rrdcached-integration.sh create mode 100755 src/pmxcfs-rs/integration-tests/tests/rrd/05-column-skip-transform.sh create mode 100644 src/pmxcfs-rs/integration-tests/tests/rrd/README-MIXED-CLUSTER-RRD.md create mode 100644 src/pmxcfs-rs/integration-tests/tests/rrd/README.md create mode 100755 src/pmxcfs-rs/integration-tests/tests/run-c-tests.sh create mode 100755 src/pmxcfs-rs/integration-tests/tests/status/01-status-tracking.sh create mode 100755 src/pmxcfs-rs/integration-tests/tests/status/02-status-operations.sh create mode 100755 src/pmxcfs-rs/integration-tests/tests/status/03-multinode-sync.sh create mode 100644 src/pmxcfs-rs/integration-tests/tests/test-config.sh 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 create mode 100644 src/pmxcfs-rs/pmxcfs-config/Cargo.toml create mode 100644 src/pmxcfs-rs/pmxcfs-config/README.md create mode 100644 src/pmxcfs-rs/pmxcfs-config/src/lib.rs create mode 100644 src/pmxcfs-rs/pmxcfs-dfsm/Cargo.toml create mode 100644 src/pmxcfs-rs/pmxcfs-dfsm/README.md create mode 100644 src/pmxcfs-rs/pmxcfs-dfsm/src/callbacks.rs create mode 100644 src/pmxcfs-rs/pmxcfs-dfsm/src/cluster_database_service.rs create mode 100644 src/pmxcfs-rs/pmxcfs-dfsm/src/cpg_service.rs create mode 100644 src/pmxcfs-rs/pmxcfs-dfsm/src/dfsm_message.rs create mode 100644 src/pmxcfs-rs/pmxcfs-dfsm/src/fuse_message.rs create mode 100644 src/pmxcfs-rs/pmxcfs-dfsm/src/kv_store_message.rs create mode 100644 src/pmxcfs-rs/pmxcfs-dfsm/src/lib.rs create mode 100644 src/pmxcfs-rs/pmxcfs-dfsm/src/message.rs create mode 100644 src/pmxcfs-rs/pmxcfs-dfsm/src/state_machine.rs create mode 100644 src/pmxcfs-rs/pmxcfs-dfsm/src/status_sync_service.rs create mode 100644 src/pmxcfs-rs/pmxcfs-dfsm/src/types.rs create mode 100644 src/pmxcfs-rs/pmxcfs-dfsm/src/wire_format.rs create mode 100644 src/pmxcfs-rs/pmxcfs-dfsm/tests/multi_node_sync_tests.rs create mode 100644 src/pmxcfs-rs/pmxcfs-ipc/Cargo.toml create mode 100644 src/pmxcfs-rs/pmxcfs-ipc/README.md create mode 100644 src/pmxcfs-rs/pmxcfs-ipc/examples/test_server.rs create mode 100644 src/pmxcfs-rs/pmxcfs-ipc/src/connection.rs create mode 100644 src/pmxcfs-rs/pmxcfs-ipc/src/handler.rs create mode 100644 src/pmxcfs-rs/pmxcfs-ipc/src/lib.rs create mode 100644 src/pmxcfs-rs/pmxcfs-ipc/src/protocol.rs create mode 100644 src/pmxcfs-rs/pmxcfs-ipc/src/ringbuffer.rs create mode 100644 src/pmxcfs-rs/pmxcfs-ipc/src/server.rs create mode 100644 src/pmxcfs-rs/pmxcfs-ipc/src/socket.rs create mode 100644 src/pmxcfs-rs/pmxcfs-ipc/tests/auth_test.rs create mode 100644 src/pmxcfs-rs/pmxcfs-ipc/tests/edge_cases_test.rs create mode 100644 src/pmxcfs-rs/pmxcfs-ipc/tests/qb_wire_compat.rs create mode 100644 src/pmxcfs-rs/pmxcfs-logger/Cargo.toml create mode 100644 src/pmxcfs-rs/pmxcfs-logger/README.md create mode 100644 src/pmxcfs-rs/pmxcfs-logger/src/cluster_log.rs create mode 100644 src/pmxcfs-rs/pmxcfs-logger/src/entry.rs create mode 100644 src/pmxcfs-rs/pmxcfs-logger/src/hash.rs create mode 100644 src/pmxcfs-rs/pmxcfs-logger/src/lib.rs create mode 100644 src/pmxcfs-rs/pmxcfs-logger/src/ring_buffer.rs create mode 100644 src/pmxcfs-rs/pmxcfs-logger/tests/binary_compatibility_tests.rs create mode 100644 src/pmxcfs-rs/pmxcfs-logger/tests/performance_tests.rs create mode 100644 src/pmxcfs-rs/pmxcfs-memdb/Cargo.toml create mode 100644 src/pmxcfs-rs/pmxcfs-memdb/README.md create mode 100644 src/pmxcfs-rs/pmxcfs-memdb/src/database.rs create mode 100644 src/pmxcfs-rs/pmxcfs-memdb/src/index.rs create mode 100644 src/pmxcfs-rs/pmxcfs-memdb/src/lib.rs create mode 100644 src/pmxcfs-rs/pmxcfs-memdb/src/locks.rs create mode 100644 src/pmxcfs-rs/pmxcfs-memdb/src/sync.rs create mode 100644 src/pmxcfs-rs/pmxcfs-memdb/src/traits.rs create mode 100644 src/pmxcfs-rs/pmxcfs-memdb/src/types.rs create mode 100644 src/pmxcfs-rs/pmxcfs-memdb/src/vmlist.rs create mode 100644 src/pmxcfs-rs/pmxcfs-memdb/tests/checksum_test.rs create mode 100644 src/pmxcfs-rs/pmxcfs-memdb/tests/sync_integration_tests.rs create mode 100644 src/pmxcfs-rs/pmxcfs-rrd/Cargo.toml create mode 100644 src/pmxcfs-rs/pmxcfs-rrd/README.md create mode 100644 src/pmxcfs-rs/pmxcfs-rrd/src/backend.rs create mode 100644 src/pmxcfs-rs/pmxcfs-rrd/src/backend/backend_daemon.rs create mode 100644 src/pmxcfs-rs/pmxcfs-rrd/src/backend/backend_direct.rs create mode 100644 src/pmxcfs-rs/pmxcfs-rrd/src/backend/backend_fallback.rs create mode 100644 src/pmxcfs-rs/pmxcfs-rrd/src/daemon.rs create mode 100644 src/pmxcfs-rs/pmxcfs-rrd/src/key_type.rs create mode 100644 src/pmxcfs-rs/pmxcfs-rrd/src/lib.rs create mode 100644 src/pmxcfs-rs/pmxcfs-rrd/src/parse.rs create mode 100644 src/pmxcfs-rs/pmxcfs-rrd/src/rrdcached/LICENSE create mode 100644 src/pmxcfs-rs/pmxcfs-rrd/src/rrdcached/client.rs create mode 100644 src/pmxcfs-rs/pmxcfs-rrd/src/rrdcached/consolidation_function.rs create mode 100644 src/pmxcfs-rs/pmxcfs-rrd/src/rrdcached/create.rs create mode 100644 src/pmxcfs-rs/pmxcfs-rrd/src/rrdcached/errors.rs create mode 100644 src/pmxcfs-rs/pmxcfs-rrd/src/rrdcached/mod.rs create mode 100644 src/pmxcfs-rs/pmxcfs-rrd/src/rrdcached/now.rs create mode 100644 src/pmxcfs-rs/pmxcfs-rrd/src/rrdcached/parsers.rs create mode 100644 src/pmxcfs-rs/pmxcfs-rrd/src/rrdcached/sanitisation.rs create mode 100644 src/pmxcfs-rs/pmxcfs-rrd/src/schema.rs create mode 100644 src/pmxcfs-rs/pmxcfs-rrd/src/writer.rs create mode 100644 src/pmxcfs-rs/pmxcfs-services/Cargo.toml create mode 100644 src/pmxcfs-rs/pmxcfs-services/README.md create mode 100644 src/pmxcfs-rs/pmxcfs-services/src/error.rs create mode 100644 src/pmxcfs-rs/pmxcfs-services/src/lib.rs create mode 100644 src/pmxcfs-rs/pmxcfs-services/src/manager.rs create mode 100644 src/pmxcfs-rs/pmxcfs-services/src/service.rs create mode 100644 src/pmxcfs-rs/pmxcfs-services/tests/service_tests.rs create mode 100644 src/pmxcfs-rs/pmxcfs-status/Cargo.toml create mode 100644 src/pmxcfs-rs/pmxcfs-status/README.md create mode 100644 src/pmxcfs-rs/pmxcfs-status/src/lib.rs create mode 100644 src/pmxcfs-rs/pmxcfs-status/src/status.rs create mode 100644 src/pmxcfs-rs/pmxcfs-status/src/traits.rs create mode 100644 src/pmxcfs-rs/pmxcfs-status/src/types.rs create mode 100644 src/pmxcfs-rs/pmxcfs-test-utils/Cargo.toml create mode 100644 src/pmxcfs-rs/pmxcfs-test-utils/src/lib.rs create mode 100644 src/pmxcfs-rs/pmxcfs-test-utils/src/mock_memdb.rs create mode 100644 src/pmxcfs-rs/pmxcfs/Cargo.toml create mode 100644 src/pmxcfs-rs/pmxcfs/README.md create mode 100644 src/pmxcfs-rs/pmxcfs/src/cluster_config_service.rs create mode 100644 src/pmxcfs-rs/pmxcfs/src/daemon.rs create mode 100644 src/pmxcfs-rs/pmxcfs/src/file_lock.rs create mode 100644 src/pmxcfs-rs/pmxcfs/src/fuse/README.md create mode 100644 src/pmxcfs-rs/pmxcfs/src/fuse/filesystem.rs create mode 100644 src/pmxcfs-rs/pmxcfs/src/fuse/mod.rs create mode 100644 src/pmxcfs-rs/pmxcfs/src/ipc/mod.rs create mode 100644 src/pmxcfs-rs/pmxcfs/src/ipc/request.rs create mode 100644 src/pmxcfs-rs/pmxcfs/src/ipc/service.rs create mode 100644 src/pmxcfs-rs/pmxcfs/src/lib.rs create mode 100644 src/pmxcfs-rs/pmxcfs/src/logging.rs create mode 100644 src/pmxcfs-rs/pmxcfs/src/main.rs create mode 100644 src/pmxcfs-rs/pmxcfs/src/memdb_callbacks.rs create mode 100644 src/pmxcfs-rs/pmxcfs/src/plugins/README.md create mode 100644 src/pmxcfs-rs/pmxcfs/src/plugins/clusterlog.rs create mode 100644 src/pmxcfs-rs/pmxcfs/src/plugins/debug.rs create mode 100644 src/pmxcfs-rs/pmxcfs/src/plugins/members.rs create mode 100644 src/pmxcfs-rs/pmxcfs/src/plugins/mod.rs create mode 100644 src/pmxcfs-rs/pmxcfs/src/plugins/registry.rs create mode 100644 src/pmxcfs-rs/pmxcfs/src/plugins/rrd.rs create mode 100644 src/pmxcfs-rs/pmxcfs/src/plugins/types.rs create mode 100644 src/pmxcfs-rs/pmxcfs/src/plugins/version.rs create mode 100644 src/pmxcfs-rs/pmxcfs/src/plugins/vmlist.rs create mode 100644 src/pmxcfs-rs/pmxcfs/src/quorum_service.rs create mode 100644 src/pmxcfs-rs/pmxcfs/src/restart_flag.rs create mode 100644 src/pmxcfs-rs/pmxcfs/src/status_callbacks.rs create mode 100644 src/pmxcfs-rs/pmxcfs/tests/common/mod.rs create mode 100644 src/pmxcfs-rs/pmxcfs/tests/fuse_basic_test.rs create mode 100644 src/pmxcfs-rs/pmxcfs/tests/fuse_cluster_test.rs create mode 100644 src/pmxcfs-rs/pmxcfs/tests/fuse_integration_test.rs create mode 100644 src/pmxcfs-rs/pmxcfs/tests/fuse_locks_test.rs create mode 100644 src/pmxcfs-rs/pmxcfs/tests/local_integration.rs create mode 100644 src/pmxcfs-rs/pmxcfs/tests/quorum_behavior.rs create mode 100644 src/pmxcfs-rs/pmxcfs/tests/single_node_functional.rs create mode 100644 src/pmxcfs-rs/pmxcfs/tests/symlink_quorum_test.rs create mode 100644 src/pmxcfs-rs/tests/fuse_basic_test.rs create mode 100644 src/pmxcfs-rs/tests/fuse_cluster_test.rs create mode 100644 src/pmxcfs-rs/tests/fuse_integration_test.rs create mode 100644 src/pmxcfs-rs/tests/fuse_locks_test.rs create mode 100644 src/pmxcfs-rs/tests/local_integration.rs create mode 100644 src/pmxcfs-rs/tests/quorum_behavior_test.rs create mode 100644 src/pmxcfs-rs/tests/single_node_test.rs create mode 100644 src/pmxcfs-rs/tests/symlink_quorum_test.rs create mode 100644 src/pmxcfs-rs/tests/two_node_test.rs create mode 100644 src/pmxcfs-rs/vendor/rust-corosync/Cargo.toml create mode 100644 src/pmxcfs-rs/vendor/rust-corosync/Cargo.toml.orig create mode 100644 src/pmxcfs-rs/vendor/rust-corosync/LICENSE create mode 100644 src/pmxcfs-rs/vendor/rust-corosync/README.PATCH.md create mode 100644 src/pmxcfs-rs/vendor/rust-corosync/README.md create mode 100644 src/pmxcfs-rs/vendor/rust-corosync/build.rs create mode 100644 src/pmxcfs-rs/vendor/rust-corosync/regenerate-sys.sh create mode 100644 src/pmxcfs-rs/vendor/rust-corosync/src/cfg.rs create mode 100644 src/pmxcfs-rs/vendor/rust-corosync/src/cmap.rs create mode 100644 src/pmxcfs-rs/vendor/rust-corosync/src/cpg.rs create mode 100644 src/pmxcfs-rs/vendor/rust-corosync/src/lib.rs create mode 100644 src/pmxcfs-rs/vendor/rust-corosync/src/quorum.rs create mode 100644 src/pmxcfs-rs/vendor/rust-corosync/src/sys/cfg.rs create mode 100644 src/pmxcfs-rs/vendor/rust-corosync/src/sys/cmap.rs create mode 100644 src/pmxcfs-rs/vendor/rust-corosync/src/sys/cpg.rs create mode 100644 src/pmxcfs-rs/vendor/rust-corosync/src/sys/mod.rs create mode 100644 src/pmxcfs-rs/vendor/rust-corosync/src/sys/quorum.rs create mode 100644 src/pmxcfs-rs/vendor/rust-corosync/src/sys/votequorum.rs create mode 100644 src/pmxcfs-rs/vendor/rust-corosync/src/votequorum.rs -- 2.47.3