Skip to content

Offer a means to send the tty to the Apple log system#199

Merged
ijc merged 6 commits intomoby:masterfrom
akimd:asl2
Apr 10, 2018
Merged

Offer a means to send the tty to the Apple log system#199
ijc merged 6 commits intomoby:masterfrom
akimd:asl2

Conversation

@akimd
Copy link
Contributor

@akimd akimd commented Apr 9, 2018

This is #196 rewritten with comments from @rn and @ijc integrated.

On Docker for Windows, all the logs are aggregated: GUI, LinuxKit, etc. Currently debugging on Docker for Mac is less easy, in particular because LinuxKit's log are sent to the consolefile rings of fixed sized buffers. As a result, it's hard to find the interleaving of actions between Docker for Mac and LinuxKit, the console files are fragmented and full of '\0', etc.

It is possible to have hyperkit redirect the tty's output to its stderr/stdout, and then its caller (Docker for Mac's driver) could redirect these streams to the logger. Unfortunately on recent macOS releases, asl is replaced by os_log which uses exclusively the path of the executable as source (changing argv[0] is useless). As a result, hyperkit's logs are "credited" to the driver.

The most elegant approach is to embrace asl/os_log.

Currently Docker for Mac still targets 10.11, and os_log appeared in macOS 10.12, so we cannot use directly os_log's API, we use it through the asl shim.

  • add a new device configuration, asl, that sends the tty's output to asl
  • in Go, add a new ConsoleLog enum to enum it.

Since some of the logs use escapes for the terminal, escapes appear in the logs. But that's another issue.

