diff --git a/moby.spec b/moby.spec index d1b95bd6266fea21e9e3011bc041ec9c6a8b9e69..7e01b312be48af96d535d34bea02df9178ebdf9f 100644 --- a/moby.spec +++ b/moby.spec @@ -5,9 +5,9 @@ %global _source_docker_init tini-0.19.0 %global _source_docker_proxy libnetwork-dcdf8f17 -Name: docker +Name: moby Version: 20.10.24 -Release: 1 +Release: 2 Summary: The open-source application container engine License: ASL 2.0 URL: https://www.docker.com @@ -210,6 +210,10 @@ fi %systemd_postun_with_restart docker.service %changelog +* Sun Jul 16 2023 xulei - 20.10.24-2 +- DESC: fix non-blocking awslogs log drop bug + fix panic if mount is not a volume + * Mon Apr 10 2023 xulei - 20.10.24-1 - DESC: update to 20.10.24 diff --git a/patch/0001-awslogs-fix-non-blocking-log-drop-bug.patch b/patch/0001-awslogs-fix-non-blocking-log-drop-bug.patch new file mode 100644 index 0000000000000000000000000000000000000000..d766900f9c0b42733a655fee569d67e3c9321cc3 --- /dev/null +++ b/patch/0001-awslogs-fix-non-blocking-log-drop-bug.patch @@ -0,0 +1,148 @@ +From ad45ece6fe93c6870080341daa12fe8da6271fa9 Mon Sep 17 00:00:00 2001 +From: Wesley Pettit +Date: Wed, 29 Mar 2023 16:09:07 -0700 +Subject: [PATCH 451/483] awslogs: fix non-blocking log drop bug + +Previously, the AWSLogs driver attempted to implement +non-blocking itself. Non-blocking is supposed to +implemented solely by the Docker RingBuffer that +wraps the log driver. + +Please see issue and explanation here: +https://github.com/moby/moby/issues/45217 + +Signed-off-by: Wesley Pettit +(cherry picked from commit c8f8d11ac42c16be9779565093e6a45bcf1a3b7b) +--- + daemon/logger/awslogs/cloudwatchlogs.go | 18 ++--------- + daemon/logger/awslogs/cloudwatchlogs_test.go | 32 ++------------------ + 2 files changed, 6 insertions(+), 44 deletions(-) + +diff --git a/daemon/logger/awslogs/cloudwatchlogs.go b/daemon/logger/awslogs/cloudwatchlogs.go +index acaf261c93..5ceb0c913f 100644 +--- a/daemon/logger/awslogs/cloudwatchlogs.go ++++ b/daemon/logger/awslogs/cloudwatchlogs.go +@@ -71,7 +71,6 @@ type logStream struct { + logStreamName string + logGroupName string + logCreateGroup bool +- logNonBlocking bool + forceFlushInterval time.Duration + multilinePattern *regexp.Regexp + client api +@@ -85,7 +84,6 @@ type logStreamConfig struct { + logStreamName string + logGroupName string + logCreateGroup bool +- logNonBlocking bool + forceFlushInterval time.Duration + maxBufferedEvents int + multilinePattern *regexp.Regexp +@@ -147,11 +145,12 @@ func New(info logger.Info) (logger.Logger, error) { + return nil, err + } + ++ logNonBlocking := info.Config["mode"] == "non-blocking" ++ + containerStream := &logStream{ + logStreamName: containerStreamConfig.logStreamName, + logGroupName: containerStreamConfig.logGroupName, + logCreateGroup: containerStreamConfig.logCreateGroup, +- logNonBlocking: containerStreamConfig.logNonBlocking, + forceFlushInterval: containerStreamConfig.forceFlushInterval, + multilinePattern: containerStreamConfig.multilinePattern, + client: client, +@@ -159,7 +158,7 @@ func New(info logger.Info) (logger.Logger, error) { + } + + creationDone := make(chan bool) +- if containerStream.logNonBlocking { ++ if logNonBlocking { + go func() { + backoff := 1 + maxBackoff := 32 +@@ -215,8 +214,6 @@ func newStreamConfig(info logger.Info) (*logStreamConfig, error) { + } + } + +- logNonBlocking := info.Config["mode"] == "non-blocking" +- + forceFlushInterval := defaultForceFlushInterval + if info.Config[forceFlushIntervalKey] != "" { + forceFlushIntervalAsInt, err := strconv.Atoi(info.Config[forceFlushIntervalKey]) +@@ -247,7 +244,6 @@ func newStreamConfig(info logger.Info) (*logStreamConfig, error) { + logStreamName: logStreamName, + logGroupName: logGroupName, + logCreateGroup: logCreateGroup, +- logNonBlocking: logNonBlocking, + forceFlushInterval: forceFlushInterval, + maxBufferedEvents: maxBufferedEvents, + multilinePattern: multilinePattern, +@@ -412,14 +408,6 @@ func (l *logStream) Log(msg *logger.Message) error { + if l.closed { + return errors.New("awslogs is closed") + } +- if l.logNonBlocking { +- select { +- case l.messages <- msg: +- return nil +- default: +- return errors.New("awslogs buffer is full") +- } +- } + l.messages <- msg + return nil + } +diff --git a/daemon/logger/awslogs/cloudwatchlogs_test.go b/daemon/logger/awslogs/cloudwatchlogs_test.go +index 688a3b5e2f..c5a0788303 100644 +--- a/daemon/logger/awslogs/cloudwatchlogs_test.go ++++ b/daemon/logger/awslogs/cloudwatchlogs_test.go +@@ -325,42 +325,16 @@ func TestLogBlocking(t *testing.T) { + } + } + +-func TestLogNonBlockingBufferEmpty(t *testing.T) { ++func TestLogBufferEmpty(t *testing.T) { + mockClient := newMockClient() + stream := &logStream{ +- client: mockClient, +- messages: make(chan *logger.Message, 1), +- logNonBlocking: true, ++ client: mockClient, ++ messages: make(chan *logger.Message, 1), + } + err := stream.Log(&logger.Message{}) + assert.NilError(t, err) + } + +-func TestLogNonBlockingBufferFull(t *testing.T) { +- mockClient := newMockClient() +- stream := &logStream{ +- client: mockClient, +- messages: make(chan *logger.Message, 1), +- logNonBlocking: true, +- } +- stream.messages <- &logger.Message{} +- errorCh := make(chan error, 1) +- started := make(chan bool) +- go func() { +- started <- true +- err := stream.Log(&logger.Message{}) +- errorCh <- err +- }() +- <-started +- select { +- case err := <-errorCh: +- if err == nil { +- t.Fatal("Expected non-nil error") +- } +- case <-time.After(30 * time.Second): +- t.Fatal("Expected Log call to not block") +- } +-} + func TestPublishBatchSuccess(t *testing.T) { + mockClient := newMockClient() + stream := &logStream{ +-- +2.32.0 (Apple Git-132) + diff --git a/patch/0002-daemon-daemon.prepareMountPoints-fix-panic-if-mount-.patch b/patch/0002-daemon-daemon.prepareMountPoints-fix-panic-if-mount-.patch new file mode 100644 index 0000000000000000000000000000000000000000..8d7f6effd5036368e50a8187b931afb4a812f2fd --- /dev/null +++ b/patch/0002-daemon-daemon.prepareMountPoints-fix-panic-if-mount-.patch @@ -0,0 +1,81 @@ +From 44152f6fb66da0ade1aa226f0b66ebbaa43d54b1 Mon Sep 17 00:00:00 2001 +From: Sebastiaan van Stijn +Date: Fri, 7 Jul 2023 14:54:04 +0200 +Subject: [PATCH 478/483] daemon: daemon.prepareMountPoints(): fix panic if + mount is not a volume + +The daemon.lazyInitializeVolume() function only handles restoring Volumes +if a Driver is specified. The Container's MountPoints field may also +contain other kind of mounts (e.g., bind-mounts). Those were ignored, and +don't return an error; https://github.com/moby/moby/blob/1d9c8619cded4657af1529779c5771127e8ad0e7/daemon/volumes.go#L243-L252C2 + +However, the prepareMountPoints() assumed each MountPoint was a volume, +and logged an informational message about the volume being restored; +https://github.com/moby/moby/blob/1d9c8619cded4657af1529779c5771127e8ad0e7/daemon/mounts.go#L18-L25 + +This would panic if the MountPoint was not a volume; + + github.com/docker/docker/daemon.(*Daemon).prepareMountPoints(0xc00054b7b8?, 0xc0007c2500) + /root/rpmbuild/BUILD/src/engine/.gopath/src/github.com/docker/docker/daemon/mounts.go:24 +0x1c0 + github.com/docker/docker/daemon.(*Daemon).restore.func5(0xc0007c2500, 0x0?) + /root/rpmbuild/BUILD/src/engine/.gopath/src/github.com/docker/docker/daemon/daemon.go:552 +0x271 + created by github.com/docker/docker/daemon.(*Daemon).restore + /root/rpmbuild/BUILD/src/engine/.gopath/src/github.com/docker/docker/daemon/daemon.go:530 +0x8d8 + panic: runtime error: invalid memory address or nil pointer dereference + [signal SIGSEGV: segmentation violation code=0x1 addr=0x30 pc=0x564e9be4c7c0] + +This issue was introduced in 647c2a6cdd86d79230df1bf690d0b6a2930d6db2 + +Signed-off-by: Sebastiaan van Stijn +(cherry picked from commit a490248f4d19164d78d3ef4f91cf142c3aad1790) +Signed-off-by: Cory Snider +--- + daemon/mounts.go | 4 ++++ + integration/daemon/daemon_test.go | 18 ++++++++++++++++++ + 2 files changed, 22 insertions(+) + +diff --git a/daemon/mounts.go b/daemon/mounts.go +index 424e375037..3c79b0d447 100644 +--- a/daemon/mounts.go ++++ b/daemon/mounts.go +@@ -17,6 +17,10 @@ func (daemon *Daemon) prepareMountPoints(container *container.Container) error { + if err := daemon.lazyInitializeVolume(container.ID, config); err != nil { + return err + } ++ if config.Volume == nil { ++ // FIXME(thaJeztah): should we check for config.Type here as well? (i.e., skip bind-mounts etc) ++ continue ++ } + if alive { + logrus.WithFields(logrus.Fields{ + "container": container.ID, +diff --git a/integration/daemon/daemon_test.go b/integration/daemon/daemon_test.go +index 47dac3b762..416b19d2b5 100644 +--- a/integration/daemon/daemon_test.go ++++ b/integration/daemon/daemon_test.go +@@ -102,4 +102,22 @@ func testLiveRestoreVolumeReferences(t *testing.T) { + err = c.VolumeRemove(ctx, v.Name, false) + assert.NilError(t, err) + }) ++ ++ // Make sure that we don't panic if the container has bind-mounts ++ // (which should not be "restored") ++ // Regression test for https://github.com/moby/moby/issues/45898 ++ t.Run("container with bind-mounts", func(t *testing.T) { ++ m := mount.Mount{ ++ Type: mount.TypeBind, ++ Source: os.TempDir(), ++ Target: "/foo", ++ } ++ cID := container.Run(ctx, t, c, container.WithMount(m), container.WithCmd("top")) ++ defer c.ContainerRemove(ctx, cID, types.ContainerRemoveOptions{Force: true}) ++ ++ d.Restart(t, "--live-restore", "--iptables=false") ++ ++ err := c.ContainerRemove(ctx, cID, types.ContainerRemoveOptions{Force: true}) ++ assert.NilError(t, err) ++ }) + } +-- +2.32.0 (Apple Git-132) + diff --git a/patch/README.md b/patch/README.md deleted file mode 100644 index dbd56a08c000daf8a43aa57a8eafcca9fe4f1751..0000000000000000000000000000000000000000 --- a/patch/README.md +++ /dev/null @@ -1 +0,0 @@ -This directory is used to apply patches for the project diff --git a/series.conf b/series.conf index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..f5beaceb137dfac4848be1e04565e8e5f4b2f0e8 100644 --- a/series.conf +++ b/series.conf @@ -0,0 +1,2 @@ +patch/0001-awslogs-fix-non-blocking-log-drop-bug.patch +patch/0002-daemon-daemon.prepareMountPoints-fix-panic-if-mount-.patch