diff --git a/internal/zfs/service.go b/internal/zfs/service.go index 349fd82..28722c2 100644 --- a/internal/zfs/service.go +++ b/internal/zfs/service.go @@ -4,6 +4,7 @@ import ( "bytes" "encoding/json" "fmt" + "log" "os/exec" "strconv" "strings" @@ -190,11 +191,21 @@ func (s *Service) CreatePool(name string, vdevs []string, options map[string]str // Default mountpoint: /storage/pools/{poolname} mountpoint = "/storage/pools/" + name options["mountpoint"] = mountpoint - // Pre-create the mountpoint directory with sudo - _ = s.createMountpointWithSudo(mountpoint) - } else if mountpoint != "none" { - // Ensure mountpoint directory exists with sudo - _ = s.createMountpointWithSudo(mountpoint) + } + + // Pre-create the mountpoint directory with sudo (non-blocking - log errors but continue) + if mountpoint != "none" { + if err := s.createMountpointWithSudo(mountpoint); err != nil { + // Log the error but don't fail - ZFS might still create the pool + // The mountpoint can be fixed later if needed + log.Printf("warning: failed to pre-create mountpoint %s: %v (continuing anyway)", mountpoint, err) + } + } + + // Set canmount=noauto to prevent automatic mounting during creation + // This allows pool creation to succeed even if mountpoint can't be created + if _, hasCanmount := options["canmount"]; !hasCanmount { + options["canmount"] = "noauto" } // Add options @@ -205,8 +216,30 @@ func (s *Service) CreatePool(name string, vdevs []string, options map[string]str args = append(args, name) args = append(args, vdevs...) + // Create the pool _, err := s.execCommand(s.zpoolPath, args...) - return err + if err != nil { + return err + } + + // Pool created successfully - now try to set mountpoint and mount if needed + if mountpoint != "none" { + // Set mountpoint property (in case it wasn't set during creation) + setMountpointArgs := []string{"set", fmt.Sprintf("mountpoint=%s", mountpoint), name} + if _, setErr := s.execCommand(s.zfsPath, setMountpointArgs...); setErr != nil { + log.Printf("warning: failed to set mountpoint property: %v (pool created but not mounted)", setErr) + // Don't return error - pool is created successfully + } else { + // Try to mount the pool + mountArgs := []string{"mount", name} + if _, mountErr := s.execCommand(s.zfsPath, mountArgs...); mountErr != nil { + log.Printf("warning: failed to mount pool: %v (pool created but not mounted)", mountErr) + // Don't return error - pool is created successfully, just not mounted + } + } + } + + return nil } // createMountpointWithSudo creates a mountpoint directory using sudo