Commit Graph
51 Commits
Author SHA1 Message Date
cozis 776f8c1015 Fix scheduling issue where time didn't advance if a host was always ready 2026-01-23 18:37:26 +01:00
Claude 9948716be8 Fix assertion failure in file_tree_read when read operation fails
Initialize *gen to NO_GENERATION at the start of file_tree_read so that
error paths (FILETREE_BADPATH, FILETREE_NOENT, FILETREE_ISDIR) have a
well-defined value. Previously, when file_tree_read failed, gen was
uninitialized, causing the assertion in process_client_read to fire.

The assertion checking gen != NO_GENERATION before the error check was
removed since:
1. On error paths, gen is not used
2. On success paths, the assertion at line 482 already validates gen
2026-01-16 18:48:23 +00:00
cozis c10493881b Add Quakey 2026-01-16 14:45:09 +01:00
Claudeandcozis 6746b0d5fb Add MISSING_FILE_GENERATION special value for "file does not exist"
Implements a new special generation counter value (UINT64_MAX) that
allows clients to assert that a file should NOT exist when performing
operations.

Primary use case: Atomic "create-if-not-exists" operations
When combined with TOASTY_WRITE_CREATE_IF_MISSING flag:
- File doesn't exist → server creates file and writes (SUCCESS)
- File exists → gen_match fails → BADGEN error (prevents overwrite)

This enables race-condition-free file creation where you want to
create a NEW file or fail if it already exists.

Key changes:
- Added MISSING_FILE_GENERATION constant to file_tree.h
- Updated gen_match() to return false when checking existing entities
  against MISSING_FILE_GENERATION
- Modified file_tree_delete_entity() to succeed (no-op) when file is
  missing and MISSING_FILE_GENERATION is specified (idempotent delete)
- Modified file_tree_write() to validate against the new value
- Added documentation in metadata_server.c explaining how
  MISSING_FILE_GENERATION works WITH CREATE_IF_MISSING
- Updated protocol documentation in PROTOCOL.txt
- Added comprehensive feature documentation in MISSING_FILE_GENERATION.md

Additional use cases:
- Idempotent delete operations (delete only if not already gone)
- Detecting unexpected file creation in validation/testing scenarios

The implementation is backward compatible and type-safe. Files are
never assigned MISSING_FILE_GENERATION as their actual generation value.
2025-12-05 09:10:17 +01:00
cozis e73bb3a7d8 Add crash logger 2025-12-04 12:25:19 +01:00
Claude 4bcee9a617 Add TOASTY_WRITE_TRUNCATE_AFTER flag for HTTP PUT semantics
Adds support for truncating files after write operations, enabling proper
HTTP PUT semantics where the entire file content should be replaced.

Implementation:
- Added TOASTY_WRITE_TRUNCATE_AFTER flag (0x02) to ToastyFS API
- Updated file_tree_write() to accept truncate_after parameter:
  * When true, sets file size to exactly offset+length
  * Removes chunks beyond the new file size
  * Marks removed chunks for garbage collection
- Metadata server extracts and passes truncate flag to file_tree_write()
- WAL replay passes false for truncate_after (already handled in original write)
- Web proxy PUT now uses both CREATE_IF_MISSING and TRUNCATE_AFTER flags
- Updated documentation in PROTOCOL.txt, DESIGN.txt, and web/DESIGN.txt

Benefits:
- Proper HTTP PUT semantics (replace entire file content)
- Efficient: single write operation truncates and updates file
- Works with both sync and async APIs
- Garbage collection automatically removes orphaned chunks
2025-12-03 19:49:48 +00:00
Claude 8160c5ac51 Add TOASTY_WRITE_CREATE_IF_MISSING flag for server-side file auto-creation
Adds support for automatically creating files when write operations target
non-existent files. This is essential for REST PUT operations which should
be able to create new resources.

