refactor: Merge drive and reader config to enable implementations of tape management without synchronization
This commit is contained in:
@@ -1,7 +1,6 @@
|
||||
package cmd
|
||||
|
||||
import (
|
||||
"github.com/pojntfx/stfs/pkg/config"
|
||||
"github.com/pojntfx/stfs/pkg/hardware"
|
||||
"github.com/pojntfx/stfs/pkg/tape"
|
||||
"github.com/spf13/cobra"
|
||||
@@ -16,7 +15,7 @@ var driveEjectCmd = &cobra.Command{
|
||||
return err
|
||||
}
|
||||
|
||||
reader, readerIsRegular, err := tape.OpenTapeReadOnly(
|
||||
reader, _, err := tape.OpenTapeReadOnly(
|
||||
viper.GetString(driveFlag),
|
||||
)
|
||||
if err != nil {
|
||||
@@ -24,12 +23,7 @@ var driveEjectCmd = &cobra.Command{
|
||||
}
|
||||
defer reader.Close()
|
||||
|
||||
return hardware.Eject(
|
||||
config.DriveConfig{
|
||||
Drive: reader,
|
||||
DriveIsRegular: readerIsRegular,
|
||||
},
|
||||
)
|
||||
return hardware.Eject(reader.Fd())
|
||||
},
|
||||
}
|
||||
|
||||
|
||||
@@ -3,7 +3,6 @@ package cmd
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"github.com/pojntfx/stfs/pkg/config"
|
||||
"github.com/pojntfx/stfs/pkg/hardware"
|
||||
"github.com/pojntfx/stfs/pkg/tape"
|
||||
"github.com/spf13/cobra"
|
||||
@@ -18,7 +17,7 @@ var driveTellCmd = &cobra.Command{
|
||||
return err
|
||||
}
|
||||
|
||||
reader, readerIsRegular, err := tape.OpenTapeReadOnly(
|
||||
reader, _, err := tape.OpenTapeReadOnly(
|
||||
viper.GetString(driveFlag),
|
||||
)
|
||||
if err != nil {
|
||||
@@ -26,12 +25,7 @@ var driveTellCmd = &cobra.Command{
|
||||
}
|
||||
defer reader.Close()
|
||||
|
||||
currentRecord, err := hardware.Tell(
|
||||
config.DriveConfig{
|
||||
Drive: reader,
|
||||
DriveIsRegular: readerIsRegular,
|
||||
},
|
||||
)
|
||||
currentRecord, err := hardware.Tell(reader.Fd())
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
@@ -87,9 +87,6 @@ var operationArchiveCmd = &cobra.Command{
|
||||
|
||||
GetReader: tm.GetReader,
|
||||
CloseReader: tm.Close,
|
||||
|
||||
GetDrive: tm.GetDrive,
|
||||
CloseDrive: tm.Close,
|
||||
},
|
||||
config.MetadataConfig{
|
||||
Metadata: metadataPersister,
|
||||
|
||||
@@ -71,9 +71,6 @@ var operationDeleteCmd = &cobra.Command{
|
||||
|
||||
GetReader: tm.GetReader,
|
||||
CloseReader: tm.Close,
|
||||
|
||||
GetDrive: tm.GetDrive,
|
||||
CloseDrive: tm.Close,
|
||||
},
|
||||
config.MetadataConfig{
|
||||
Metadata: metadataPersister,
|
||||
|
||||
@@ -67,9 +67,6 @@ var operationMoveCmd = &cobra.Command{
|
||||
|
||||
GetReader: tm.GetReader,
|
||||
CloseReader: tm.Close,
|
||||
|
||||
GetDrive: tm.GetDrive,
|
||||
CloseDrive: tm.Close,
|
||||
},
|
||||
config.MetadataConfig{
|
||||
Metadata: metadataPersister,
|
||||
|
||||
@@ -75,9 +75,6 @@ var operationRestoreCmd = &cobra.Command{
|
||||
|
||||
GetReader: tm.GetReader,
|
||||
CloseReader: tm.Close,
|
||||
|
||||
GetDrive: tm.GetDrive,
|
||||
CloseDrive: tm.Close,
|
||||
},
|
||||
config.MetadataConfig{
|
||||
Metadata: metadataPersister,
|
||||
|
||||
@@ -77,9 +77,6 @@ var operationUpdateCmd = &cobra.Command{
|
||||
|
||||
GetReader: tm.GetReader,
|
||||
CloseReader: tm.Close,
|
||||
|
||||
GetDrive: tm.GetDrive,
|
||||
CloseDrive: tm.Close,
|
||||
},
|
||||
config.MetadataConfig{
|
||||
Metadata: metadataPersister,
|
||||
|
||||
@@ -71,10 +71,6 @@ var recoveryFetchCmd = &cobra.Command{
|
||||
Drive: reader,
|
||||
DriveIsRegular: readerIsRegular,
|
||||
},
|
||||
config.DriveConfig{
|
||||
Drive: reader,
|
||||
DriveIsRegular: readerIsRegular,
|
||||
},
|
||||
config.PipeConfig{
|
||||
Compression: viper.GetString(compressionFlag),
|
||||
Encryption: viper.GetString(encryptionFlag),
|
||||
|
||||
@@ -70,10 +70,6 @@ var recoveryIndexCmd = &cobra.Command{
|
||||
Drive: reader,
|
||||
DriveIsRegular: readerIsRegular,
|
||||
},
|
||||
config.DriveConfig{
|
||||
Drive: reader,
|
||||
DriveIsRegular: readerIsRegular,
|
||||
},
|
||||
config.MetadataConfig{
|
||||
Metadata: metadataPersister,
|
||||
},
|
||||
|
||||
@@ -60,10 +60,6 @@ var recoveryQueryCmd = &cobra.Command{
|
||||
Drive: reader,
|
||||
DriveIsRegular: readerIsRegular,
|
||||
},
|
||||
config.DriveConfig{
|
||||
Drive: reader,
|
||||
DriveIsRegular: readerIsRegular,
|
||||
},
|
||||
config.PipeConfig{
|
||||
Compression: viper.GetString(compressionFlag),
|
||||
Encryption: viper.GetString(encryptionFlag),
|
||||
|
||||
@@ -139,9 +139,6 @@ var serveFTPCmd = &cobra.Command{
|
||||
|
||||
GetReader: tm.GetReader,
|
||||
CloseReader: tm.Close,
|
||||
|
||||
GetDrive: tm.GetDrive,
|
||||
CloseDrive: tm.Close,
|
||||
}
|
||||
readCryptoConfig := config.CryptoConfig{
|
||||
Recipient: signatureRecipient,
|
||||
|
||||
@@ -95,9 +95,6 @@ var serveHTTPCmd = &cobra.Command{
|
||||
|
||||
GetReader: tm.GetReader,
|
||||
CloseReader: tm.Close,
|
||||
|
||||
GetDrive: tm.GetDrive,
|
||||
CloseDrive: tm.Close,
|
||||
},
|
||||
config.MetadataConfig{
|
||||
Metadata: metadataPersister,
|
||||
|
||||
@@ -118,9 +118,6 @@ func createFs(
|
||||
|
||||
GetReader: tm.GetReader,
|
||||
CloseReader: tm.Close,
|
||||
|
||||
GetDrive: tm.GetDrive,
|
||||
CloseDrive: tm.Close,
|
||||
}
|
||||
readCryptoConfig := config.CryptoConfig{
|
||||
Recipient: signatureRecipient,
|
||||
|
||||
@@ -54,9 +54,6 @@ func main() {
|
||||
|
||||
GetReader: tm.GetReader,
|
||||
CloseReader: tm.Close,
|
||||
|
||||
GetDrive: tm.GetDrive,
|
||||
CloseDrive: tm.Close,
|
||||
}
|
||||
readCryptoConfig := config.CryptoConfig{}
|
||||
|
||||
|
||||
@@ -7,8 +7,13 @@ import (
|
||||
"time"
|
||||
)
|
||||
|
||||
type ReadSeekFder interface {
|
||||
io.ReadSeeker
|
||||
Fd() uintptr
|
||||
}
|
||||
|
||||
type DriveReaderConfig struct {
|
||||
Drive io.ReadSeeker
|
||||
Drive ReadSeekFder
|
||||
DriveIsRegular bool
|
||||
}
|
||||
|
||||
@@ -17,24 +22,12 @@ type DriveWriterConfig struct {
|
||||
DriveIsRegular bool
|
||||
}
|
||||
|
||||
type Drive interface {
|
||||
Fd() uintptr
|
||||
}
|
||||
|
||||
type DriveConfig struct {
|
||||
Drive Drive
|
||||
DriveIsRegular bool
|
||||
}
|
||||
|
||||
type BackendConfig struct {
|
||||
GetWriter func() (DriveWriterConfig, error)
|
||||
CloseWriter func() error
|
||||
|
||||
GetReader func() (DriveReaderConfig, error)
|
||||
CloseReader func() error
|
||||
|
||||
GetDrive func() (DriveConfig, error)
|
||||
CloseDrive func() error
|
||||
}
|
||||
|
||||
type Header struct {
|
||||
|
||||
@@ -218,10 +218,6 @@ func (f *STFS) Initialize(rootProposal string, rootPerm os.FileMode) (root strin
|
||||
existingRoot, err := f.metadata.Metadata.GetRootPath(context.Background())
|
||||
if err == config.ErrNoRootDirectory {
|
||||
mkdirRoot := func() (string, error) {
|
||||
if err := f.readOps.GetBackend().CloseDrive(); err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
if err := f.readOps.GetBackend().CloseReader(); err != nil {
|
||||
return "", err
|
||||
}
|
||||
@@ -238,11 +234,6 @@ func (f *STFS) Initialize(rootProposal string, rootPerm os.FileMode) (root strin
|
||||
return f.metadata.Metadata.GetRootPath(context.Background())
|
||||
}
|
||||
|
||||
drive, err := f.readOps.GetBackend().GetDrive()
|
||||
if err != nil {
|
||||
return mkdirRoot()
|
||||
}
|
||||
|
||||
reader, err := f.readOps.GetBackend().GetReader()
|
||||
if err != nil {
|
||||
return mkdirRoot()
|
||||
@@ -250,7 +241,6 @@ func (f *STFS) Initialize(rootProposal string, rootPerm os.FileMode) (root strin
|
||||
|
||||
if err := recovery.Index(
|
||||
reader,
|
||||
drive,
|
||||
f.readOps.GetMetadata(),
|
||||
f.readOps.GetPipes(),
|
||||
f.readOps.GetCrypto(),
|
||||
|
||||
@@ -369,9 +369,6 @@ func createSTFS(
|
||||
|
||||
GetReader: tm.GetReader,
|
||||
CloseReader: tm.Close,
|
||||
|
||||
GetDrive: tm.GetDrive,
|
||||
CloseDrive: tm.Close,
|
||||
}
|
||||
readCryptoConfig := config.CryptoConfig{
|
||||
Recipient: signatureRecipient,
|
||||
|
||||
@@ -2,11 +2,8 @@ package hardware
|
||||
|
||||
import (
|
||||
"github.com/pojntfx/stfs/internal/mtio"
|
||||
"github.com/pojntfx/stfs/pkg/config"
|
||||
)
|
||||
|
||||
func Eject(
|
||||
state config.DriveConfig,
|
||||
) error {
|
||||
return mtio.EjectTape(state.Drive.Fd())
|
||||
func Eject(fd uintptr) error {
|
||||
return mtio.EjectTape(fd)
|
||||
}
|
||||
|
||||
@@ -2,11 +2,8 @@ package hardware
|
||||
|
||||
import (
|
||||
"github.com/pojntfx/stfs/internal/mtio"
|
||||
"github.com/pojntfx/stfs/pkg/config"
|
||||
)
|
||||
|
||||
func Tell(
|
||||
state config.DriveConfig,
|
||||
) (int64, error) {
|
||||
return mtio.GetCurrentRecordFromTape(state.Drive.Fd())
|
||||
func Tell(fd uintptr) (int64, error) {
|
||||
return mtio.GetCurrentRecordFromTape(fd)
|
||||
}
|
||||
|
||||
@@ -262,15 +262,8 @@ func (o *Operations) Archive(
|
||||
}
|
||||
defer o.backend.CloseReader()
|
||||
|
||||
drive, err := o.backend.GetDrive()
|
||||
if err != nil {
|
||||
return []*tar.Header{}, err
|
||||
}
|
||||
defer o.backend.CloseDrive()
|
||||
|
||||
return hdrs, recovery.Index(
|
||||
reader,
|
||||
drive,
|
||||
o.metadata,
|
||||
o.pipes,
|
||||
o.crypto,
|
||||
|
||||
@@ -109,15 +109,8 @@ func (o *Operations) Delete(name string) error {
|
||||
}
|
||||
defer o.backend.CloseReader()
|
||||
|
||||
drive, err := o.backend.GetDrive()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer o.backend.CloseDrive()
|
||||
|
||||
return recovery.Index(
|
||||
reader,
|
||||
drive,
|
||||
o.metadata,
|
||||
o.pipes,
|
||||
o.crypto,
|
||||
|
||||
@@ -128,15 +128,8 @@ func (o *Operations) Move(from string, to string) error {
|
||||
}
|
||||
defer o.backend.CloseReader()
|
||||
|
||||
drive, err := o.backend.GetDrive()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer o.backend.CloseDrive()
|
||||
|
||||
return recovery.Index(
|
||||
reader,
|
||||
drive,
|
||||
o.metadata,
|
||||
o.pipes,
|
||||
o.crypto,
|
||||
|
||||
@@ -60,12 +60,6 @@ func (o *Operations) Restore(
|
||||
}
|
||||
defer o.backend.CloseReader()
|
||||
|
||||
drive, err := o.backend.GetDrive()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer o.backend.CloseDrive()
|
||||
|
||||
for _, dbhdr := range headersToRestore {
|
||||
if o.onHeader != nil {
|
||||
o.onHeader(&config.HeaderEvent{
|
||||
@@ -90,7 +84,6 @@ func (o *Operations) Restore(
|
||||
|
||||
if err := recovery.Fetch(
|
||||
reader,
|
||||
drive,
|
||||
o.pipes,
|
||||
o.crypto,
|
||||
|
||||
|
||||
@@ -289,15 +289,8 @@ func (o *Operations) Update(
|
||||
}
|
||||
defer o.backend.CloseReader()
|
||||
|
||||
drive, err := o.backend.GetDrive()
|
||||
if err != nil {
|
||||
return []*tar.Header{}, err
|
||||
}
|
||||
defer o.backend.CloseDrive()
|
||||
|
||||
return hdrs, recovery.Index(
|
||||
reader,
|
||||
drive,
|
||||
o.metadata,
|
||||
o.pipes,
|
||||
o.crypto,
|
||||
|
||||
@@ -19,7 +19,6 @@ import (
|
||||
|
||||
func Fetch(
|
||||
reader config.DriveReaderConfig,
|
||||
drive config.DriveConfig,
|
||||
pipes config.PipeConfig,
|
||||
crypto config.CryptoConfig,
|
||||
|
||||
@@ -45,7 +44,7 @@ func Fetch(
|
||||
tr = tar.NewReader(reader.Drive)
|
||||
} else {
|
||||
// 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
|
||||
}
|
||||
|
||||
@@ -67,7 +66,7 @@ func Fetch(
|
||||
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
|
||||
}
|
||||
|
||||
@@ -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 {
|
||||
return err
|
||||
}
|
||||
|
||||
@@ -21,7 +21,6 @@ import (
|
||||
|
||||
func Index(
|
||||
reader config.DriveReaderConfig,
|
||||
drive config.DriveConfig,
|
||||
metadata config.MetadataConfig,
|
||||
pipes config.PipeConfig,
|
||||
crypto config.CryptoConfig,
|
||||
@@ -150,7 +149,7 @@ func Index(
|
||||
}
|
||||
} else {
|
||||
// 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
|
||||
}
|
||||
|
||||
@@ -172,13 +171,13 @@ func Index(
|
||||
hdr, err := tr.Next()
|
||||
if err != nil {
|
||||
if err == io.EOF {
|
||||
if err := mtio.GoToNextFileOnTape(drive.Drive.Fd()); err != nil {
|
||||
if err := mtio.GoToNextFileOnTape(reader.Drive.Fd()); err != nil {
|
||||
// EOD
|
||||
|
||||
break
|
||||
}
|
||||
|
||||
record, err = mtio.GetCurrentRecordFromTape(drive.Drive.Fd())
|
||||
record, err = mtio.GetCurrentRecordFromTape(reader.Drive.Fd())
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -200,7 +199,7 @@ func Index(
|
||||
return err
|
||||
}
|
||||
|
||||
if err := verifyHeader(hdr, drive.DriveIsRegular); err != nil {
|
||||
if err := verifyHeader(hdr, reader.DriveIsRegular); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
|
||||
@@ -17,7 +17,6 @@ import (
|
||||
|
||||
func Query(
|
||||
reader config.DriveReaderConfig,
|
||||
drive config.DriveConfig,
|
||||
pipes config.PipeConfig,
|
||||
crypto config.CryptoConfig,
|
||||
|
||||
@@ -132,7 +131,7 @@ func Query(
|
||||
}
|
||||
} else {
|
||||
// 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
|
||||
}
|
||||
|
||||
@@ -153,13 +152,13 @@ func Query(
|
||||
hdr, err := tr.Next()
|
||||
if err != nil {
|
||||
if err == io.EOF {
|
||||
if err := mtio.GoToNextFileOnTape(drive.Drive.Fd()); err != nil {
|
||||
if err := mtio.GoToNextFileOnTape(reader.Drive.Fd()); err != nil {
|
||||
// EOD
|
||||
|
||||
break
|
||||
}
|
||||
|
||||
record, err = mtio.GetCurrentRecordFromTape(drive.Drive.Fd())
|
||||
record, err = mtio.GetCurrentRecordFromTape(reader.Drive.Fd())
|
||||
if err != nil {
|
||||
return []*tar.Header{}, err
|
||||
}
|
||||
|
||||
@@ -13,7 +13,7 @@ type TapeManager struct {
|
||||
recordSize int
|
||||
overwrite bool
|
||||
|
||||
driveLock sync.Mutex
|
||||
physicalLock sync.Mutex
|
||||
|
||||
readerLock sync.Mutex
|
||||
reader *os.File
|
||||
@@ -37,7 +37,7 @@ func NewTapeManager(
|
||||
}
|
||||
|
||||
func (m *TapeManager) GetWriter() (config.DriveWriterConfig, error) {
|
||||
m.driveLock.Lock()
|
||||
m.physicalLock.Lock()
|
||||
|
||||
overwrite := m.overwrite
|
||||
if m.overwrote {
|
||||
@@ -73,17 +73,6 @@ func (m *TapeManager) GetReader() (config.DriveReaderConfig, error) {
|
||||
}, 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 {
|
||||
if m.closer != nil {
|
||||
if err := m.closer(); err != nil {
|
||||
@@ -91,7 +80,7 @@ func (m *TapeManager) Close() error {
|
||||
}
|
||||
}
|
||||
|
||||
m.driveLock.Unlock()
|
||||
m.physicalLock.Unlock()
|
||||
|
||||
return nil
|
||||
}
|
||||
@@ -109,7 +98,7 @@ func (m *TapeManager) openOrReuseReader() error {
|
||||
}
|
||||
|
||||
if reopen {
|
||||
m.driveLock.Lock()
|
||||
m.physicalLock.Lock()
|
||||
|
||||
r, rr, err := OpenTapeReadOnly(m.drive)
|
||||
if err != nil {
|
||||
|
||||
Reference in New Issue
Block a user