Skip to content

Commit

Permalink
rpm: wait til command is finished
Browse files Browse the repository at this point in the history
Running old code may cause a race condition because cmd.Run() closes a
output pipeline before a reading goroutine finishes reading an output.
By breaking cmd.Run() into cmd.Start() and cmd.Wait() we make sure that
file descriptor is closed after reading goroutine finishes.

Signed-off-by: Hank Donnay <[email protected]>
  • Loading branch information
Allda authored and hdonnay committed Sep 22, 2020
1 parent 3008cba commit d75ba4c
Showing 1 changed file with 11 additions and 8 deletions.
19 changes: 11 additions & 8 deletions rpm/packagescanner.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,6 @@ import (
"strings"

"github.com/rs/zerolog"
"golang.org/x/sync/errgroup"

"github.com/quay/claircore"
"github.com/quay/claircore/internal/indexer"
Expand All @@ -25,7 +24,7 @@ import (
const (
pkgName = "rpm"
pkgKind = "package"
pkgVersion = "v0.0.1"
pkgVersion = "v0.0.2"
)

// DbNames is a set of files that make up an rpm database.
Expand Down Expand Up @@ -176,7 +175,6 @@ func (ps *Scanner) Scan(ctx context.Context, layer *claircore.Layer) ([]*clairco
// Using --root and --dbpath, run rpm query on every suspected database
for _, db := range found {
log.Debug().Str("db", db).Msg("examining database")
eg, ctx := errgroup.WithContext(ctx)

cmd := exec.CommandContext(ctx, "rpm",
`--root`, root, `--dbpath`, db,
Expand All @@ -188,8 +186,12 @@ func (ps *Scanner) Scan(ctx context.Context, layer *claircore.Layer) ([]*clairco
errbuf := bytes.Buffer{}
cmd.Stderr = &errbuf
log.Debug().Str("db", db).Strs("cmd", cmd.Args).Msg("rpm invocation")
eg.Go(cmd.Run)
eg.Go(func() error {
if err := cmd.Start(); err != nil {
r.Close()
return nil, err
}
// Use a closure to defer the Close call.
if err := func() error {
defer r.Close()
srcs := make(map[string]*claircore.Package)
s := bufio.NewScanner(r)
Expand All @@ -205,9 +207,7 @@ func (ps *Scanner) Scan(ctx context.Context, layer *claircore.Layer) ([]*clairco
}

return s.Err()
})

if err := eg.Wait(); err != nil {
}(); err != nil {
if errbuf.Len() != 0 {
log.Warn().
Str("db", db).
Expand All @@ -217,6 +217,9 @@ func (ps *Scanner) Scan(ctx context.Context, layer *claircore.Layer) ([]*clairco
}
return nil, fmt.Errorf("rpm: error reading rpm output: %w", err)
}
if err := cmd.Wait(); err != nil {
return nil, err
}
}

return pkgs, nil
Expand Down

0 comments on commit d75ba4c

Please sign in to comment.