提交 1153c74a 编写于 作者: H holyfei 提交者: yangfeiyu

store: add CleanContainer and lock for store

Fix #I1TUG8

reason:
1. add lock for store
2. add CleanContainer function, concurrent call of it will be
under the protection of lock
Signed-off-by: Nyangfeiyu <yangfeiyu2@huawei.com>
上级 c8504d54
...@@ -158,11 +158,8 @@ func (c *cmdBuilder) getCopyContextDir(from string) (string, func(), error) { ...@@ -158,11 +158,8 @@ func (c *cmdBuilder) getCopyContextDir(from string) (string, func(), error) {
} }
cleanup := func() { cleanup := func() {
if _, uerr := c.stage.localStore.Unmount(imgDesc.ContainerDesc.ContainerID, false); uerr != nil { if cerr := c.stage.localStore.CleanContainer(imgDesc.ContainerDesc.ContainerID); cerr != nil {
logrus.Warnf("Unmount layer[%s] for COPY from[%s] failed: %v", imgDesc.ContainerDesc.ContainerID, from, uerr) logrus.Warnf("Clean layer[%s] for COPY from[%s] failed: %v", imgDesc.ContainerDesc.ContainerID, from, cerr)
}
if derr := c.stage.localStore.DeleteContainer(imgDesc.ContainerDesc.ContainerID); derr != nil {
logrus.Warnf("Delete layer[%s] for COPY from[%s] failed: %v", imgDesc.ContainerDesc.ContainerID, from, derr)
} }
} }
......
...@@ -353,19 +353,11 @@ func (s *stageBuilder) commit(ctx context.Context) (string, error) { ...@@ -353,19 +353,11 @@ func (s *stageBuilder) commit(ctx context.Context) (string, error) {
// delete cleans up temporary resources which are created during stage building. // delete cleans up temporary resources which are created during stage building.
func (s *stageBuilder) delete() error { func (s *stageBuilder) delete() error {
var retErr error if s.containerID == "" {
return nil
if s.containerID != "" {
if _, err := s.localStore.Unmount(s.containerID, false); err != nil {
s.builder.Logger().Warnf("Unmount mountpoint of containerID[%q] for stage[%q] failed: %v", s.containerID, s.name, err)
retErr = errors.Wrapf(err, "unmount mountpoint of containerID[%q] for stage[%q] failed", s.containerID, s.name)
}
if err := s.localStore.DeleteContainer(s.containerID); err != nil {
s.builder.Logger().Warnf("Delete mountpoint of containerID[%q] for stage[%q] failed: %v", s.containerID, s.name, err)
retErr = errors.Wrapf(err, "delete mountpoint of containerID[%q] for stage[%q] failed", s.containerID, s.name)
} }
s.mountpoint = "" s.mountpoint = ""
}
return retErr return s.localStore.CleanContainer(s.containerID)
} }
...@@ -88,7 +88,7 @@ func runDaemon(cmd *cobra.Command, args []string) error { ...@@ -88,7 +88,7 @@ func runDaemon(cmd *cobra.Command, args []string) error {
return err return err
} }
// cleanup the residual container store if it exists // cleanup the residual container store if it exists
store.CleanContainerStore() store.CleanContainers()
// Ensure we have only one daemon running at the same time // Ensure we have only one daemon running at the same time
lock, err := util.SetDaemonLock(daemonOpts.RunRoot, lockFileName) lock, err := util.SetDaemonLock(daemonOpts.RunRoot, lockFileName)
if err != nil { if err != nil {
......
...@@ -36,7 +36,6 @@ import ( ...@@ -36,7 +36,6 @@ import (
"isula.org/isula-build/util" "isula.org/isula-build/util"
) )
// Options carries the options configured to daemon // Options carries the options configured to daemon
type Options struct { type Options struct {
Debug bool Debug bool
...@@ -86,8 +85,8 @@ func (d *Daemon) Run() (err error) { ...@@ -86,8 +85,8 @@ func (d *Daemon) Run() (err error) {
gc := gc.NewGC() gc := gc.NewGC()
gc.StartGC(ctx) gc.StartGC(ctx)
if err := d.registerSubReaper(gc); err != nil { if rerr := d.registerSubReaper(gc); rerr != nil {
return err return rerr
} }
logrus.Debugf("Daemon start with option %#v", d.opts) logrus.Debugf("Daemon start with option %#v", d.opts)
...@@ -189,7 +188,7 @@ func (d *Daemon) Cleanup() error { ...@@ -189,7 +188,7 @@ func (d *Daemon) Cleanup() error {
logrus.Info("Delete key failed") logrus.Info("Delete key failed")
} }
d.deleteAllBuilders() d.deleteAllBuilders()
d.localStore.CleanContainerStore() d.localStore.CleanContainers()
_, err := d.localStore.Shutdown(false) _, err := d.localStore.Shutdown(false)
return err return err
} }
...@@ -225,4 +224,3 @@ func (d *Daemon) registerSubReaper(g *gc.GarbageCollector) error { ...@@ -225,4 +224,3 @@ func (d *Daemon) registerSubReaper(g *gc.GarbageCollector) error {
return g.RegisterGC(opt) return g.RegisterGC(opt)
} }
...@@ -15,6 +15,8 @@ ...@@ -15,6 +15,8 @@
package store package store
import ( import (
"sync"
is "github.com/containers/image/v5/storage" is "github.com/containers/image/v5/storage"
"github.com/containers/storage" "github.com/containers/storage"
"github.com/sirupsen/logrus" "github.com/sirupsen/logrus"
...@@ -36,6 +38,7 @@ var ( ...@@ -36,6 +38,7 @@ var (
type Store struct { type Store struct {
// storage.Store wraps up the various types of file-based stores // storage.Store wraps up the various types of file-based stores
storage.Store storage.Store
sync.RWMutex
} }
// GetDefaultStoreOptions returns default store options. // GetDefaultStoreOptions returns default store options.
...@@ -103,11 +106,11 @@ func GetStore() (Store, error) { ...@@ -103,11 +106,11 @@ func GetStore() (Store, error) {
is.Transport.SetStore(store) is.Transport.SetStore(store)
return Store{store}, nil return Store{Store: store}, nil
} }
// CleanContainerStore unmount the containers and delete them // CleanContainers unmount the containers and delete them
func (s *Store) CleanContainerStore() { func (s *Store) CleanContainers() {
containers, err := s.Containers() containers, err := s.Containers()
if err != nil { if err != nil {
logrus.Warn("Failed to get containers while cleaning the container store") logrus.Warn("Failed to get containers while cleaning the container store")
...@@ -115,11 +118,28 @@ func (s *Store) CleanContainerStore() { ...@@ -115,11 +118,28 @@ func (s *Store) CleanContainerStore() {
} }
for _, container := range containers { for _, container := range containers {
if _, err := s.Unmount(container.ID, false); err != nil { if cerr := s.CleanContainer(container.ID); cerr != nil {
logrus.Warnf("Unmount container store failed while cleaning %q", container.ID) logrus.Warnf("Clean container %q failed", container.ID)
}
} }
if err := s.DeleteContainer(container.ID); err != nil { }
logrus.Warnf("Delete container store failed while cleaning %q", container.ID)
// CleanContainer cleans the container in store
func (s *Store) CleanContainer(id string) error {
s.Lock()
defer s.Unlock()
// Do not care about all the errors whiling cleaning the container,
// just return one if the error occurs.
var err error
if _, uerr := s.Unmount(id, false); uerr != nil {
err = uerr
logrus.Warnf("Unmount container store failed while cleaning %q", id)
} }
if derr := s.DeleteContainer(id); derr != nil {
err = derr
logrus.Warnf("Delete container store failed while cleaning %q", id)
} }
return err
} }
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册