diff --git a/cmd/stfs/cmd/drive_eject.go b/cmd/stfs/cmd/drive_eject.go index 2061383..99b85ff 100644 --- a/cmd/stfs/cmd/drive_eject.go +++ b/cmd/stfs/cmd/drive_eject.go @@ -2,6 +2,7 @@ package cmd import ( "github.com/pojntfx/stfs/pkg/hardware" + "github.com/pojntfx/stfs/pkg/mtio" "github.com/pojntfx/stfs/pkg/tape" "github.com/spf13/cobra" "github.com/spf13/viper" @@ -23,7 +24,10 @@ var driveEjectCmd = &cobra.Command{ } defer reader.Close() - return hardware.Eject(reader.Fd()) + return hardware.Eject( + mtio.MagneticTapeIO{}, + reader.Fd(), + ) }, } diff --git a/cmd/stfs/cmd/drive_tell.go b/cmd/stfs/cmd/drive_tell.go index c67b05b..0fdd3cc 100644 --- a/cmd/stfs/cmd/drive_tell.go +++ b/cmd/stfs/cmd/drive_tell.go @@ -4,6 +4,7 @@ import ( "fmt" "github.com/pojntfx/stfs/pkg/hardware" + "github.com/pojntfx/stfs/pkg/mtio" "github.com/pojntfx/stfs/pkg/tape" "github.com/spf13/cobra" "github.com/spf13/viper" @@ -25,7 +26,10 @@ var driveTellCmd = &cobra.Command{ } defer reader.Close() - currentRecord, err := hardware.Tell(reader.Fd()) + currentRecord, err := hardware.Tell( + mtio.MagneticTapeIO{}, + reader.Fd(), + ) if err != nil { return err } diff --git a/cmd/stfs/cmd/operation_archive.go b/cmd/stfs/cmd/operation_archive.go index 9628018..aa4f34f 100644 --- a/cmd/stfs/cmd/operation_archive.go +++ b/cmd/stfs/cmd/operation_archive.go @@ -12,6 +12,7 @@ import ( "github.com/pojntfx/stfs/internal/logging" "github.com/pojntfx/stfs/pkg/config" "github.com/pojntfx/stfs/pkg/keys" + "github.com/pojntfx/stfs/pkg/mtio" "github.com/pojntfx/stfs/pkg/operations" "github.com/pojntfx/stfs/pkg/persisters" "github.com/pojntfx/stfs/pkg/tape" @@ -69,8 +70,10 @@ var operationArchiveCmd = &cobra.Command{ return err } + mt := mtio.MagneticTapeIO{} tm := tape.NewTapeManager( viper.GetString(driveFlag), + mt, viper.GetInt(recordSizeFlag), viper.GetBool(overwriteFlag), ) @@ -87,6 +90,8 @@ var operationArchiveCmd = &cobra.Command{ GetReader: tm.GetReader, CloseReader: tm.Close, + + MagneticTapeIO: mt, }, config.MetadataConfig{ Metadata: metadataPersister, diff --git a/cmd/stfs/cmd/operation_delete.go b/cmd/stfs/cmd/operation_delete.go index 0e8a060..7873d6f 100644 --- a/cmd/stfs/cmd/operation_delete.go +++ b/cmd/stfs/cmd/operation_delete.go @@ -6,6 +6,7 @@ import ( "github.com/pojntfx/stfs/internal/logging" "github.com/pojntfx/stfs/pkg/config" "github.com/pojntfx/stfs/pkg/keys" + "github.com/pojntfx/stfs/pkg/mtio" "github.com/pojntfx/stfs/pkg/operations" "github.com/pojntfx/stfs/pkg/persisters" "github.com/pojntfx/stfs/pkg/tape" @@ -53,8 +54,10 @@ var operationDeleteCmd = &cobra.Command{ return err } + mt := mtio.MagneticTapeIO{} tm := tape.NewTapeManager( viper.GetString(driveFlag), + mt, viper.GetInt(recordSizeFlag), false, ) @@ -71,6 +74,8 @@ var operationDeleteCmd = &cobra.Command{ GetReader: tm.GetReader, CloseReader: tm.Close, + + MagneticTapeIO: mt, }, config.MetadataConfig{ Metadata: metadataPersister, diff --git a/cmd/stfs/cmd/operation_move.go b/cmd/stfs/cmd/operation_move.go index d204c71..4190318 100644 --- a/cmd/stfs/cmd/operation_move.go +++ b/cmd/stfs/cmd/operation_move.go @@ -6,6 +6,7 @@ import ( "github.com/pojntfx/stfs/internal/logging" "github.com/pojntfx/stfs/pkg/config" "github.com/pojntfx/stfs/pkg/keys" + "github.com/pojntfx/stfs/pkg/mtio" "github.com/pojntfx/stfs/pkg/operations" "github.com/pojntfx/stfs/pkg/persisters" "github.com/pojntfx/stfs/pkg/tape" @@ -49,8 +50,10 @@ var operationMoveCmd = &cobra.Command{ return err } + mt := mtio.MagneticTapeIO{} tm := tape.NewTapeManager( viper.GetString(driveFlag), + mt, viper.GetInt(recordSizeFlag), false, ) @@ -67,6 +70,8 @@ var operationMoveCmd = &cobra.Command{ GetReader: tm.GetReader, CloseReader: tm.Close, + + MagneticTapeIO: mt, }, config.MetadataConfig{ Metadata: metadataPersister, diff --git a/cmd/stfs/cmd/operation_restore.go b/cmd/stfs/cmd/operation_restore.go index 754adac..c2114bf 100644 --- a/cmd/stfs/cmd/operation_restore.go +++ b/cmd/stfs/cmd/operation_restore.go @@ -10,6 +10,7 @@ import ( "github.com/pojntfx/stfs/internal/logging" "github.com/pojntfx/stfs/pkg/config" "github.com/pojntfx/stfs/pkg/keys" + "github.com/pojntfx/stfs/pkg/mtio" "github.com/pojntfx/stfs/pkg/operations" "github.com/pojntfx/stfs/pkg/persisters" "github.com/pojntfx/stfs/pkg/tape" @@ -57,8 +58,10 @@ var operationRestoreCmd = &cobra.Command{ return err } + mt := mtio.MagneticTapeIO{} tm := tape.NewTapeManager( viper.GetString(driveFlag), + mt, viper.GetInt(recordSizeFlag), false, ) @@ -75,6 +78,8 @@ var operationRestoreCmd = &cobra.Command{ GetReader: tm.GetReader, CloseReader: tm.Close, + + MagneticTapeIO: mt, }, config.MetadataConfig{ Metadata: metadataPersister, diff --git a/cmd/stfs/cmd/operation_update.go b/cmd/stfs/cmd/operation_update.go index 6c971a6..723b6c5 100644 --- a/cmd/stfs/cmd/operation_update.go +++ b/cmd/stfs/cmd/operation_update.go @@ -12,6 +12,7 @@ import ( "github.com/pojntfx/stfs/internal/logging" "github.com/pojntfx/stfs/pkg/config" "github.com/pojntfx/stfs/pkg/keys" + "github.com/pojntfx/stfs/pkg/mtio" "github.com/pojntfx/stfs/pkg/operations" "github.com/pojntfx/stfs/pkg/persisters" "github.com/pojntfx/stfs/pkg/tape" @@ -59,8 +60,10 @@ var operationUpdateCmd = &cobra.Command{ return err } + mt := mtio.MagneticTapeIO{} tm := tape.NewTapeManager( viper.GetString(driveFlag), + mt, viper.GetInt(recordSizeFlag), false, ) @@ -77,6 +80,8 @@ var operationUpdateCmd = &cobra.Command{ GetReader: tm.GetReader, CloseReader: tm.Close, + + MagneticTapeIO: mt, }, config.MetadataConfig{ Metadata: metadataPersister, diff --git a/cmd/stfs/cmd/recovery_fetch.go b/cmd/stfs/cmd/recovery_fetch.go index 3a3ef95..29a00f0 100644 --- a/cmd/stfs/cmd/recovery_fetch.go +++ b/cmd/stfs/cmd/recovery_fetch.go @@ -10,6 +10,7 @@ import ( "github.com/pojntfx/stfs/internal/logging" "github.com/pojntfx/stfs/pkg/config" "github.com/pojntfx/stfs/pkg/keys" + "github.com/pojntfx/stfs/pkg/mtio" "github.com/pojntfx/stfs/pkg/recovery" "github.com/pojntfx/stfs/pkg/tape" "github.com/spf13/cobra" @@ -71,6 +72,7 @@ var recoveryFetchCmd = &cobra.Command{ Drive: reader, DriveIsRegular: readerIsRegular, }, + mtio.MagneticTapeIO{}, config.PipeConfig{ Compression: viper.GetString(compressionFlag), Encryption: viper.GetString(encryptionFlag), diff --git a/cmd/stfs/cmd/recovery_index.go b/cmd/stfs/cmd/recovery_index.go index ea23961..618de0d 100644 --- a/cmd/stfs/cmd/recovery_index.go +++ b/cmd/stfs/cmd/recovery_index.go @@ -9,6 +9,7 @@ import ( "github.com/pojntfx/stfs/pkg/config" "github.com/pojntfx/stfs/pkg/encryption" "github.com/pojntfx/stfs/pkg/keys" + "github.com/pojntfx/stfs/pkg/mtio" "github.com/pojntfx/stfs/pkg/persisters" "github.com/pojntfx/stfs/pkg/recovery" "github.com/pojntfx/stfs/pkg/signature" @@ -70,6 +71,7 @@ var recoveryIndexCmd = &cobra.Command{ Drive: reader, DriveIsRegular: readerIsRegular, }, + mtio.MagneticTapeIO{}, config.MetadataConfig{ Metadata: metadataPersister, }, diff --git a/cmd/stfs/cmd/recovery_query.go b/cmd/stfs/cmd/recovery_query.go index 38ed275..e892c08 100644 --- a/cmd/stfs/cmd/recovery_query.go +++ b/cmd/stfs/cmd/recovery_query.go @@ -6,6 +6,7 @@ import ( "github.com/pojntfx/stfs/internal/logging" "github.com/pojntfx/stfs/pkg/config" "github.com/pojntfx/stfs/pkg/keys" + "github.com/pojntfx/stfs/pkg/mtio" "github.com/pojntfx/stfs/pkg/recovery" "github.com/pojntfx/stfs/pkg/tape" "github.com/spf13/cobra" @@ -60,6 +61,7 @@ var recoveryQueryCmd = &cobra.Command{ Drive: reader, DriveIsRegular: readerIsRegular, }, + mtio.MagneticTapeIO{}, config.PipeConfig{ Compression: viper.GetString(compressionFlag), Encryption: viper.GetString(encryptionFlag), diff --git a/cmd/stfs/cmd/serve_ftp.go b/cmd/stfs/cmd/serve_ftp.go index f3182be..b9e1180 100644 --- a/cmd/stfs/cmd/serve_ftp.go +++ b/cmd/stfs/cmd/serve_ftp.go @@ -15,6 +15,7 @@ import ( "github.com/pojntfx/stfs/pkg/config" "github.com/pojntfx/stfs/pkg/fs" "github.com/pojntfx/stfs/pkg/keys" + "github.com/pojntfx/stfs/pkg/mtio" "github.com/pojntfx/stfs/pkg/operations" "github.com/pojntfx/stfs/pkg/persisters" "github.com/pojntfx/stfs/pkg/tape" @@ -111,8 +112,10 @@ var serveFTPCmd = &cobra.Command{ return err } + mt := mtio.MagneticTapeIO{} tm := tape.NewTapeManager( viper.GetString(driveFlag), + mt, viper.GetInt(recordSizeFlag), false, ) @@ -139,6 +142,8 @@ var serveFTPCmd = &cobra.Command{ GetReader: tm.GetReader, CloseReader: tm.Close, + + MagneticTapeIO: mt, } readCryptoConfig := config.CryptoConfig{ Recipient: signatureRecipient, diff --git a/cmd/stfs/cmd/serve_http.go b/cmd/stfs/cmd/serve_http.go index af71b14..41677c2 100644 --- a/cmd/stfs/cmd/serve_http.go +++ b/cmd/stfs/cmd/serve_http.go @@ -15,6 +15,7 @@ import ( "github.com/pojntfx/stfs/pkg/config" "github.com/pojntfx/stfs/pkg/fs" "github.com/pojntfx/stfs/pkg/keys" + "github.com/pojntfx/stfs/pkg/mtio" "github.com/pojntfx/stfs/pkg/operations" "github.com/pojntfx/stfs/pkg/persisters" "github.com/pojntfx/stfs/pkg/tape" @@ -70,8 +71,10 @@ var serveHTTPCmd = &cobra.Command{ return err } + mt := mtio.MagneticTapeIO{} tm := tape.NewTapeManager( viper.GetString(driveFlag), + mt, viper.GetInt(recordSizeFlag), false, ) @@ -95,6 +98,8 @@ var serveHTTPCmd = &cobra.Command{ GetReader: tm.GetReader, CloseReader: tm.Close, + + MagneticTapeIO: mt, }, config.MetadataConfig{ Metadata: metadataPersister, diff --git a/examples/full/main.go b/examples/full/main.go index 7422780..4f27f94 100644 --- a/examples/full/main.go +++ b/examples/full/main.go @@ -11,6 +11,7 @@ import ( "github.com/pojntfx/stfs/pkg/config" "github.com/pojntfx/stfs/pkg/fs" "github.com/pojntfx/stfs/pkg/keys" + "github.com/pojntfx/stfs/pkg/mtio" "github.com/pojntfx/stfs/pkg/operations" "github.com/pojntfx/stfs/pkg/persisters" "github.com/pojntfx/stfs/pkg/tape" @@ -88,8 +89,10 @@ func createFs( return nil, err } + mt := mtio.MagneticTapeIO{} tm := tape.NewTapeManager( drive, + mt, recordSize, false, ) @@ -118,6 +121,8 @@ func createFs( GetReader: tm.GetReader, CloseReader: tm.Close, + + MagneticTapeIO: mt, } readCryptoConfig := config.CryptoConfig{ Recipient: signatureRecipient, diff --git a/examples/simple/main.go b/examples/simple/main.go index 1e00d6e..e9271a9 100644 --- a/examples/simple/main.go +++ b/examples/simple/main.go @@ -10,6 +10,7 @@ import ( "github.com/pojntfx/stfs/pkg/cache" "github.com/pojntfx/stfs/pkg/config" "github.com/pojntfx/stfs/pkg/fs" + "github.com/pojntfx/stfs/pkg/mtio" "github.com/pojntfx/stfs/pkg/operations" "github.com/pojntfx/stfs/pkg/persisters" "github.com/pojntfx/stfs/pkg/tape" @@ -24,8 +25,10 @@ func main() { flag.Parse() + mt := mtio.MagneticTapeIO{} tm := tape.NewTapeManager( *driveFlag, + mt, *recordSizeFlag, false, ) @@ -54,6 +57,8 @@ func main() { GetReader: tm.GetReader, CloseReader: tm.Close, + + MagneticTapeIO: mt, } readCryptoConfig := config.CryptoConfig{} diff --git a/internal/mtio/constants.go b/internal/mtio/constants.go deleted file mode 100644 index 0b4b51d..0000000 --- a/internal/mtio/constants.go +++ /dev/null @@ -1,5 +0,0 @@ -package mtio - -const ( - BlockSize = 512 -) diff --git a/internal/mtio/mtio_stub.go b/internal/mtio/mtio_stub.go deleted file mode 100644 index 170f9f3..0000000 --- a/internal/mtio/mtio_stub.go +++ /dev/null @@ -1,27 +0,0 @@ -//go:build !linux - -package mtio - -import ( - "github.com/pojntfx/stfs/pkg/config" -) - -func GetCurrentRecordFromTape(fd uintptr) (int64, error) { - return -1, config.ErrTapeDrivesUnsupported -} - -func GoToEndOfTape(fd uintptr) error { - return config.ErrTapeDrivesUnsupported -} - -func GoToNextFileOnTape(fd uintptr) error { - return config.ErrTapeDrivesUnsupported -} - -func EjectTape(fd uintptr) error { - return config.ErrTapeDrivesUnsupported -} - -func SeekToRecordOnTape(fd uintptr, record int32) error { - return config.ErrTapeDrivesUnsupported -} diff --git a/internal/tarext/write.go b/internal/tarext/write.go index d6adfba..af6a251 100644 --- a/internal/tarext/write.go +++ b/internal/tarext/write.go @@ -6,7 +6,7 @@ import ( "io" "github.com/pojntfx/stfs/internal/ioext" - "github.com/pojntfx/stfs/internal/mtio" + "github.com/pojntfx/stfs/pkg/config" ) func NewTapeWriter(f io.Writer, isRegular bool, recordSize int) (tw *tar.Writer, cleanup func(dirty *bool) error, err error) { @@ -15,7 +15,7 @@ func NewTapeWriter(f io.Writer, isRegular bool, recordSize int) (tw *tar.Writer, if isRegular { tw = tar.NewWriter(f) } else { - bw = bufio.NewWriterSize(f, mtio.BlockSize*recordSize) + bw = bufio.NewWriterSize(f, config.MagneticTapeBlockSize*recordSize) counter = &ioext.CounterWriter{Writer: bw, BytesRead: 0} tw = tar.NewWriter(counter) } @@ -28,9 +28,9 @@ func NewTapeWriter(f io.Writer, isRegular bool, recordSize int) (tw *tar.Writer, } if !isRegular { - if mtio.BlockSize*recordSize-counter.BytesRead > 0 { + if config.MagneticTapeBlockSize*recordSize-counter.BytesRead > 0 { // Fill the rest of the record with zeros - if _, err := bw.Write(make([]byte, mtio.BlockSize*recordSize-counter.BytesRead)); err != nil { + if _, err := bw.Write(make([]byte, config.MagneticTapeBlockSize*recordSize-counter.BytesRead)); err != nil { return err } } diff --git a/pkg/compression/compress.go b/pkg/compression/compress.go index 04b0e87..d636ecf 100644 --- a/pkg/compression/compress.go +++ b/pkg/compression/compress.go @@ -11,7 +11,6 @@ import ( "github.com/klauspost/pgzip" "github.com/pierrec/lz4/v4" "github.com/pojntfx/stfs/internal/ioext" - "github.com/pojntfx/stfs/internal/mtio" "github.com/pojntfx/stfs/pkg/config" ) @@ -28,7 +27,7 @@ func Compress( case config.CompressionFormatParallelGZipKey: if compressionFormat == config.CompressionFormatGZipKey { if !isRegular { - maxSize := getNearestPowerOf2Lower(mtio.BlockSize * recordSize) + maxSize := getNearestPowerOf2Lower(config.MagneticTapeBlockSize * recordSize) if maxSize < 65535 { // See https://www.daylight.com/meetings/mug00/Sayle/gzip.html#:~:text=Stored%20blocks%20are%20allowed%20to,size%20of%20the%20gzip%20header. return nil, config.ErrCompressionFormatRequiresLargerRecordSize @@ -82,7 +81,7 @@ func Compress( opts := []lz4.Option{lz4.CompressionLevelOption(l), lz4.ConcurrencyOption(-1)} if !isRegular { - maxSize := getNearestPowerOf2Lower(mtio.BlockSize * recordSize) + maxSize := getNearestPowerOf2Lower(config.MagneticTapeBlockSize * recordSize) if uint32(maxSize) < uint32(lz4.Block64Kb) { return nil, config.ErrCompressionFormatRequiresLargerRecordSize @@ -120,7 +119,7 @@ func Compress( opts := []zstd.EOption{zstd.WithEncoderLevel(l)} if !isRegular { - opts = append(opts, zstd.WithWindowSize(getNearestPowerOf2Lower(mtio.BlockSize*recordSize))) + opts = append(opts, zstd.WithWindowSize(getNearestPowerOf2Lower(config.MagneticTapeBlockSize*recordSize))) } zz, err := zstd.NewWriter(dst, opts...) diff --git a/pkg/config/config.go b/pkg/config/config.go index e590baf..dd17433 100644 --- a/pkg/config/config.go +++ b/pkg/config/config.go @@ -28,6 +28,8 @@ type BackendConfig struct { GetReader func() (DriveReaderConfig, error) CloseReader func() error + + MagneticTapeIO MagneticTapeIO } type Header struct { @@ -96,3 +98,11 @@ type FileConfig struct { Path string Link string } + +type MagneticTapeIO interface { + GetCurrentRecordFromTape(fd uintptr) (int64, error) + GoToEndOfTape(fd uintptr) error + GoToNextFileOnTape(fd uintptr) error + EjectTape(fd uintptr) error + SeekToRecordOnTape(fd uintptr, record int32) error +} diff --git a/pkg/config/constants.go b/pkg/config/constants.go index 436b98c..99f6e04 100644 --- a/pkg/config/constants.go +++ b/pkg/config/constants.go @@ -34,6 +34,8 @@ const ( WriteCacheTypeMemory = "memory" WriteCacheTypeFile = "file" + + MagneticTapeBlockSize = 512 ) var ( diff --git a/pkg/fs/filesystem.go b/pkg/fs/filesystem.go index d4a533d..1016d44 100644 --- a/pkg/fs/filesystem.go +++ b/pkg/fs/filesystem.go @@ -241,6 +241,7 @@ func (f *STFS) Initialize(rootProposal string, rootPerm os.FileMode) (root strin if err := recovery.Index( reader, + f.readOps.GetBackend().MagneticTapeIO, f.readOps.GetMetadata(), f.readOps.GetPipes(), f.readOps.GetCrypto(), diff --git a/pkg/fs/filesystem_test.go b/pkg/fs/filesystem_test.go index bcfdaf9..4ffd3b6 100644 --- a/pkg/fs/filesystem_test.go +++ b/pkg/fs/filesystem_test.go @@ -21,6 +21,7 @@ import ( "github.com/pojntfx/stfs/pkg/cache" "github.com/pojntfx/stfs/pkg/config" "github.com/pojntfx/stfs/pkg/keys" + "github.com/pojntfx/stfs/pkg/mtio" "github.com/pojntfx/stfs/pkg/operations" "github.com/pojntfx/stfs/pkg/persisters" "github.com/pojntfx/stfs/pkg/tape" @@ -339,8 +340,10 @@ func createSTFS( initialize bool, ) (afero.Fs, error) { + mt := mtio.MagneticTapeIO{} tm := tape.NewTapeManager( drive, + mt, recordSize, false, ) @@ -369,6 +372,8 @@ func createSTFS( GetReader: tm.GetReader, CloseReader: tm.Close, + + MagneticTapeIO: mt, } readCryptoConfig := config.CryptoConfig{ Recipient: signatureRecipient, diff --git a/pkg/hardware/eject.go b/pkg/hardware/eject.go index 095f6de..18d46b6 100644 --- a/pkg/hardware/eject.go +++ b/pkg/hardware/eject.go @@ -1,9 +1,7 @@ package hardware -import ( - "github.com/pojntfx/stfs/internal/mtio" -) +import "github.com/pojntfx/stfs/pkg/config" -func Eject(fd uintptr) error { - return mtio.EjectTape(fd) +func Eject(mt config.MagneticTapeIO, fd uintptr) error { + return mt.EjectTape(fd) } diff --git a/pkg/hardware/tell.go b/pkg/hardware/tell.go index 6b42ce8..a5b8ad3 100644 --- a/pkg/hardware/tell.go +++ b/pkg/hardware/tell.go @@ -1,9 +1,7 @@ package hardware -import ( - "github.com/pojntfx/stfs/internal/mtio" -) +import "github.com/pojntfx/stfs/pkg/config" -func Tell(fd uintptr) (int64, error) { - return mtio.GetCurrentRecordFromTape(fd) +func Tell(mt config.MagneticTapeIO, fd uintptr) (int64, error) { + return mt.GetCurrentRecordFromTape(fd) } diff --git a/internal/mtio/mtio_linux.go b/pkg/mtio/mtio_linux.go similarity index 82% rename from internal/mtio/mtio_linux.go rename to pkg/mtio/mtio_linux.go index bceac16..3230170 100644 --- a/internal/mtio/mtio_linux.go +++ b/pkg/mtio/mtio_linux.go @@ -30,7 +30,9 @@ type operation struct { count int32 // Operation count } -func GetCurrentRecordFromTape(fd uintptr) (int64, error) { +type MagneticTapeIO struct{} + +func (t MagneticTapeIO) GetCurrentRecordFromTape(fd uintptr) (int64, error) { pos := &position{} if _, _, err := syscall.Syscall( syscall.SYS_IOCTL, @@ -44,7 +46,7 @@ func GetCurrentRecordFromTape(fd uintptr) (int64, error) { return pos.blkNo, nil } -func GoToEndOfTape(fd uintptr) error { +func (t MagneticTapeIO) GoToEndOfTape(fd uintptr) error { if _, _, err := syscall.Syscall( syscall.SYS_IOCTL, fd, @@ -61,7 +63,7 @@ func GoToEndOfTape(fd uintptr) error { return nil } -func GoToNextFileOnTape(fd uintptr) error { +func (t MagneticTapeIO) GoToNextFileOnTape(fd uintptr) error { if _, _, err := syscall.Syscall( syscall.SYS_IOCTL, fd, @@ -79,7 +81,7 @@ func GoToNextFileOnTape(fd uintptr) error { return nil } -func EjectTape(fd uintptr) error { +func (t MagneticTapeIO) EjectTape(fd uintptr) error { if _, _, err := syscall.Syscall( syscall.SYS_IOCTL, fd, @@ -96,7 +98,7 @@ func EjectTape(fd uintptr) error { return nil } -func SeekToRecordOnTape(fd uintptr, record int32) error { +func (t MagneticTapeIO) SeekToRecordOnTape(fd uintptr, record int32) error { if _, _, err := syscall.Syscall( syscall.SYS_IOCTL, fd, diff --git a/pkg/mtio/mtio_stub.go b/pkg/mtio/mtio_stub.go new file mode 100644 index 0000000..c03412a --- /dev/null +++ b/pkg/mtio/mtio_stub.go @@ -0,0 +1,29 @@ +//go:build !linux + +package mtio + +import ( + "github.com/pojntfx/stfs/pkg/config" +) + +type MagneticTapeIO struct{} + +func (t MagneticTapeIO) GetCurrentRecordFromTape(fd uintptr) (int64, error) { + return -1, config.ErrTapeDrivesUnsupported +} + +func (t MagneticTapeIO) GoToEndOfTape(fd uintptr) error { + return config.ErrTapeDrivesUnsupported +} + +func (t MagneticTapeIO) GoToNextFileOnTape(fd uintptr) error { + return config.ErrTapeDrivesUnsupported +} + +func (t MagneticTapeIO) EjectTape(fd uintptr) error { + return config.ErrTapeDrivesUnsupported +} + +func (t MagneticTapeIO) SeekToRecordOnTape(fd uintptr, record int32) error { + return config.ErrTapeDrivesUnsupported +} diff --git a/pkg/operations/archive.go b/pkg/operations/archive.go index 4e8ef5e..3505347 100644 --- a/pkg/operations/archive.go +++ b/pkg/operations/archive.go @@ -10,7 +10,6 @@ import ( "github.com/pojntfx/stfs/internal/converters" "github.com/pojntfx/stfs/internal/ioext" - "github.com/pojntfx/stfs/internal/mtio" "github.com/pojntfx/stfs/internal/records" "github.com/pojntfx/stfs/internal/suffix" "github.com/pojntfx/stfs/internal/tarext" @@ -116,7 +115,7 @@ func (o *Operations) Archive( return []*tar.Header{}, err } } else { - buf := make([]byte, mtio.BlockSize*o.pipes.RecordSize) + buf := make([]byte, config.MagneticTapeBlockSize*o.pipes.RecordSize) if _, err := io.CopyBuffer(compressor, signer, buf); err != nil { return []*tar.Header{}, err } @@ -220,7 +219,7 @@ func (o *Operations) Archive( return []*tar.Header{}, err } } else { - buf := make([]byte, mtio.BlockSize*o.pipes.RecordSize) + buf := make([]byte, config.MagneticTapeBlockSize*o.pipes.RecordSize) if _, err := io.CopyBuffer(compressor, f, buf); err != nil { return []*tar.Header{}, err } @@ -264,6 +263,7 @@ func (o *Operations) Archive( return hdrs, recovery.Index( reader, + o.backend.MagneticTapeIO, o.metadata, o.pipes, o.crypto, diff --git a/pkg/operations/delete.go b/pkg/operations/delete.go index f5602f6..f7c9eb5 100644 --- a/pkg/operations/delete.go +++ b/pkg/operations/delete.go @@ -111,6 +111,7 @@ func (o *Operations) Delete(name string) error { return recovery.Index( reader, + o.backend.MagneticTapeIO, o.metadata, o.pipes, o.crypto, diff --git a/pkg/operations/move.go b/pkg/operations/move.go index 2758910..4c6b73b 100644 --- a/pkg/operations/move.go +++ b/pkg/operations/move.go @@ -130,6 +130,7 @@ func (o *Operations) Move(from string, to string) error { return recovery.Index( reader, + o.backend.MagneticTapeIO, o.metadata, o.pipes, o.crypto, diff --git a/pkg/operations/restore.go b/pkg/operations/restore.go index adc68da..65c8ebd 100644 --- a/pkg/operations/restore.go +++ b/pkg/operations/restore.go @@ -84,6 +84,7 @@ func (o *Operations) Restore( if err := recovery.Fetch( reader, + o.backend.MagneticTapeIO, o.pipes, o.crypto, diff --git a/pkg/operations/update.go b/pkg/operations/update.go index f759b57..dd51257 100644 --- a/pkg/operations/update.go +++ b/pkg/operations/update.go @@ -9,7 +9,6 @@ import ( "github.com/pojntfx/stfs/internal/converters" "github.com/pojntfx/stfs/internal/ioext" - "github.com/pojntfx/stfs/internal/mtio" "github.com/pojntfx/stfs/internal/records" "github.com/pojntfx/stfs/internal/suffix" "github.com/pojntfx/stfs/internal/tarext" @@ -112,7 +111,7 @@ func (o *Operations) Update( return []*tar.Header{}, err } } else { - buf := make([]byte, mtio.BlockSize*o.pipes.RecordSize) + buf := make([]byte, config.MagneticTapeBlockSize*o.pipes.RecordSize) if _, err := io.CopyBuffer(compressor, signer, buf); err != nil { return []*tar.Header{}, err } @@ -219,7 +218,7 @@ func (o *Operations) Update( return []*tar.Header{}, err } } else { - buf := make([]byte, mtio.BlockSize*o.pipes.RecordSize) + buf := make([]byte, config.MagneticTapeBlockSize*o.pipes.RecordSize) if _, err := io.CopyBuffer(compressor, f, buf); err != nil { return []*tar.Header{}, err } @@ -291,6 +290,7 @@ func (o *Operations) Update( return hdrs, recovery.Index( reader, + o.backend.MagneticTapeIO, o.metadata, o.pipes, o.crypto, diff --git a/pkg/recovery/fetch.go b/pkg/recovery/fetch.go index 3f2749a..1ae1c15 100644 --- a/pkg/recovery/fetch.go +++ b/pkg/recovery/fetch.go @@ -9,7 +9,6 @@ import ( "path/filepath" "github.com/pojntfx/stfs/internal/converters" - "github.com/pojntfx/stfs/internal/mtio" "github.com/pojntfx/stfs/internal/records" "github.com/pojntfx/stfs/pkg/compression" "github.com/pojntfx/stfs/pkg/config" @@ -19,6 +18,7 @@ import ( func Fetch( reader config.DriveReaderConfig, + mt config.MagneticTapeIO, pipes config.PipeConfig, crypto config.CryptoConfig, @@ -37,20 +37,20 @@ func Fetch( var tr *tar.Reader if reader.DriveIsRegular { // Seek to record and block - if _, err := reader.Drive.Seek(int64((pipes.RecordSize*mtio.BlockSize*record)+block*mtio.BlockSize), io.SeekStart); err != nil { + if _, err := reader.Drive.Seek(int64((pipes.RecordSize*config.MagneticTapeBlockSize*record)+block*config.MagneticTapeBlockSize), io.SeekStart); err != nil { return err } tr = tar.NewReader(reader.Drive) } else { // Seek to record - if err := mtio.SeekToRecordOnTape(reader.Drive.Fd(), int32(record)); err != nil { + if err := mt.SeekToRecordOnTape(reader.Drive.Fd(), int32(record)); err != nil { return err } // Seek to block - br := bufio.NewReaderSize(reader.Drive, mtio.BlockSize*pipes.RecordSize) - if _, err := br.Read(make([]byte, block*mtio.BlockSize)); err != nil { + br := bufio.NewReaderSize(reader.Drive, config.MagneticTapeBlockSize*pipes.RecordSize) + if _, err := br.Read(make([]byte, block*config.MagneticTapeBlockSize)); err != nil { return err } diff --git a/pkg/recovery/index.go b/pkg/recovery/index.go index e577b5c..351384e 100644 --- a/pkg/recovery/index.go +++ b/pkg/recovery/index.go @@ -13,7 +13,6 @@ import ( "github.com/pojntfx/stfs/internal/converters" models "github.com/pojntfx/stfs/internal/db/sqlite/models/metadata" "github.com/pojntfx/stfs/internal/ioext" - "github.com/pojntfx/stfs/internal/mtio" "github.com/pojntfx/stfs/internal/records" "github.com/pojntfx/stfs/internal/suffix" "github.com/pojntfx/stfs/pkg/config" @@ -21,6 +20,7 @@ import ( func Index( reader config.DriveReaderConfig, + mt config.MagneticTapeIO, metadata config.MetadataConfig, pipes config.PipeConfig, crypto config.CryptoConfig, @@ -50,7 +50,7 @@ func Index( if reader.DriveIsRegular { // Seek to record and block - if _, err := reader.Drive.Seek(int64((pipes.RecordSize*mtio.BlockSize*record)+block*mtio.BlockSize), 0); err != nil { + if _, err := reader.Drive.Seek(int64((pipes.RecordSize*config.MagneticTapeBlockSize*record)+block*config.MagneticTapeBlockSize), 0); err != nil { return err } @@ -69,7 +69,7 @@ func Index( return err } - nextTotalBlocks := math.Ceil(float64((curr)) / float64(mtio.BlockSize)) + nextTotalBlocks := math.Ceil(float64((curr)) / float64(config.MagneticTapeBlockSize)) record = int64(nextTotalBlocks) / int64(pipes.RecordSize) block = int64(nextTotalBlocks) - (record * int64(pipes.RecordSize)) @@ -82,7 +82,7 @@ func Index( } // Seek to record and block - if _, err := reader.Drive.Seek(int64((pipes.RecordSize*mtio.BlockSize*int(record))+int(block)*mtio.BlockSize), io.SeekStart); err != nil { + if _, err := reader.Drive.Seek(int64((pipes.RecordSize*config.MagneticTapeBlockSize*int(record))+int(block)*config.MagneticTapeBlockSize), io.SeekStart); err != nil { return err } @@ -136,7 +136,7 @@ func Index( return err } - nextTotalBlocks := math.Ceil(float64(curr+(currAndSize-curr)) / float64(mtio.BlockSize)) + nextTotalBlocks := math.Ceil(float64(curr+(currAndSize-curr)) / float64(config.MagneticTapeBlockSize)) record = int64(nextTotalBlocks) / int64(pipes.RecordSize) block = int64(nextTotalBlocks) - (record * int64(pipes.RecordSize)) @@ -149,20 +149,20 @@ func Index( } } else { // Seek to record - if err := mtio.SeekToRecordOnTape(reader.Drive.Fd(), int32(record)); err != nil { + if err := mt.SeekToRecordOnTape(reader.Drive.Fd(), int32(record)); err != nil { return err } // Seek to block - br := bufio.NewReaderSize(reader.Drive, mtio.BlockSize*pipes.RecordSize) - if _, err := br.Read(make([]byte, block*mtio.BlockSize)); err != nil { + br := bufio.NewReaderSize(reader.Drive, config.MagneticTapeBlockSize*pipes.RecordSize) + if _, err := br.Read(make([]byte, block*config.MagneticTapeBlockSize)); err != nil { return err } record := int64(record) block := int64(block) - curr := int64((pipes.RecordSize * mtio.BlockSize * int(record)) + (int(block) * mtio.BlockSize)) + curr := int64((pipes.RecordSize * config.MagneticTapeBlockSize * int(record)) + (int(block) * config.MagneticTapeBlockSize)) counter := &ioext.CounterReader{Reader: br, BytesRead: int(curr)} i := 0 @@ -171,20 +171,20 @@ func Index( hdr, err := tr.Next() if err != nil { if err == io.EOF { - if err := mtio.GoToNextFileOnTape(reader.Drive.Fd()); err != nil { + if err := mt.GoToNextFileOnTape(reader.Drive.Fd()); err != nil { // EOD break } - record, err = mtio.GetCurrentRecordFromTape(reader.Drive.Fd()) + record, err = mt.GetCurrentRecordFromTape(reader.Drive.Fd()) if err != nil { return err } block = 0 - br = bufio.NewReaderSize(reader.Drive, mtio.BlockSize*pipes.RecordSize) - curr = int64(int64(pipes.RecordSize) * mtio.BlockSize * record) + br = bufio.NewReaderSize(reader.Drive, config.MagneticTapeBlockSize*pipes.RecordSize) + curr = int64(int64(pipes.RecordSize) * config.MagneticTapeBlockSize * record) counter = &ioext.CounterReader{Reader: br, BytesRead: int(curr)} tr = tar.NewReader(counter) @@ -216,7 +216,7 @@ func Index( currAndSize := int64(counter.BytesRead) - nextTotalBlocks := math.Ceil(float64(curr+(currAndSize-curr)) / float64(mtio.BlockSize)) + nextTotalBlocks := math.Ceil(float64(curr+(currAndSize-curr)) / float64(config.MagneticTapeBlockSize)) record = int64(nextTotalBlocks) / int64(pipes.RecordSize) block = int64(nextTotalBlocks) - (record * int64(pipes.RecordSize)) diff --git a/pkg/recovery/query.go b/pkg/recovery/query.go index c717d5a..f2c1b02 100644 --- a/pkg/recovery/query.go +++ b/pkg/recovery/query.go @@ -9,7 +9,6 @@ import ( "github.com/pojntfx/stfs/internal/converters" "github.com/pojntfx/stfs/internal/ioext" - "github.com/pojntfx/stfs/internal/mtio" "github.com/pojntfx/stfs/pkg/config" "github.com/pojntfx/stfs/pkg/encryption" "github.com/pojntfx/stfs/pkg/signature" @@ -17,6 +16,7 @@ import ( func Query( reader config.DriveReaderConfig, + mt config.MagneticTapeIO, pipes config.PipeConfig, crypto config.CryptoConfig, @@ -29,7 +29,7 @@ func Query( if reader.DriveIsRegular { // Seek to record and block - if _, err := reader.Drive.Seek(int64((pipes.RecordSize*mtio.BlockSize*record)+block*mtio.BlockSize), 0); err != nil { + if _, err := reader.Drive.Seek(int64((pipes.RecordSize*config.MagneticTapeBlockSize*record)+block*config.MagneticTapeBlockSize), 0); err != nil { return []*tar.Header{}, err } @@ -47,7 +47,7 @@ func Query( return []*tar.Header{}, err } - nextTotalBlocks := math.Ceil(float64((curr)) / float64(mtio.BlockSize)) + nextTotalBlocks := math.Ceil(float64((curr)) / float64(config.MagneticTapeBlockSize)) record = int64(nextTotalBlocks) / int64(pipes.RecordSize) block = int64(nextTotalBlocks) - (record * int64(pipes.RecordSize)) @@ -60,7 +60,7 @@ func Query( } // Seek to record and block - if _, err := reader.Drive.Seek(int64((pipes.RecordSize*mtio.BlockSize*int(record))+int(block)*mtio.BlockSize), io.SeekStart); err != nil { + if _, err := reader.Drive.Seek(int64((pipes.RecordSize*config.MagneticTapeBlockSize*int(record))+int(block)*config.MagneticTapeBlockSize), io.SeekStart); err != nil { return []*tar.Header{}, err } @@ -120,7 +120,7 @@ func Query( return []*tar.Header{}, err } - nextTotalBlocks := math.Ceil(float64(curr+(currAndSize-curr)) / float64(mtio.BlockSize)) + nextTotalBlocks := math.Ceil(float64(curr+(currAndSize-curr)) / float64(config.MagneticTapeBlockSize)) record = int64(nextTotalBlocks) / int64(pipes.RecordSize) block = int64(nextTotalBlocks) - (record * int64(pipes.RecordSize)) @@ -131,20 +131,20 @@ func Query( } } else { // Seek to record - if err := mtio.SeekToRecordOnTape(reader.Drive.Fd(), int32(record)); err != nil { + if err := mt.SeekToRecordOnTape(reader.Drive.Fd(), int32(record)); err != nil { return []*tar.Header{}, err } // Seek to block - br := bufio.NewReaderSize(reader.Drive, mtio.BlockSize*pipes.RecordSize) - if _, err := br.Read(make([]byte, block*mtio.BlockSize)); err != nil { + br := bufio.NewReaderSize(reader.Drive, config.MagneticTapeBlockSize*pipes.RecordSize) + if _, err := br.Read(make([]byte, block*config.MagneticTapeBlockSize)); err != nil { return []*tar.Header{}, err } record := int64(record) block := int64(block) - curr := int64((pipes.RecordSize * mtio.BlockSize * int(record)) + (int(block) * mtio.BlockSize)) + curr := int64((pipes.RecordSize * config.MagneticTapeBlockSize * int(record)) + (int(block) * config.MagneticTapeBlockSize)) counter := &ioext.CounterReader{Reader: br, BytesRead: int(curr)} tr := tar.NewReader(counter) @@ -152,20 +152,20 @@ func Query( hdr, err := tr.Next() if err != nil { if err == io.EOF { - if err := mtio.GoToNextFileOnTape(reader.Drive.Fd()); err != nil { + if err := mt.GoToNextFileOnTape(reader.Drive.Fd()); err != nil { // EOD break } - record, err = mtio.GetCurrentRecordFromTape(reader.Drive.Fd()) + record, err = mt.GetCurrentRecordFromTape(reader.Drive.Fd()) if err != nil { return []*tar.Header{}, err } block = 0 - br = bufio.NewReaderSize(reader.Drive, mtio.BlockSize*pipes.RecordSize) - curr := int64(int64(pipes.RecordSize) * mtio.BlockSize * record) + br = bufio.NewReaderSize(reader.Drive, config.MagneticTapeBlockSize*pipes.RecordSize) + curr := int64(int64(pipes.RecordSize) * config.MagneticTapeBlockSize * record) counter := &ioext.CounterReader{Reader: br, BytesRead: int(curr)} tr = tar.NewReader(counter) @@ -200,7 +200,7 @@ func Query( currAndSize := int64(counter.BytesRead) - nextTotalBlocks := math.Ceil(float64(curr+(currAndSize-curr)) / float64(mtio.BlockSize)) + nextTotalBlocks := math.Ceil(float64(curr+(currAndSize-curr)) / float64(config.MagneticTapeBlockSize)) record = int64(nextTotalBlocks) / int64(pipes.RecordSize) block = int64(nextTotalBlocks) - (record * int64(pipes.RecordSize)) diff --git a/pkg/tape/manager.go b/pkg/tape/manager.go index 53c44db..eb60314 100644 --- a/pkg/tape/manager.go +++ b/pkg/tape/manager.go @@ -10,6 +10,7 @@ import ( type TapeManager struct { drive string + mt config.MagneticTapeIO recordSize int overwrite bool @@ -26,11 +27,13 @@ type TapeManager struct { func NewTapeManager( drive string, + mt config.MagneticTapeIO, recordSize int, overwrite bool, ) *TapeManager { return &TapeManager{ drive: drive, + mt: mt, recordSize: recordSize, overwrite: overwrite, } @@ -47,6 +50,7 @@ func (m *TapeManager) GetWriter() (config.DriveWriterConfig, error) { writer, writerIsRegular, err := OpenTapeWriteOnly( m.drive, + m.mt, m.recordSize, overwrite, ) diff --git a/pkg/tape/write.go b/pkg/tape/write.go index a3e3bfe..0fd031e 100644 --- a/pkg/tape/write.go +++ b/pkg/tape/write.go @@ -3,10 +3,15 @@ package tape import ( "os" - "github.com/pojntfx/stfs/internal/mtio" + "github.com/pojntfx/stfs/pkg/config" ) -func OpenTapeWriteOnly(drive string, recordSize int, overwrite bool) (f *os.File, isRegular bool, err error) { +func OpenTapeWriteOnly( + drive string, + mt config.MagneticTapeIO, + recordSize int, + overwrite bool, +) (f *os.File, isRegular bool, err error) { stat, err := os.Stat(drive) if err == nil { isRegular = stat.Mode().IsRegular() @@ -40,7 +45,7 @@ func OpenTapeWriteOnly(drive string, recordSize int, overwrite bool) (f *os.File } // Seek to the start of the tape - if err := mtio.SeekToRecordOnTape(f.Fd(), 0); err != nil { + if err := mt.SeekToRecordOnTape(f.Fd(), 0); err != nil { return nil, false, err } @@ -65,7 +70,7 @@ func OpenTapeWriteOnly(drive string, recordSize int, overwrite bool) (f *os.File if !overwrite { // Go to end of tape - if err := mtio.GoToEndOfTape(f.Fd()); err != nil { + if err := mt.GoToEndOfTape(f.Fd()); err != nil { return nil, false, err } }