1
0
Fork 0
mirror of https://github.com/moby/moby.git synced 2022-11-09 12:21:53 -05:00
moby--moby/daemon
Kir Kolyshkin 916eabd459 daemon.ContainerLogs(): fix resource leak on follow
When daemon.ContainerLogs() is called with options.follow=true
(as in "docker logs --follow"), the "loggerutils.followLogs()"
function never returns (even then the logs consumer is gone).
As a result, all the resources associated with it (including
an opened file descriptor for the log file being read, two FDs
for a pipe, and two FDs for inotify watch) are never released.

If this is repeated (such as by running "docker logs --follow"
and pressing Ctrl-C a few times), this results in DoS caused by
either hitting the limit of inotify watches, or the limit of
opened files. The only cure is daemon restart.

Apparently, what happens is:

1. logs producer (a container) is gone, calling (*LogWatcher).Close()
for all its readers (daemon/logger/jsonfilelog/jsonfilelog.go:175).

2. WatchClose() is properly handled by a dedicated goroutine in
followLogs(), cancelling the context.

3. Upon receiving the ctx.Done(), the code in followLogs()
(daemon/logger/loggerutils/logfile.go#L626-L638) keeps to
send messages _synchronously_ (which is OK for now).

4. Logs consumer is gone (Ctrl-C is pressed on a terminal running
"docker logs --follow"). Method (*LogWatcher).Close() is properly
called (see daemon/logs.go:114). Since it was called before and
due to to once.Do(), nothing happens (which is kinda good, as
otherwise it will panic on closing a closed channel).

5. A goroutine (see item 3 above) keeps sending log messages
synchronously to the logWatcher.Msg channel. Since the
channel reader is gone, the channel send operation blocks forever,
and resource cleanup set up in defer statements at the beginning
of followLogs() never happens.

Alas, the fix is somewhat complicated:

1. Distinguish between close from logs producer and logs consumer.
To that effect,
 - yet another channel is added to LogWatcher();
 - {Watch,}Close() are renamed to {Watch,}ProducerGone();
 - {Watch,}ConsumerGone() are added;

*NOTE* that ProducerGone()/WatchProducerGone() pair is ONLY needed
in order to stop ConsumerLogs(follow=true) when a container is stopped;
otherwise we're not interested in it. In other words, we're only
using it in followLogs().

2. Code that was doing (logWatcher*).Close() is modified to either call
ProducerGone() or ConsumerGone(), depending on the context.

3. Code that was waiting for WatchClose() is modified to wait for
either ConsumerGone() or ProducerGone(), or both, depending on the
context.

4. followLogs() are modified accordingly:
 - context cancellation is happening on WatchProducerGone(),
and once it's received the FileWatcher is closed and waitRead()
returns errDone on EOF (i.e. log rotation handling logic is disabled);
 - due to this, code that was writing synchronously to logWatcher.Msg
can be and is removed as the code above it handles this case;
 - function returns once ConsumerGone is received, freeing all the
resources -- this is the bugfix itself.

While at it,

1. Let's also remove the ctx usage to simplify the code a bit.
It was introduced by commit a69a59ffc7 ("Decouple removing the
fileWatcher from reading") in order to fix a bug. The bug was actually
a deadlock in fsnotify, and the fix was just a workaround. Since then
the fsnofify bug has been fixed, and a new fsnotify was vendored in.
For more details, please see
https://github.com/moby/moby/pull/27782#issuecomment-416794490

2. Since `(*filePoller).Close()` is fixed to remove all the files
being watched, there is no need to explicitly call
fileWatcher.Remove(name) anymore, so get rid of the extra code.

Should fix https://github.com/moby/moby/issues/37391

Signed-off-by: Kir Kolyshkin <kolyshkin@gmail.com>
2018-09-06 11:47:42 -07:00
..
caps lcow: Allow the client to add or remove capabilities 2018-06-15 16:03:33 -07:00
cluster Merge pull request #37650 from anshulpundir/vndr 2018-08-22 12:51:47 +01:00
config Fix logic when enabling buildkit 2018-08-21 23:49:08 +00:00
discovery Update tests to use gotest.tools 👼 2018-06-13 09:04:30 +02:00
events Add canonical import comment 2018-02-05 16:51:57 -05:00
exec Fix race condition between exec start and resize 2018-06-08 11:07:48 +08:00
graphdriver Merge pull request #37659 from Microsoft/jjh/37356 2018-08-17 15:48:35 -07:00
images distribution: fix passing platform struct to puller 2018-06-27 14:59:31 -07:00
initlayer Add ADD/COPY --chown flag support to Windows 2018-08-13 21:59:11 -07:00
links Add canonical import comment 2018-02-05 16:51:57 -05:00
listeners Adapt listeners to upstream API changes in go-systemd 2018-05-23 21:57:30 +02:00
logger daemon.ContainerLogs(): fix resource leak on follow 2018-09-06 11:47:42 -07:00
names Add canonical import comment 2018-02-05 16:51:57 -05:00
network Block task starting until node attachments are ready 2018-08-20 15:28:15 -05:00
stats Fix stats collector spinning CPU if no stats are collected 2018-03-15 17:56:15 +01:00
testdata
apparmor_default.go Add canonical import comment 2018-02-05 16:51:57 -05:00
apparmor_default_unsupported.go Add canonical import comment 2018-02-05 16:51:57 -05:00
archive.go Add canonical import comment 2018-02-05 16:51:57 -05:00
archive_tarcopyoptions.go Add ADD/COPY --chown flag support to Windows 2018-08-13 21:59:11 -07:00
archive_tarcopyoptions_unix.go Add ADD/COPY --chown flag support to Windows 2018-08-13 21:59:11 -07:00
archive_tarcopyoptions_windows.go Add canonical import comment 2018-02-05 16:51:57 -05:00
archive_unix.go Move mount parsing to separate package. 2018-04-19 06:35:54 -04:00
archive_windows.go Add canonical import comment 2018-02-05 16:51:57 -05:00
attach.go daemon.ContainerLogs(): fix resource leak on follow 2018-09-06 11:47:42 -07:00
auth.go Switch from x/net/context -> context 2018-04-23 13:52:44 -07:00
bindmount_unix.go Add canonical import comment 2018-02-05 16:51:57 -05:00
changes.go c.RWLayer: check for nil before use 2018-02-09 11:24:09 -08:00
checkpoint.go Add canonical import comment 2018-02-05 16:51:57 -05:00
cluster.go Move network conversions out of API router 2018-06-27 17:11:29 -07:00
commit.go Move all daemon image methods into imageService 2018-02-26 16:48:29 -05:00
configs.go Merge configs/secrets in unix implementation 2018-02-16 11:25:14 -05:00
configs_linux.go Add canonical import comment 2018-02-05 16:51:57 -05:00
configs_unsupported.go Add canonical import comment 2018-02-05 16:51:57 -05:00
configs_windows.go Add canonical import comment 2018-02-05 16:51:57 -05:00
container.go Move mount parsing to separate package. 2018-04-19 06:35:54 -04:00
container_linux.go Add canonical import comment 2018-02-05 16:51:57 -05:00
container_operations.go Fixes for resolv.conf 2018-07-26 11:17:56 -07:00
container_operations_unix.go Add ADD/COPY --chown flag support to Windows 2018-08-13 21:59:11 -07:00
container_operations_windows.go Fixes for resolv.conf 2018-07-26 11:17:56 -07:00
container_unix_test.go Update tests to use gotest.tools 👼 2018-06-13 09:04:30 +02:00
container_windows.go Add canonical import comment 2018-02-05 16:51:57 -05:00
create.go Add ADD/COPY --chown flag support to Windows 2018-08-13 21:59:11 -07:00
create_test.go Update tests to use gotest.tools 👼 2018-06-13 09:04:30 +02:00
create_unix.go Add ADD/COPY --chown flag support to Windows 2018-08-13 21:59:11 -07:00
create_windows.go Extract volume interaction to a volumes service 2018-05-25 14:21:07 -04:00
daemon.go allow features option live reloadable 2018-08-31 12:43:04 -07:00
daemon_linux.go Fixes for resolv.conf 2018-07-26 11:17:56 -07:00
daemon_linux_test.go Add ADD/COPY --chown flag support to Windows 2018-08-13 21:59:11 -07:00
daemon_test.go Add ADD/COPY --chown flag support to Windows 2018-08-13 21:59:11 -07:00
daemon_unix.go Add ADD/COPY --chown flag support to Windows 2018-08-13 21:59:11 -07:00
daemon_unix_test.go Remove old/uneeded volume migration from vers 1.7 2018-04-17 14:06:53 -04:00
daemon_unsupported.go Fixes for resolv.conf 2018-07-26 11:17:56 -07:00
daemon_windows.go Add ADD/COPY --chown flag support to Windows 2018-08-13 21:59:11 -07:00
daemon_windows_test.go Add canonical import comment 2018-02-05 16:51:57 -05:00
debugtrap_unix.go Add canonical import comment 2018-02-05 16:51:57 -05:00
debugtrap_unsupported.go Add canonical import comment 2018-02-05 16:51:57 -05:00
debugtrap_windows.go Add canonical import comment 2018-02-05 16:51:57 -05:00
delete.go Extract volume interaction to a volumes service 2018-05-25 14:21:07 -04:00
delete_test.go Update tests to use gotest.tools 👼 2018-06-13 09:04:30 +02:00
dependency.go Add canonical import comment 2018-02-05 16:51:57 -05:00
disk_usage.go Extract volume interaction to a volumes service 2018-05-25 14:21:07 -04:00
errors.go Extract volume interaction to a volumes service 2018-05-25 14:21:07 -04:00
events.go Image events 2018-02-21 18:26:16 -05:00
events_test.go Add canonical import comment 2018-02-05 16:51:57 -05:00
exec.go Fix race condition between exec start and resize 2018-06-08 11:07:48 +08:00
exec_linux.go Fix AppArmor not being applied to Exec processes 2018-03-02 14:05:36 +01:00
exec_linux_test.go Update tests to use gotest.tools 👼 2018-06-13 09:04:30 +02:00
exec_windows.go Add canonical import comment 2018-02-05 16:51:57 -05:00
export.go Add ADD/COPY --chown flag support to Windows 2018-08-13 21:59:11 -07:00
health.go Switch from x/net/context -> context 2018-04-23 13:52:44 -07:00
health_test.go Add canonical import comment 2018-02-05 16:51:57 -05:00
info.go Add warning if REST API is accessible through an insecure connection 2018-08-21 22:03:24 +02:00
info_unix.go Add "Warnings" to /info endpoint, and move detection to the daemon 2018-08-21 11:36:15 +02:00
info_unix_test.go Update tests to use gotest.tools 👼 2018-06-13 09:04:30 +02:00
info_windows.go Add "Warnings" to /info endpoint, and move detection to the daemon 2018-08-21 11:36:15 +02:00
inspect.go Extract volume interaction to a volumes service 2018-05-25 14:21:07 -04:00
inspect_linux.go Add canonical import comment 2018-02-05 16:51:57 -05:00
inspect_test.go Update tests to use gotest.tools 👼 2018-06-13 09:04:30 +02:00
inspect_windows.go Add canonical import comment 2018-02-05 16:51:57 -05:00
keys.go Add canonical import comment 2018-02-05 16:51:57 -05:00
keys_unsupported.go Add canonical import comment 2018-02-05 16:51:57 -05:00
kill.go daemon/*.go: fix some Wrap[f]/Warn[f] errors 2018-07-11 15:51:51 +02:00
licensing.go Expose license status in Info (#37612) 2018-08-17 17:05:21 -07:00
licensing_test.go Expose license status in Info (#37612) 2018-08-17 17:05:21 -07:00
links.go Add canonical import comment 2018-02-05 16:51:57 -05:00
list.go Fix regression when filtering container names using a leading slash 2018-08-28 21:40:13 +02:00
list_test.go Fix regression when filtering container names using a leading slash 2018-08-28 21:40:13 +02:00
list_unix.go Add canonical import comment 2018-02-05 16:51:57 -05:00
list_windows.go Add canonical import comment 2018-02-05 16:51:57 -05:00
logdrivers_linux.go Add new local log driver 2018-08-17 09:36:56 -07:00
logdrivers_windows.go enable gcplogs driver on windows 2018-08-23 20:02:04 +00:00
logs.go daemon.ContainerLogs(): fix resource leak on follow 2018-09-06 11:47:42 -07:00
logs_test.go Add canonical import comment 2018-02-05 16:51:57 -05:00
metrics.go Move plugin client to separate interface 2018-05-30 15:22:10 -04:00
metrics_unix.go Move plugin client creation to the extension point 2018-05-25 15:18:53 -04:00
metrics_unsupported.go Add canonical import comment 2018-02-05 16:51:57 -05:00
monitor.go daemon/*.go: fix some Wrap[f]/Warn[f] errors 2018-07-11 15:51:51 +02:00
mounts.go Extract volume interaction to a volumes service 2018-05-25 14:21:07 -04:00
names.go Add canonical import comment 2018-02-05 16:51:57 -05:00
network.go builder: setup code for a bridge networking 2018-08-20 18:55:01 +00:00
oci.go lcow: Allow the client to add device cgroup rules 2018-06-15 16:14:17 -07:00
oci_linux.go Fix docker --init with /dev bind mount 2018-08-27 15:38:46 -07:00
oci_linux_test.go Add ADD/COPY --chown flag support to Windows 2018-08-13 21:59:11 -07:00
oci_windows.go lcow: Allow the client to add device cgroup rules 2018-06-15 16:14:17 -07:00
pause.go Add canonical import comment 2018-02-05 16:51:57 -05:00
prune.go Move network conversions out of API router 2018-06-27 17:11:29 -07:00
reload.go allow features option live reloadable 2018-08-31 12:43:04 -07:00
reload_test.go Update tests to use gotest.tools 👼 2018-06-13 09:04:30 +02:00
reload_unix.go Add canonical import comment 2018-02-05 16:51:57 -05:00
reload_windows.go Add canonical import comment 2018-02-05 16:51:57 -05:00
rename.go Add canonical import comment 2018-02-05 16:51:57 -05:00
resize.go Fix race condition between exec start and resize 2018-06-08 11:07:48 +08:00
resize_test.go Update tests to use gotest.tools 👼 2018-06-13 09:04:30 +02:00
restart.go Add canonical import comment 2018-02-05 16:51:57 -05:00
seccomp_disabled.go Add canonical import comment 2018-02-05 16:51:57 -05:00
seccomp_linux.go Add canonical import comment 2018-02-05 16:51:57 -05:00
seccomp_unsupported.go Add canonical import comment 2018-02-05 16:51:57 -05:00
secrets.go Add canonical import comment 2018-02-05 16:51:57 -05:00
secrets_linux.go Add canonical import comment 2018-02-05 16:51:57 -05:00
secrets_unsupported.go Add canonical import comment 2018-02-05 16:51:57 -05:00
secrets_windows.go Add canonical import comment 2018-02-05 16:51:57 -05:00
selinux_linux.go Add canonical import comment 2018-02-05 16:51:57 -05:00
selinux_unsupported.go Add canonical import comment 2018-02-05 16:51:57 -05:00
start.go Move ImageService to new package 2018-02-26 16:49:37 -05:00
start_unix.go vendor: update containerd to 63522d9 2018-06-08 19:19:06 -07:00
start_windows.go Add canonical import comment 2018-02-05 16:51:57 -05:00
stats.go Switch from x/net/context -> context 2018-04-23 13:52:44 -07:00
stats_collector.go Add canonical import comment 2018-02-05 16:51:57 -05:00
stats_unix.go Add canonical import comment 2018-02-05 16:51:57 -05:00
stats_windows.go Add canonical import comment 2018-02-05 16:51:57 -05:00
stop.go daemon.ContainerStop(): fix for a negative timeout 2018-05-03 10:04:33 -07:00
top_unix.go ContainerTop: improve error message 2018-05-24 18:24:36 -07:00
top_unix_test.go Add canonical import comment 2018-02-05 16:51:57 -05:00
top_windows.go Add canonical import comment 2018-02-05 16:51:57 -05:00
trustkey.go Add canonical import comment 2018-02-05 16:51:57 -05:00
trustkey_test.go Update tests to use gotest.tools 👼 2018-06-13 09:04:30 +02:00
unpause.go daemon/*.go: fix some Wrap[f]/Warn[f] errors 2018-07-11 15:51:51 +02:00
update.go Add canonical import comment 2018-02-05 16:51:57 -05:00
update_linux.go Various code-cleanup 2018-05-23 17:50:54 +02:00
update_windows.go Add canonical import comment 2018-02-05 16:51:57 -05:00
util_test.go Fix race condition between exec start and resize 2018-06-08 11:07:48 +08:00
volumes.go Fix relabeling local volume source dir 2018-08-30 15:58:49 -07:00
volumes_linux.go Fix the several typos detected by github.com/client9/misspell 2018-08-09 00:45:00 +09:00
volumes_linux_test.go Use rslave propagation for mounts from daemon root 2018-02-07 14:27:09 -05:00
volumes_unit_test.go Move mount parsing to separate package. 2018-04-19 06:35:54 -04:00
volumes_unix.go Add ADD/COPY --chown flag support to Windows 2018-08-13 21:59:11 -07:00
volumes_unix_test.go Move mount parsing to separate package. 2018-04-19 06:35:54 -04:00
volumes_windows.go Add ADD/COPY --chown flag support to Windows 2018-08-13 21:59:11 -07:00
wait.go Switch from x/net/context -> context 2018-04-23 13:52:44 -07:00
workdir.go Add ADD/COPY --chown flag support to Windows 2018-08-13 21:59:11 -07:00