From 38819a06d25224cab54d45e445290b5e4dfa4ef4 Mon Sep 17 00:00:00 2001 From: Felicitas Pojtinger Date: Thu, 18 Nov 2021 22:46:26 +0100 Subject: [PATCH] feat: Enable moving over file marks on tape --- cmd/stfs-tvf-simple/main.go | 67 ++++++++++++++++++++++++++++++++++--- 1 file changed, 62 insertions(+), 5 deletions(-) diff --git a/cmd/stfs-tvf-simple/main.go b/cmd/stfs-tvf-simple/main.go index a26b046..762819f 100644 --- a/cmd/stfs-tvf-simple/main.go +++ b/cmd/stfs-tvf-simple/main.go @@ -7,6 +7,8 @@ import ( "io" "log" "os" + "syscall" + "unsafe" ) // See https://github.com/benmcclelland/mtio @@ -133,7 +135,8 @@ func main() { br := bufio.NewReaderSize(f, blockSize**recordSize) counter := &Counter{Reader: br} - errorCounter := 0 + lastBytesRead := 0 + dirty := false record := int64(0) block := int64(0) @@ -142,21 +145,43 @@ func main() { tr := tar.NewReader(counter) hdr, err := tr.Next() if err != nil { - if counter.BytesRead != 0 && errorCounter == counter.BytesRead { - // EOD + if lastBytesRead == counter.BytesRead { + if dirty { + // EOD - break + break + } + + if err := goToNextFileOnTape(f); err != nil { + // EOD + + break + } + + currentRecord, err := getCurrentRecordFromTape(f) + if err != nil { + panic(err) + } + + br = bufio.NewReaderSize(f, blockSize**recordSize) + counter = &Counter{Reader: br, BytesRead: (int(currentRecord) * *recordSize * blockSize)} // We asume we are at record n, block 0 + + dirty = true } - errorCounter = counter.BytesRead + lastBytesRead = counter.BytesRead continue } + lastBytesRead = counter.BytesRead + if hdr.Format == tar.FormatUnknown { continue } + dirty = false + log.Println("Record:", record, "Block:", block, "Header:", hdr) nextBytes := int64(counter.BytesRead) + hdr.Size + blockSize - 1 @@ -166,3 +191,35 @@ func main() { } } } + +func goToNextFileOnTape(f *os.File) error { + if _, _, err := syscall.Syscall( + syscall.SYS_IOCTL, + f.Fd(), + MTIOCTOP, + uintptr(unsafe.Pointer( + &Operation{ + Op: MTFSF, + Count: 1, + }, + )), + ); err != 0 { + return err + } + + return nil +} + +func getCurrentRecordFromTape(f *os.File) (int64, error) { + pos := &Position{} + if _, _, err := syscall.Syscall( + syscall.SYS_IOCTL, + f.Fd(), + MTIOCPOS, + uintptr(unsafe.Pointer(pos)), + ); err != 0 { + return 0, err + } + + return pos.BlkNo, nil +}