0034-Try-to-repair-lowers-file-if-current-layer-is-reusin.patch 6.3 KB
Newer Older
1
From 2cc89729e944e8761ed698d69824e21e17b65b89 Mon Sep 17 00:00:00 2001
2 3
From: WangFengTu <wangfengtu@huawei.com>
Date: Mon, 30 Dec 2019 10:20:56 +0800
4
Subject: [PATCH 34/43] Try to repair lowers file if current layer is reusing
5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192

Signed-off-by: WangFengTu <wangfengtu@huawei.com>
---
 .../containers/image/storage/storage_image.go |  7 ++++
 .../containers/storage/drivers/driver.go      |  4 +++
 .../storage/drivers/overlay/overlay.go        | 29 +++++++++++++++-
 .../github.com/containers/storage/layers.go   | 11 ++++++
 vendor/github.com/containers/storage/store.go | 34 +++++++++++++++++++
 5 files changed, 84 insertions(+), 1 deletion(-)

diff --git a/vendor/github.com/containers/image/storage/storage_image.go b/vendor/github.com/containers/image/storage/storage_image.go
index 257ff6e..9d8366c 100644
--- a/vendor/github.com/containers/image/storage/storage_image.go
+++ b/vendor/github.com/containers/image/storage/storage_image.go
@@ -593,6 +593,13 @@ func (s *storageImageDestination) Commit(ctx context.Context) error {
 			id = digest.Canonical.FromBytes([]byte(lastLayer + "+" + diffID.Hex())).Hex()
 		}
 		if layer, err2 := s.imageRef.transport.store.Layer(id); layer != nil && err2 == nil {
+			// If layer is reused, layer's lowers file may point to invalid link because
+			// parent layer's link changed when it is repulled or reloaded.
+			err := s.imageRef.transport.store.TryRepairLayerLowers(layer.ID, lastLayer)
+			if err != nil {
+				logrus.Errorf("Try to repair layer's lowers file failed: %v", err)
+			}
+
 			// There's already a layer that should have the right contents, just reuse it.
 			lastLayer = layer.ID
 			continue
diff --git a/vendor/github.com/containers/storage/drivers/driver.go b/vendor/github.com/containers/storage/drivers/driver.go
index 476b551..cd061bd 100644
--- a/vendor/github.com/containers/storage/drivers/driver.go
+++ b/vendor/github.com/containers/storage/drivers/driver.go
@@ -182,6 +182,10 @@ type Checker interface {
 	IsMounted(path string) bool
 }
 
+type LowersRepair interface {
+	TryRepairLowers(id, parent string) error
+}
+
 func init() {
 	drivers = make(map[string]InitFunc)
 }
diff --git a/vendor/github.com/containers/storage/drivers/overlay/overlay.go b/vendor/github.com/containers/storage/drivers/overlay/overlay.go
index dfac1f0..213acd1 100644
--- a/vendor/github.com/containers/storage/drivers/overlay/overlay.go
+++ b/vendor/github.com/containers/storage/drivers/overlay/overlay.go
@@ -15,6 +15,7 @@ import (
 	"strings"
 	"sync"
 
+	"bufio"
 	"github.com/containers/storage/drivers"
 	"github.com/containers/storage/drivers/overlayutils"
 	"github.com/containers/storage/drivers/quota"
@@ -34,7 +35,6 @@ import (
 	"github.com/pkg/errors"
 	"github.com/sirupsen/logrus"
 	"golang.org/x/sys/unix"
-	"bufio"
 )
 
 var (
@@ -1108,6 +1108,33 @@ func (d *Driver) SupportsShifting() bool {
 	return d.options.mountProgram != ""
 }
 
+func (d *Driver) TryRepairLowers(id, parent string) error {
+	// Find if lowers need repair
+	lowersStr, err := ioutil.ReadFile(path.Join(d.dir(id), lowerFile))
+	if err != nil && !os.IsNotExist(err) {
+		return err
+	}
+
+	lowers := strings.Split(string(lowersStr), ":")
+	if len(lowers) != 0 {
+		if _, err := os.Stat(path.Join(d.home, lowers[0])); err == nil {
+			return nil
+		}
+	}
+
+	// Try repair lowers
+	lower, err := d.getLower(parent)
+	if err != nil {
+		return err
+	}
+	if lower != "" {
+		if err := ioutil.WriteFile(path.Join(d.dir(id), lowerFile), []byte(lower), 0666); err != nil {
+			return err
+		}
+	}
+	return nil
+}
+
 // dumbJoin is more or less a dumber version of filepath.Join, but one which
 // won't Clean() the path, allowing us to append ".." as a component and trust
 // pathname resolution to do some non-obvious work.
diff --git a/vendor/github.com/containers/storage/layers.go b/vendor/github.com/containers/storage/layers.go
index cf6dd10..b03de66 100644
--- a/vendor/github.com/containers/storage/layers.go
+++ b/vendor/github.com/containers/storage/layers.go
@@ -226,6 +226,8 @@ type LayerStore interface {
 
 	LoadLayerMountPoint(layer *Layer) error
 
+	TryRepairLowers(id, parent string) error
+
 	// ParentOwners returns the UIDs and GIDs of parents of the layer's mountpoint
 	// for which the layer's UID and GID maps don't contain corresponding entries.
 	ParentOwners(id string) (uids, gids []int, err error)
@@ -585,6 +587,15 @@ func (r *layerStore) LoadLayerMountPoint(layer *Layer) error {
 	return nil
 }
 
+func (r *layerStore) TryRepairLowers(id, parent string) error {
+	repair, ok := r.driver.(drivers.LowersRepair)
+	if !ok {
+		return nil
+	}
+
+	return repair.TryRepairLowers(id, parent)
+}
+
 func (r *layerStore) Save() error {
 	if !r.IsReadWrite() {
 		return errors.Wrapf(ErrStoreIsReadOnly, "not allowed to modify the layer store at %q", r.layerspath())
diff --git a/vendor/github.com/containers/storage/store.go b/vendor/github.com/containers/storage/store.go
index b327274..f346dc9 100644
--- a/vendor/github.com/containers/storage/store.go
+++ b/vendor/github.com/containers/storage/store.go
@@ -414,6 +414,10 @@ type Store interface {
 
 	CleanupCheckedLayers()
 
+	DeleteUncheckedLayers() error
+
+	TryRepairLayerLowers(id, parent string) error
+
 	// ImagesByDigest returns a list of images which contain a big data item
 	// named ImageDigestBigDataKey whose contents have the specified digest.
 	ImagesByDigest(d digest.Digest) ([]*Image, error)
@@ -2189,6 +2193,24 @@ func (s *store) GetCheckedLayers() {
 	return
 }
 
+func (s *store) DeleteUncheckedLayers() error {
+	layers, err := s.Layers()
+	if err != nil {
+		return err
+	}
+
+	for _, l := range layers {
+		if s.checkedLayers[l.ID] {
+			continue
+		}
+		logrus.Errorf("Delete unchecked layer %v due to no related image", l.ID)
+		if err := s.DeleteLayer(l.ID); err != nil {
+			logrus.Errorf("Failed to delete unchecked layer %v: %v", l.ID, err)
+		}
+	}
+	return nil
+}
+
 func (s *store) addCheckedLayer(id string) error {
 	s.checkedLayers[id] = true
 
@@ -2275,6 +2297,18 @@ func (s *store) DeleteContainersByImage(id string) error {
 	return nil
 }
 
+func (s *store) TryRepairLayerLowers(id, parent string) error {
+	rlstore, err := s.LayerStore()
+	if err != nil {
+		return err
+	}
+
+	rlstore.Lock()
+	defer rlstore.Unlock()
+
+	return rlstore.TryRepairLowers(id, parent)
+}
+
 func (s *store) CheckImage(id string) error {
 	rlstore, err := s.LayerStore()
 	if err != nil {
-- 
2.19.1