Merge pull request #1650 from dmcgowan/fix-gc-race
gc: fix race and test failures
This commit is contained in:
commit
79dad0ab02
@ -28,6 +28,7 @@ var snapshotCommand = cli.Command{
|
||||
mountSnapshotCommand,
|
||||
commitSnapshotCommand,
|
||||
infoSnapshotCommand,
|
||||
labelSnapshotCommand,
|
||||
},
|
||||
}
|
||||
|
||||
@ -343,6 +344,58 @@ var infoSnapshotCommand = cli.Command{
|
||||
},
|
||||
}
|
||||
|
||||
var labelSnapshotCommand = cli.Command{
|
||||
Name: "label",
|
||||
Usage: "add labels to content",
|
||||
ArgsUsage: "[flags] <name> [<label>=<value> ...]",
|
||||
Description: `Labels snapshots in the snapshotter`,
|
||||
Flags: []cli.Flag{},
|
||||
Action: func(clicontext *cli.Context) error {
|
||||
var (
|
||||
key, labels = objectWithLabelArgs(clicontext)
|
||||
)
|
||||
ctx, cancel := appContext(clicontext)
|
||||
defer cancel()
|
||||
|
||||
snapshotter, err := getSnapshotter(clicontext)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
info := snapshot.Info{
|
||||
Name: key,
|
||||
Labels: map[string]string{},
|
||||
}
|
||||
|
||||
var paths []string
|
||||
for k, v := range labels {
|
||||
paths = append(paths, fmt.Sprintf("labels.%s", k))
|
||||
if v != "" {
|
||||
info.Labels[k] = v
|
||||
}
|
||||
}
|
||||
|
||||
// Nothing updated, do no clear
|
||||
if len(paths) == 0 {
|
||||
info, err = snapshotter.Stat(ctx, info.Name)
|
||||
} else {
|
||||
info, err = snapshotter.Update(ctx, info, paths...)
|
||||
}
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
var labelStrings []string
|
||||
for k, v := range info.Labels {
|
||||
labelStrings = append(labelStrings, fmt.Sprintf("%s=%s", k, v))
|
||||
}
|
||||
|
||||
fmt.Println(strings.Join(labelStrings, ","))
|
||||
|
||||
return nil
|
||||
},
|
||||
}
|
||||
|
||||
type snapshotTreeNode struct {
|
||||
Name string
|
||||
Parent string
|
||||
|
@ -37,8 +37,8 @@ const (
|
||||
// datastores for content and snapshots.
|
||||
type DB struct {
|
||||
db *bolt.DB
|
||||
ss map[string]snapshot.Snapshotter
|
||||
cs content.Store
|
||||
ss map[string]*snapshotter
|
||||
cs *contentStore
|
||||
|
||||
// wlock is used to protect access to the data structures during garbage
|
||||
// collection. While the wlock is held no writable transactions can be
|
||||
@ -60,12 +60,19 @@ type DB struct {
|
||||
// NewDB creates a new metadata database using the provided
|
||||
// bolt database, content store, and snapshotters.
|
||||
func NewDB(db *bolt.DB, cs content.Store, ss map[string]snapshot.Snapshotter) *DB {
|
||||
return &DB{
|
||||
m := &DB{
|
||||
db: db,
|
||||
ss: ss,
|
||||
cs: cs,
|
||||
ss: make(map[string]*snapshotter, len(ss)),
|
||||
dirtySS: map[string]struct{}{},
|
||||
}
|
||||
|
||||
// Initialize data stores
|
||||
m.cs = newContentStore(m, cs)
|
||||
for name, sn := range ss {
|
||||
m.ss[name] = newSnapshotter(m, name, sn)
|
||||
}
|
||||
|
||||
return m
|
||||
}
|
||||
|
||||
// Init ensures the database is at the correct version
|
||||
@ -158,7 +165,7 @@ func (m *DB) ContentStore() content.Store {
|
||||
if m.cs == nil {
|
||||
return nil
|
||||
}
|
||||
return newContentStore(m, m.cs)
|
||||
return m.cs
|
||||
}
|
||||
|
||||
// Snapshotter returns a namespaced content store for
|
||||
@ -168,7 +175,7 @@ func (m *DB) Snapshotter(name string) snapshot.Snapshotter {
|
||||
if !ok {
|
||||
return nil
|
||||
}
|
||||
return newSnapshotter(m, name, sn)
|
||||
return sn
|
||||
}
|
||||
|
||||
// View runs a readonly transaction on the metadata store.
|
||||
@ -292,7 +299,7 @@ func (m *DB) cleanupSnapshotter(name string) {
|
||||
return
|
||||
}
|
||||
|
||||
err := newSnapshotter(m, name, sn).garbageCollect(ctx)
|
||||
err := sn.garbageCollect(ctx)
|
||||
if err != nil {
|
||||
log.G(ctx).WithError(err).WithField("snapshotter", name).Warn("garbage collection failed")
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user