2018-03-30 10:09:04.784291 +0200	par défaut	75122	com.docker.hyperkit	\^[[34mINFO\^[[0m[0000] starting containerd                           \^[[34mmodule\^[[0m=containerd \^[[34mrevision\^[[0m=9b55aab90508bd389d7654c4baf173a981477d55 \^[[34mversion\^[[0m=v1.0.1
2018-03-30 10:09:04.785597 +0200	par défaut	75122	com.docker.hyperkit	\^[[34mINFO\^[[0m[0000] loading plugin "io.containerd.content.v1.content"...  \^[[34mmodule\^[[0m=containerd \^[[34mtype\^[[0m=io.containerd.content.v1
2018-03-30 10:09:04.786756 +0200	par défaut	75122	com.docker.hyperkit	\^[[34mINFO\^[[0m[0000] loading plugin "io.containerd.snapshotter.v1.btrfs"...  \^[[34mmodule\^[[0m=containerd \^[[34mtype\^[[0m=io.containerd.snapshotter.v1
2018-03-30 10:09:04.788161 +0200	par défaut	75122	com.docker.hyperkit	\^[[33mWARN\^[[0m[0000] failed to load plugin io.containerd.snapshotter.v1.btrfs  \^[[33merror\^[[0m="path /var/lib/containerd/io.containerd.snapshotter.v1.btrfs must be a btrfs filesystem to be used with the btrfs snapshotter" \^[[33mmodule\^[[0m=containerd

@ijc
Copy link
Collaborator

ijc commented Apr 9, 2018

FYI you can force push to an existing branch with a PR and GH will do the right thing, you don't close the PR and carry just to do a rebase.

Anyway, this LGTM (once CI is green) if @rn is happy with the commit split.

}


/* Send one character to the logger: wait for full lines before actually sending. */
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There's a slight risk that hyperkit or the guest might crash with something useful still buffered.

There isn't much we can sensibly do if hyperkit has crashed, but a guest crash will look like a VM shutdown and be controlled from the hypervisor PoV -- perhaps (as a future improvement?) we should add a log_flush somewhere on the hyperkit exit path?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sounds good.

{
buf[buf_idx] = 0;
asl_log(log_client, log_msg, ASL_LEVEL_NOTICE, "%s", buf);
buf_idx = 0;
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we care that \n\n\n\n will log a bunch of blank messages? A simple if (buf_idx == 0) return check at the top would fix that if we did.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actually, that's what I wanted, to keep the current output.

image

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah, yes, that's a good point.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

BTW, would you happen to know why we have two whales? Maybe it's D4D specific, I have not checked yet, but I'm kinda worried by the backslashes having been processed.

image

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There was some strangeness wrt how/where motd was handled in linuxkit but that was more than a year ago, I don't recall having seen anything like this recently.

Are you running the getty in a container or within the root? Or even both (which might explain things)?

I presume the console is functional (i.e. you can login and type normally)? If it isn't that might suggest you've got two getty processes somehow.

Only other thought I have is if you had configured two serial ports you would get a getty and motd on both of them, but the patches here would combine them into the logs without indicating which was which. If that were the case I'd expect them to be more mixed up though.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Before these patches, both whales were already in console-ring. I have not dug the issue yet, so I can't even answer to your questions now. It was just in case it rang a bell. Thanks for the hints, I'll use them when I focus on the twin-whale-issue.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actually looks like I misremembered. In LinuxKit (modern ones at least) it is actually an initscript which cats /etc/issue (not motd) to any device with a console= on the kernel command line.

Looks like agetty (which LinuxKit uses) will also print /etc/issue but if it is in a container then that is a different /etc/issue, unless you bind it in or arrange to use a different getty container. LinuxKit demos don't have that bind but maybe you do? Or if you were running getty on the host you would see it.

@ijc
Copy link
Collaborator

ijc commented Apr 9, 2018

Two things occurred to me right after I said "LGTM", but neither need to be blockers IMHO.

@akimd
Copy link
Contributor Author

akimd commented Apr 9, 2018

@ijc I will make more changes anyway, so let's log_flush this now :)

The failure is not mine I think, but I'm not allowed to restart.

@ijc
Copy link
Collaborator

ijc commented Apr 9, 2018

I've kicked the CI to have another go.

@ijc
Copy link
Collaborator

ijc commented Apr 9, 2018

Seems like either brew or the base image used by CircleCI is a bit fucked at the moment:

Error: The `brew link` step did not complete successfully
The formula built, but is not symlinked into /usr/local
Could not symlink bin/2to3-2
Target /usr/local/bin/2to3-2
is a symlink belonging to python. You can unlink it:
  brew unlink python

To force the link and overwrite all conflicting files:
  brew link --overwrite python@2

To list all files that would be deleted:
  brew link --overwrite --dry-run python@2

Not sure how to workaround that. I'm going to give it a day and see if things resolve themselves.

@ijc
Copy link
Collaborator

ijc commented Apr 10, 2018

I've added a workaround for the CI breakage in #202 which has now been merged. Please rebase onto current master to pickup the change and force push the change to your branch here. Sorry for the inconvenience.

@akimd
Copy link
Contributor Author

akimd commented Apr 10, 2018

Different failure :)

@ijc
Copy link
Collaborator

ijc commented Apr 10, 2018

Oh ffs, investigating now...

@ijc
Copy link
Collaborator

ijc commented Apr 10, 2018

The fix in #207 is merged, please rebase again (sorry)

akimd added 6 commits April 10, 2018 17:22
Signed-off-by: Akim Demaille <akim.demaille@docker.com>
Signed-off-by: Akim Demaille <akim.demaille@docker.com>
On Docker for Windows, all the logs are aggregated: GUI, LinuxKit,
etc.  Currently debugging on Docker for Mac is less easy, in
particular because LinuxKit's log are sent to the consolefile rings of
fixed sized buffers.  As a result, it's hard to find the interleaving
of actions between Docker for Mac and LinuxKit, the console files are
fragmented and full of '\0', etc.

It is possible to have hyperkit redirect the tty's output to its
stderr/stdout, and then its caller (Docker for Mac's driver) could
redirect these streams to the logger.  Unfortunately on recent macOS
releases, asl is replaced by os_log which uses exclusively the path of
the executable as source (changing `argv[0]` is useless).  As a
result, hyperkit's logs are "credited" to the driver.

The most elegant approach is to embrace asl/os_log.

Currently Docker for Mac still targets 10.11, and os_log appeared in
macOS 10.12, so we cannot use directly os_log's API, we use it through
the asl shim.

Add a new device configuration, asl, that sends the tty's output to asl.

Signed-off-by: Akim Demaille <akim.demaille@docker.com>
In some earlier experiment this function was called several times.
Since it made the code slightly easier to understand, I left it.

Signed-off-by: Akim Demaille <akim.demaille@docker.com>
Hyperkit.check verifies that if `h.Console == ConsoleStdio`, then
either `isTerminal(os.Stdout)` or `h.StateDir != ""`.

In the next commit, the device configuration becomes more complex, and
simplifying this conditional by eliminating impossible situations
makes this next commit clearer.

Signed-off-by: Akim Demaille <akim.demaille@docker.com>
Signed-off-by: Akim Demaille <akim.demaille@docker.com>
@akimd
Copy link
Contributor Author

akimd commented Apr 10, 2018

No worries!

I guess I guess what ffs means, and it never occurred to me that Franz Ferdinand and the Sparks could have been naughty...

@ijc
Copy link
Collaborator

ijc commented Apr 10, 2018

Heh, I was not previously aware of their work!

Merging now while we have the chance, before CI gets picky again...

@ijc ijc merged commit af56683 into moby:master Apr 10, 2018
@akimd
Copy link
Contributor Author

akimd commented Apr 10, 2018

Yeah!

@akimd akimd deleted the asl2 branch April 10, 2018 16:01
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants