refactor: Merge drive and reader config to enable implementations of tape management without synchronization

This commit is contained in:
Felicitas Pojtinger
2022-01-16 22:46:18 +01:00
parent 17e3c64f29
commit 5b84583403
28 changed files with 28 additions and 154 deletions

View File

@@ -1,7 +1,6 @@
package cmd package cmd
import ( import (
"github.com/pojntfx/stfs/pkg/config"
"github.com/pojntfx/stfs/pkg/hardware" "github.com/pojntfx/stfs/pkg/hardware"
"github.com/pojntfx/stfs/pkg/tape" "github.com/pojntfx/stfs/pkg/tape"
"github.com/spf13/cobra" "github.com/spf13/cobra"
@@ -16,7 +15,7 @@ var driveEjectCmd = &cobra.Command{
return err return err
} }
reader, readerIsRegular, err := tape.OpenTapeReadOnly( reader, _, err := tape.OpenTapeReadOnly(
viper.GetString(driveFlag), viper.GetString(driveFlag),
) )
if err != nil { if err != nil {
@@ -24,12 +23,7 @@ var driveEjectCmd = &cobra.Command{
} }
defer reader.Close() defer reader.Close()
return hardware.Eject( return hardware.Eject(reader.Fd())
config.DriveConfig{
Drive: reader,
DriveIsRegular: readerIsRegular,
},
)
}, },
} }

View File

