{"push_id":2863833392,"size":5,"distinct_size":5,"ref":"refs/heads/master","head":"77faf158f5265711dbcbff0ffb855eed2e3b6ccd","before":"703a04ebc90d6d3a9eba878d1170ce446f088738","commits":[{"sha":"2e4c2a6bf9cb47fd07e42f9c043024ed3dbcd04d","author":{"name":"Kir Kolyshkin","email":"3a017b8ddb3f9cf3e4a59978b004111bdeb97f08@gmail.com"},"message":"daemon.ContainerLogs: minor debug logging cleanup\n\nThis code has many return statements, for some of them the\n\"end logs\" or \"end stream\" message was not printed, giving\nthe impression that this \"for\" loop never ended.\n\nMake sure that \"begin logs\" is to be followed by \"end logs\".\n\nSigned-off-by: Kir Kolyshkin <kolyshkin@gmail.com>","distinct":true,"url":"https://api.github.com/repos/docker/engine/commits/2e4c2a6bf9cb47fd07e42f9c043024ed3dbcd04d"},{"sha":"d37a11bfbab83ab42b1160f116e863daac046192","author":{"name":"Brian Goff","email":"dc73d0991b982a8303e713ef531a313af77e242a@gmail.com"},"message":"daemon/logger/loggerutils: add TestFollowLogsClose\n\nThis test case checks that followLogs() exits once the reader is gone.\nCurrently it does not (i.e. this test is supposed to fail) due to #37391.\n\n[kolyshkin@: test case Brian Goff, changelog and all bugs are by me]\nSource: https://gist.github.com/cpuguy83/e538793de18c762608358ee0eaddc197\n\nSigned-off-by: Kir Kolyshkin <kolyshkin@gmail.com>","distinct":true,"url":"https://api.github.com/repos/docker/engine/commits/d37a11bfbab83ab42b1160f116e863daac046192"},{"sha":"916eabd459fe707b5c4a86377d12e2ad1871b353","author":{"name":"Kir Kolyshkin","email":"3a017b8ddb3f9cf3e4a59978b004111bdeb97f08@gmail.com"},"message":"daemon.ContainerLogs(): fix resource leak on follow\n\nWhen daemon.ContainerLogs() is called with options.follow=true\n(as in \"docker logs --follow\"), the \"loggerutils.followLogs()\"\nfunction never returns (even then the logs consumer is gone).\nAs a result, all the resources associated with it (including\nan opened file descriptor for the log file being read, two FDs\nfor a pipe, and two FDs for inotify watch) are never released.\n\nIf this is repeated (such as by running \"docker logs --follow\"\nand pressing Ctrl-C a few times), this results in DoS caused by\neither hitting the limit of inotify watches, or the limit of\nopened files. The only cure is daemon restart.\n\nApparently, what happens is:\n\n1. logs producer (a container) is gone, calling (*LogWatcher).Close()\nfor all its readers (daemon/logger/jsonfilelog/jsonfilelog.go:175).\n\n2. WatchClose() is properly handled by a dedicated goroutine in\nfollowLogs(), cancelling the context.\n\n3. Upon receiving the ctx.Done(), the code in followLogs()\n(daemon/logger/loggerutils/logfile.go#L626-L638) keeps to\nsend messages _synchronously_ (which is OK for now).\n\n4. Logs consumer is gone (Ctrl-C is pressed on a terminal running\n\"docker logs --follow\"). Method (*LogWatcher).Close() is properly\ncalled (see daemon/logs.go:114). Since it was called before and\ndue to to once.Do(), nothing happens (which is kinda good, as\notherwise it will panic on closing a closed channel).\n\n5. A goroutine (see item 3 above) keeps sending log messages\nsynchronously to the logWatcher.Msg channel. Since the\nchannel reader is gone, the channel send operation blocks forever,\nand resource cleanup set up in defer statements at the beginning\nof followLogs() never happens.\n\nAlas, the fix is somewhat complicated:\n\n1. Distinguish between close from logs producer and logs consumer.\nTo that effect,\n - yet another channel is added to LogWatcher();\n - {Watch,}Close() are renamed to {Watch,}ProducerGone();\n - {Watch,}ConsumerGone() are added;\n\n*NOTE* that ProducerGone()/WatchProducerGone() pair is ONLY needed\nin order to stop ConsumerLogs(follow=true) when a container is stopped;\notherwise we're not interested in it. In other words, we're only\nusing it in followLogs().\n\n2. Code that was doing (logWatcher*).Close() is modified to either call\nProducerGone() or ConsumerGone(), depending on the context.\n\n3. Code that was waiting for WatchClose() is modified to wait for\neither ConsumerGone() or ProducerGone(), or both, depending on the\ncontext.\n\n4. followLogs() are modified accordingly:\n - context cancellation is happening on WatchProducerGone(),\nand once it's received the FileWatcher is closed and waitRead()\nreturns errDone on EOF (i.e. log rotation handling logic is disabled);\n - due to this, code that was writing synchronously to logWatcher.Msg\ncan be and is removed as the code above it handles this case;\n - function returns once ConsumerGone is received, freeing all the\nresources -- this is the bugfix itself.\n\nWhile at it,\n\n1. Let's also remove the ctx usage to simplify the code a bit.\nIt was introduced by commit a69a59ffc7e3d (\"Decouple removing the\nfileWatcher from reading\") in order to fix a bug. The bug was actually\na deadlock in fsnotify, and the fix was just a workaround. Since then\nthe fsnofify bug has been fixed, and a new fsnotify was vendored in.\nFor more details, please see\nhttps://github.com/moby/moby/pull/27782#issuecomment-416794490\n\n2. Since `(*filePoller).Close()` is fixed to remove all the files\nbeing watched, there is no need to explicitly call\nfileWatcher.Remove(name) anymore, so get rid of the extra code.\n\nShould fix https://github.com/moby/moby/issues/37391\n\nSigned-off-by: Kir Kolyshkin <kolyshkin@gmail.com>","distinct":true,"url":"https://api.github.com/repos/docker/engine/commits/916eabd459fe707b5c4a86377d12e2ad1871b353"},{"sha":"f845d76d047760c91dc0c7076aea840291fbdbc5","author":{"name":"Kir Kolyshkin","email":"3a017b8ddb3f9cf3e4a59978b004111bdeb97f08@gmail.com"},"message":"TestFollowLogsProducerGone: add\n\nThis should test that\n - all the messages produced are delivered (i.e. not lost)\n - followLogs() exits\n\nLoosely based on the test having the same name by Brian Goff, see\nhttps://gist.github.com/cpuguy83/e538793de18c762608358ee0eaddc197\n\nSigned-off-by: Kir Kolyshkin <kolyshkin@gmail.com>","distinct":true,"url":"https://api.github.com/repos/docker/engine/commits/f845d76d047760c91dc0c7076aea840291fbdbc5"},{"sha":"77faf158f5265711dbcbff0ffb855eed2e3b6ccd","author":{"name":"Sebastiaan van Stijn","email":"2b34a3e3e055981c6c83bcd4f9afd06751b4ac0e@users.noreply.github.com"},"message":"Merge pull request #37576 from kolyshkin/logs-f-leak\n\ndaemon.ContainerLogs(): fix resource leak on follow","distinct":true,"url":"https://api.github.com/repos/docker/engine/commits/77faf158f5265711dbcbff0ffb855eed2e3b6ccd"}]}
{"actor":{"display_login":"docker-jenkins"}}