fix: Dynamic snapshot sizing to prevent I/O errors

Problem: Fixed 500MB snapshot size was too small for large/active LVs,
causing I/O errors when snapshot space was exhausted during backup.

Solution: Calculate appropriate snapshot size based on LV size:
- Use 10% of LV size for snapshot space
- Minimum 1GB to handle reasonable activity
- Shows snapshot size in logs for transparency

Example:
- 20GB LV → 2GB snapshot
- 100GB LV → 10GB snapshot
- 500MB LV → 1GB snapshot (minimum)

This prevents snapshot overflow and resulting I/O errors during backup.

Changes:
- GUI: Calculate snapshot size before creating
- CLI: Same dynamic sizing logic
- Both show calculated snapshot size in output
- Handles both single LV and VG backup modes
This commit is contained in:
root
2025-10-09 01:06:12 +02:00
parent c86fee78cb
commit f12d07be7f
2 changed files with 50 additions and 7 deletions

View File

@@ -518,8 +518,19 @@ class SimpleBackupGUI:
snapshot_name = f"{lv_name}_borg_snap"
self.current_snapshot = f"/dev/{vg_name}/{snapshot_name}"
self.log(f"Creating snapshot: {snapshot_name}")
success, output = self.run_command(f"lvcreate -L1G -s -n {snapshot_name} {source_lv}")
# Get LV size to determine appropriate snapshot size
success, lv_size_output = self.run_command(f"lvs --noheadings -o lv_size --units b {source_lv}", show_output=False)
if success:
lv_size_bytes = int(lv_size_output.strip().replace('B', ''))
# Use 10% of LV size or minimum 1GB for snapshot
snapshot_size_bytes = max(lv_size_bytes // 10, 1024**3) # Min 1GB
snapshot_size_gb = snapshot_size_bytes // (1024**3)
snapshot_size = f"{snapshot_size_gb}G"
else:
snapshot_size = "2G" # Default fallback
self.log(f"Creating snapshot: {snapshot_name} (size: {snapshot_size})")
success, output = self.run_command(f"lvcreate -L{snapshot_size} -s -n {snapshot_name} {source_lv}")
if not success:
raise Exception(f"Failed to create snapshot: {output}")
@@ -609,9 +620,20 @@ class SimpleBackupGUI:
snapshot_path = f"/dev/{source_vg}/{snapshot_name}"
lv_path = f"/dev/{source_vg}/{lv_name}"
# Get LV size to determine appropriate snapshot size
success, lv_size_output = self.run_command(f"lvs --noheadings -o lv_size --units b {lv_path}", show_output=False)
if success:
lv_size_bytes = int(lv_size_output.strip().replace('B', ''))
# Use 10% of LV size or minimum 1GB for snapshot
snapshot_size_bytes = max(lv_size_bytes // 10, 1024**3) # Min 1GB
snapshot_size_gb = snapshot_size_bytes // (1024**3)
snapshot_size = f"{snapshot_size_gb}G"
else:
snapshot_size = "2G" # Default fallback
self.log(f"Processing LV: {lv_name}")
self.log(f"Creating snapshot: {snapshot_name}")
success, output = self.run_command(f"lvcreate -L500M -s -n {snapshot_name} {lv_path}")
self.log(f"Creating snapshot: {snapshot_name} (size: {snapshot_size})")
success, output = self.run_command(f"lvcreate -L{snapshot_size} -s -n {snapshot_name} {lv_path}")
if not success:
self.log(f"Warning: Failed to create snapshot for {lv_name}: {output}")
continue