Skip to content

pkg/system: move process-functions to pkg/process, improve pkg/pidfile and reduce overlap#44304

Merged
thaJeztah merged 11 commits intomoby:masterfrom
thaJeztah:sys_move_process
Nov 5, 2022
Merged

pkg/system: move process-functions to pkg/process, improve pkg/pidfile and reduce overlap#44304
thaJeztah merged 11 commits intomoby:masterfrom
thaJeztah:sys_move_process

Conversation

@thaJeztah
Copy link
Copy Markdown
Member

@thaJeztah thaJeztah commented Oct 15, 2022

See individual commits for details 😅

@thaJeztah thaJeztah added status/2-code-review kind/refactor PR's that refactor, or clean-up code labels Oct 15, 2022
@thaJeztah thaJeztah added this to the v-next milestone Oct 15, 2022
@thaJeztah thaJeztah marked this pull request as draft October 15, 2022 20:28
@thaJeztah thaJeztah marked this pull request as ready for review October 15, 2022 23:56
Comment thread pkg/process/process_unix.go
Comment thread pkg/process/process_test.go Outdated
Comment thread pkg/pidfile/pidfile_test.go Outdated
Comment thread pkg/process/process_unix.go Outdated
Comment thread pkg/process/process_unix.go Outdated
if pid < 1 {
return
}
_ = unix.Kill(pid, unix.SIGKILL)
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Since this is a new package without any back-compat concerns, thoughts on returning the error to the caller?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

I guess I did so to keep the old signature (to make it a drop-in replacement), but I can change it (and just make a thin wrapper for the alias) 👍

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

Hmm.. actually getting back to this; wondering how useful the error would be; SIGKILL cannot be ignored, so the process "must" be terminated, so in which case would we get a useful error?

  • no permissions (not running as root ?)
  • process doesn't (no longer) exist; the intent of this function is to terminate the process, so this should be fine as well 🤔

Was there a specific error-case you had in mind?

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

EPERM would absolutely be a useful error to return, because this function is inside a pkg-tree package. Since the policy is that pkg-tree packages are meant to be reusable outside of the daemon, functions in these packages shouldn't really be assuming they will be running as root. I think it would make sense to swallow ESRCH (no such process) because, as you point out, the intent of the call is to make the PID not exist so task failed successfully.

I think it would also be useful to not swallow any "impossible" errors such as ENOSYS or EINVAL. It's not outside the realm of possibility for some sysadmin to apply a seccomp filter or apparmor profile to the daemon which blocks the kill syscall, for example. Though the calling process would be running in a very insane environment if SIGKILL is an invalid signal or the syscall is returning nonsensical errors; perhaps the only sane thing to do in an insane world is to panic()?

Comment thread pkg/pidfile/pidfile.go Outdated
@thaJeztah thaJeztah force-pushed the sys_move_process branch 3 times, most recently from 1df8639 to 2c0c270 Compare November 3, 2022 21:00
@thaJeztah
Copy link
Copy Markdown
Member Author

@corhere updated; PTAL 👍

Comment thread pkg/process/process_windows.go Outdated
}

// Kill force-stops a process.
func Kill(pid int) {
Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

oh! forgot the windows one; give me 5 minutes

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

done 👍

Copy link
Copy Markdown
Contributor

@corhere corhere left a comment

Choose a reason for hiding this comment

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

LGTM!

Comment thread daemon/container_operations_unix.go Outdated
// Since we can not kill a zombie pid, add zombie check here
isZombie, err := system.IsProcessZombie(pid)
isZombie, err := process.Zombie(pid)
// TODO(thaJeztah) should we ignore os.IsNotExist() here? ("/proc/<pid>/stat" will be gone if the process exited)
Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

Oh! Forgot this TODO; that one can be removed now

If the file doesn't exist, the process isn't running, so we should be able
to ignore that.

Also remove an intermediate variable.

Signed-off-by: Sebastiaan van Stijn <[email protected]>
…stead

bytes.SplitN() is more performant, and skips having to do the conversion.

Signed-off-by: Sebastiaan van Stijn <[email protected]>
Using the implementation from pkg/pidfile for windows, as that implementation
looks to be handling more cases to check if a process is still alive (or to be
considered alive).

Signed-off-by: Sebastiaan van Stijn <[email protected]>
unix.Kill() does not produce an error for PID 0, -1. As a result, checking
process.Alive() would return "true" for both 0 and -1 on macOS (and previously
on Linux as well).

Let's shortcut these values to consider them "not alive", to prevent someone
trying to kill them.

A basic test was added to check the behavior.

Given that the intent of these functions is to handle single processes, this patch
also prevents 0 and negative values to be used.

From KILL(2): https://man7.org/linux/man-pages/man2/kill.2.html

    If pid is positive, then signal sig is sent to the process with
    the ID specified by pid.

    If pid equals 0, then sig is sent to every process in the process
    group of the calling process.

    If pid equals -1, then sig is sent to every process for which the
    calling process has permission to send signals, except for
    process 1 (init), but see below.

    If pid is less than -1, then sig is sent to every process in the
    process group whose ID is -pid.

Signed-off-by: Sebastiaan van Stijn <[email protected]>
This allows it to be used for processes other than the daemon itself.

Signed-off-by: Sebastiaan van Stijn <[email protected]>
While this was convenient for our use, it's somewhat unexpected for a function
that writes a file to also create all parent directories; even more because
this function may be executed as root.

This patch makes the package more "safe" to use as a generic package by removing
this functionality, and leaving it up to the caller to create parent directories,
if needed.

Signed-off-by: Sebastiaan van Stijn <[email protected]>
This allows consumers to read back the pidFile and to check if the
PID is still running.

Signed-off-by: Sebastiaan van Stijn <[email protected]>
…file

Also updated a variable name that collided with a package const.

Signed-off-by: Sebastiaan van Stijn <[email protected]>
@thaJeztah
Copy link
Copy Markdown
Member Author

Let me bring this one in 👍

@thaJeztah thaJeztah merged commit 4f3c5b2 into moby:master Nov 5, 2022
@thaJeztah thaJeztah deleted the sys_move_process branch November 5, 2022 17:41
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

kind/refactor PR's that refactor, or clean-up code status/2-code-review

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants