aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMatthew Heon <mheon@redhat.com>2019-06-20 10:17:38 -0400
committerMatthew Heon <matthew.heon@pm.me>2019-08-05 14:40:28 -0400
commit5255a1bb11da5e3a9310c672011efb2796ba9412 (patch)
tree281e0cc2073fff1eb3b400ed947b9d7a2a8d34d5
parenta682cd3814cb4ea959a1e96e8b54cf068c1e4aed (diff)
downloadpodman-5255a1bb11da5e3a9310c672011efb2796ba9412.tar.gz
podman-5255a1bb11da5e3a9310c672011efb2796ba9412.tar.bz2
podman-5255a1bb11da5e3a9310c672011efb2796ba9412.zip
Avoid a read-write transaction on DB init
Instead, use a less expensive read-only transaction to see if the DB is ready for use (it probably is), and only fire the expensive RW transaction if absolutely necessary. Signed-off-by: Matthew Heon <mheon@redhat.com>
-rw-r--r--libpod/boltdb_state.go70
1 files changed, 39 insertions, 31 deletions
diff --git a/libpod/boltdb_state.go b/libpod/boltdb_state.go
index 63e40a98f..12c364993 100644
--- a/libpod/boltdb_state.go
+++ b/libpod/boltdb_state.go
@@ -73,42 +73,50 @@ func NewBoltState(path string, runtime *Runtime) (State, error) {
// As such, just a db.Close() is fine here.
defer db.Close()
- // Perform initial database setup
- err = db.Update(func(tx *bolt.Tx) error {
- if _, err := tx.CreateBucketIfNotExists(idRegistryBkt); err != nil {
- return errors.Wrapf(err, "error creating id-registry bucket")
- }
- if _, err := tx.CreateBucketIfNotExists(nameRegistryBkt); err != nil {
- return errors.Wrapf(err, "error creating name-registry bucket")
- }
- if _, err := tx.CreateBucketIfNotExists(nsRegistryBkt); err != nil {
- return errors.Wrapf(err, "error creating ns-registry bucket")
- }
- if _, err := tx.CreateBucketIfNotExists(ctrBkt); err != nil {
- return errors.Wrapf(err, "error creating containers bucket")
- }
- if _, err := tx.CreateBucketIfNotExists(allCtrsBkt); err != nil {
- return errors.Wrapf(err, "error creating all containers bucket")
- }
- if _, err := tx.CreateBucketIfNotExists(podBkt); err != nil {
- return errors.Wrapf(err, "error creating pods bucket")
- }
- if _, err := tx.CreateBucketIfNotExists(allPodsBkt); err != nil {
- return errors.Wrapf(err, "error creating all pods bucket")
- }
- if _, err := tx.CreateBucketIfNotExists(volBkt); err != nil {
- return errors.Wrapf(err, "error creating volume bucket")
- }
- if _, err := tx.CreateBucketIfNotExists(allVolsBkt); err != nil {
- return errors.Wrapf(err, "error creating all volumes bucket")
+ createBuckets := [][]byte{
+ idRegistryBkt,
+ nameRegistryBkt,
+ nsRegistryBkt,
+ ctrBkt,
+ allCtrsBkt,
+ podBkt,
+ allPodsBkt,
+ volBkt,
+ allVolsBkt,
+ runtimeConfigBkt,
+ }
+
+ // Does the DB need an update?
+ needsUpdate := false
+ err = db.View(func(tx *bolt.Tx) error {
+ for _, bkt := range createBuckets {
+ if test := tx.Bucket(bkt); test == nil {
+ needsUpdate = true
+ break
+ }
}
- if _, err := tx.CreateBucketIfNotExists(runtimeConfigBkt); err != nil {
- return errors.Wrapf(err, "error creating runtime-config bucket")
+ return nil
+ })
+ if err != nil {
+ return nil, errors.Wrapf(err, "error checking DB schema")
+ }
+
+ if !needsUpdate {
+ state.valid = true
+ return state, nil
+ }
+
+ // Ensure schema is properly created in DB
+ err = db.Update(func(tx *bolt.Tx) error {
+ for _, bkt := range createBuckets {
+ if _, err := tx.CreateBucketIfNotExists(bkt); err != nil {
+ return errors.Wrapf(err, "error creating bucket %s", string(bkt))
+ }
}
return nil
})
if err != nil {
- return nil, errors.Wrapf(err, "error creating initial database layout")
+ return nil, errors.Wrapf(err, "error creating buckets for DB")
}
state.valid = true