refactor: Inject mtio package to allow for remote implementation

This commit is contained in:
Felix Pojtinger
2022-01-16 23:50:47 +01:00
parent 5bb79b6d9e
commit 25cacd34d8
36 changed files with 183 additions and 100 deletions

View File

@@ -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...)

View File

@@ -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
}

View File

@@ -34,6 +34,8 @@ const (
WriteCacheTypeMemory = "memory"
WriteCacheTypeFile = "file"
MagneticTapeBlockSize = 512
)
var (

View File

@@ -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(),

View File

@@ -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,

View File

@@ -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)
}

View File

@@ -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)
}

117
pkg/mtio/mtio_linux.go Normal file
View File

@@ -0,0 +1,117 @@
//go:build linux
package mtio
import (
"syscall"
"unsafe"
)
// See https://github.com/benmcclelland/mtio
const (
mtioCpos = 0x80086d03 // Get tape position
mtioCtop = 0x40086d01 // Do magnetic tape operation
mtFsf = 1 // Forward space over FileMark, position at first record of next file
mtOffl = 7 // Rewind and put the drive offline (eject?)
mtEom = 12 // Goto end of recorded media (for appending files)
mtSeek = 22 // Seek to block
)
// position is struct for MTIOCPOS
type position struct {
blkNo int64 // Current block number
}
// operation is struct for MTIOCTOP
type operation struct {
op int16 // Operation ID
pad int16 // Padding to match C structures
count int32 // Operation count
}
type MagneticTapeIO struct{}
func (t MagneticTapeIO) GetCurrentRecordFromTape(fd uintptr) (int64, error) {
pos := &position{}
if _, _, err := syscall.Syscall(
syscall.SYS_IOCTL,
fd,
mtioCpos,
uintptr(unsafe.Pointer(pos)),
); err != 0 {
return 0, err
}
return pos.blkNo, nil
}
func (t MagneticTapeIO) GoToEndOfTape(fd uintptr) error {
if _, _, err := syscall.Syscall(
syscall.SYS_IOCTL,
fd,
mtioCtop,
uintptr(unsafe.Pointer(
&operation{
op: mtEom,
},
)),
); err != 0 {
return err
}
return nil
}
func (t MagneticTapeIO) GoToNextFileOnTape(fd uintptr) error {
if _, _, err := syscall.Syscall(
syscall.SYS_IOCTL,
fd,
mtioCtop,
uintptr(unsafe.Pointer(
&operation{
op: mtFsf,
count: 1,
},
)),
); err != 0 {
return err
}
return nil
}
func (t MagneticTapeIO) EjectTape(fd uintptr) error {
if _, _, err := syscall.Syscall(
syscall.SYS_IOCTL,
fd,
mtioCtop,
uintptr(unsafe.Pointer(
&operation{
op: mtOffl,
},
)),
); err != 0 {
return err
}
return nil
}
func (t MagneticTapeIO) SeekToRecordOnTape(fd uintptr, record int32) error {
if _, _, err := syscall.Syscall(
syscall.SYS_IOCTL,
fd,
mtioCtop,
uintptr(unsafe.Pointer(
&operation{
op: mtSeek,
count: record,
},
)),
); err != 0 {
return err
}
return nil
}

29
pkg/mtio/mtio_stub.go Normal file
View File

@@ -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
}

View File

@@ -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,

View File

@@ -111,6 +111,7 @@ func (o *Operations) Delete(name string) error {
return recovery.Index(
reader,
o.backend.MagneticTapeIO,
o.metadata,
o.pipes,
o.crypto,

View File

@@ -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,

View File

@@ -84,6 +84,7 @@ func (o *Operations) Restore(
if err := recovery.Fetch(
reader,
o.backend.MagneticTapeIO,
o.pipes,
o.crypto,

View File

@@ -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,

View File

@@ -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
}

View File

@@ -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))

View File

@@ -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))

View File

@@ -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,
)

View File

@@ -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
}
}