Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Prevent invalid errors from terminate #1295

Closed
wants to merge 1 commit into from

Conversation

stevenh
Copy link
Contributor

@stevenh stevenh commented Jan 24, 2017

Both Process.Kill() and Process.Wait() can return errors that don't impact the correct behaviour of terminate.

Instead of letting these get returned and logged, which causes confusion, silently ignore them.

Currently the test needs to be a string test as the errors are private to the runtime packages, so its our only option.

This can be seen if init fails during the setns.

Signed-off-by: Steven Hartland steven.hartland@multiplay.co.uk


// TODO(steve): Update these to none string checks if the runtime exports them.
switch err.Error() {
case "os: process already finished", "exec: Wait was already called":
Copy link
Member

Choose a reason for hiding this comment

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

NACK. That's just not a good idea. Can you explain why you need the errors to be filtered? "Just silently ignore them inside a library" smells bad to me.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

We've requested the process be terminated, reporting an error due to the fact that the process had already gone is something the caller simply isn't interested in, as the desired effect has been achieved.

Its analogous to a method to remove a file reporting "file doesn't exist", the caller simply doesn't care.

To bring in some context:

  1. When the init process fails to exec execSetns fails.
  2. When execSetns fails it calls p.cmd.Wait() so the process has gone before return.
  3. newParentProcess returns the error.
  4. The cleanup code in container start() ensures everything is cleaned up by calling terminate.
  5. terminate returns the bogus error os: process already finished which is then logged.

Copy link
Member

@cyphar cyphar Jan 25, 2017

Choose a reason for hiding this comment

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

We've requested the process be terminated, reporting an error due to the fact that the process had already gone is something the caller simply isn't interested in, as the desired effect has been achieved.

That depends on your perspective, and is not logic that should exist in a library. If you've asked us to destroy a container, under the assumption the container already exists, then pretending as though it already exists can cause logic bugs and other such issues.

Its analogous to a method to remove a file reporting "file doesn't exist", the caller simply doesn't care.

Some callers might care, and that's why unlink(2) (for example) does return -ENOENT in such cases. It's up to the user of the API to make a decision about what they care about -- not the library.

  1. The cleanup code in container start() ensures everything is cleaned up by calling terminate.
  2. terminate returns the bogus error os: process already finished which is then logged.

Right, so it looks like our code is incorrectly handling this case. The solution is to fix the calling code -- not to filter code inside this code.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

If this was an public method I would totally agree, but as this is private and used solely for error recovery this seemed good.

However you are indeed correct that even though its private additional consumers of terminate could still be added where this behaviour is not desired, so I've moved the check to the consumer instead.

Both Process.Kill() and Process.Wait() can return errors that don't impact the correct behaviour of terminate.

Instead of letting these get returned and logged, which causes confusion, silently ignore them.

Currently the test needs to be a string test as the errors are private to the runtime packages, so its our only option.

This can be seen if init fails during the setns.

Signed-off-by: Steven Hartland <steven.hartland@multiplay.co.uk>
@stevenh
Copy link
Contributor Author

stevenh commented Feb 15, 2017

@cyphar does the move of the test satisfy your requirement?

@stevenh
Copy link
Contributor Author

stevenh commented Jun 7, 2017

@cyphar any update on this?

@cyphar
Copy link
Member

cyphar commented Jun 9, 2017

I think the point I was trying to make was that the solution was to fix when we call .terminate() internally, such that we won't call .terminate() when unecessary. But looking at it again, I want to see what the other maintainers think. I'll be honest, my main concern is how heavily this depends on the string representation of errors.

/cc @crosbymichael @mrunalp

@hqhq hqhq closed this in #1607 Oct 20, 2017
@stevenh stevenh deleted the terminate-errors branch October 20, 2017 07:55
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.

2 participants