Implementation:
- Added TOASTY_WRITE_CREATE_IF_MISSING flag to ToastyFS API header
- Updated toasty_write() and toasty_begin_write() to accept flags parameter
- Client sends write flags in MESSAGE_TYPE_WRITE message to metadata server
- Metadata server parses flags and handles file auto-creation atomically:
  * When write fails with FILETREE_NOENT and flag is set
  * Logs creation to WAL for crash consistency
  * Creates file with default 4096-byte chunk size
  * Retries write with newly created file's generation tag
- Updated web proxy PUT handler to use TOASTY_WRITE_CREATE_IF_MISSING
- Updated examples and simulation client for new API signature

Benefits:
- Works for both sync and async APIs
- Single round trip (atomic server-side operation)
- Prevents race conditions
- Proper WAL logging ensures crash consistency
2025-12-03 18:48:42 +00:00
cozis 0d099a1fa6 Return version tags in directory listing 2025-11-25 12:08:33 +01:00
Claude acb1336d47 Implement synchronization protocol from PROTOCOL.txt
Updated both client.c and metadata_server.c to match the protocol
specification in misc/PROTOCOL.txt:

Client-to-Server Messages:
- Added expect_gen field to DELETE, LIST, READ, and WRITE messages
- Removed old_hash and chunk_size from WRITE message chunks

Server-to-Client Responses:
- Added generation counter to CREATE_SUCCESS response
- Added generation counter to LIST_SUCCESS response
- Fixed LIST_SUCCESS field order (gen, truncated, item_count)
- Added generation counter to READ_SUCCESS response
- Added generation counter to WRITE_SUCCESS response

All changes compile successfully and pass valgrind memory checks.
2025-11-24 12:16:55 +00:00
cozis 49091aff6d Document communication between metadata server and clients in the misc/PROTOCOL.txt file and add generation counters for files 2025-11-24 13:04:29 +01:00
Claude f856bd0e05 Track actual bytes read in read operations
Add functionality to determine the actual number of bytes read during
read operations, making it possible to detect when a read was truncated
because it went past the end of the file.

Changes:
- Modified file_tree_read() to calculate and return actual_bytes via
  new output parameter
- Updated metadata server to send actual_bytes in READ_SUCCESS messages
- Added bytes_read field to ToastyResult structure
- Modified client to parse, store, and report actual bytes read
- Updated toasty_read() to return the actual number of bytes read
  instead of always returning 0
- Fixed web server to use bytes_read field instead of non-existent
  count field

This allows clients to distinguish between:
- Reading zeros because the file is sparse (has holes)
- Reading past the end of the file (truncated read)
2025-11-22 22:22:43 +00:00
cozis e1fa3729c6 Drop the MAX_CONNS macro and define TCP_CONNECTION_LIMIT, TCP_POLL_CAPACITY, TCP_EVENT_CAPACITY instead 2025-11-22 22:59:32 +01:00
cozis b0313ffcf8 Make toasty client thread-safe and implement toasty_wakeup 2025-11-20 03:51:01 +01:00
cozis fb28e94a83 Continued work on the WAL 2025-11-17 21:52:44 +01:00
cozis a4a37b7a36 Minor fixes 2025-11-16 01:18:05 +01:00
cozis 11054cae86 Add new chunk hashes to the cs_add_list when creating or updating them in the chunk server 2025-11-15 10:55:11 +01:00
cozis a366b46398 Bug fixes 2025-11-15 10:38:45 +01:00
cozis bbae5fdb7f Fix compilation errors 2025-11-14 21:06:38 +01:00
cozis 2bbe1ac0e8 Clean up download logic for missing/lost chunks 2025-11-14 11:56:29 +01:00
cozis 9a944feb01 Rewrote simulation scheduler and fixed some bugs 2025-11-14 01:16:48 +01:00
cozis 3a2173c154 Minor bug fixes 2025-11-13 23:37:42 +01:00
cozis 3048f3d66b Bug fixes 2025-11-13 23:02:25 +01:00
cozis 7b01ac6384 Fix compilation errors 2025-11-13 20:21:26 +01:00
cozis cdce267768 Update DESIGN.txt and code accordingly 2025-11-13 17:27:00 +01:00
cozis e4c5390ca7 Implement CHUNK_LIST endpoints on the metadata server 2025-11-13 00:43:18 +01:00
cozis 7012f582d2 Add chunk management notes to DESIGN.txt 2025-11-12 12:13:52 +01:00
Claude e1869b4cf1 Fix DOWNLOAD_LOCATIONS message implementation
Fixed critical bugs in the DOWNLOAD_LOCATIONS message exchange between
metadata server and chunk server:

Metadata server changes:
- Fixed bug using wrong index (j instead of holders[j]) when writing
  chunk server addresses
- Added missing hash field to the message (was only read, never written)
- Added trace output for STATE_UPDATE_ERROR messages
- Pre-read all missing chunks before building response

Chunk server changes:
- Updated message parser to match metadata server's message format
- Changed from group-based format to per-chunk format
- Updated type sizes (uint32_t for counts instead of uint8_t/uint16_t)
- Correctly accumulates addresses from all holders before adding to
  pending download list

The message now follows this structure:
- num_missing (uint32_t)
- For each missing chunk:
  - num_holders (uint32_t)
  - For each holder: server addresses (num_ipv4, num_ipv6, addresses)
  - hash (SHA256)

Tested successfully with mousefs_random_test under valgrind with no
memory errors detected.
2025-11-10 22:01:24 +00:00
cozis 9a3a874514 Implement DOWNLOAD_LOCATIONS message in metadata server 2025-11-10 22:48:41 +01:00
cozis d25d79c1f1 Clean up state update logic in chunk server 2025-11-10 18:36:11 +01:00
cozis 50dd662057 Add asserts 2025-11-10 17:24:15 +01:00
cozis 6a608051d6 Clean up timeout code in metadata server 2025-11-10 15:07:38 +01:00
Claude 02b58a26a7 Implement periodic health checks for chunk servers
This implements the periodic STATE_UPDATE mechanism described in DESIGN.txt
lines 80-99, where the metadata server periodically sends synchronization
messages to chunk servers.

Changes:

1. Added timing fields to ChunkServerPeer:
   - last_sync_time: tracks when STATE_UPDATE was last sent
   - last_response_time: tracks when chunk server last responded

2. Added health check configuration constants (config.h):
   - HEALTH_CHECK_INTERVAL: 30 seconds between STATE_UPDATE messages
   - HEALTH_CHECK_TIMEOUT: 90 seconds before marking server as unhealthy

3. Implemented send_state_update() function:
   - Serializes and sends add_list and rem_list to chunk servers
   - Updates last_sync_time when messages are sent

4. Added message handlers for chunk server responses:
   - process_chunk_server_state_update_success(): merges add_list into old_list,
     clears pending lists, updates last_response_time
   - process_chunk_server_state_update_error(): handles missing chunks,
     updates last_response_time, logs errors

5. Implemented periodic timer logic in metadata_server_step():
   - Calculates when next STATE_UPDATE should be sent to each chunk server
   - Sends updates when HEALTH_CHECK_INTERVAL has elapsed
   - Logs warnings when chunk servers haven't responded within HEALTH_CHECK_TIMEOUT
   - Sets appropriate poll() timeout to wake up for next health check

The implementation ensures that:
- Chunk servers receive regular synchronization messages with add_list/rem_list
- The metadata server tracks chunk server health based on response times
- STATE_UPDATE messages are sent periodically (every 30 seconds by default)
- Failed/missing chunks are detected and logged for recovery

This completes the health check mechanism described in the architecture design,
enabling the metadata server to maintain accurate state with chunk servers and
detect unhealthy servers.
2025-11-10 12:50:15 +00:00
cozis 9cdf636eb6 Bug fix 2025-11-10 12:41:18 +01:00
cozis bab8558511 Progress 2025-11-09 20:36:08 +01:00
cozis d2140bdb13 Progress 2025-11-09 14:12:19 +01:00
cozis c3e20eceef Progress 2025-11-09 13:20:04 +01:00
cozis a2e949e5e4 Progress 2025-11-09 12:51:51 +01:00
cozis 739d6a7aee Progress 2025-11-09 12:08:22 +01:00
Claude 43768781c8 Fix valgrind uninitialized memory errors
Fixed multiple uninitialized memory issues detected by valgrind:

1. SHA256 struct size mismatch: Changed from 64 bytes to 32 bytes to
   match the actual output of sha256() function (which produces 256
   bits = 32 bytes).

2. File tree chunk allocation: Fixed loop that wasn't initializing
   newly allocated chunks because num_chunks was updated before the
   initialization loop. Now saves old_num_chunks first.

3. Metadata server process_client_write: Initialized results[i].num_addrs
   to 0 before use to prevent reading uninitialized value.

4. Address struct initialization: Zero-initialize Address structs before
   setting fields to ensure the entire union is initialized (union
   contains either IPv4 or IPv6, leaving unused bytes uninitialized).

5. Fixed bug in IPv6 address creation: Changed incorrect is_ipv4=true
   to is_ipv4=false for IPv6 addresses.

6. Fixed all_chunk_servers_holding_chunk: Function was incrementing
   counter for all chunk servers instead of only those containing the
   hash, causing access to uninitialized array elements.

All valgrind errors resolved: ERROR SUMMARY: 0 errors from 0 contexts
2025-11-08 16:26:12 +00:00
cozis 7846607651 Progress 2025-11-08 11:51:24 +01:00
cozis 8ab426770f Progress 2025-11-07 22:18:05 +01:00
cozis d7cf946431 Progress 2025-11-07 20:26:15 +01:00
cozis 44fb1c4f36 Progress 2025-11-07 00:30:28 +01:00
cozis 896bc0a23b Progress 2025-11-06 13:15:05 +01:00
cozis e7455cc4ed Progress 2025-11-06 01:00:39 +01:00
cozis e124952fe2 Progress 2025-11-05 14:26:57 +01:00
cozis 31a4b2cc32 Bug fixes 2025-11-03 18:32:14 +01:00
cozis e135d871c1 Progress 2025-11-03 15:52:25 +01:00
Claude 88a3a6e4f0 Add timeout parameter to metadata_server and chunk_server init/step functions
Unified the function signatures across all process types (metadata server,
chunk server, and simulation client) to accept an int *timeout parameter.
This provides consistency in the simulation framework and allows all
process types to control their wakeup times.

**Changes:**

**Headers (metadata_server.h, chunk_server.h):**
- Updated metadata_server_init() to accept int *timeout parameter
- Updated metadata_server_step() to accept int *timeout parameter
- Updated chunk_server_init() to accept int *timeout parameter
- Updated chunk_server_step() to accept int *timeout parameter

**Implementations (metadata_server.c, chunk_server.c):**
- Modified init functions to set *timeout = -1 (no timeout needed)
- Modified step functions to set *timeout = -1 (no timeout needed)
- Both server types currently don't require periodic wakeups, but the
  parameter allows for future timeout-based behavior

**System Integration (system.c):**
- Updated spawn_simulated_process() to declare timeout variable once
  and pass it to all process init functions uniformly
- Updated update_simulation() to declare timeout variable once and
  pass it to all process step functions uniformly
- Simplified control flow by removing special case for client timeout
  handling - now all process types use the same timeout logic
- Consolidated timeout-to-wakeup_time conversion after switch statements

**Benefits:**
- Consistent API across all process types
- Cleaner code with reduced duplication
- Future-proof for server timeout requirements
- All processes now managed uniformly by simulation framework

The simulation continues to run correctly with all process types
handling timeout parameter appropriately.
2025-11-02 12:33:40 +00:00
cozis 174f37c6c0 Continue work on DST framework 2025-10-29 21:46:17 +01:00