100 lines
2.4 KiB
Go
100 lines
2.4 KiB
Go
package iscsi
|
|
|
|
import (
|
|
"fmt"
|
|
"os"
|
|
"path/filepath"
|
|
)
|
|
|
|
// AddLUN adds a LUN to a target
|
|
func (s *Service) AddLUN(targetID string, lunNumber int, devicePath string, lunType string) error {
|
|
s.logger.Info("Adding LUN to target", "target", targetID, "lun", lunNumber, "device", devicePath, "type", lunType)
|
|
|
|
// Validate device exists
|
|
if _, err := os.Stat(devicePath); err != nil {
|
|
return fmt.Errorf("device not found: %s", devicePath)
|
|
}
|
|
|
|
// Validate LUN type
|
|
if lunType != "disk" && lunType != "tape" {
|
|
return fmt.Errorf("invalid LUN type: %s (must be 'disk' or 'tape')", lunType)
|
|
}
|
|
|
|
// For tape library:
|
|
// LUN 0 = Media changer
|
|
// LUN 1-8 = Tape drives
|
|
if lunType == "tape" {
|
|
if lunNumber == 0 {
|
|
// Media changer
|
|
devicePath = "/dev/sg0" // Default media changer
|
|
} else if lunNumber >= 1 && lunNumber <= 8 {
|
|
// Tape drive
|
|
devicePath = fmt.Sprintf("/dev/nst%d", lunNumber-1)
|
|
} else {
|
|
return fmt.Errorf("invalid LUN number for tape: %d (must be 0-8)", lunNumber)
|
|
}
|
|
}
|
|
|
|
// Update target configuration
|
|
target, err := s.GetTarget(targetID)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
// Check if LUN already exists
|
|
for _, lun := range target.LUNs {
|
|
if lun.Number == lunNumber {
|
|
return fmt.Errorf("LUN %d already exists", lunNumber)
|
|
}
|
|
}
|
|
|
|
// Add LUN
|
|
target.LUNs = append(target.LUNs, LUN{
|
|
Number: lunNumber,
|
|
Device: devicePath,
|
|
Type: lunType,
|
|
})
|
|
|
|
// Write updated config
|
|
return s.writeSCSTConfig(target)
|
|
}
|
|
|
|
// RemoveLUN removes a LUN from a target
|
|
func (s *Service) RemoveLUN(targetID string, lunNumber int) error {
|
|
s.logger.Info("Removing LUN from target", "target", targetID, "lun", lunNumber)
|
|
|
|
target, err := s.GetTarget(targetID)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
// Find and remove LUN
|
|
found := false
|
|
newLUNs := []LUN{}
|
|
for _, lun := range target.LUNs {
|
|
if lun.Number != lunNumber {
|
|
newLUNs = append(newLUNs, lun)
|
|
} else {
|
|
found = true
|
|
}
|
|
}
|
|
|
|
if !found {
|
|
return fmt.Errorf("LUN %d not found", lunNumber)
|
|
}
|
|
|
|
target.LUNs = newLUNs
|
|
return s.writeSCSTConfig(target)
|
|
}
|
|
|
|
// MapRepositoryToLUN maps a disk repository to an iSCSI LUN
|
|
func (s *Service) MapRepositoryToLUN(targetID string, repositoryPath string, lunNumber int) error {
|
|
// Resolve repository path to device
|
|
devicePath, err := filepath.EvalSymlinks(repositoryPath)
|
|
if err != nil {
|
|
return fmt.Errorf("failed to resolve repository path: %w", err)
|
|
}
|
|
|
|
return s.AddLUN(targetID, lunNumber, devicePath, "disk")
|
|
}
|