diff --git a/VERSION-openeuler b/VERSION-openeuler index ad7f921e1ff164c01848018901b240eb03c59d36..e6dba377a5d2844c46c4c137f5a3dcdfa8ab8064 100644 --- a/VERSION-openeuler +++ b/VERSION-openeuler @@ -1 +1 @@ -18.09.0.215 +18.09.0.220 diff --git a/docker-engine-openeuler.spec b/docker-engine-openeuler.spec index 24603c800db2495711c919394aa6aade1d6b56b7..70fea8efc76261265fa748482703a69083ad10c5 100644 --- a/docker-engine-openeuler.spec +++ b/docker-engine-openeuler.spec @@ -1,6 +1,6 @@ Name: docker-engine Version: 18.09.0 -Release: 215 +Release: 220 Summary: The open-source application container engine Group: Tools/Docker @@ -201,6 +201,36 @@ fi %endif %changelog +* Sat Mar 9 2022 chenjiankun - 18.09.0-220 +- Type:bugfix +- ID:NA +- SUG:NA +- DESC:check db file size before start containerd + +* Sat Mar 9 2022 chenjiankun - 18.09.0-219 +- Type:bugfix +- ID:NA +- SUG:NA +- DESC:fix ProcessEvent block when CloseStreams block + +* Sat Mar 9 2022 chenjiankun - 18.09.0-218 +- Type:bugfix +- ID:NA +- SUG:NA +- DESC:fix runc data and dm left when periodically kill containerd + +* Sat Mar 9 2022 chenjiankun - 18.09.0-217 +- Type:bugfix +- ID:NA +- SUG:NA +- DESC:fix race condition in cmdStream + +* Sat Mar 9 2022 chenjiankun - 18.09.0-216 +- Type:bugfix +- ID:NA +- SUG:NA +- DESC:Unexport testcase.Cleanup to fix Go 1.14 + * Tue Mar 8 2022 chenjiankun - 18.09.0-215 - Type:bugfix - ID:NA diff --git a/patch/0205-docker-Unexport-testcase.Cleanup-to-fix-Go-1.14.patch b/patch/0205-docker-Unexport-testcase.Cleanup-to-fix-Go-1.14.patch new file mode 100644 index 0000000000000000000000000000000000000000..39e8d433c7e45425b538227c3640597053d3ac7e --- /dev/null +++ b/patch/0205-docker-Unexport-testcase.Cleanup-to-fix-Go-1.14.patch @@ -0,0 +1,40 @@ +From 57bbb50663f80e78cbdb5283b28be19b64f14ea9 Mon Sep 17 00:00:00 2001 +From: chenjiankun +Date: Thu, 13 May 2021 11:15:40 +0800 +Subject: [PATCH] docker: [backport] Unexport testcase.Cleanup to fix Go 1.14 + +Conflict:NA +Reference:https://github.com/gotestyourself/gotest.tools/pull/169/commits/6bc35c2eea35a967a8fe3cf05f491da2cc1793d0 + +--- + components/engine/vendor/gotest.tools/x/subtest/context.go | 6 +++--- + 1 file changed, 3 insertions(+), 3 deletions(-) + +diff --git a/components/engine/vendor/gotest.tools/x/subtest/context.go b/components/engine/vendor/gotest.tools/x/subtest/context.go +index 878bdebf1..bcf13eed5 100644 +--- a/components/engine/vendor/gotest.tools/x/subtest/context.go ++++ b/components/engine/vendor/gotest.tools/x/subtest/context.go +@@ -27,9 +27,9 @@ func (tc *testcase) Ctx() context.Context { + return tc.ctx + } + +-// Cleanup runs all cleanup functions. Functions are run in the opposite order ++// cleanup runs all cleanup functions. Functions are run in the opposite order + // in which they were added. Cleanup is called automatically before Run exits. +-func (tc *testcase) Cleanup() { ++func (tc *testcase) cleanup() { + for _, f := range tc.cleanupFuncs { + // Defer all cleanup functions so they all run even if one calls + // t.FailNow() or panics. Deferring them also runs them in reverse order. +@@ -59,7 +59,7 @@ type parallel interface { + func Run(t *testing.T, name string, subtest func(t TestContext)) bool { + return t.Run(name, func(t *testing.T) { + tc := &testcase{TB: t} +- defer tc.Cleanup() ++ defer tc.cleanup() + subtest(tc) + }) + } +-- +2.27.0 + diff --git a/patch/0206-docker-archive-fix-race-condition-in-cmdStream.patch b/patch/0206-docker-archive-fix-race-condition-in-cmdStream.patch new file mode 100644 index 0000000000000000000000000000000000000000..fc4e10aabf1e9338e73cd37bad4820004cf6b36b --- /dev/null +++ b/patch/0206-docker-archive-fix-race-condition-in-cmdStream.patch @@ -0,0 +1,79 @@ +From 782d36eae49ceff3e4fbd43c5a8112d9958dc791 Mon Sep 17 00:00:00 2001 +From: Stephen Benjamin +Date: Tue, 3 Sep 2019 10:56:45 -0400 +Subject: [PATCH] archive: [backport] fix race condition in cmdStream + +There is a race condition in pkg/archive when using `cmd.Start` for pigz +and xz where the `*bufio.Reader` could be returned to the pool while the +command is still writing to it, and then picked up and used by a new +command. + +The command is wrapped in a `CommandContext` where the process will be +killed when the context is cancelled, however this is not instantaneous, +so there's a brief window while the command is still running but the +`*bufio.Reader` was already returned to the pool. + +wrapReadCloser calls `cancel()`, and then `readBuf.Close()` which +eventually returns the buffer to the pool. However, because cmdStream +runs `cmd.Wait` in a go routine that we never wait for to finish, it is +not safe to return the reader to the pool yet. We need to ensure we +wait for `cmd.Wait` to finish! + +Signed-off-by: Stephen Benjamin +(cherry picked from commit 89dd10b06efe93d4f427057f043abf560c461281) +Signed-off-by: WangFengTu +--- + components/engine/pkg/archive/archive.go | 12 +++++++++++- + components/engine/pkg/archive/archive_test.go | 4 +++- + 2 files changed, 14 insertions(+), 2 deletions(-) + +diff --git a/components/engine/pkg/archive/archive.go b/components/engine/pkg/archive/archive.go +index 070dccb756..82cd0a6c6f 100644 +--- a/components/engine/pkg/archive/archive.go ++++ b/components/engine/pkg/archive/archive.go +@@ -1216,6 +1216,9 @@ func cmdStream(cmd *exec.Cmd, input io.Reader) (io.ReadCloser, error) { + return nil, err + } + ++ // Ensure the command has exited before we clean anything up ++ done := make(chan struct{}) ++ + // Copy stdout to the returned pipe + go func() { + if err := cmd.Wait(); err != nil { +@@ -1223,9 +1226,16 @@ func cmdStream(cmd *exec.Cmd, input io.Reader) (io.ReadCloser, error) { + } else { + pipeW.Close() + } ++ close(done) + }() + +- return pipeR, nil ++ return ioutils.NewReadCloserWrapper(pipeR, func() error { ++ // Close pipeR, and then wait for the command to complete before returning. We have to close pipeR first, as ++ // cmd.Wait waits for any non-file stdout/stderr/stdin to close. ++ err := pipeR.Close() ++ <-done ++ return err ++ }), nil + } + + // NewTempArchive reads the content of src into a temporary file, and returns the contents +diff --git a/components/engine/pkg/archive/archive_test.go b/components/engine/pkg/archive/archive_test.go +index b448bac49a..f77b7c202d 100644 +--- a/components/engine/pkg/archive/archive_test.go ++++ b/components/engine/pkg/archive/archive_test.go +@@ -1356,7 +1356,9 @@ func TestPigz(t *testing.T) { + _, err := exec.LookPath("unpigz") + if err == nil { + t.Log("Tested whether Pigz is used, as it installed") +- assert.Equal(t, reflect.TypeOf(contextReaderCloserWrapper.Reader), reflect.TypeOf(&io.PipeReader{})) ++ // For the command wait wrapper ++ cmdWaitCloserWrapper := contextReaderCloserWrapper.Reader.(*ioutils.ReadCloserWrapper) ++ assert.Equal(t, reflect.TypeOf(cmdWaitCloserWrapper.Reader), reflect.TypeOf(&io.PipeReader{})) + } else { + t.Log("Tested whether Pigz is not used, as it not installed") + assert.Equal(t, reflect.TypeOf(contextReaderCloserWrapper.Reader), reflect.TypeOf(&gzip.Reader{})) +-- +2.27.0 + diff --git a/patch/0207-docker-fix-runc-data-and-dm-left-when-periodically-kill-containerd.patch b/patch/0207-docker-fix-runc-data-and-dm-left-when-periodically-kill-containerd.patch new file mode 100644 index 0000000000000000000000000000000000000000..3aeea26673d52c0390829764d85d62cc99059a0d --- /dev/null +++ b/patch/0207-docker-fix-runc-data-and-dm-left-when-periodically-kill-containerd.patch @@ -0,0 +1,64 @@ +From 20b8dbbf705988f94d16a401e9d4f510387cbd0d Mon Sep 17 00:00:00 2001 +From: chenjiankun +Date: Mon, 7 Jun 2021 11:23:33 +0800 +Subject: [PATCH] docker: fix runc data and dm left when periodically kill + containerd + +--- + components/engine/daemon/start.go | 20 ++++++++++++++++++-- + 1 file changed, 18 insertions(+), 2 deletions(-) + +diff --git a/components/engine/daemon/start.go b/components/engine/daemon/start.go +index 07bffaa27..7a7e2b2ee 100644 +--- a/components/engine/daemon/start.go ++++ b/components/engine/daemon/start.go +@@ -2,6 +2,7 @@ package daemon // import "github.com/docker/docker/daemon" + + import ( + "context" ++ "os/exec" + "runtime" + "time" + +@@ -14,6 +15,12 @@ import ( + "github.com/sirupsen/logrus" + ) + ++const RootDirectory = "/var/run/docker/runtime-runc/moby" ++ ++func deleteForce(containerID string) error { ++ return exec.Command("runc", "--root", RootDirectory, "delete", "--force", containerID).Run() ++} ++ + // ContainerStart starts a container. + func (daemon *Daemon) ContainerStart(name string, hostConfig *containertypes.HostConfig, checkpoint string, checkpointDir string) error { + if checkpoint != "" && !daemon.HasExperimental() { +@@ -210,7 +217,11 @@ func (daemon *Daemon) containerStart(container *container.Container, checkpoint + if err != nil { + if err := daemon.containerd.Delete(context.Background(), container.ID); err != nil { + logrus.WithError(err).WithField("container", container.ID). +- Error("failed to delete failed start container") ++ Error("failed to delete failed start container, try to delete directly") ++ err := deleteForce(container.ID) ++ if err != nil { ++ logrus.Errorf("failed to directly delete container %s", container.ID) ++ } + } + return translateContainerdStartErr(container.Path, container.SetExitCode, err) + } +@@ -273,6 +284,11 @@ func (daemon *Daemon) Cleanup(container *container.Container) { + container.CancelAttachContext() + + if err := daemon.containerd.Delete(context.Background(), container.ID); err != nil { +- logrus.Errorf("%s cleanup: failed to delete container from containerd: %v", container.ID, err) ++ logrus.Errorf("%s cleanup: failed to delete container from containerd, try to delete directly: %v", container.ID, err) ++ ++ err := deleteForce(container.ID) ++ if err != nil { ++ logrus.Errorf("%s cleanup: failed to directly delete container", container.ID) ++ } + } + } +-- +2.27.0 + diff --git a/patch/0208-docker-fix-ProcessEvent-block-when-CloseStreams-block.patch b/patch/0208-docker-fix-ProcessEvent-block-when-CloseStreams-block.patch new file mode 100644 index 0000000000000000000000000000000000000000..6ed75818421dd8a099edacaa995b2417cf456b38 --- /dev/null +++ b/patch/0208-docker-fix-ProcessEvent-block-when-CloseStreams-block.patch @@ -0,0 +1,82 @@ +From 210d1acba11aee0cb4a543fa97feb9ecfc4ba532 Mon Sep 17 00:00:00 2001 +From: chenjiankun +Date: Tue, 15 Jun 2021 20:51:10 +0800 +Subject: [PATCH] docker: fix ProcessEvent block when CloseStreams block + +The ProcessEvent function will block if the CloseStreams function block in +exit event processing. The reason is the ProcessEvent function is serial +processing. So we need add a timeout mechanism to deal with it. + +--- + components/engine/container/stream/streams.go | 42 ++++++++++++------- + 1 file changed, 27 insertions(+), 15 deletions(-) + +diff --git a/components/engine/container/stream/streams.go b/components/engine/container/stream/streams.go +index 585f9e8e3..1a7ef33d4 100644 +--- a/components/engine/container/stream/streams.go ++++ b/components/engine/container/stream/streams.go +@@ -7,6 +7,7 @@ import ( + "io/ioutil" + "strings" + "sync" ++ "time" + + "github.com/containerd/containerd/cio" + "github.com/docker/docker/pkg/broadcaster" +@@ -92,27 +93,38 @@ func (c *Config) NewNopInputPipe() { + + // CloseStreams ensures that the configured streams are properly closed. + func (c *Config) CloseStreams() error { +- var errors []string ++ done := make(chan struct{}) ++ var errorsInLine error + +- if c.stdin != nil { +- if err := c.stdin.Close(); err != nil { +- errors = append(errors, fmt.Sprintf("error close stdin: %s", err)) ++ go func() { ++ var errors []string ++ if c.stdin != nil { ++ if err := c.stdin.Close(); err != nil { ++ errors = append(errors, fmt.Sprintf("error close stdin: %s", err)) ++ } + } +- } + +- if err := c.stdout.Clean(); err != nil { +- errors = append(errors, fmt.Sprintf("error close stdout: %s", err)) +- } ++ if err := c.stdout.Clean(); err != nil { ++ errors = append(errors, fmt.Sprintf("error close stdout: %s", err)) ++ } + +- if err := c.stderr.Clean(); err != nil { +- errors = append(errors, fmt.Sprintf("error close stderr: %s", err)) +- } ++ if err := c.stderr.Clean(); err != nil { ++ errors = append(errors, fmt.Sprintf("error close stderr: %s", err)) ++ } + +- if len(errors) > 0 { +- return fmt.Errorf(strings.Join(errors, "\n")) +- } ++ if len(errors) > 0 { ++ errorsInLine = fmt.Errorf(strings.Join(errors, "\n")) ++ } ++ ++ close(done) ++ }() + +- return nil ++ select { ++ case <-done: ++ return errorsInLine ++ case <-time.After(3 * time.Second): ++ return fmt.Errorf("close stream timeout") ++ } + } + + // CopyToPipe connects streamconfig with a libcontainerd.IOPipe +-- +2.27.0 + diff --git a/patch/0209-docker-check-db-file-size-before-start-containerd.patch b/patch/0209-docker-check-db-file-size-before-start-containerd.patch new file mode 100644 index 0000000000000000000000000000000000000000..cabaf1fad6d96613e6ef1b64cfc7f15d7ae07b0e --- /dev/null +++ b/patch/0209-docker-check-db-file-size-before-start-containerd.patch @@ -0,0 +1,90 @@ +From c79f7bc343ebb9b855e7a28282d8c9ebcaf7e63c Mon Sep 17 00:00:00 2001 +From: chenjiankun +Date: Thu, 5 Aug 2021 15:12:14 +0800 +Subject: [PATCH] docker: check db file size before start containerd + +if the db file's metadata is damaged, the db will load failed +with error "file size too small" when starting. we need to check it +before start containerd. +--- + components/engine/cmd/dockerd/daemon.go | 45 +++++++++++++------------ + 1 file changed, 24 insertions(+), 21 deletions(-) + +diff --git a/components/engine/cmd/dockerd/daemon.go b/components/engine/cmd/dockerd/daemon.go +index 04bc06b92..a96c9d98b 100644 +--- a/components/engine/cmd/dockerd/daemon.go ++++ b/components/engine/cmd/dockerd/daemon.go +@@ -113,28 +113,29 @@ func resumeDM() { + } + } + +-func cleanupLocalDB(db string) { +- _, err := os.Stat(db) +- if err == nil { +- err = os.Remove(db) +- logrus.Infof("cleanup DB %s error=%v", db, err) ++func cleanupLocalDB(db string, checkSize bool) { ++ if info, err := os.Stat(db); err == nil { ++ if checkSize == false || int(info.Size()) < 2*os.Getpagesize() { ++ err = os.Remove(db) ++ logrus.Infof("cleanup DB %s error=%v", db, err) ++ } + } + } + + // DB files may corrupted on exception poweroff but can be rebuild at run time, + // so we can remove DB files on OS starts avoid daemon can not startup. + func cleanupLocalDBs(run, root string) { ++ checkSize := true ++ + // check db lock is exist, do nothing if file is existed + dbLockPath := filepath.Join(run, "dblock") +- _, err := os.Stat(dbLockPath) +- if err == nil { +- return +- } +- if !os.IsNotExist(err) { +- logrus.Errorf("stat dblock failed %v", err) +- return ++ _, statErr := os.Stat(dbLockPath) ++ if os.IsNotExist(statErr) { ++ checkSize = false ++ logrus.Errorf("stat dblock failed %v", statErr) ++ logrus.Devour(ioutil.WriteFile(dbLockPath, []byte{}, 0600)) + } +- logrus.Devour(ioutil.WriteFile(dbLockPath, []byte{}, 0600)) ++ + files, err := ioutil.ReadDir(filepath.Join(run, "containerd")) + logrus.Devour(err) + olds, err := ioutil.ReadDir(filepath.Join(run, "libcontainerd")) +@@ -145,17 +146,19 @@ func cleanupLocalDBs(run, root string) { + return + } + } ++ + if os.Getenv("DISABLE_CRASH_FILES_DELETE") == "true" { + return + } +- cleanupLocalDB(filepath.Join(root, "containerd/daemon/io.containerd.metadata.v1.bolt/meta.db")) +- cleanupLocalDB(filepath.Join(root, "builder/fscache.db")) +- cleanupLocalDB(filepath.Join(root, "volumes/metadata.db")) +- cleanupLocalDB(filepath.Join(root, "network/files/local-kv.db")) +- cleanupLocalDB(filepath.Join(root, "accelerator/accel.db")) +- cleanupLocalDB(filepath.Join(root, "buildkit/metadata.db")) +- cleanupLocalDB(filepath.Join(root, "buildkit/cache.db")) +- cleanupLocalDB(filepath.Join(root, "buildkit/snapshots.db")) ++ ++ cleanupLocalDB(filepath.Join(root, "containerd/daemon/io.containerd.metadata.v1.bolt/meta.db"), checkSize) ++ cleanupLocalDB(filepath.Join(root, "builder/fscache.db"), checkSize) ++ cleanupLocalDB(filepath.Join(root, "volumes/metadata.db"), checkSize) ++ cleanupLocalDB(filepath.Join(root, "network/files/local-kv.db"), checkSize) ++ cleanupLocalDB(filepath.Join(root, "accelerator/accel.db"), checkSize) ++ cleanupLocalDB(filepath.Join(root, "buildkit/metadata.db"), checkSize) ++ cleanupLocalDB(filepath.Join(root, "buildkit/cache.db"), checkSize) ++ cleanupLocalDB(filepath.Join(root, "buildkit/snapshots.db"), checkSize) + } + + func (cli *DaemonCli) start(opts *daemonOptions) (err error) { +-- +2.27.0 + diff --git a/series.conf b/series.conf index c204c45c5090f4d90cfee9f896ca343176cf3abc..be116974e2e03b0999f4e57d866a8ea2aeb869ad 100644 --- a/series.conf +++ b/series.conf @@ -198,4 +198,9 @@ patch/0201-docker-use-info-level-for-create-start-stop-command.patch patch/0202-docker-rollback-if-docker-restart-when-doing-BlkDiscard.patch patch/0203-docker-Fix-for-lack-of-syncromization-in-daemon-update.go.patch patch/0204-docker-Don-t-fail-on-two-concurrent-reference.store.AddDige.patch +patch/0205-docker-Unexport-testcase.Cleanup-to-fix-Go-1.14.patch +patch/0206-docker-archive-fix-race-condition-in-cmdStream.patch +patch/0207-docker-fix-runc-data-and-dm-left-when-periodically-kill-containerd.patch +patch/0208-docker-fix-ProcessEvent-block-when-CloseStreams-block.patch +patch/0209-docker-check-db-file-size-before-start-containerd.patch #end