Merge pull request #1650 from dmcgowan/fix-gc-race

gc: fix race and test failures
This commit is contained in:
Kenfe-Mickaël Laventure 2017-10-16 12:57:14 -07:00 committed by GitHub
commit 79dad0ab02
2 changed files with 68 additions and 8 deletions

View File

@ -28,6 +28,7 @@ var snapshotCommand = cli.Command{
mountSnapshotCommand, mountSnapshotCommand,
commitSnapshotCommand, commitSnapshotCommand,
infoSnapshotCommand, 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 { type snapshotTreeNode struct {
Name string Name string
Parent string Parent string

View File

@ -37,8 +37,8 @@ const (
// datastores for content and snapshots. // datastores for content and snapshots.
type DB struct { type DB struct {
db *bolt.DB db *bolt.DB
ss map[string]snapshot.Snapshotter ss map[string]*snapshotter
cs content.Store cs *contentStore
// wlock is used to protect access to the data structures during garbage // wlock is used to protect access to the data structures during garbage
// collection. While the wlock is held no writable transactions can be // 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 // NewDB creates a new metadata database using the provided
// bolt database, content store, and snapshotters. // bolt database, content store, and snapshotters.
func NewDB(db *bolt.DB, cs content.Store, ss map[string]snapshot.Snapshotter) *DB { func NewDB(db *bolt.DB, cs content.Store, ss map[string]snapshot.Snapshotter) *DB {
return &DB{ m := &DB{
db: db, db: db,
ss: ss, ss: make(map[string]*snapshotter, len(ss)),
cs: cs,
dirtySS: map[string]struct{}{}, 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 // Init ensures the database is at the correct version
@ -158,7 +165,7 @@ func (m *DB) ContentStore() content.Store {
if m.cs == nil { if m.cs == nil {
return nil return nil
} }
return newContentStore(m, m.cs) return m.cs
} }
// Snapshotter returns a namespaced content store for // Snapshotter returns a namespaced content store for
@ -168,7 +175,7 @@ func (m *DB) Snapshotter(name string) snapshot.Snapshotter {
if !ok { if !ok {
return nil return nil
} }
return newSnapshotter(m, name, sn) return sn
} }
// View runs a readonly transaction on the metadata store. // View runs a readonly transaction on the metadata store.
@ -292,7 +299,7 @@ func (m *DB) cleanupSnapshotter(name string) {
return return
} }
err := newSnapshotter(m, name, sn).garbageCollect(ctx) err := sn.garbageCollect(ctx)
if err != nil { if err != nil {
log.G(ctx).WithError(err).WithField("snapshotter", name).Warn("garbage collection failed") log.G(ctx).WithError(err).WithField("snapshotter", name).Warn("garbage collection failed")
} }