@@ -3,7 +3,6 @@ package cmd
import ( import (
"fmt" "fmt"
"github.com/pojntfx/stfs/pkg/config"
"github.com/pojntfx/stfs/pkg/hardware" "github.com/pojntfx/stfs/pkg/hardware"
"github.com/pojntfx/stfs/pkg/tape" "github.com/pojntfx/stfs/pkg/tape"
"github.com/spf13/cobra" "github.com/spf13/cobra"
@@ -18,7 +17,7 @@ var driveTellCmd = &cobra.Command{
return err return err
} }
reader, readerIsRegular, err := tape.OpenTapeReadOnly( reader, _, err := tape.OpenTapeReadOnly(
viper.GetString(driveFlag), viper.GetString(driveFlag),
) )
if err != nil { if err != nil {
@@ -26,12 +25,7 @@ var driveTellCmd = &cobra.Command{
} }
defer reader.Close() defer reader.Close()
currentRecord, err := hardware.Tell( currentRecord, err := hardware.Tell(reader.Fd())
config.DriveConfig{
Drive: reader,
DriveIsRegular: readerIsRegular,
},
)
if err != nil { if err != nil {
return err return err
} }

View File

@@ -87,9 +87,6 @@ var operationArchiveCmd = &cobra.Command{
GetReader: tm.GetReader, GetReader: tm.GetReader,
CloseReader: tm.Close, CloseReader: tm.Close,
GetDrive: tm.GetDrive,
CloseDrive: tm.Close,
}, },
config.MetadataConfig{ config.MetadataConfig{
Metadata: metadataPersister, Metadata: metadataPersister,

View File

@@ -71,9 +71,6 @@ var operationDeleteCmd = &cobra.Command{
GetReader: tm.GetReader, GetReader: tm.GetReader,
CloseReader: tm.Close, CloseReader: tm.Close,
GetDrive: tm.GetDrive,
CloseDrive: tm.Close,
}, },
config.MetadataConfig{ config.MetadataConfig{
Metadata: metadataPersister, Metadata: metadataPersister,

View File

@@ -67,9 +67,6 @@ var operationMoveCmd = &cobra.Command{
GetReader: tm.GetReader, GetReader: tm.GetReader,
CloseReader: tm.Close, CloseReader: tm.Close,
GetDrive: tm.GetDrive,
CloseDrive: tm.Close,
}, },
config.MetadataConfig{ config.MetadataConfig{
Metadata: metadataPersister, Metadata: metadataPersister,

View File

@@ -75,9 +75,6 @@ var operationRestoreCmd = &cobra.Command{
GetReader: tm.GetReader, GetReader: tm.GetReader,
CloseReader: tm.Close, CloseReader: tm.Close,
GetDrive: tm.GetDrive,
CloseDrive: tm.Close,
}, },
config.MetadataConfig{ config.MetadataConfig{
Metadata: metadataPersister, Metadata: metadataPersister,

View File

@@ -77,9 +77,6 @@ var operationUpdateCmd = &cobra.Command{
GetReader: tm.GetReader, GetReader: tm.GetReader,
CloseReader: tm.Close, CloseReader: tm.Close,
GetDrive: tm.GetDrive,
CloseDrive: tm.Close,
}, },
config.MetadataConfig{ config.MetadataConfig{
Metadata: metadataPersister, Metadata: metadataPersister,

View File

@@ -71,10 +71,6 @@ var recoveryFetchCmd = &cobra.Command{
Drive: reader, Drive: reader,
DriveIsRegular: readerIsRegular, DriveIsRegular: readerIsRegular,
}, },
config.DriveConfig{
Drive: reader,
DriveIsRegular: readerIsRegular,
},
config.PipeConfig{ config.PipeConfig{
Compression: viper.GetString(compressionFlag), Compression: viper.GetString(compressionFlag),
Encryption: viper.GetString(encryptionFlag), Encryption: viper.GetString(encryptionFlag),

View File

@@ -70,10 +70,6 @@ var recoveryIndexCmd = &cobra.Command{
Drive: reader, Drive: reader,
DriveIsRegular: readerIsRegular, DriveIsRegular: readerIsRegular,
}, },
config.DriveConfig{
Drive: reader,
DriveIsRegular: readerIsRegular,
},
config.MetadataConfig{ config.MetadataConfig{
Metadata: metadataPersister, Metadata: metadataPersister,
}, },

View File

@@ -60,10 +60,6 @@ var recoveryQueryCmd = &cobra.Command{
Drive: reader, Drive: reader,
DriveIsRegular: readerIsRegular, DriveIsRegular: readerIsRegular,
}, },
config.DriveConfig{
Drive: reader,
DriveIsRegular: readerIsRegular,
},
config.PipeConfig{ config.PipeConfig{
Compression: viper.GetString(compressionFlag), Compression: viper.GetString(compressionFlag),
Encryption: viper.GetString(encryptionFlag), Encryption: viper.GetString(encryptionFlag),

View File

@@ -139,9 +139,6 @@ var serveFTPCmd = &cobra.Command{
GetReader: tm.GetReader, GetReader: tm.GetReader,
CloseReader: tm.Close, CloseReader: tm.Close,
GetDrive: tm.GetDrive,
CloseDrive: tm.Close,
} }
readCryptoConfig := config.CryptoConfig{ readCryptoConfig := config.CryptoConfig{
Recipient: signatureRecipient, Recipient: signatureRecipient,

View File

@@ -95,9 +95,6 @@ var serveHTTPCmd = &cobra.Command{
GetReader: tm.GetReader, GetReader: tm.GetReader,
CloseReader: tm.Close, CloseReader: tm.Close,
GetDrive: tm.GetDrive,
CloseDrive: tm.Close,
}, },
config.MetadataConfig{ config.MetadataConfig{
Metadata: metadataPersister, Metadata: metadataPersister,

View File

@@ -118,9 +118,6 @@ func createFs(
GetReader: tm.GetReader, GetReader: tm.GetReader,
CloseReader: tm.Close, CloseReader: tm.Close,
GetDrive: tm.GetDrive,
CloseDrive: tm.Close,
} }
readCryptoConfig := config.CryptoConfig{ readCryptoConfig := config.CryptoConfig{
Recipient: signatureRecipient, Recipient: signatureRecipient,

View File

@@ -54,9 +54,6 @@ func main() {
GetReader: tm.GetReader, GetReader: tm.GetReader,
CloseReader: tm.Close, CloseReader: tm.Close,
GetDrive: tm.GetDrive,
CloseDrive: tm.Close,
} }
readCryptoConfig := config.CryptoConfig{} readCryptoConfig := config.CryptoConfig{}

View File

@@ -7,8 +7,13 @@ import (
"time" "time"
) )
type ReadSeekFder interface {
io.ReadSeeker
Fd() uintptr
}
type DriveReaderConfig struct { type DriveReaderConfig struct {
Drive io.ReadSeeker Drive ReadSeekFder
DriveIsRegular bool DriveIsRegular bool
} }
@@ -17,24 +22,12 @@ type DriveWriterConfig struct {
DriveIsRegular bool DriveIsRegular bool
} }
type Drive interface {
Fd() uintptr
}
type DriveConfig struct {
Drive Drive
DriveIsRegular bool
}
type BackendConfig struct { type BackendConfig struct {
GetWriter func() (DriveWriterConfig, error) GetWriter func() (DriveWriterConfig, error)
CloseWriter func() error CloseWriter func() error
GetReader func() (DriveReaderConfig, error) GetReader func() (DriveReaderConfig, error)
CloseReader func() error CloseReader func() error
GetDrive func() (DriveConfig, error)
CloseDrive func() error
} }
type Header struct { type Header struct {

View File

@@ -218,10 +218,6 @@ func (f *STFS) Initialize(rootProposal string, rootPerm os.FileMode) (root strin
existingRoot, err := f.metadata.Metadata.GetRootPath(context.Background()) existingRoot, err := f.metadata.Metadata.GetRootPath(context.Background())
if err == config.ErrNoRootDirectory { if err == config.ErrNoRootDirectory {
mkdirRoot := func() (string, error) { mkdirRoot := func() (string, error) {
if err := f.readOps.GetBackend().CloseDrive(); err != nil {
return "", err
}
if err := f.readOps.GetBackend().CloseReader(); err != nil { if err := f.readOps.GetBackend().CloseReader(); err != nil {
return "", err return "", err
} }
@@ -238,11 +234,6 @@ func (f *STFS) Initialize(rootProposal string, rootPerm os.FileMode) (root strin
return f.metadata.Metadata.GetRootPath(context.Background()) return f.metadata.Metadata.GetRootPath(context.Background())
} }
drive, err := f.readOps.GetBackend().GetDrive()
if err != nil {
return mkdirRoot()
}
reader, err := f.readOps.GetBackend().GetReader() reader, err := f.readOps.GetBackend().GetReader()
if err != nil { if err != nil {
return mkdirRoot() return mkdirRoot()
@@ -250,7 +241,6 @@ func (f *STFS) Initialize(rootProposal string, rootPerm os.FileMode) (root strin
if err := recovery.Index( if err := recovery.Index(
reader, reader,
drive,
f.readOps.GetMetadata(), f.readOps.GetMetadata(),
f.readOps.GetPipes(), f.readOps.GetPipes(),
f.readOps.GetCrypto(), f.readOps.GetCrypto(),

View File

@@ -369,9 +369,6 @@ func createSTFS(
GetReader: tm.GetReader, GetReader: tm.GetReader,
CloseReader: tm.Close, CloseReader: tm.Close,
GetDrive: tm.GetDrive,
CloseDrive: tm.Close,
} }
readCryptoConfig := config.CryptoConfig{ readCryptoConfig := config.CryptoConfig{
Recipient: signatureRecipient, Recipient: signatureRecipient,

View File

@@ -2,11 +2,8 @@ package hardware
import ( import (
"github.com/pojntfx/stfs/internal/mtio" "github.com/pojntfx/stfs/internal/mtio"
"github.com/pojntfx/stfs/pkg/config"
) )
func Eject( func Eject(fd uintptr) error {
state config.DriveConfig, return mtio.EjectTape(fd)
) error {
return mtio.EjectTape(state.Drive.Fd())
} }

View File

@@ -2,11 +2,8 @@ package hardware
import ( import (
"github.com/pojntfx/stfs/internal/mtio" "github.com/pojntfx/stfs/internal/mtio"
"github.com/pojntfx/stfs/pkg/config"
) )
func Tell( func Tell(fd uintptr) (int64, error) {
state config.DriveConfig, return mtio.GetCurrentRecordFromTape(fd)
) (int64, error) {
return mtio.GetCurrentRecordFromTape(state.Drive.Fd())
} }

View File

@@ -262,15 +262,8 @@ func (o *Operations) Archive(
} }
defer o.backend.CloseReader() defer o.backend.CloseReader()
drive, err := o.backend.GetDrive()
if err != nil {
return []*tar.Header{}, err
}
defer o.backend.CloseDrive()
return hdrs, recovery.Index( return hdrs, recovery.Index(
reader, reader,
drive,
o.metadata, o.metadata,
o.pipes, o.pipes,
o.crypto, o.crypto,

View File

@@ -109,15 +109,8 @@ func (o *Operations) Delete(name string) error {
} }
defer o.backend.CloseReader() defer o.backend.CloseReader()
drive, err := o.backend.GetDrive()
if err != nil {
return err
}
defer o.backend.CloseDrive()
return recovery.Index( return recovery.Index(
reader, reader,
drive,
o.metadata, o.metadata,
o.pipes, o.pipes,
o.crypto, o.crypto,

View File

@@ -128,15 +128,8 @@ func (o *Operations) Move(from string, to string) error {
} }
defer o.backend.CloseReader() defer o.backend.CloseReader()
drive, err := o.backend.GetDrive()
if err != nil {
return err
}
defer o.backend.CloseDrive()
return recovery.Index( return recovery.Index(
reader, reader,
drive,
o.metadata, o.metadata,
o.pipes, o.pipes,
o.crypto, o.crypto,

View File

@@ -60,12 +60,6 @@ func (o *Operations) Restore(
} }
defer o.backend.CloseReader() defer o.backend.CloseReader()
drive, err := o.backend.GetDrive()
if err != nil {
return err
}
defer o.backend.CloseDrive()
for _, dbhdr := range headersToRestore { for _, dbhdr := range headersToRestore {
if o.onHeader != nil { if o.onHeader != nil {
o.onHeader(&config.HeaderEvent{ o.onHeader(&config.HeaderEvent{
@@ -90,7 +84,6 @@ func (o *Operations) Restore(
if err := recovery.Fetch( if err := recovery.Fetch(
reader, reader,
drive,
o.pipes, o.pipes,
o.crypto, o.crypto,

View File

@@ -289,15 +289,8 @@ func (o *Operations) Update(
} }
defer o.backend.CloseReader() defer o.backend.CloseReader()
drive, err := o.backend.GetDrive()
if err != nil {
return []*tar.Header{}, err
}
defer o.backend.CloseDrive()
return hdrs, recovery.Index( return hdrs, recovery.Index(
reader, reader,
drive,
o.metadata, o.metadata,
o.pipes, o.pipes,
o.crypto, o.crypto,

View File

@@ -19,7 +19,6 @@ import (
func Fetch( func Fetch(
reader config.DriveReaderConfig, reader config.DriveReaderConfig,
drive config.DriveConfig,
pipes config.PipeConfig, pipes config.PipeConfig,
crypto config.CryptoConfig, crypto config.CryptoConfig,
@@ -45,7 +44,7 @@ func Fetch(
tr = tar.NewReader(reader.Drive) tr = tar.NewReader(reader.Drive)
} else { } else {
// Seek to record // Seek to record
if err := mtio.SeekToRecordOnTape(drive.Drive.Fd(), int32(record)); err != nil { if err := mtio.SeekToRecordOnTape(reader.Drive.Fd(), int32(record)); err != nil {
return err return err
} }
@@ -67,7 +66,7 @@ func Fetch(
return err return err
} }
if err := signature.VerifyHeader(hdr, drive.DriveIsRegular, pipes.Signature, crypto.Recipient); err != nil { if err := signature.VerifyHeader(hdr, reader.DriveIsRegular, pipes.Signature, crypto.Recipient); err != nil {
return err return err
} }
@@ -120,7 +119,7 @@ func Fetch(
} }
} }
verifier, verify, err := signature.Verify(decompressor, drive.DriveIsRegular, pipes.Signature, crypto.Recipient, sig) verifier, verify, err := signature.Verify(decompressor, reader.DriveIsRegular, pipes.Signature, crypto.Recipient, sig)
if err != nil { if err != nil {
return err return err
} }

View File

@@ -21,7 +21,6 @@ import (
func Index( func Index(
reader config.DriveReaderConfig, reader config.DriveReaderConfig,
drive config.DriveConfig,
metadata config.MetadataConfig, metadata config.MetadataConfig,
pipes config.PipeConfig, pipes config.PipeConfig,
crypto config.CryptoConfig, crypto config.CryptoConfig,
@@ -150,7 +149,7 @@ func Index(
} }
} else { } else {
// Seek to record // Seek to record
if err := mtio.SeekToRecordOnTape(drive.Drive.Fd(), int32(record)); err != nil { if err := mtio.SeekToRecordOnTape(reader.Drive.Fd(), int32(record)); err != nil {
return err return err
} }
@@ -172,13 +171,13 @@ func Index(
hdr, err := tr.Next() hdr, err := tr.Next()
if err != nil { if err != nil {
if err == io.EOF { if err == io.EOF {
if err := mtio.GoToNextFileOnTape(drive.Drive.Fd()); err != nil { if err := mtio.GoToNextFileOnTape(reader.Drive.Fd()); err != nil {
// EOD // EOD
break break
} }
record, err = mtio.GetCurrentRecordFromTape(drive.Drive.Fd()) record, err = mtio.GetCurrentRecordFromTape(reader.Drive.Fd())
if err != nil { if err != nil {
return err return err
} }
@@ -200,7 +199,7 @@ func Index(
return err return err
} }
if err := verifyHeader(hdr, drive.DriveIsRegular); err != nil { if err := verifyHeader(hdr, reader.DriveIsRegular); err != nil {
return err return err
} }

View File

@@ -17,7 +17,6 @@ import (
func Query( func Query(
reader config.DriveReaderConfig, reader config.DriveReaderConfig,
drive config.DriveConfig,
pipes config.PipeConfig, pipes config.PipeConfig,
crypto config.CryptoConfig, crypto config.CryptoConfig,
@@ -132,7 +131,7 @@ func Query(
} }
} else { } else {
// Seek to record // Seek to record
if err := mtio.SeekToRecordOnTape(drive.Drive.Fd(), int32(record)); err != nil { if err := mtio.SeekToRecordOnTape(reader.Drive.Fd(), int32(record)); err != nil {
return []*tar.Header{}, err return []*tar.Header{}, err
} }
@@ -153,13 +152,13 @@ func Query(
hdr, err := tr.Next() hdr, err := tr.Next()
if err != nil { if err != nil {
if err == io.EOF { if err == io.EOF {
if err := mtio.GoToNextFileOnTape(drive.Drive.Fd()); err != nil { if err := mtio.GoToNextFileOnTape(reader.Drive.Fd()); err != nil {
// EOD // EOD
break break
} }
record, err = mtio.GetCurrentRecordFromTape(drive.Drive.Fd()) record, err = mtio.GetCurrentRecordFromTape(reader.Drive.Fd())
if err != nil { if err != nil {
return []*tar.Header{}, err return []*tar.Header{}, err
} }

View File

@@ -13,7 +13,7 @@ type TapeManager struct {
recordSize int recordSize int
overwrite bool overwrite bool
driveLock sync.Mutex physicalLock sync.Mutex
readerLock sync.Mutex readerLock sync.Mutex
reader *os.File reader *os.File
@@ -37,7 +37,7 @@ func NewTapeManager(
} }
func (m *TapeManager) GetWriter() (config.DriveWriterConfig, error) { func (m *TapeManager) GetWriter() (config.DriveWriterConfig, error) {
m.driveLock.Lock() m.physicalLock.Lock()
overwrite := m.overwrite overwrite := m.overwrite
if m.overwrote { if m.overwrote {
@@ -73,17 +73,6 @@ func (m *TapeManager) GetReader() (config.DriveReaderConfig, error) {
}, nil }, nil
} }
func (m *TapeManager) GetDrive() (config.DriveConfig, error) {
if err := m.openOrReuseReader(); err != nil {
return config.DriveConfig{}, err
}
return config.DriveConfig{
Drive: m.reader,
DriveIsRegular: m.readerIsRegular,
}, nil
}
func (m *TapeManager) Close() error { func (m *TapeManager) Close() error {
if m.closer != nil { if m.closer != nil {
if err := m.closer(); err != nil { if err := m.closer(); err != nil {
@@ -91,7 +80,7 @@ func (m *TapeManager) Close() error {
} }
} }
m.driveLock.Unlock() m.physicalLock.Unlock()
return nil return nil
} }
@@ -109,7 +98,7 @@ func (m *TapeManager) openOrReuseReader() error {
} }
if reopen { if reopen {
m.driveLock.Lock() m.physicalLock.Lock()
r, rr, err := OpenTapeReadOnly(m.drive) r, rr, err := OpenTapeReadOnly(m.drive)
if err != nil { if err != nil {