# Bacula VTL Integration - Root Cause Analysis & Troubleshooting ## Issue Summary Bacula Storage Daemon was unable to read slots from mhVTL (Virtual Tape Library) autochanger devices, reporting "Device has 0 slots" despite mtx-changer script working correctly when called manually. ## Environment - **OS**: Ubuntu Linux - **Bacula Version**: 13.0.4 - **VTL**: mhVTL (Virtual Tape Library) - **Autochangers**: - Quantum Scalar i500 (4 drives, 43 slots) - Quantum Scalar i40 (4 drives, 44 slots) - **Tape Drives**: 8x QUANTUM ULTRIUM-HH8 (LTO-8) ## Root Cause Analysis ### Primary Issues Identified #### 1. **Incorrect Tape Device Type** **Problem**: Using rewinding tape devices (`/dev/st*`) instead of non-rewinding devices (`/dev/nst*`) **Impact**: Tape would rewind after each operation, causing data loss and operational failures **Solution**: Changed all Archive Device directives from `/dev/st*` to `/dev/nst*` ```diff Device { Name = Drive-0 - Archive Device = /dev/st0 + Archive Device = /dev/nst0 } ``` #### 2. **Missing Drive Index Parameter** **Problem**: Device configurations lacked Drive Index parameter **Impact**: Bacula couldn't properly identify which physical drive in the autochanger to use **Solution**: Added Drive Index (0-3) to each Device resource ```diff Device { Name = Drive-0 + Drive Index = 0 Archive Device = /dev/nst0 } ``` #### 3. **Incorrect AlwaysOpen Setting** **Problem**: AlwaysOpen was set to `no` **Impact**: Device wouldn't remain open, causing connection issues with VTL **Solution**: Changed AlwaysOpen to `yes` for all tape devices ```diff Device { Name = Drive-0 - AlwaysOpen = no + AlwaysOpen = yes } ``` #### 4. **Wrong Changer Device Path** **Problem**: Using `/dev/sch*` (medium changer device) instead of `/dev/sg*` (generic SCSI device) **Impact**: bacula user couldn't access the changer due to permission issues (cdrom group vs tape group) **Solution**: Changed Changer Device to use sg devices ```diff Autochanger { Name = Scalar-i500 - Changer Device = /dev/sch0 + Changer Device = /dev/sg7 } ``` **Device Mapping**: - `/dev/sch0` → `/dev/sg7` (Scalar i500) - `/dev/sch1` → `/dev/sg8` (Scalar i40) #### 5. **Missing User Permissions** **Problem**: bacula user not in required groups for device access **Impact**: "Permission denied" errors when accessing tape and changer devices **Solution**: Added bacula user to tape and cdrom groups ```bash usermod -a -G tape,cdrom bacula systemctl restart bacula-sd ``` #### 6. **Incorrect Storage Resource Configuration** **Problem**: Storage resource in Director config referenced autochanger name instead of individual drives **Impact**: Bacula couldn't properly communicate with individual tape drives **Solution**: Listed all drives explicitly in Storage resource ```diff Storage { Name = Scalar-i500 - Device = Scalar-i500 + Device = Drive-0 + Device = Drive-1 + Device = Drive-2 + Device = Drive-3 Autochanger = Scalar-i500 } ``` #### 7. **mtx-changer List Output Format** **Problem**: Script output format didn't match Bacula's expected format **Impact**: "Invalid Slot number" errors, preventing volume labeling **Original Output**: `1 Full:VolumeTag=E01001L8` **Expected Output**: `1:E01001L8` **Solution**: Fixed sed pattern in list command ```bash # Original (incorrect) list) ${MTX} -f $ctl status | grep "Storage Element" | grep "Full" | awk '{print $3 $4}' | sed 's/:/ /' ;; # Fixed list) ${MTX} -f $ctl status | grep "Storage Element" | grep "Full" | awk '{print $3 $4}' | sed 's/:Full:VolumeTag=/:/' ;; ``` ## Troubleshooting Steps ### Step 1: Verify mtx-changer Script Works Manually ```bash # Test slots command /usr/lib/bacula/scripts/mtx-changer /dev/sg7 slots # Expected output: 43 # Test list command /usr/lib/bacula/scripts/mtx-changer /dev/sg7 list # Expected output: 1:E01001L8, 2:E01002L8, etc. ``` ### Step 2: Test as bacula User ```bash # Test if bacula user can access devices su -s /bin/bash bacula -c "/usr/lib/bacula/scripts/mtx-changer /dev/sg7 slots" # If permission denied, check groups groups bacula # Should include: bacula tape cdrom ``` ### Step 3: Verify Device Permissions ```bash # Check changer devices ls -l /dev/sch* /dev/sg7 /dev/sg8 # sg devices should be in tape group # Check tape devices ls -l /dev/nst* # Should be in tape group with rw permissions ``` ### Step 4: Test Bacula Storage Daemon Connection ```bash # From bconsole echo "status storage=Scalar-i500" | bconsole # Should show autochanger and drives ``` ### Step 5: Update Slots ```bash echo -e "update slots storage=Scalar-i500\n0\n" | bconsole # Should show: Device "Drive-0" has 43 slots # NOT: Device has 0 slots ``` ### Step 6: Label Tapes ```bash echo -e "label barcodes storage=Scalar-i500 pool=Default\n0\nyes\n" | bconsole # Should successfully label tapes using barcodes ``` ## Configuration Files ### /etc/bacula/bacula-sd.conf (Storage Daemon) ```bash Autochanger { Name = Scalar-i500 Device = Drive-0, Drive-1, Drive-2, Drive-3 Changer Command = "/usr/lib/bacula/scripts/mtx-changer %c %o %S %a %d" Changer Device = /dev/sg7 } Device { Name = Drive-0 Drive Index = 0 Changer Device = /dev/sg7 Media Type = LTO-8 Archive Device = /dev/nst0 AutomaticMount = yes AlwaysOpen = yes RemovableMedia = yes RandomAccess = no AutoChanger = yes Maximum Concurrent Jobs = 1 } ``` ### /etc/bacula/bacula-dir.conf (Director) ```bash Storage { Name = Scalar-i500 Address = localhost SDPort = 9103 Password = "QJQPnZ5Q5p6D73RcvR7ksrOm9UG3mAhvV" Device = Drive-0 Device = Drive-1 Device = Drive-2 Device = Drive-3 Media Type = LTO-8 Autochanger = Scalar-i500 Maximum Concurrent Jobs = 4 } ``` ### /usr/lib/bacula/scripts/mtx-changer ```bash #!/bin/sh MTX=/usr/sbin/mtx ctl=$1 cmd="$2" slot=$3 device=$4 drive=$5 case "$cmd" in loaded) ${MTX} -f $ctl status | grep "Data Transfer Element $slot:Full" >/dev/null 2>&1 if [ $? -eq 0 ]; then ${MTX} -f $ctl status | grep "Data Transfer Element $slot:Full" | awk '{print $7}' | sed 's/.*=//' else echo "0" fi ;; load) ${MTX} -f $ctl load $slot $drive ;; unload) ${MTX} -f $ctl unload $slot $drive ;; list) ${MTX} -f $ctl status | grep "Storage Element" | grep "Full" | awk '{print $3 $4}' | sed 's/:Full:VolumeTag=/:/' ;; slots) ${MTX} -f $ctl status | grep "Storage Changer" | awk '{print $5}' ;; *) echo "Invalid command: $cmd" exit 1 ;; esac exit 0 ``` ## Verification Commands ### Check Device Mapping ```bash lsscsi -g | grep -E "mediumx|tape" ``` ### Check VTL Services ```bash systemctl list-units 'vtl*' ``` ### Test Manual Tape Load ```bash # Load tape to drive mtx -f /dev/sg7 load 1 0 # Check drive status mt -f /dev/nst0 status # Unload tape mtx -f /dev/sg7 unload 1 0 ``` ### List Labeled Volumes ```bash echo "list volumes pool=Default" | bconsole ``` ## Common Errors and Solutions ### Error: "Device has 0 slots" **Cause**: Wrong changer device or permission issues **Solution**: Use /dev/sg* devices and verify bacula user in tape/cdrom groups ### Error: "Permission denied" accessing /dev/sch0 **Cause**: bacula user not in cdrom group **Solution**: `usermod -a -G cdrom bacula && systemctl restart bacula-sd` ### Error: "Invalid Slot number" **Cause**: mtx-changer list output format incorrect **Solution**: Fix sed pattern to output `slot:volumetag` format ### Error: "No medium found" after successful load **Cause**: Using rewinding devices (/dev/st*) or AlwaysOpen=no **Solution**: Use /dev/nst* and set AlwaysOpen=yes ### Error: "READ ELEMENT STATUS Command Failed" **Cause**: Permission issue or VTL service problem **Solution**: Check user permissions and restart vtllibrary service ## Results ### Scalar i500 (WORKING) - ✅ 43 slots detected - ✅ 20 tapes successfully labeled (E01001L8 - E01020L8) - ✅ Autochanger operations functional - ✅ Ready for backup jobs ### Scalar i40 (ISSUE) - ⚠️ 44 slots detected - ❌ Hardware Error during tape load operations - ❌ 0 tapes labeled - **Status**: Requires mhVTL configuration investigation or system restart ## References - Bacula Documentation: https://www.bacula.org/ - Article: "Using Bacula with mhVTL" - https://karellen.blogspot.com/2012/02/using-bacula-with-mhvtl.html - mhVTL Project: https://github.com/markh794/mhvtl ## Date Created: 2025-12-31 Author: Warp AI Agent