From 5bf40bf7cbea5c4111f8e1ccdfe351a84ca5b116 Mon Sep 17 00:00:00 2001 From: Felicitas Pojtinger Date: Sun, 21 Nov 2021 19:14:47 +0100 Subject: [PATCH] fix: Ensure that full records are written to tape so that EOF marks work --- cmd/stbak/cmd/archive.go | 21 +++++++++++++++++++-- cmd/stbak/cmd/remove.go | 27 ++++++++++++++++++++++++++- pkg/counters/read_write.go | 31 +++++++++++++++++++++++++++++++ pkg/readers/counter.go | 17 ----------------- 4 files changed, 76 insertions(+), 20 deletions(-) create mode 100644 pkg/counters/read_write.go delete mode 100644 pkg/readers/counter.go diff --git a/cmd/stbak/cmd/archive.go b/cmd/stbak/cmd/archive.go index d3a1778..cb7b61b 100644 --- a/cmd/stbak/cmd/archive.go +++ b/cmd/stbak/cmd/archive.go @@ -10,6 +10,7 @@ import ( "github.com/pojntfx/stfs/pkg/adapters" "github.com/pojntfx/stfs/pkg/controllers" + "github.com/pojntfx/stfs/pkg/counters" "github.com/pojntfx/stfs/pkg/formatting" "github.com/spf13/cobra" "github.com/spf13/viper" @@ -83,11 +84,14 @@ var archiveCmd = &cobra.Command{ dirty := false var tw *tar.Writer + var bw *bufio.Writer + var counter *counters.CounterWriter if isRegular { tw = tar.NewWriter(f) } else { - bw := bufio.NewWriterSize(f, controllers.BlockSize*viper.GetInt(recordSizeFlag)) - tw = tar.NewWriter(bw) + bw = bufio.NewWriterSize(f, controllers.BlockSize*viper.GetInt(recordSizeFlag)) + counter = &counters.CounterWriter{Writer: bw, BytesRead: 0} + tw = tar.NewWriter(counter) } defer func() { // Only write the trailer if we wrote to the archive @@ -95,6 +99,19 @@ var archiveCmd = &cobra.Command{ if err := tw.Close(); err != nil { panic(err) } + + if !isRegular { + if controllers.BlockSize*viper.GetInt(recordSizeFlag)-counter.BytesRead > 0 { + // Fill the rest of the record with zeros + if _, err := bw.Write(make([]byte, controllers.BlockSize*viper.GetInt(recordSizeFlag)-counter.BytesRead)); err != nil { + panic(err) + } + } + + if err := bw.Flush(); err != nil { + panic(err) + } + } } }() diff --git a/cmd/stbak/cmd/remove.go b/cmd/stbak/cmd/remove.go index 0735f57..4b91410 100644 --- a/cmd/stbak/cmd/remove.go +++ b/cmd/stbak/cmd/remove.go @@ -2,11 +2,13 @@ package cmd import ( "archive/tar" + "bufio" "context" "os" "github.com/pojntfx/stfs/pkg/controllers" "github.com/pojntfx/stfs/pkg/converters" + "github.com/pojntfx/stfs/pkg/counters" "github.com/pojntfx/stfs/pkg/formatting" "github.com/pojntfx/stfs/pkg/pax" "github.com/pojntfx/stfs/pkg/persisters" @@ -61,13 +63,35 @@ var removeCmd = &cobra.Command{ defer f.Close() dirty := false - tw := tar.NewWriter(f) + var tw *tar.Writer + var bw *bufio.Writer + var counter *counters.CounterWriter + if isRegular { + tw = tar.NewWriter(f) + } else { + bw = bufio.NewWriterSize(f, controllers.BlockSize*viper.GetInt(recordSizeFlag)) + counter = &counters.CounterWriter{Writer: bw, BytesRead: 0} + tw = tar.NewWriter(counter) + } defer func() { // Only write the trailer if we wrote to the archive if dirty { if err := tw.Close(); err != nil { panic(err) } + + if !isRegular { + if controllers.BlockSize*viper.GetInt(recordSizeFlag)-counter.BytesRead > 0 { + // Fill the rest of the record with zeros + if _, err := bw.Write(make([]byte, controllers.BlockSize*viper.GetInt(recordSizeFlag)-counter.BytesRead)); err != nil { + panic(err) + } + } + + if err := bw.Flush(); err != nil { + panic(err) + } + } } }() @@ -109,6 +133,7 @@ var removeCmd = &cobra.Command{ } func init() { + removeCmd.PersistentFlags().IntP(recordSizeFlag, "e", 20, "Amount of 512-bit blocks per record") removeCmd.PersistentFlags().StringP(nameFlag, "n", "", "Name of the file to remove") viper.AutomaticEnv() diff --git a/pkg/counters/read_write.go b/pkg/counters/read_write.go new file mode 100644 index 0000000..a964c28 --- /dev/null +++ b/pkg/counters/read_write.go @@ -0,0 +1,31 @@ +package counters + +import "io" + +type CounterReader struct { + Reader io.Reader + + BytesRead int +} + +func (r *CounterReader) Read(p []byte) (n int, err error) { + n, err = r.Reader.Read(p) + + r.BytesRead += n + + return n, err +} + +type CounterWriter struct { + Writer io.Writer + + BytesRead int +} + +func (w *CounterWriter) Write(p []byte) (n int, err error) { + n, err = w.Writer.Write(p) + + w.BytesRead += n + + return n, err +} diff --git a/pkg/readers/counter.go b/pkg/readers/counter.go deleted file mode 100644 index bf133aa..0000000 --- a/pkg/readers/counter.go +++ /dev/null @@ -1,17 +0,0 @@ -package readers - -import "io" - -type Counter struct { - Reader io.Reader - - BytesRead int -} - -func (r *Counter) Read(p []byte) (n int, err error) { - n, err = r.Reader.Read(p) - - r.BytesRead += n - - return n, err -}